From dcf852aae41a2d407f770324f30a5b5138a51039 Mon Sep 17 00:00:00 2001 From: Len Ovens Date: Mon, 13 Jun 2016 11:57:15 -0700 Subject: [PATCH] OSC: Catch new strips, gone strips and redo banks and observers. Add more select feedback. --- libs/surfaces/osc/osc.cc | 70 +++++++++++++++++++++--- libs/surfaces/osc/osc.h | 7 +++ libs/surfaces/osc/osc_route_observer.cc | 1 - libs/surfaces/osc/osc_select_observer.cc | 30 +++++++--- 4 files changed, 93 insertions(+), 15 deletions(-) diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index edaf5b76b4..80b79c9be2 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -49,6 +49,7 @@ #include "ardour/phase_control.h" #include "ardour/solo_isolate_control.h" #include "ardour/solo_safe_control.h" +#include "ardour/vca_manager.h" #include "osc_select_observer.h" #include "osc.h" @@ -90,6 +91,8 @@ OSC::OSC (Session& s, uint32_t port) , _osc_unix_server (0) , _send_route_changes (true) , _debugmode (Off) + , tick (true) + , bank_dirty (false) , gui (0) { _instance = this; @@ -246,8 +249,15 @@ OSC::start () periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &OSC::periodic)); periodic_timeout->attach (main_loop()->get_context()); + // catch GUI select changes for GUI_select mode StripableSelectionChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::gui_selection_changed, this, _1), this); + // catch track reordering + // receive routes added + session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::notify_routes_added, this, _1), this); + // receive VCAs added + session->vca_manager().VCAAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::notify_vca_added, this, _1), this); + return 0; } @@ -646,7 +656,15 @@ OSC::listen_to_route (boost::shared_ptr strip, lo_address addr) OSCRouteObserver* o = new OSCRouteObserver (strip, addr, sid, s->gainmode, s->feedback); route_observers.push_back (o); - strip->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::drop_route, this, boost::weak_ptr (strip)), this); + strip->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::route_lost, this, boost::weak_ptr (strip)), this); +} + +void +OSC::route_lost (boost::weak_ptr wr) +{ + tick = false; + drop_route (wr); + bank_dirty = true; } void @@ -1251,6 +1269,29 @@ OSC::global_feedback (bitset<32> feedback, lo_address msg, uint32_t gainmode) } } +void +OSC::notify_routes_added (ARDOUR::RouteList &) +{ + recalcbanks(); +} + +void +OSC::notify_vca_added (ARDOUR::VCAList &) +{ + recalcbanks(); +} + +void +OSC::recalcbanks () +{ + for (uint32_t it = 0; it < _surface.size(); ++it) { + OSCSurface* sur = &_surface[it]; + // find lo_address + lo_address addr = lo_address_new_from_url (sur->remote_url.c_str()); + _set_bank (sur->bank, addr); + } +} + /* * This gets called not only when bank changes but also: * - bank size change @@ -1263,6 +1304,12 @@ OSC::global_feedback (bitset<32> feedback, lo_address msg, uint32_t gainmode) */ int OSC::set_bank (uint32_t bank_start, lo_message msg) +{ + return _set_bank (bank_start, lo_message_get_source (msg)); +} + +int +OSC::_set_bank (uint32_t bank_start, lo_address addr) { if (!session) { return -1; @@ -1281,18 +1328,18 @@ OSC::set_bank (uint32_t bank_start, lo_message msg) nstrips = session->nroutes() - 1; } // reset local select - _strip_select (0, lo_message_get_source (msg)); + _strip_select (0, addr); // undo all listeners for this url for (int n = 0; n <= (int) nstrips; ++n) { boost::shared_ptr stp = session->get_remote_nth_stripable (n, PresentationInfo::Route); if (stp) { - end_listen (stp, lo_message_get_source (msg)); + end_listen (stp, addr); } } - OSCSurface *s = get_surface (lo_message_get_source (msg)); + OSCSurface *s = get_surface (addr); uint32_t b_size; if (!s->bank_size) { @@ -1318,15 +1365,17 @@ OSC::set_bank (uint32_t bank_start, lo_message msg) boost::shared_ptr stp = session->get_remote_nth_stripable (n - 1, PresentationInfo::Route); if (stp) { - listen_to_route(stp, lo_message_get_source (msg)); + listen_to_route(stp, addr); if (!s->feedback[10]) { if (stp->is_selected()) { - _strip_select (n, lo_message_get_source (msg)); + _strip_select (n, addr); } } } } } + bank_dirty = false; + tick = true; return 0; } @@ -1832,6 +1881,7 @@ OSC::_strip_select (int ssid, lo_address addr) if (s) { sur->surface_sel = ssid; OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, ssid, sur->gainmode, sur->feedback); + s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); sur->sel_obs = sel_fb; } else { route_send_fail ("select", ssid, 0 , addr); @@ -2338,6 +2388,12 @@ OSC::gui_selection_changed (StripableNotificationListPtr stripables) bool OSC::periodic (void) { + if (!tick) { + if (bank_dirty) { + recalcbanks (); + } + } + for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end(); x++) { OSCGlobalObserver* go; @@ -2354,7 +2410,7 @@ OSC::periodic (void) ro->tick(); } } - for (uint32_t it = 0; it < _surface.size(); ++it) { + for (uint32_t it = 0; it < _surface.size(); it++) { OSCSurface* sur = &_surface[it]; OSCSelectObserver* so; if ((so = dynamic_cast(sur->sel_obs)) != 0) { diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index 7ef4b5aaf5..a2ebc80510 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -167,6 +167,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI std::string _osc_url_file; bool _send_route_changes; OSCDebugMode _debugmode; + bool tick; + bool bank_dirty; void register_callbacks (); @@ -451,6 +453,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI //banking functions int set_bank (uint32_t bank_start, lo_message msg); + int _set_bank (uint32_t bank_start, lo_address addr); int bank_up (lo_message msg); int bank_down (lo_message msg); int set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gmode, lo_message msg); @@ -487,9 +490,13 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI void listen_to_route (boost::shared_ptr, lo_address); void end_listen (boost::shared_ptr, lo_address); void drop_route (boost::weak_ptr); + void route_lost (boost::weak_ptr); void gui_selection_changed (ARDOUR::StripableNotificationListPtr stripables); void route_name_changed (const PBD::PropertyChange&, boost::weak_ptr r, lo_address addr); + void recalcbanks (); + void notify_routes_added (ARDOUR::RouteList &); + void notify_vca_added (ARDOUR::VCAList &); void update_clock (); bool periodic (void); diff --git a/libs/surfaces/osc/osc_route_observer.cc b/libs/surfaces/osc/osc_route_observer.cc index e077fc923a..3626c5764c 100644 --- a/libs/surfaces/osc/osc_route_observer.cc +++ b/libs/surfaces/osc/osc_route_observer.cc @@ -378,7 +378,6 @@ OSCRouteObserver::send_select_status () } else { lo_message_add_int32 (msg, ssid); } - //std::cout << "strip: " << ssid << " strip name: " << _strip->name() << " select: " << _strip->is_selected() << "\n"; lo_message_add_float (msg, _strip->is_selected()); lo_send_message (addr, path.c_str(), msg); lo_message_free (msg); diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc index a51f9e702a..8836de3792 100644 --- a/libs/surfaces/osc/osc_select_observer.cc +++ b/libs/surfaces/osc/osc_select_observer.cc @@ -27,6 +27,7 @@ #include "ardour/phase_control.h" #include "ardour/solo_isolate_control.h" #include "ardour/solo_safe_control.h" +#include "ardour/route.h" #include "osc.h" #include "osc_select_observer.h" @@ -324,18 +325,33 @@ OSCSelectObserver::name_changed (const PBD::PropertyChange& what_changed) lo_message msg = lo_message_new (); - // ssid is the strip on the surface this observer refers to - // not part of the internal ordering. string path = "/select/name"; - /*if (feedback[2]) { - path = set_path (path); - } else { - lo_message_add_int32 (msg, ssid); - }*/ lo_message_add_string (msg, _strip->name().c_str()); lo_send_message (addr, path.c_str(), msg); lo_message_free (msg); + + //spit out the comment at the same time + msg = lo_message_new (); + path = "/select/comment"; + boost::shared_ptr route = boost::dynamic_pointer_cast (_strip); + lo_message_add_string (msg, route->comment().c_str()); + lo_send_message (addr, path.c_str(), msg); + lo_message_free (msg); + + // lets tell the surface how many inputs this strip has + msg = lo_message_new (); + path = "/select/n_inputs"; + lo_message_add_int32 (msg, route->n_inputs().n_total()); + lo_send_message (addr, path.c_str(), msg); + lo_message_free (msg); + // lets tell the surface how many outputs this strip has + msg = lo_message_new (); + path = "/select/n_outputs"; + lo_message_add_int32 (msg, route->n_outputs().n_total()); + lo_send_message (addr, path.c_str(), msg); + lo_message_free (msg); + } void