From 2a310e5f798e7921715cd11e17e61327d2614e6d Mon Sep 17 00:00:00 2001 From: Ben Loftis Date: Thu, 19 Oct 2017 11:53:08 -0500 Subject: [PATCH] US2400: Mark controls dirty and send them from the periodic update thread. --- libs/surfaces/us2400/button.h | 2 + libs/surfaces/us2400/controls.h | 2 + libs/surfaces/us2400/fader.h | 2 + libs/surfaces/us2400/led.cc | 5 +- libs/surfaces/us2400/led.h | 8 ++-- libs/surfaces/us2400/meter.h | 2 + libs/surfaces/us2400/pot.h | 2 + libs/surfaces/us2400/strip.cc | 38 +++++++++------ libs/surfaces/us2400/strip.h | 6 ++- libs/surfaces/us2400/surface.cc | 13 ++++-- libs/surfaces/us2400/surface_port.cc | 3 +- .../us2400/us2400_control_protocol.cc | 46 +++++++++---------- 12 files changed, 74 insertions(+), 55 deletions(-) diff --git a/libs/surfaces/us2400/button.h b/libs/surfaces/us2400/button.h index 182e88fefc..9091fb21e5 100644 --- a/libs/surfaces/us2400/button.h +++ b/libs/surfaces/us2400/button.h @@ -104,6 +104,8 @@ public: Surface& surface() const { return _surface; } + void mark_dirty() { _led.mark_dirty(); } + void pressed (); void released (); diff --git a/libs/surfaces/us2400/controls.h b/libs/surfaces/us2400/controls.h index 11e27b2ac5..1dcc5e4131 100644 --- a/libs/surfaces/us2400/controls.h +++ b/libs/surfaces/us2400/controls.h @@ -71,6 +71,8 @@ public: virtual void set_control (boost::shared_ptr); virtual void reset_control () { normal_ac.reset(); } + virtual void mark_dirty() = 0; + float get_value (); void set_value (float val, PBD::Controllable::GroupControlDisposition gcd = PBD::Controllable::UseGroup); diff --git a/libs/surfaces/us2400/fader.h b/libs/surfaces/us2400/fader.h index 169cf454d4..2a3c99e9fc 100644 --- a/libs/surfaces/us2400/fader.h +++ b/libs/surfaces/us2400/fader.h @@ -26,6 +26,8 @@ class Fader : public Control static Control* factory (Surface&, int id, const char*, Group&); + void mark_dirty() { last_update_position = llast_update_position = -1; } + private: float position; int last_update_position; diff --git a/libs/surfaces/us2400/led.cc b/libs/surfaces/us2400/led.cc index 49466ad957..8b85fc7f20 100644 --- a/libs/surfaces/us2400/led.cc +++ b/libs/surfaces/us2400/led.cc @@ -52,12 +52,9 @@ Led::set_state (LedState new_state) llast_state = last_state; last_state = new_state; - - state = new_state; - MIDI::byte msg = 0; - switch (state.state()) { + switch (new_state.state()) { case LedState::on: msg = 0x7f; break; diff --git a/libs/surfaces/us2400/led.h b/libs/surfaces/us2400/led.h index 4ef4660d55..1259723878 100644 --- a/libs/surfaces/us2400/led.h +++ b/libs/surfaces/us2400/led.h @@ -41,12 +41,13 @@ public: Led (int id, std::string name, Group & group) : Control (id, name, group) - , state (off) - , last_state (off) - , llast_state (on) + , last_state (none) + , llast_state (none) { } + void mark_dirty() { last_state = llast_state = none; } + Led & led() { return *this; } MidiByteArray set_state (LedState); @@ -55,7 +56,6 @@ public: static Control* factory (Surface&, int id, const char*, Group&); private: - LedState state; LedState last_state; LedState llast_state; }; diff --git a/libs/surfaces/us2400/meter.h b/libs/surfaces/us2400/meter.h index 0ef9e78c33..41028d14ae 100644 --- a/libs/surfaces/us2400/meter.h +++ b/libs/surfaces/us2400/meter.h @@ -46,6 +46,8 @@ public: void send_update (Surface&, float dB); bool enabled () const { return _enabled; } + void mark_dirty() {} + MidiByteArray zero(); static Control* factory (Surface&, int id, const char*, Group&); diff --git a/libs/surfaces/us2400/pot.h b/libs/surfaces/us2400/pot.h index 1ee1142fa1..1bd8a5c257 100644 --- a/libs/surfaces/us2400/pot.h +++ b/libs/surfaces/us2400/pot.h @@ -51,6 +51,8 @@ public: static Control* factory (Surface&, int id, const char*, Group&); + void mark_dirty() { last_update_position = llast_update_position = -1; } + int last_update_position; int llast_update_position; diff --git a/libs/surfaces/us2400/strip.cc b/libs/surfaces/us2400/strip.cc index 185f49ca52..9071601620 100644 --- a/libs/surfaces/us2400/strip.cc +++ b/libs/surfaces/us2400/strip.cc @@ -171,18 +171,9 @@ Strip::set_stripable (boost::shared_ptr r, bool /*with_messages*/) _fader->set_control (boost::shared_ptr()); _vpot->set_control (boost::shared_ptr()); - _surface->write (_solo->set_state(on)); - _surface->write (_solo->set_state(off)); - - _surface->write (_mute->set_state(on)); - _surface->write (_mute->set_state(off)); - - _surface->write (_select->set_state(on)); - _surface->write (_select->set_state(off)); - _stripable = r; - reset_saved_values (); + mark_dirty (); if (!r) { DEBUG_TRACE (DEBUG::US2400, string_compose ("Surface %1 Strip %2 mapped to null route\n", _surface->number(), _index)); @@ -263,7 +254,7 @@ Strip::reset_stripable () _stripable.reset(); - reset_saved_values (); + mark_dirty (); notify_all (); } @@ -300,6 +291,7 @@ Strip::notify_solo_changed () // _surface->write (_solo->set_state (_stripable->solo_control()->soloed() ? on : off)); // } + _solo->mark_dirty (); _trickle_counter = 0; } @@ -316,6 +308,7 @@ Strip::notify_mute_changed () // _surface->write (_mute->zero()); // } + _mute->mark_dirty (); _trickle_counter = 0; } @@ -334,6 +327,7 @@ Strip::notify_stripable_deleted () void Strip::notify_gain_changed (bool force_update) { + _fader->mark_dirty(); _trickle_counter = 0; } @@ -350,6 +344,7 @@ Strip::notify_property_changed (const PropertyChange& what_changed) void Strip::update_selection_state () { + _select->mark_dirty (); _trickle_counter = 0; // if(_stripable) { @@ -365,12 +360,14 @@ Strip::show_stripable_name () void Strip::notify_vpot_change () { + _vpot->mark_dirty(); _trickle_counter = 0; } void Strip::notify_panner_azi_changed (bool force_update) { + _vpot->mark_dirty(); _trickle_counter = 0; } @@ -402,6 +399,8 @@ Strip::select_event (Button&, ButtonState bs) DEBUG_TRACE (DEBUG::US2400, "remove select button on release\n"); _surface->mcp().remove_down_select_button (_surface->number(), _index); } + + _trickle_counter = 0; } void @@ -602,7 +601,7 @@ Strip::periodic (ARDOUR::microseconds_t now) update_meter (); - if ( _trickle_counter %5 == 0 ) { + if ( _trickle_counter %24 == 0 ) { if ( _fader->control() ) { _surface->write (_fader->set_position (_fader->control()->internal_to_interface (_fader->control()->get_value ()))); @@ -627,7 +626,13 @@ Strip::periodic (ARDOUR::microseconds_t now) } } + + //after a hard write, queue us for trickling data later + if (_trickle_counter == 0) + _trickle_counter = global_index()+1; + _trickle_counter++; + } void @@ -932,7 +937,7 @@ Strip::set_vpot_parameter (AutomationType p) DEBUG_TRACE (DEBUG::US2400, string_compose ("switch to vpot mode %1\n", p)); - reset_saved_values (); + mark_dirty (); switch (p) { case PanAzimuthAutomation: @@ -967,8 +972,13 @@ Strip::is_midi_track () const } void -Strip::reset_saved_values () +Strip::mark_dirty () { + _fader->mark_dirty(); + _vpot->mark_dirty(); + _solo->mark_dirty(); + _mute->mark_dirty(); + _trickle_counter=0; } void diff --git a/libs/surfaces/us2400/strip.h b/libs/surfaces/us2400/strip.h index 0836657956..d963c12836 100644 --- a/libs/surfaces/us2400/strip.h +++ b/libs/surfaces/us2400/strip.h @@ -85,7 +85,8 @@ public: void update_selection_state (); - int global_index() { return _surface->mcp().global_index (*this); } + void set_global_index( int g ) { _global_index = g; } + int global_index() { return _global_index; } private: enum VPotDisplayMode { @@ -101,6 +102,7 @@ private: Fader* _fader; Meter* _meter; int _index; + int _global_index; Surface* _surface; bool _controls_locked; bool _transport_is_rolling; @@ -139,7 +141,7 @@ private: void set_vpot_parameter (ARDOUR::AutomationType); void show_stripable_name (); - void reset_saved_values (); + void mark_dirty (); bool is_midi_track () const; diff --git a/libs/surfaces/us2400/surface.cc b/libs/surfaces/us2400/surface.cc index 08f40e4600..063d628694 100644 --- a/libs/surfaces/us2400/surface.cc +++ b/libs/surfaces/us2400/surface.cc @@ -352,6 +352,8 @@ Surface::init_strips (uint32_t n) Strip* strip = new Strip (*this, name, i, strip_buttons); + strip->set_global_index( _number*n + i ); + groups[name] = strip; strips.push_back (strip); } @@ -801,8 +803,7 @@ Surface::turn_it_on () _active = true; - if ( _stype == st_mcu ) //do this once, when we hear from the master. this sets up current bank, etc - _mcp.device_ready (); + _mcp.device_ready (); //this gets redundantly called with each new surface connection; but this is desirable to get the banks set up correctly for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { (*s)->notify_all (); @@ -896,9 +897,11 @@ Surface::zero_controls () void Surface::periodic (uint64_t now_usecs) { - master_gain_changed(); - for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { - (*s)->periodic (now_usecs); + if (_active) { + master_gain_changed(); + for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { + (*s)->periodic (now_usecs); + } } } diff --git a/libs/surfaces/us2400/surface_port.cc b/libs/surfaces/us2400/surface_port.cc index 88c1df11c9..c090bcb47f 100644 --- a/libs/surfaces/us2400/surface_port.cc +++ b/libs/surfaces/us2400/surface_port.cc @@ -155,7 +155,7 @@ int SurfacePort::write (const MidiByteArray & mba) { if (mba.empty()) { - DEBUG_TRACE (DEBUG::US2400, string_compose ("port %1 asked to write an empty MBA\n", output_port().name())); +// DEBUG_TRACE (DEBUG::US2400, string_compose ("port %1 asked to write an empty MBA\n", output_port().name())); return 0; } @@ -170,6 +170,7 @@ SurfacePort::write (const MidiByteArray & mba) */ int count = output_port().write (&mba[0], mba.size(), 0); + g_usleep (1000); if (count != (int) mba.size()) { diff --git a/libs/surfaces/us2400/us2400_control_protocol.cc b/libs/surfaces/us2400/us2400_control_protocol.cc index 4a1ba6231e..0a6f950d44 100644 --- a/libs/surfaces/us2400/us2400_control_protocol.cc +++ b/libs/surfaces/us2400/us2400_control_protocol.cc @@ -412,7 +412,7 @@ US2400Protocol::set_active (bool yn) /* set up periodic task for timecode display and metering and automation */ - Glib::RefPtr periodic_timeout = Glib::TimeoutSource::create (100); // milliseconds + Glib::RefPtr periodic_timeout = Glib::TimeoutSource::create (10); // milliseconds periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &US2400Protocol::periodic)); periodic_timeout->attach (main_loop()->get_context()); @@ -540,26 +540,12 @@ void US2400Protocol::device_ready () { DEBUG_TRACE (DEBUG::US2400, string_compose ("device ready init (active=%1)\n", active())); + + //this gets called every time a new surface appears; we have to do this to reset the banking etc + //particularly when the user is setting it up the first time; we can't guarantee the order that they will be connected + update_surfaces (); - update_global_button (Button::Send, on); - update_global_button (Button::Send, off); - - update_global_button (Button::Scrub, on); - update_global_button (Button::Scrub, off); - - update_global_button (Button::ClearSolo, on); - update_global_button (Button::ClearSolo, off); - - update_global_button (Button::Pan, off); - update_global_button (Button::Pan, on); - - update_global_button (Button::Flip, on); - update_global_button (Button::Flip, off); - - update_global_button (Button::MstrSelect, on); - update_global_button (Button::MstrSelect, off); - set_subview_mode (US2400Protocol::None, first_selected_stripable()); } @@ -595,7 +581,22 @@ US2400Protocol::initialize() } - // update global buttons and displays + update_global_button (Button::Send, on); + update_global_button (Button::Send, off); + + update_global_button (Button::Scrub, on); + update_global_button (Button::Scrub, off); + + notify_solo_active_changed(false); + + update_global_button (Button::Pan, off); + update_global_button (Button::Pan, on); + + update_global_button (Button::Flip, on); + update_global_button (Button::Flip, off); + + update_global_button (Button::MstrSelect, on); + update_global_button (Button::MstrSelect, off); notify_transport_state_changed(); @@ -1853,15 +1854,11 @@ US2400Protocol::stripable_selection_changed () (*si)->update_strip_selection (); } -printf("stripable_selection_changed\n"); - //first check for the dedicated Master strip boost::shared_ptr s = ControlProtocol::first_selected_stripable(); if (s && s->is_master()) { -printf("stripable_selection_changed found master as selected_stripable\n"); update_global_button(Button::MstrSelect, on); //NOTE: surface does not respond to this } else { -if (s) printf("stripable_selection_changed not master: %s\n", s->name().c_str()); update_global_button(Button::MstrSelect, off); //not the master; now check for other strips ( this will only allow a selection if the strip is mapped on our surface ) @@ -1879,7 +1876,6 @@ if (s) printf("stripable_selection_changed not master: %s\n", s->name().c_str( */ if (set_subview_mode (TrackView, s)) { -printf("set_subview_mode failed for master... (?)\n"); set_subview_mode (None, boost::shared_ptr()); }