From 618020424e7be8e73d7003124dee6f5b3e61221a Mon Sep 17 00:00:00 2001 From: Len Ovens Date: Thu, 19 Oct 2017 08:46:55 -0700 Subject: [PATCH] OSC: Cue observer simplified. --- libs/surfaces/osc/osc.cc | 32 ++--- libs/surfaces/osc/osc_cue_observer.cc | 178 +++++++++++++------------- libs/surfaces/osc/osc_cue_observer.h | 11 +- 3 files changed, 110 insertions(+), 111 deletions(-) diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 71d4762d34..f6117c671a 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -116,10 +116,9 @@ OSC::OSC (Session& s, uint32_t port) OSC::~OSC() { tick = false; - std::cout << "OSC term before stop\n"; stop (); - std::cout << "OSC term after stop\n"; tear_down_gui (); + std::cout << "OSC stopped.\n"; _instance = 0; } @@ -307,7 +306,6 @@ OSC::stop () surface_destroy (sur); } _surface.clear(); - std::cout << "sur cleared.\n"; periodic_connection.disconnect (); session_connections.drop_connections (); @@ -357,7 +355,7 @@ OSC::surface_destroy (OSCSurface* sur) sur->sel_obs = 0; } if (sur->cue_obs) { - // sur->cue_obs->clear_observer (); + sur->cue_obs->clear_observer (); delete sur->cue_obs; sur->cue_obs = 0; } @@ -1598,22 +1596,16 @@ OSC::get_surface (lo_address addr) { _surface.push_back (s); } - std::cout << "surface saved, do gui_selection\n"; // moved this down here as selection may need s. set if (!_select || (_select != ControlProtocol::first_selected_stripable())) { gui_selection_changed(); } - std::cout << "after gui_selection, call strip_feedback\n"; // set bank and strip feedback strip_feedback (&s); - std::cout << "after strip_feedback, call global_feedback\n"; // Set global/master feedback global_feedback (&s, addr); - usleep ((uint32_t) 20000); - - std::cout << "after global_feedback\n"; return &_surface[_surface.size() - 1]; } @@ -1634,14 +1626,12 @@ OSC::global_feedback (OSCSurface* sur, lo_address addr) void OSC::strip_feedback (OSCSurface* sur) { - std::cout << "strip_feedback, begin\n"; // delete old observers for (uint32_t i = 0; i < sur->observers.size(); i++) { sur->observers[i]->clear_strip (); delete sur->observers[i]; } sur->observers.clear(); - std::cout << string_compose ("observers delected: size: %1\n", sur->observers.size()); // get freash striplist - just in case sur->strips = get_sorted_stripables(sur->strip_types, sur->cue); @@ -1657,7 +1647,6 @@ OSC::strip_feedback (OSCSurface* sur) sur->observers.push_back (o); } } - std::cout << string_compose ("observers created: size: %1\n", sur->observers.size()); } void @@ -4976,6 +4965,7 @@ OSC::cue_parse (const char *path, const char* types, lo_arg **argv, int argc, lo int OSC::cue_set (uint32_t aux, lo_message msg) { + set_surface_feedback (0, msg); return _cue_set (aux, get_address (msg)); } @@ -5014,9 +5004,13 @@ OSC::_cue_set (uint32_t aux, lo_address addr) // make a list of stripables with sends that go to this bus s->sends = cue_get_sorted_stripables(stp, aux, addr); - // start cue observer - OSCCueObserver* co = new OSCCueObserver (stp, s->sends, addr); - s->cue_obs = co; + if (s->cue_obs) { + s->cue_obs->refresh_strip (false); + } else { + // start cue observer + OSCCueObserver* co = new OSCCueObserver (*this, s); + s->cue_obs = co; + } ret = 0; } @@ -5170,7 +5164,7 @@ OSC::float_message_with_id (std::string path, uint32_t ssid, float value, lo_add { OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->feedback[2]) { + if (sur->cue || sur->feedback[2]) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); @@ -5187,7 +5181,7 @@ OSC::int_message_with_id (std::string path, uint32_t ssid, int value, lo_address { OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->feedback[2]) { + if (sur->cue || sur->feedback[2]) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); @@ -5218,7 +5212,7 @@ OSC::text_message_with_id (std::string path, uint32_t ssid, std::string val, lo_ { OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->feedback[2]) { + if (sur->cue || sur->feedback[2]) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); diff --git a/libs/surfaces/osc/osc_cue_observer.cc b/libs/surfaces/osc/osc_cue_observer.cc index c1eed2921e..6cdc50e11e 100644 --- a/libs/surfaces/osc/osc_cue_observer.cc +++ b/libs/surfaces/osc/osc_cue_observer.cc @@ -35,12 +35,73 @@ using namespace PBD; using namespace ARDOUR; using namespace ArdourSurface; -OSCCueObserver::OSCCueObserver (boost::shared_ptr s, std::vector >& snds, lo_address a) - : sends (snds) - , _strip (s) +OSCCueObserver::OSCCueObserver (OSC& o, ArdourSurface::OSC::OSCSurface* su) + : _osc (o) + ,sur (su) , tick_enable (false) { - addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a)); + addr = lo_address_new_from_url (sur->remote_url.c_str()); + refresh_strip (true); +} + +OSCCueObserver::~OSCCueObserver () +{ + tick_enable = false; + no_strip (); + lo_address_free (addr); +} + +void +OSCCueObserver::clear_observer () +{ + tick_enable = false; + + strip_connections.drop_connections (); + send_end (); + // all strip buttons should be off and faders 0 and etc. + _osc.text_message_with_id ("/cue/name", 0, " ", addr); + _osc.float_message ("/cue/mute", 0, addr); + _osc.float_message ("/cue/fader", 0, addr); + _osc.float_message ("/cue/signal", 0, addr); + +} + +void +OSCCueObserver::no_strip () +{ + // This gets called on drop references + tick_enable = false; + + strip_connections.drop_connections (); + /* + * The strip will sit idle at this point doing nothing until + * the surface has recalculated it's strip list and then calls + * refresh_strip. Otherwise refresh strip will get a strip address + * that does not exist... Crash + */ + } + +void +OSCCueObserver::refresh_strip (bool force) +{ + tick_enable = false; + + uint32_t sid = sur->aux - 1; + if (sid >= sur->strips.size ()) { + sid = 0; + } + + boost::shared_ptr new_strip = sur->strips[sid]; + if (_strip && (new_strip == _strip) && !force) { + tick_enable = true; + return; + } + strip_connections.drop_connections (); + + send_end (); + _strip = new_strip; + _strip->DropReferences.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::no_strip, this), OSC::instance()); + sends = sur->sends; _strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::name_changed, this, boost::lambda::_1, 0), OSC::instance()); name_changed (ARDOUR::Properties::name, 0); @@ -49,9 +110,9 @@ OSCCueObserver::OSCCueObserver (boost::shared_ptr s, std::vectormute_control()); gain_timeout.push_back (0); - _last_gain.push_back (0.0); - _strip->gain_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_gain_message, this, 0, _strip->gain_control()), OSC::instance()); - send_gain_message (0, _strip->gain_control()); + _last_gain.push_back (-1.0); + _strip->gain_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_gain_message, this, 0, _strip->gain_control(), false), OSC::instance()); + send_gain_message (0, _strip->gain_control(), true); send_init (); @@ -59,21 +120,6 @@ OSCCueObserver::OSCCueObserver (boost::shared_ptr s, std::vectorgain_control()) { gain_timeout.push_back (0); - _last_gain.push_back (0.0); - send->gain_control()->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_gain_message, this, i + 1, send->gain_control()), OSC::instance()); - send_gain_message (i + 1, send->gain_control()); + _last_gain.push_back (-1.0); + send->gain_control()->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_gain_message, this, i + 1, send->gain_control(), false), OSC::instance()); + send_gain_message (i + 1, send->gain_control(), true); } boost::shared_ptr proc = boost::dynamic_pointer_cast (send); @@ -151,10 +193,12 @@ OSCCueObserver::send_end () { send_connections.drop_connections (); for (uint32_t i = 1; i <= sends.size(); i++) { - clear_strip (string_compose ("/cue/send/fader/%1", i), 0); - clear_strip (string_compose ("/cue/send/enable/%1", i), 0); - text_with_id ("/cue/send/name", i, " "); + _osc.float_message (string_compose ("/cue/send/fader/%1", i), 0, addr); + _osc.float_message (string_compose ("/cue/send/enable/%1", i), 0, addr); + _osc.text_message_with_id ("/cue/send/name", i, " ", addr); } + gain_timeout.clear (); + _last_gain.clear (); } void @@ -177,90 +221,48 @@ OSCCueObserver::name_changed (const PBD::PropertyChange& what_changed, uint32_t return; } if (id) { - text_with_id ("/cue/send/name", id, sends[id - 1]->name()); + _osc.text_message_with_id ("/cue/send/name", id, sends[id - 1]->name(), addr); } else { - text_with_id ("/cue/name", 0, _strip->name()); + _osc.text_message ("/cue/name", _strip->name(), addr); } } void OSCCueObserver::send_change_message (string path, uint32_t id, boost::shared_ptr controllable) { - lo_message msg = lo_message_new (); - + // maybe don't need ID only used for mute- maybe mute can use enable if (id) { path = string_compose("%1/%2", path, id); } float val = controllable->get_value(); - lo_message_add_float (msg, (float) controllable->internal_to_interface (val)); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); + _osc.float_message (path, (float) controllable->internal_to_interface (val), addr); } void -OSCCueObserver::text_with_id (string path, uint32_t id, string val) -{ - lo_message msg = lo_message_new (); - if (id) { - path = string_compose("%1/%2", path, id); - } - - lo_message_add_string (msg, val.c_str()); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); -} - -void -OSCCueObserver::send_gain_message (uint32_t id, boost::shared_ptr controllable) +OSCCueObserver::send_gain_message (uint32_t id, boost::shared_ptr controllable, bool force) { if (_last_gain[id] != controllable->get_value()) { _last_gain[id] = controllable->get_value(); } else { return; } - string path = "/cue"; if (id) { - path = "/cue/send"; + _osc.text_message_with_id ("/cue/send/name", id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), addr); + _osc.float_message_with_id ("/cue/send/fader", id, controllable->internal_to_interface (controllable->get_value()), addr); + } else { + _osc.text_message ("/cue/name", string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), addr); + _osc.float_message ("/cue/fader", controllable->internal_to_interface (controllable->get_value()), addr); } - text_with_id (string_compose ("%1/name", path), id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value()))); - path = string_compose ("%1/fader", path); - if (id) { - path = string_compose ("%1/%2", path, id); - } - lo_message msg = lo_message_new (); - lo_message_add_float (msg, controllable->internal_to_interface (controllable->get_value())); gain_timeout[id] = 8; - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); } void OSCCueObserver::send_enabled_message (std::string path, uint32_t id, boost::shared_ptr proc) { - lo_message msg = lo_message_new (); - if (id) { - path = string_compose("%1/%2", path, id); + _osc.float_message_with_id (path, id, (float) proc->enabled(), addr); + } else { + _osc.float_message (path, (float) proc->enabled(), addr); } - lo_message_add_float (msg, (float) proc->enabled()); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); - } - -void -OSCCueObserver::clear_strip (string path, float val) -{ - lo_message msg = lo_message_new (); - lo_message_add_float (msg, val); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); - -} - diff --git a/libs/surfaces/osc/osc_cue_observer.h b/libs/surfaces/osc/osc_cue_observer.h index eb669ee167..92a46e0111 100644 --- a/libs/surfaces/osc/osc_cue_observer.h +++ b/libs/surfaces/osc/osc_cue_observer.h @@ -33,7 +33,7 @@ class OSCCueObserver { public: - OSCCueObserver (boost::shared_ptr, std::vector >& sends, lo_address addr); + OSCCueObserver (ArdourSurface::OSC& o, ArdourSurface::OSC::OSCSurface* sur); ~OSCCueObserver (); boost::shared_ptr strip () const { return _strip; } @@ -41,16 +41,20 @@ class OSCCueObserver void tick (void); typedef std::vector > Sorted; Sorted sends; + void clear_observer (void); + void refresh_strip (bool force); private: boost::shared_ptr _strip; + ArdourSurface::OSC& _osc; PBD::ScopedConnectionList strip_connections; PBD::ScopedConnectionList send_connections; lo_address addr; std::string path; + ArdourSurface::OSC::OSCSurface* sur; float _last_meter; std::vector gain_timeout; bool tick_enable; @@ -58,13 +62,12 @@ class OSCCueObserver void name_changed (const PBD::PropertyChange& what_changed, uint32_t id); void send_change_message (std::string path, uint32_t id, boost::shared_ptr controllable); - void text_with_id (std::string path, uint32_t id, std::string val); - void send_gain_message (uint32_t id, boost::shared_ptr controllable); + void send_gain_message (uint32_t id, boost::shared_ptr controllable, bool force); void send_enabled_message (std::string path, uint32_t id, boost::shared_ptr proc); - void clear_strip (std::string path, float val); void send_init (void); void send_end (void); void send_restart (void); + void no_strip (); }; #endif /* __osc_osccueobserver_h__ */