diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-04-24 22:45:19 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-04-24 22:45:19 +0000 |
commit | 028e1ebc4a392572cae586d0e9044a32b867cba4 (patch) | |
tree | 36d3a748486feb3f41575708bef8b153fef2cad4 /libs/surfaces | |
parent | 484debb45c5ea45bccf0f9cb05b1239a9c2244a3 (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/SConscript | 2 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.cc | 10 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.h | 4 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/interface.cc | 2 | ||||
-rw-r--r-- | libs/surfaces/tranzport/SConscript | 2 | ||||
-rw-r--r-- | libs/surfaces/tranzport/interface.cc | 2 | ||||
-rw-r--r-- | libs/surfaces/tranzport/tranzport_control_protocol.cc | 730 | ||||
-rw-r--r-- | libs/surfaces/tranzport/tranzport_control_protocol.h | 77 |
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 (¤t_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, ¤t_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, ¤t_screen[row][base_col], 4)) { - - /* different, so update */ - - memcpy (¤t_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 |