summaryrefslogtreecommitdiff
path: root/libs/surfaces
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-04-24 22:45:19 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-04-24 22:45:19 +0000
commit028e1ebc4a392572cae586d0e9044a32b867cba4 (patch)
tree36d3a748486feb3f41575708bef8b153fef2cad4 /libs/surfaces
parent484debb45c5ea45bccf0f9cb05b1239a9c2244a3 (diff)
a) completely refactor abstract UI code
b) single-thread Tranzport implementation c) implement BasicUI to share functionality across multiple controllers d) various minor fixes here and there git-svn-id: svn://localhost/trunk/ardour2@468 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces')
-rw-r--r--libs/surfaces/generic_midi/SConscript2
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc10
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h4
-rw-r--r--libs/surfaces/generic_midi/interface.cc2
-rw-r--r--libs/surfaces/tranzport/SConscript2
-rw-r--r--libs/surfaces/tranzport/interface.cc2
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.cc730
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.h77
8 files changed, 503 insertions, 326 deletions
diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript
index 51e0ff88c8..7e6ef1cf85 100644
--- a/libs/surfaces/generic_midi/SConscript
+++ b/libs/surfaces/generic_midi/SConscript
@@ -46,6 +46,8 @@ Default(libardour_genericmidi)
if env['NLS']:
i18n (genericmidi, genericmidi_files, env)
+env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_genericmidi))
+
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
genericmidi_files +
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 61a8b7974e..86f8934c05 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -22,10 +22,10 @@ GenericMidiControlProtocol::~GenericMidiControlProtocol ()
}
int
-GenericMidiControlProtocol::init ()
+GenericMidiControlProtocol::set_active (bool yn)
{
/* start delivery/outbound thread */
- return init_thread ();
+ return 0;
}
void
@@ -63,9 +63,3 @@ GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes)
}
}
-bool
-GenericMidiControlProtocol::active() const
-{
- return _port && send();
-}
-
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
index 54831b2982..ec789815f1 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
@@ -14,9 +14,7 @@ class GenericMidiControlProtocol : public ControlProtocol {
GenericMidiControlProtocol (Session&);
virtual ~GenericMidiControlProtocol();
- int init ();
-
- bool active() const;
+ int set_active (bool yn);
void set_port (MIDI::Port*);
MIDI::Port* port () const { return _port; }
diff --git a/libs/surfaces/generic_midi/interface.cc b/libs/surfaces/generic_midi/interface.cc
index 500d745deb..8fb50cdaae 100644
--- a/libs/surfaces/generic_midi/interface.cc
+++ b/libs/surfaces/generic_midi/interface.cc
@@ -9,7 +9,7 @@ new_generic_midi_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
GenericMidiControlProtocol* gmcp = new GenericMidiControlProtocol (*s);
- if (gmcp->init ()) {
+ if (gmcp->set_active (true)) {
delete gmcp;
return 0;
}
diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript
index e43f0bc77c..2739f17614 100644
--- a/libs/surfaces/tranzport/SConscript
+++ b/libs/surfaces/tranzport/SConscript
@@ -46,6 +46,8 @@ Default(libardour_tranzport)
if env['NLS']:
i18n (tranzport, tranzport_files, env)
+env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_tranzport))
+
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
tranzport_files +
diff --git a/libs/surfaces/tranzport/interface.cc b/libs/surfaces/tranzport/interface.cc
index f2160c3144..ab9c93348b 100644
--- a/libs/surfaces/tranzport/interface.cc
+++ b/libs/surfaces/tranzport/interface.cc
@@ -9,7 +9,7 @@ new_tranzport_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
TranzportControlProtocol* tcp = new TranzportControlProtocol (*s);
- if (tcp->init ()) {
+ if (tcp->set_active (true)) {
delete tcp;
return 0;
}
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc
index 6760caac63..a0f04443ef 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.cc
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc
@@ -1,7 +1,29 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
#include <iostream>
#include <algorithm>
+#include <float.h>
#include <sys/time.h>
+#include <errno.h>
#include <pbd/pthread_utils.h>
@@ -19,8 +41,16 @@ using namespace sigc;
#include "i18n.h"
+#include <pbd/abstract_ui.cc>
+
+BaseUI::RequestType LEDChange = BaseUI::new_request_type ();
+BaseUI::RequestType Print = BaseUI::new_request_type ();
+BaseUI::RequestType SetCurrentTrack = BaseUI::new_request_type ();
+
TranzportControlProtocol::TranzportControlProtocol (Session& s)
- : ControlProtocol (s, _("Tranzport"))
+ : ControlProtocol (s, X_("Tranzport")),
+ AbstractUI<TranzportRequest> (X_("Tranzport"), false)
+
{
timeout = 60000;
buttonmask = 0;
@@ -34,91 +64,78 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s)
wheel_shift_mode = WheelShiftGain;
timerclear (&last_wheel_motion);
last_wheel_dir = 1;
+ last_track_gain = FLT_MAX;
display_mode = DisplayNormal;
- requested_display_mode = display_mode;
memset (current_screen, 0, sizeof (current_screen));
+ memset (pending_screen, 0, sizeof (pending_screen));
for (uint32_t i = 0; i < sizeof(lights)/sizeof(lights[0]); ++i) {
lights[i] = false;
}
- session.RecordStateChanged.connect (mem_fun (*this, &TranzportControlProtocol::record_status_changed));
+ for (uint32_t i = 0; i < sizeof(pending_lights)/sizeof(pending_lights[0]); ++i) {
+ pending_lights[i] = false;
+ }
}
TranzportControlProtocol::~TranzportControlProtocol ()
{
- if (udev) {
- pthread_cancel_one (thread);
- lcd_clear ();
- close ();
- }
+ set_active (false);
}
int
-TranzportControlProtocol::init ()
+TranzportControlProtocol::set_active (bool yn)
{
- if (open ()) {
- return -1;
- }
+ if (yn != _active) {
- lcd_clear ();
- lights_off ();
-
- show_wheel_mode();
- next_track ();
- show_transport_time ();
+ if (yn) {
- /* outbound thread */
+ if (open ()) {
+ return -1;
+ }
+
+ if (pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _monitor_work, this) == 0) {
+ _active = true;
+ } else {
+ return -1;
+ }
- init_thread ();
+ } else {
- /* inbound thread */
-
- pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _monitor_work, this);
+ pthread_cancel_one (thread);
+ lcd_clear ();
+ close ();
+ _active = false;
+ }
+ }
return 0;
}
-bool
-TranzportControlProtocol::active() const
-{
- return true;
-}
-
void
-TranzportControlProtocol::send_route_feedback (list<Route*>& routes)
+TranzportControlProtocol::show_track_gain ()
{
+ if (current_route) {
+ gain_t g = current_route->gain();
+ if (g != last_track_gain) {
+ char buf[16];
+ snprintf (buf, sizeof (buf), "%6.1fdB", coefficient_to_dB (current_route->gain()));
+ print (0, 9, buf);
+ last_track_gain = g;
+ }
+ } else {
+ print (0, 9, " ");
+ }
}
void
-TranzportControlProtocol::send_global_feedback ()
+TranzportControlProtocol::normal_update ()
{
- if (requested_display_mode != display_mode) {
- switch (requested_display_mode) {
- case DisplayNormal:
- enter_normal_display_mode ();
- break;
- case DisplayBigMeter:
- enter_big_meter_mode ();
- break;
- }
- }
-
- switch (display_mode) {
- case DisplayBigMeter:
- show_meter ();
- break;
-
- case DisplayNormal:
- show_transport_time ();
- if (session.soloing()) {
- light_on (LightAnysolo);
- } else {
- light_off (LightAnysolo);
- }
- break;
- }
+ show_current_track ();
+ show_transport_time ();
+ show_track_gain ();
+ show_wheel_mode ();
}
void
@@ -126,11 +143,11 @@ TranzportControlProtocol::next_display_mode ()
{
switch (display_mode) {
case DisplayNormal:
- requested_display_mode = DisplayBigMeter;
+ display_mode = DisplayBigMeter;
break;
case DisplayBigMeter:
- requested_display_mode = DisplayNormal;
+ display_mode = DisplayNormal;
break;
}
}
@@ -147,11 +164,14 @@ TranzportControlProtocol::enter_big_meter_mode ()
void
TranzportControlProtocol::enter_normal_display_mode ()
{
+ last_where += 1; /* force time redisplay */
+ last_track_gain = FLT_MAX; /* force gain redisplay */
+
lcd_clear ();
lights_off ();
show_current_track ();
show_wheel_mode ();
- last_where += 1; /* force time redisplay */
+ show_wheel_mode ();
show_transport_time ();
display_mode = DisplayNormal;
}
@@ -205,7 +225,7 @@ TranzportControlProtocol::show_meter ()
uint32_t fill = (uint32_t) floor (fraction * 40);
char buf[21];
- int i;
+ uint32_t i;
if (fill == last_meter_fill) {
/* nothing to do */
@@ -286,20 +306,6 @@ TranzportControlProtocol::_monitor_work (void* arg)
return static_cast<TranzportControlProtocol*>(arg)->monitor_work ();
}
-void*
-TranzportControlProtocol::monitor_work ()
-{
- PBD::ThreadCreated (pthread_self(), X_("tranzport monitor"));
-
- while (true) {
- if (read ()) {
- break;
- }
- }
-
- return 0;
-}
-
int
TranzportControlProtocol::open ()
{
@@ -366,6 +372,7 @@ TranzportControlProtocol::close ()
if (usb_close (udev)) {
error << _("Tranzport: cannot close device") << endmsg;
+ udev = 0;
ret = 0;
}
@@ -377,10 +384,7 @@ TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
{
int val;
- {
- LockMonitor lm (write_lock, __LINE__, __FILE__);
- val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout);
- }
+ val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout);
if (val < 0)
return val;
@@ -405,29 +409,56 @@ TranzportControlProtocol::lcd_clear ()
cmd[6] = ' ';
cmd[7] = 0x00;
- {
- LockMonitor lp (print_lock, __LINE__, __FILE__);
- LockMonitor lw (write_lock, __LINE__, __FILE__);
-
- for (uint8_t i = 0; i < 10; ++i) {
- cmd[2] = i;
- usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, 500);
- }
-
- memset (current_screen, ' ', sizeof (current_screen));
+ for (uint8_t i = 0; i < 10; ++i) {
+ cmd[2] = i;
+ usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, 500);
}
+
+ memset (current_screen, ' ', sizeof (current_screen));
+ memset (pending_screen, ' ', sizeof (pending_screen));
}
void
TranzportControlProtocol::lights_off ()
{
- light_off (LightRecord);
- light_off (LightTrackrec);
- light_off (LightTrackmute);
- light_off (LightTracksolo);
- light_off (LightAnysolo);
- light_off (LightLoop);
- light_off (LightPunch);
+ uint8_t cmd[8];
+
+ cmd[0] = 0x00;
+ cmd[1] = 0x00;
+ cmd[3] = 0x00;
+ cmd[4] = 0x00;
+ cmd[5] = 0x00;
+ cmd[6] = 0x00;
+ cmd[7] = 0x00;
+
+ cmd[2] = LightRecord;
+ if (write (cmd, 500) == 0) {
+ lights[LightRecord] = false;
+ }
+ cmd[2] = LightTrackrec;
+ if (write (cmd, 500) == 0) {
+ lights[LightTrackrec] = false;
+ }
+ cmd[2] = LightTrackmute;
+ if (write (cmd, 500) == 0) {
+ lights[LightTrackmute] = false;
+ }
+ cmd[2] = LightTracksolo;
+ if (write (cmd, 500) == 0) {
+ lights[LightTracksolo] = false;
+ }
+ cmd[2] = LightAnysolo;
+ if (write (cmd, 500) == 0) {
+ lights[LightAnysolo] = false;
+ }
+ cmd[2] = LightLoop;
+ if (write (cmd, 500) == 0) {
+ lights[LightLoop] = false;
+ }
+ cmd[2] = LightPunch;
+ if (write (cmd, 500) == 0) {
+ lights[LightPunch] = false;
+ }
}
int
@@ -486,25 +517,250 @@ TranzportControlProtocol::light_off (LightID light)
}
}
-int
-TranzportControlProtocol::read (uint32_t timeout_override)
+void*
+TranzportControlProtocol::monitor_work ()
{
+ struct sched_param rtparam;
+ int err;
uint8_t buf[8];
int val;
- memset(buf, 0, 8);
- again:
- val = usb_interrupt_read(udev, READ_ENDPOINT, (char*) buf, 8, timeout_override ? timeout_override : timeout);
- if (val < 0) {
- return val;
+ PBD::ThreadCreated (pthread_self(), X_("Tranzport"));
+
+ memset (&rtparam, 0, sizeof (rtparam));
+ rtparam.sched_priority = 3; /* XXX should be relative to audio (JACK) thread */
+
+ if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
+ // do we care? not particularly.
+ info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), BaseUI::name(), strerror (errno)) << endmsg;
+ }
+
+ pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
+
+ /* set initial state */
+
+ lcd_clear ();
+ lights_off ();
+
+ show_wheel_mode();
+ next_track ();
+ show_transport_time ();
+
+ while (true) {
+
+ /* bInterval for this beastie is 10ms */
+
+ pthread_testcancel();
+ usleep (20000);
+ pthread_testcancel();
+
+ /* anything to read ? */
+
+ val = usb_interrupt_read (udev, READ_ENDPOINT, (char*) buf, 8, 0);
+
+ /* any requests to handle? */
+
+ handle_ui_requests ();
+
+ if (val == 8) {
+ process (buf);
+ }
+
+ /* update whatever needs updating */
+
+ update_state ();
}
- if (val != 8) {
- if (val == 0) {
- goto again;
+
+ return (void*) 0;
+}
+
+int
+TranzportControlProtocol::update_state ()
+{
+ int row;
+ int col_base;
+ int col;
+ int cell;
+
+ /* do the text updates */
+
+ switch (display_mode) {
+ case DisplayBigMeter:
+ show_meter ();
+ break;
+
+ case DisplayNormal:
+ normal_update ();
+ break;
+ }
+
+ /* next: flush LCD */
+
+ cell = 0;
+
+ for (row = 0; row < 2; ++row) {
+
+ for (col_base = 0, col = 0; col < 20; ) {
+
+ if (pending_screen[row][col] != current_screen[row][col]) {
+
+ /* something in this cell is different, so dump the cell
+ to the device.
+ */
+
+ uint8_t cmd[8];
+
+ cmd[0] = 0x00;
+ cmd[1] = 0x01;
+ cmd[2] = cell;
+ cmd[3] = pending_screen[row][col_base];
+ cmd[4] = pending_screen[row][col_base+1];
+ cmd[5] = pending_screen[row][col_base+2];
+ cmd[6] = pending_screen[row][col_base+3];
+ cmd[7] = 0x00;
+
+ if (usb_interrupt_write (udev, WRITE_ENDPOINT, (char *) cmd, 8, 500) == 8) {
+ /* successful write: copy to current */
+ memcpy (&current_screen[row][col_base], &pending_screen[row][col_base], 4);
+ }
+
+ /* skip the rest of the 4 character cell since we wrote+copied it already */
+
+ col_base += 4;
+ col = col_base;
+ cell++;
+
+ } else {
+
+ col++;
+
+ if (col && col % 4 == 0) {
+ cell++;
+ col_base += 4;
+ }
+ }
}
- return -1;
}
+ /* now update LED's */
+
+ /* per track */
+
+ if (current_route) {
+ AudioTrack* at = dynamic_cast<AudioTrack*> (current_route);
+ if (at && at->record_enabled()) {
+ pending_lights[LightTrackrec] = true;
+ } else {
+ pending_lights[LightTrackrec] = false;
+ }
+ if (current_route->muted()) {
+ pending_lights[LightTrackmute] = true;
+ } else {
+ pending_lights[LightTrackmute] = false;
+ }
+ if (current_route->soloed()) {
+ pending_lights[LightTracksolo] = true;
+ } else {
+ pending_lights[LightTracksolo] = false;
+ }
+
+ } else {
+ pending_lights[LightTrackrec] = false;
+ pending_lights[LightTracksolo] = false;
+ pending_lights[LightTrackmute] = false;
+ }
+
+ /* global */
+
+ if (session.get_auto_loop()) {
+ pending_lights[LightLoop] = true;
+ } else {
+ pending_lights[LightLoop] = false;
+ }
+
+ if (session.get_punch_in() || session.get_punch_out()) {
+ pending_lights[LightPunch] = true;
+ } else {
+ pending_lights[LightPunch] = false;
+ }
+
+ if (session.get_record_enabled()) {
+ pending_lights[LightRecord] = true;
+ } else {
+ pending_lights[LightRecord] = false;
+ }
+
+ if (session.soloing ()) {
+ pending_lights[LightAnysolo] = true;
+ } else {
+ pending_lights[LightAnysolo] = false;
+ }
+
+ /* flush changed light change */
+
+ if (pending_lights[LightRecord] != lights[LightRecord]) {
+ if (pending_lights[LightRecord]) {
+ light_on (LightRecord);
+ } else {
+ light_off (LightRecord);
+ }
+ }
+
+ if (pending_lights[LightTracksolo] != lights[LightTracksolo]) {
+ if (pending_lights[LightTracksolo]) {
+ light_on (LightTracksolo);
+ } else {
+ light_off (LightTracksolo);
+ }
+ }
+
+ if (pending_lights[LightTrackmute] != lights[LightTrackmute]) {
+ if (pending_lights[LightTrackmute]) {
+ light_on (LightTrackmute);
+ } else {
+ light_off (LightTrackmute);
+ }
+ }
+
+ if (pending_lights[LightTracksolo] != lights[LightTracksolo]) {
+ if (pending_lights[LightTracksolo]) {
+ light_on (LightTracksolo);
+ } else {
+ light_off (LightTracksolo);
+ }
+ }
+
+ if (pending_lights[LightAnysolo] != lights[LightAnysolo]) {
+ if (pending_lights[LightAnysolo]) {
+ light_on (LightAnysolo);
+ } else {
+ light_off (LightAnysolo);
+ }
+ }
+
+ if (pending_lights[LightLoop] != lights[LightLoop]) {
+ if (pending_lights[LightLoop]) {
+ light_on (LightLoop);
+ } else {
+ light_off (LightLoop);
+ }
+ }
+
+ if (pending_lights[LightPunch] != lights[LightPunch]) {
+ if (pending_lights[LightPunch]) {
+ light_on (LightPunch);
+ } else {
+ light_off (LightPunch);
+ }
+ }
+
+ return 0;
+}
+
+int
+TranzportControlProtocol::process (uint8_t* buf)
+{
// printf("read: %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
uint32_t this_button_mask;
@@ -672,87 +928,14 @@ TranzportControlProtocol::read (uint32_t timeout_override)
void
TranzportControlProtocol::show_current_track ()
{
- for (vector<sigc::connection>::iterator i = track_connections.begin(); i != track_connections.end(); ++i) {
- (*i).disconnect ();
- }
- track_connections.clear ();
-
if (current_route == 0) {
print (0, 0, "--------");
- return;
- }
-
- string name = current_route->name();
-
- print (0, 0, name.substr (0, 8).c_str());
-
- track_solo_changed (0);
- track_mute_changed (0);
- track_rec_changed (0);
-
- track_connections.push_back (current_route->solo_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_solo_changed)));
- track_connections.push_back (current_route->mute_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_mute_changed)));
- track_connections.push_back (current_route->record_enable_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_rec_changed)));
- track_connections.push_back (current_route->gain_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_gain_changed)));
-}
-
-void
-TranzportControlProtocol::record_status_changed ()
-{
- if (session.get_record_enabled()) {
- light_on (LightRecord);
- } else {
- light_off (LightRecord);
- }
-}
-
-void
-TranzportControlProtocol::track_gain_changed (void* ignored)
-{
- char buf[8];
-
- switch (display_mode) {
- case DisplayNormal:
- snprintf (buf, sizeof (buf), "%.1fdB", coefficient_to_dB (current_route->gain()));
- print (0, 9, buf);
- break;
- default:
- break;
- }
-}
-
-void
-TranzportControlProtocol::track_solo_changed (void* ignored)
-{
- if (current_route->soloed()) {
- light_on (LightTracksolo);
- } else {
- light_off (LightTracksolo);
- }
-}
-
-void
-TranzportControlProtocol::track_mute_changed (void *ignored)
-{
- if (current_route->muted()) {
- light_on (LightTrackmute);
} else {
- light_off (LightTrackmute);
+ print (0, 0, current_route->name().substr (0, 8).c_str());
}
}
void
-TranzportControlProtocol::track_rec_changed (void *ignored)
-{
- if (current_route->record_enabled()) {
- light_on (LightTrackrec);
- } else {
- light_off (LightTrackrec);
- }
-}
-
-
-void
TranzportControlProtocol::button_event_battery_press (bool shifted)
{
}
@@ -798,11 +981,7 @@ void
TranzportControlProtocol::button_event_trackrec_press (bool shifted)
{
if (shifted) {
- if (session.get_record_enabled()) {
- session.record_disenable_all ();
- } else {
- session.record_enable_all ();
- }
+ toggle_all_rec_enables ();
} else {
if (current_route) {
AudioTrack* at = dynamic_cast<AudioTrack*>(current_route);
@@ -855,9 +1034,9 @@ void
TranzportControlProtocol::button_event_undo_press (bool shifted)
{
if (shifted) {
- session.redo (1);
+ redo ();
} else {
- session.undo (1);
+ undo ();
}
}
@@ -907,6 +1086,8 @@ TranzportControlProtocol::button_event_loop_press (bool shifted)
{
if (shifted) {
next_wheel_shift_mode ();
+ } else {
+ loop_toggle ();
}
}
@@ -933,8 +1114,7 @@ TranzportControlProtocol::button_event_prev_release (bool shifted)
void
TranzportControlProtocol::button_event_add_press (bool shifted)
{
- jack_nframes_t when = session.audible_frame();
- session.locations()->add (new Location (when, when, _("unnamed"), Location::IsMark));
+ add_marker ();
}
void
@@ -961,9 +1141,9 @@ void
TranzportControlProtocol::button_event_rewind_press (bool shifted)
{
if (shifted) {
- session.goto_start ();
+ goto_start ();
} else {
- session.request_transport_speed (-2.0f);
+ rewind ();
}
}
@@ -976,9 +1156,10 @@ void
TranzportControlProtocol::button_event_fastforward_press (bool shifted)
{
if (shifted) {
- session.goto_end();
+ goto_end ();
} else {
- session.request_transport_speed (2.0f);}
+ ffwd ();
+ }
}
void
@@ -992,7 +1173,7 @@ TranzportControlProtocol::button_event_stop_press (bool shifted)
if (shifted) {
next_display_mode ();
} else {
- session.request_transport_speed (0.0);
+ transport_stop ();
}
}
@@ -1004,7 +1185,7 @@ TranzportControlProtocol::button_event_stop_release (bool shifted)
void
TranzportControlProtocol::button_event_play_press (bool shifted)
{
- session.request_transport_speed (1.0);
+ transport_play ();
}
void
@@ -1016,22 +1197,9 @@ void
TranzportControlProtocol::button_event_record_press (bool shifted)
{
if (shifted) {
- session.save_state ("");
+ save_state ();
} else {
- switch (session.record_status()) {
- case Session::Disabled:
- if (session.ntracks() == 0) {
- // string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
- // MessageDialog msg (*editor, txt);
- // msg.run ();
- return;
- }
- session.maybe_enable_record ();
- break;
- case Session::Recording:
- case Session::Enabled:
- session.disable_record (true);
- }
+ rec_enable_toggle ();
}
}
@@ -1139,7 +1307,7 @@ TranzportControlProtocol::scrub ()
if (dir != last_wheel_dir) {
/* changed direction, start over */
- speed = 1.0f;
+ speed = 0.1f;
} else {
if (timerisset (&last_wheel_motion)) {
@@ -1160,7 +1328,7 @@ TranzportControlProtocol::scrub ()
last_wheel_motion = now;
last_wheel_dir = dir;
- session.request_transport_speed (speed * dir);
+ move_at (speed * dir);
}
void
@@ -1246,33 +1414,11 @@ TranzportControlProtocol::next_wheel_mode ()
}
void
-TranzportControlProtocol::next_marker ()
-{
- Location *location = session.locations()->first_location_after (session.transport_frame());
-
- if (location) {
- session.request_locate (location->start(), session.transport_rolling());
- } else {
- session.request_locate (session.current_end_frame());
- }
-}
-
-void
-TranzportControlProtocol::prev_marker ()
-{
- Location *location = session.locations()->first_location_before (session.transport_frame());
-
- if (location) {
- session.request_locate (location->start(), session.transport_rolling());
- } else {
- session.goto_start ();
- }
-}
-
-void
TranzportControlProtocol::next_track ()
{
uint32_t limit = session.nroutes();
+ uint32_t start = current_track_id;
+ Route* cr = current_route;
if (current_track_id == limit) {
current_track_id = 0;
@@ -1281,7 +1427,7 @@ TranzportControlProtocol::next_track ()
}
while (current_track_id < limit) {
- if ((current_route = session.route_by_remote_id (current_track_id)) != 0) {
+ if ((cr = session.route_by_remote_id (current_track_id)) != 0) {
break;
}
current_track_id++;
@@ -1289,14 +1435,24 @@ TranzportControlProtocol::next_track ()
if (current_track_id == limit) {
current_track_id = 0;
+ while (current_track_id != start) {
+ if ((cr = session.route_by_remote_id (current_track_id)) != 0) {
+ break;
+ }
+ current_track_id++;
+ }
}
- show_current_track ();
+ current_route = cr;
}
void
TranzportControlProtocol::prev_track ()
{
+ uint32_t limit = session.nroutes() - 1;
+ uint32_t start = current_track_id;
+ Route* cr = current_route;
+
if (current_track_id == 0) {
current_track_id = session.nroutes() - 1;
} else {
@@ -1304,17 +1460,37 @@ TranzportControlProtocol::prev_track ()
}
while (current_track_id >= 0) {
- if ((current_route = session.route_by_remote_id (current_track_id)) != 0) {
+ if ((cr = session.route_by_remote_id (current_track_id)) != 0) {
break;
}
current_track_id--;
}
if (current_track_id < 0) {
- current_track_id = 0;
+ current_track_id = limit;
+ while (current_track_id > start) {
+ if ((cr = session.route_by_remote_id (current_track_id)) != 0) {
+ break;
+ }
+ current_track_id--;
+ }
}
- show_current_track ();
+ current_route = cr;
+}
+
+void
+TranzportControlProtocol::set_current_track (Route* r)
+{
+ TranzportRequest* req = get_request (SetCurrentTrack);
+
+ if (req == 0) {
+ return;
+ }
+
+ req->track = r;
+
+ send_request (req);
}
void
@@ -1390,46 +1566,38 @@ TranzportControlProtocol::print (int row, int col, const char *text)
int offset = col % 4;
- {
-
- LockMonitor lm (print_lock, __LINE__, __FILE__);
-
- /* copy current cell contents into tmp */
-
- memcpy (tmp, &current_screen[row][base_col], 4);
-
- /* overwrite with new text */
-
- uint32_t tocopy = min ((4U - offset), left);
-
- memcpy (tmp+offset, text, tocopy);
-
- uint8_t cmd[8];
-
- /* compare with current screen */
-
- if (memcmp (tmp, &current_screen[row][base_col], 4)) {
-
- /* different, so update */
-
- memcpy (&current_screen[row][base_col], tmp, 4);
-
- cmd[0] = 0x00;
- cmd[1] = 0x01;
- cmd[2] = cell + (row * 5);
- cmd[3] = tmp[0];
- cmd[4] = tmp[1];
- cmd[5] = tmp[2];
- cmd[6] = tmp[3];
- cmd[7] = 0x00;
-
- write (cmd, 500);
- }
-
- text += tocopy;
- left -= tocopy;
- col += tocopy;
- }
+ /* copy current cell contents into tmp */
+
+ memcpy (tmp, &pending_screen[row][base_col], 4);
+
+ /* overwrite with new text */
+
+ uint32_t tocopy = min ((4U - offset), left);
+
+ memcpy (tmp+offset, text, tocopy);
+
+ /* copy it back to pending */
+
+ memcpy (&pending_screen[row][base_col], tmp, 4);
+
+ text += tocopy;
+ left -= tocopy;
+ col += tocopy;
}
}
+bool
+TranzportControlProtocol::caller_is_ui_thread ()
+{
+ return (pthread_self() == thread);
+}
+
+void
+TranzportControlProtocol::do_request (TranzportRequest* req)
+{
+ if (req->type == SetCurrentTrack) {
+ current_route = req->track;
+ }
+
+ return;
+}
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.h b/libs/surfaces/tranzport/tranzport_control_protocol.h
index 925ac72e2a..cf4a9a7d3f 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.h
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.h
@@ -10,18 +10,29 @@
#include <ardour/control_protocol.h>
#include <ardour/types.h>
-namespace ARDOUR {
+#include <pbd/abstract_ui.h>
+
+extern BaseUI::RequestType LEDChange;
+extern BaseUI::RequestType Print;
+extern BaseUI::RequestType SetCurrentTrack;
+
+struct TranzportRequest : public BaseUI::BaseRequestObject {
+ int led;
+ int row;
+ int col;
+ char* text;
+ ARDOUR::Route* track;
+};
-class TranzportControlProtocol : public ControlProtocol {
+class TranzportControlProtocol : public ARDOUR::ControlProtocol, public AbstractUI<TranzportRequest>
+{
public:
- TranzportControlProtocol (Session&);
+ TranzportControlProtocol (ARDOUR::Session&);
virtual ~TranzportControlProtocol();
- int init ();
- bool active() const;
+ int set_active (bool yn);
- void send_route_feedback (std::list<Route*>&);
- void send_global_feedback ();
+ bool caller_is_ui_thread();
private:
static const int VENDORID = 0x165b;
@@ -89,29 +100,32 @@ class TranzportControlProtocol : public ControlProtocol {
uint8_t _datawheel;
uint8_t _device_status;
usb_dev_handle* udev;
- Route* current_route;
+ ARDOUR::Route* current_route;
uint32_t current_track_id;
- char current_screen[2][20];
- bool lights[7];
WheelMode wheel_mode;
WheelShiftMode wheel_shift_mode;
- struct timeval last_wheel_motion;
- int last_wheel_dir;
DisplayMode display_mode;
- DisplayMode requested_display_mode;
- uint32_t last_meter_fill;
-
- std::vector<sigc::connection> track_connections;
- bool last_negative;
- uint32_t last_hrs;
- uint32_t last_mins;
- uint32_t last_secs;
- uint32_t last_frames;
+ void do_request (TranzportRequest*);
+
+ PBD::Lock update_lock;
+ char current_screen[2][20];
+ char pending_screen[2][20];
+ bool lights[7];
+ bool pending_lights[7];
+
+ bool last_negative;
+ uint32_t last_hrs;
+ uint32_t last_mins;
+ uint32_t last_secs;
+ uint32_t last_frames;
jack_nframes_t last_where;
+ ARDOUR::gain_t last_track_gain;
+ uint32_t last_meter_fill;
+ struct timeval last_wheel_motion;
+ int last_wheel_dir;
- PBD::Lock write_lock;
- PBD::Lock print_lock;
+ PBD::Lock io_lock;
int open ();
int read (uint32_t timeout_override = 0);
@@ -128,21 +142,19 @@ class TranzportControlProtocol : public ControlProtocol {
void enter_big_meter_mode ();
void enter_normal_display_mode ();
+
void next_display_mode ();
+ void normal_update ();
+
void show_current_track ();
+ void show_track_gain ();
void show_transport_time ();
void show_wheel_mode ();
void show_gain ();
void show_pan ();
void show_meter ();
- void track_solo_changed (void*);
- void track_rec_changed (void*);
- void track_mute_changed (void*);
- void track_gain_changed (void*);
- void record_status_changed ();
-
void datawheel ();
void scrub ();
void scroll ();
@@ -151,10 +163,9 @@ class TranzportControlProtocol : public ControlProtocol {
void next_wheel_mode ();
void next_wheel_shift_mode ();
+ void set_current_track (ARDOUR::Route*);
void next_track ();
void prev_track ();
- void next_marker ();
- void prev_marker ();
void step_gain_up ();
void step_gain_down ();
void step_pan_right ();
@@ -203,8 +214,10 @@ class TranzportControlProtocol : public ControlProtocol {
void button_event_play_release (bool shifted);
void button_event_record_press (bool shifted);
void button_event_record_release (bool shifted);
+
+ int process (uint8_t *);
+ int update_state();
};
-} // namespace
#endif // ardour_tranzport_control_protocol_h