diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 9cebb403df..71d4762d34 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -115,7 +115,10 @@ 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 (); _instance = 0; } @@ -298,6 +301,18 @@ OSC::stop () { /* stop main loop */ + // clear surfaces + for (uint32_t it = 0; it < _surface.size(); ++it) { + OSCSurface* sur = &_surface[it]; + surface_destroy (sur); + } + _surface.clear(); + std::cout << "sur cleared.\n"; + + periodic_connection.disconnect (); + session_connections.drop_connections (); + cueobserver_connections.drop_connections (); + if (local_server) { g_source_destroy (local_server); g_source_unref (local_server); @@ -330,60 +345,36 @@ OSC::stop () ::g_unlink (_osc_url_file.c_str() ); } - periodic_connection.disconnect (); - session_connections.drop_connections (); - cueobserver_connections.drop_connections (); - Glib::Threads::Mutex::Lock lm (surfaces_lock); - // Delete any active route observers - for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) { - - OSCRouteObserver* rc; - - if ((rc = dynamic_cast(*x)) != 0) { - delete *x; - x = route_observers.erase (x); - } else { - ++x; - } - } -// Should maybe do global_observers too - for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end();) { - - OSCGlobalObserver* gc; - - if ((gc = dynamic_cast(*x)) != 0) { - delete *x; - x = global_observers.erase (x); - } else { - ++x; - } - } - -// delete select observers - for (uint32_t it = 0; it < _surface.size(); ++it) { - OSCSurface* sur = &_surface[it]; - OSCSelectObserver* so; - if ((so = dynamic_cast(sur->sel_obs)) != 0) { - delete so; - } - } - -// delete cue observers - for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end();) { - - OSCCueObserver* co; - - if ((co = dynamic_cast(*x)) != 0) { - delete *x; - x = cue_observers.erase (x); - } else { - ++x; - } - } - return 0; } +void +OSC::surface_destroy (OSCSurface* sur) +{ + if (sur->sel_obs) { + sur->sel_obs->clear_observer (); + delete sur->sel_obs; + sur->sel_obs = 0; + } + if (sur->cue_obs) { + // sur->cue_obs->clear_observer (); + delete sur->cue_obs; + sur->cue_obs = 0; + } + if (sur->global_obs) { + sur->global_obs->clear_observer (); + delete sur->global_obs; + sur->global_obs = 0; + } + for (uint32_t i = 0; i < sur->observers.size(); i++) { + sur->observers[i]->clear_strip (); + delete sur->observers[i]; + } + + sur->observers.clear(); +} + + void OSC::register_callbacks() { @@ -640,7 +631,7 @@ OSC::register_callbacks() /* this is a special catchall handler, * register at the end so this is only called if no - * other handler matches (used for debug) */ + * other handler matches (also used for debug) */ lo_server_add_method (serv, 0, 0, _catchall, this); } } @@ -695,99 +686,6 @@ OSC::gui_changed () session->set_dirty(); } -void -OSC::listen_to_route (boost::shared_ptr strip, lo_address addr) -{ - if (!strip) { - return; - } - /* avoid duplicate listens */ - - for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end(); ++x) { - - OSCRouteObserver* ro; - - if ((ro = dynamic_cast(*x)) != 0) { - - int res = strcmp(lo_address_get_url(ro->address()), lo_address_get_url(addr)); - - if (ro->strip() == strip && res == 0) { - return; - } - } - } - - OSCSurface *s = get_surface(addr); - uint32_t ssid = get_sid (strip, addr); - OSCRouteObserver* o = new OSCRouteObserver (*this, ssid, s); - route_observers.push_back (o); - - 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 -OSC::drop_route (boost::weak_ptr wr) -{ - boost::shared_ptr r = wr.lock (); - - if (!r) { - return; - } - - for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) { - - OSCRouteObserver* rc; - - if ((rc = dynamic_cast(*x)) != 0) { - - if (rc->strip() == r) { - delete *x; - x = route_observers.erase (x); - } else { - ++x; - } - } else { - ++x; - } - } -} - -void -OSC::end_listen (boost::shared_ptr r, lo_address addr) -{ - RouteObservers::iterator x; - - // Remove the route observers - for (x = route_observers.begin(); x != route_observers.end();) { - - OSCRouteObserver* ro; - - if ((ro = dynamic_cast(*x)) != 0) { - - int res = strcmp(lo_address_get_url(ro->address()), lo_address_get_url(addr)); - - if (ro->strip() == r && res == 0) { - delete *x; - x = route_observers.erase (x); - } - else { - ++x; - } - } - else { - ++x; - } - } -} - void OSC::current_value_query (const char* path, size_t len, lo_arg **argv, int argc, lo_message msg) { @@ -914,7 +812,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_ ret = 0; } else - if (strcmp (path, "/strip/listen") == 0) { +/* if (strcmp (path, "/strip/listen") == 0) { check_surface (msg); cerr << "set up listener\n"; @@ -963,7 +861,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_ } ret = 0; - } else + } else */ if (strstr (path, "/strip") && (argc != 1)) { // All of the strip commands below require 1 parameter PBD::warning << "OSC: Wrong number of parameters." << endmsg; @@ -1297,8 +1195,11 @@ OSC::routes_list (lo_message msg) lo_message_add_int32 (reply, s->rec_enable_control()->get_value()); } - //Automatically listen to stripables listed + /* + * get_surface above already does this if feedback is turned on + * //Automatically listen to stripables listed listen_to_route(s, get_address (msg)); + */ if (sur->feedback[14]) { lo_send_message (get_address (msg), "/reply", reply); @@ -1355,6 +1256,7 @@ int OSC::refresh_surface (lo_message msg) { OSCSurface *s = get_surface(get_address (msg)); + surface_destroy (s); // restart all observers set_surface (s->bank_size, (uint32_t) s->strip_types.to_ulong(), (uint32_t) s->feedback.to_ulong(), \ (uint32_t) s->gainmode, (uint32_t) s->send_page_size, (uint32_t) s->plug_page_size, msg); @@ -1365,52 +1267,12 @@ void OSC::clear_devices () { tick = false; - Glib::Threads::Mutex::Lock lm (surfaces_lock); - for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) { - - OSCRouteObserver* rc; - - if ((rc = dynamic_cast(*x)) != 0) { - delete *x; - x = route_observers.erase (x); - } else { - ++x; - } - // slow devices need time to clear buffers - usleep ((uint32_t) 10); - } - // Should maybe do global_observers too - for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end();) { - - OSCGlobalObserver* gc; - - if ((gc = dynamic_cast(*x)) != 0) { - delete *x; - x = global_observers.erase (x); - } else { - ++x; - } - } - // delete select observers - for (uint32_t it = 0; it < _surface.size(); ++it) { - OSCSurface* sur = &_surface[it]; - OSCSelectObserver* so; - if ((so = dynamic_cast(sur->sel_obs)) != 0) { - delete so; - } - } - // delete cue observers - for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end();) { - OSCCueObserver* co; - if ((co = dynamic_cast(*x)) != 0) { - delete *x; - x = cue_observers.erase (x); - } else { - ++x; - } - } // clear out surfaces + for (uint32_t it = 0; it < _surface.size(); ++it) { + OSCSurface* sur = &_surface[it]; + surface_destroy (sur); + } _surface.clear(); tick = true; } @@ -1606,9 +1468,9 @@ OSC::set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gm, ui s->send_page_size = se_size; s->plug_page_size = pi_size; // set bank and strip feedback - set_bank(s->bank, msg); + strip_feedback(s); - global_feedback (*s, get_address (msg)); + global_feedback (s, get_address (msg)); sel_send_pagesize (se_size, msg); sel_plug_pagesize (pi_size, msg); return 0; @@ -1619,9 +1481,10 @@ OSC::set_surface_bank_size (uint32_t bs, lo_message msg) { OSCSurface *s = get_surface(get_address (msg)); s->bank_size = bs; + s->bank = 1; // set bank and strip feedback - set_bank(s->bank, msg); + strip_feedback (s); return 0; } @@ -1637,7 +1500,8 @@ OSC::set_surface_strip_types (uint32_t st, lo_message msg) } // set bank and strip feedback - set_bank(s->bank, msg); + s->bank = 1; + strip_feedback (s); return 0; } @@ -1648,11 +1512,11 @@ OSC::set_surface_feedback (uint32_t fb, lo_message msg) OSCSurface *s = get_surface(get_address (msg)); s->feedback = fb; - // set bank and strip feedback - set_bank(s->bank, msg); + // set strip feedback + strip_feedback (s); // Set global/master feedback - global_feedback (*s, get_address (msg)); + global_feedback (s, get_address (msg)); return 0; } @@ -1662,11 +1526,11 @@ OSC::set_surface_gainmode (uint32_t gm, lo_message msg) OSCSurface *s = get_surface(get_address (msg)); s->gainmode = gm; - // set bank and strip feedback - set_bank(s->bank, msg); + // set strip feedback + strip_feedback (s); // Set global/master feedback - global_feedback (*s, get_address (msg)); + global_feedback (s, get_address (msg)); return 0; } @@ -1695,7 +1559,6 @@ OSC::get_surface (lo_address addr) r_url = rurl; free (rurl); { - Glib::Threads::Mutex::Lock lm (surfaces_lock); for (uint32_t it = 0; it < _surface.size(); ++it) { //find setup for this server if (!_surface[it].remote_url.find(r_url)){ @@ -1711,6 +1574,9 @@ OSC::get_surface (lo_address addr) s.jogmode = JOG; s.bank = 1; s.bank_size = default_banksize; + s.observers.clear(); + s.sel_obs = 0; + s.global_obs = 0; s.strip_types = default_strip; s.feedback = default_feedback; s.gainmode = default_gainmode; @@ -1720,6 +1586,7 @@ OSC::get_surface (lo_address addr) s.expand_enable = false; s.cue = false; s.aux = 0; + s.cue_obs = 0; s.strips = get_sorted_stripables(s.strip_types, s.cue); s.send_page = 1; s.send_page_size = default_send_size; @@ -1729,53 +1596,68 @@ OSC::get_surface (lo_address addr) s.nstrips = s.strips.size(); { - Glib::Threads::Mutex::Lock lm (surfaces_lock); _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 - _set_bank(s.bank, addr); + strip_feedback (&s); + std::cout << "after strip_feedback, call global_feedback\n"; // Set global/master feedback - global_feedback (s, addr); + global_feedback (&s, addr); + usleep ((uint32_t) 20000); + + std::cout << "after global_feedback\n"; return &_surface[_surface.size() - 1]; } // setup global feedback for a surface void -OSC::global_feedback (OSCSurface sur, lo_address addr) +OSC::global_feedback (OSCSurface* sur, lo_address addr) { - // first destroy global observer for this surface - GlobalObservers::iterator x; - for (x = global_observers.begin(); x != global_observers.end();) { + std::bitset<32> feedback = sur->feedback; + if (feedback[4] || feedback[3] || feedback[5] || feedback[6]) { - OSCGlobalObserver* go; + // create a new Global Observer for this surface + OSCGlobalObserver* o = new OSCGlobalObserver (*this, *session, sur); + sur->global_obs = o; + } +} - if ((go = dynamic_cast(*x)) != 0) { +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()); - int res = strcmp(lo_address_get_url(go->address()), lo_address_get_url(addr)); + // get freash striplist - just in case + sur->strips = get_sorted_stripables(sur->strip_types, sur->cue); + sur->nstrips = sur->strips.size(); + uint32_t bank_size = sur->bank_size; + if (!bank_size) { + bank_size = sur->nstrips; + } - if (res == 0) { - delete *x; - x = global_observers.erase (x); - } else { - ++x; - } - } else { - ++x; + if (sur->feedback[0] || sur->feedback[1]) { + for (uint32_t i = 0; i < bank_size; i++) { + OSCRouteObserver* o = new OSCRouteObserver (*this, i + 1, sur); + sur->observers.push_back (o); } } - std::bitset<32> feedback = sur.feedback; - if (feedback[4] || feedback[3] || feedback[5] || feedback[6]) { - // create a new Global Observer for this surface - OSCGlobalObserver* o = new OSCGlobalObserver (*session, &sur); - global_observers.push_back (o); - } + std::cout << string_compose ("observers created: size: %1\n", sur->observers.size()); } void @@ -1804,9 +1686,10 @@ OSC::_recalcbanks () { if (!_select || (_select != ControlProtocol::first_selected_stripable())) { _select = ControlProtocol::first_selected_stripable(); + gui_selection_changed (); } - // do a set_bank for each surface we know about. + // refresh each surface we know about. for (uint32_t it = 0; it < _surface.size(); ++it) { OSCSurface* sur = &_surface[it]; // find lo_address @@ -1814,9 +1697,12 @@ OSC::_recalcbanks () if (sur->cue) { _cue_set (sur->aux, addr); } else { - _set_bank (sur->bank, addr); + for (uint32_t i = 0; i < sur->observers.size(); i++) { + sur->observers[i]->refresh_strip (false); + } } - if (sur->no_clear) { + + if (!sur->bank_size) { // This surface uses /strip/list tell it routes have changed lo_message reply; reply = lo_message_new (); @@ -1826,16 +1712,6 @@ OSC::_recalcbanks () } } -/* - * This gets called not only when bank changes but also: - * - bank size change - * - feedback change - * - strip types changes - * - fadermode changes - * - stripable creation/deletion/flag - * - to refresh what is "displayed" - * Basically any time the bank needs to be rebuilt - */ int OSC::set_bank (uint32_t bank_start, lo_message msg) { @@ -1861,19 +1737,6 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr) s->expand_enable = false; _strip_select (ControlProtocol::first_selected_stripable(), addr); - // undo all listeners for this url - StripableList stripables; - session->get_stripables (stripables); - for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) { - - boost::shared_ptr stp = *it; - if (stp) { - end_listen (stp, addr); - } - // slow devices need time to clear buffers - usleep ((uint32_t) 10); - } - s->strips = get_sorted_stripables(s->strip_types, s->cue); s->nstrips = s->strips.size(); @@ -1898,16 +1761,8 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr) if (s->feedback[0] || s->feedback[1]) { - for (uint32_t n = bank_start; n < (min ((b_size + bank_start), s->nstrips + 1)); ++n) { - if (n <= s->strips.size()) { - boost::shared_ptr stp = s->strips[n - 1]; - - if (stp) { - listen_to_route(stp, addr); - } - } - // slow devices need time to clear buffers - usleep ((uint32_t) 20); + for (uint32_t i = 0; i < s->observers.size(); i++) { + s->observers[i]->refresh_strip (false); } } // light bankup or bankdown buttons if it is possible to bank in that direction @@ -2917,7 +2772,7 @@ OSC::route_mute (int ssid, int yn, lo_message msg) } } - return route_send_fail ("mute", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/mute", ssid, 0, get_address (msg)); } int @@ -2952,7 +2807,7 @@ OSC::route_solo (int ssid, int yn, lo_message msg) } } - return route_send_fail ("solo", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo", ssid, 0, get_address (msg)); } int @@ -2969,7 +2824,7 @@ OSC::route_solo_iso (int ssid, int yn, lo_message msg) } } - return route_send_fail ("solo_iso", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo_iso", ssid, 0, get_address (msg)); } int @@ -2986,7 +2841,7 @@ OSC::route_solo_safe (int ssid, int yn, lo_message msg) } } - return route_send_fail ("solo_safe", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo_safe", ssid, 0, get_address (msg)); } int @@ -3081,7 +2936,7 @@ OSC::route_recenable (int ssid, int yn, lo_message msg) } } } - return route_send_fail ("recenable", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/recenable", ssid, 0, get_address (msg)); } int @@ -3134,7 +2989,7 @@ OSC::route_recsafe (int ssid, int yn, lo_message msg) } } } - return route_send_fail ("record_safe", ssid, 0,get_address (msg)); + return float_message_with_id ("/strip/record_safe", ssid, 0,get_address (msg)); } int @@ -3154,7 +3009,7 @@ OSC::route_monitor_input (int ssid, int yn, lo_message msg) } } - return route_send_fail ("monitor_input", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/monitor_input", ssid, 0, get_address (msg)); } int @@ -3196,7 +3051,7 @@ OSC::route_monitor_disk (int ssid, int yn, lo_message msg) } } - return route_send_fail ("monitor_disk", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/monitor_disk", ssid, 0, get_address (msg)); } int @@ -3236,7 +3091,7 @@ OSC::strip_phase (int ssid, int yn, lo_message msg) } } - return route_send_fail ("polarity", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/polarity", ssid, 0, get_address (msg)); } int @@ -3287,7 +3142,8 @@ OSC::_strip_select (boost::shared_ptr s, lo_address addr) } bool feedback_on = sur->feedback[13]; if (s && feedback_on) { - OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur); + sur->select = s; + OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, sur); s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); sur->sel_obs = sel_fb; } else if (sur->expand_enable) { @@ -3296,12 +3152,13 @@ OSC::_strip_select (boost::shared_ptr s, lo_address addr) sur->expand_enable = false; if (_select && feedback_on) { s = _select; - OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur); + sur->select = s; + OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, sur); s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); sur->sel_obs = sel_fb; } } else if (feedback_on) { - route_send_fail ("select", sur->expand, 0 , addr); + float_message_with_id ("/strip/select", sur->expand, 0 , addr); } // need to set monitor for processor changed signal // detecting processor changes requires cast to route @@ -3389,7 +3246,7 @@ OSC::strip_gui_select (int ssid, int yn, lo_message msg) SetStripableSelection (s); } else { if ((int) (sur->feedback.to_ulong())) { - route_send_fail ("select", ssid, 0, get_address (msg)); + float_message_with_id ("/strip/select", ssid, 0, get_address (msg)); } } @@ -3436,7 +3293,6 @@ int OSC::route_set_gain_dB (int ssid, float dB, lo_message msg) { if (!session) { - route_send_fail ("gain", ssid, -193, get_address (msg)); return -1; } int ret; @@ -3446,7 +3302,7 @@ OSC::route_set_gain_dB (int ssid, float dB, lo_message msg) ret = route_set_gain_abs (ssid, dB_to_coefficient (dB), msg); } if (ret != 0) { - return route_send_fail ("gain", ssid, -193, get_address (msg)); + return float_message_with_id ("/strip/gain", ssid, -193, get_address (msg)); } return 0; } @@ -3526,10 +3382,10 @@ OSC::route_set_gain_fader (int ssid, float pos, lo_message msg) fake_touch (s->gain_control()); s->gain_control()->set_value (s->gain_control()->interface_to_internal (pos), sur->usegroup); } else { - return route_send_fail ("fader", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/fader", ssid, 0, get_address (msg)); } } else { - return route_send_fail ("fader", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/fader", ssid, 0, get_address (msg)); } return 0; } @@ -3602,7 +3458,7 @@ OSC::route_set_trim_dB (int ssid, float dB, lo_message msg) int ret; ret = route_set_trim_abs(ssid, dB_to_coefficient (dB), msg); if (ret != 0) { - return route_send_fail ("trimdB", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/trimdB", ssid, 0, get_address (msg)); } return 0; @@ -3679,7 +3535,7 @@ OSC::route_set_pan_stereo_position (int ssid, float pos, lo_message msg) } } - return route_send_fail ("pan_stereo_position", ssid, 0.5, get_address (msg)); + return float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, get_address (msg)); } int @@ -3696,7 +3552,7 @@ OSC::route_set_pan_stereo_width (int ssid, float pos, lo_message msg) } } - return route_send_fail ("pan_stereo_width", ssid, 1, get_address (msg)); + return float_message_with_id ("/strip/pan_stereo_width", ssid, 1, get_address (msg)); } int @@ -4825,14 +4681,15 @@ OSC::gui_selection_changed () bool OSC::periodic (void) { + // XXXX tick turned off for testing + // return true; // no crash with this enabled :P if (!tick) { Glib::usleep(100); // let flurry of signals subside if (global_init) { - Glib::Threads::Mutex::Lock lm (surfaces_lock); for (uint32_t it = 0; it < _surface.size(); it++) { OSCSurface* sur = &_surface[it]; lo_address addr = lo_address_new_from_url (sur->remote_url.c_str()); - global_feedback (*sur, addr); + global_feedback (sur, addr); } global_init = false; tick = true; @@ -4843,6 +4700,7 @@ OSC::periodic (void) tick = true; } } + //return true; if (scrub_speed != 0) { // for those jog wheels that don't have 0 on release (touch), time out. @@ -4855,37 +4713,24 @@ OSC::periodic (void) session->request_locate (scrub_place, false); } } - - for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end(); x++) { - - OSCGlobalObserver* go; - - if ((go = dynamic_cast(*x)) != 0) { - go->tick(); - } - } - for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end(); x++) { - - OSCRouteObserver* ro; - - if ((ro = dynamic_cast(*x)) != 0) { - ro->tick(); - } - } for (uint32_t it = 0; it < _surface.size(); it++) { OSCSurface* sur = &_surface[it]; OSCSelectObserver* so; if ((so = dynamic_cast(sur->sel_obs)) != 0) { - so->tick(); + so->tick (); } - } - for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end(); x++) { - OSCCueObserver* co; - - if ((co = dynamic_cast(*x)) != 0) { - co->tick(); + if ((co = dynamic_cast(sur->cue_obs)) != 0) { + co->tick (); } + OSCGlobalObserver* go; + if ((go = dynamic_cast(sur->global_obs)) != 0) { + go->tick (); + } + for (uint32_t i = 0; i < sur->observers.size(); i++) { + sur->observers[i]->tick (); + } + } for (FakeTouchMap::iterator x = _touch_timeout.begin(); x != _touch_timeout.end();) { _touch_timeout[(*x).first] = (*x).second - 1; @@ -4901,40 +4746,6 @@ OSC::periodic (void) return true; } -int -OSC::route_send_fail (string path, uint32_t ssid, float val, lo_address addr) -{ - OSCSurface *sur = get_surface(addr); - - ostringstream os; - lo_message reply; - if (ssid) { - reply = lo_message_new (); - if (sur->feedback[2]) { - os << "/strip/" << path << "/" << ssid; - } else { - os << "/strip/" << path; - lo_message_add_int32 (reply, ssid); - } - string str_pth = os.str(); - lo_message_add_float (reply, (float) val); - - lo_send_message (addr, str_pth.c_str(), reply); - lo_message_free (reply); - } - if ((_select == get_strip (ssid, addr)) || ((sur->expand == ssid) && (sur->expand_enable))) { - os.str(""); - os << "/select/" << path; - string sel_pth = os.str(); - reply = lo_message_new (); - lo_message_add_float (reply, (float) val); - lo_send_message (addr, sel_pth.c_str(), reply); - lo_message_free (reply); - } - - return 0; -} - int OSC::sel_fail (string path, float val, lo_address addr) { @@ -5189,27 +5000,7 @@ OSC::_cue_set (uint32_t aux, lo_address addr) } s->aux = aux; - // get rid of any old CueObsevers for this address //cueobserver_connections.drop_connections (); - CueObservers::iterator x; - for (x = cue_observers.begin(); x != cue_observers.end();) { - - OSCCueObserver* co; - - if ((co = dynamic_cast(*x)) != 0) { - - int res = strcmp(lo_address_get_url(co->address()), lo_address_get_url(addr)); - - if (res == 0) { - delete *x; - x = cue_observers.erase (x); - } else { - ++x; - } - } else { - ++x; - } - } // get a list of Auxes for (uint32_t n = 0; n < s->nstrips; ++n) { @@ -5225,7 +5016,7 @@ OSC::_cue_set (uint32_t aux, lo_address addr) s->sends = cue_get_sorted_stripables(stp, aux, addr); // start cue observer OSCCueObserver* co = new OSCCueObserver (stp, s->sends, addr); - cue_observers.push_back (co); + s->cue_obs = co; ret = 0; } diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index cb2d027267..111b537be3 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -125,11 +125,26 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI // keep a surface's global setup by remote server url struct OSCSurface { public: + //global std::string remote_url; // the url these setting belong to bool no_clear; // don't send osc clear messages on strip change JogMode jogmode; // current jogmode + OSCGlobalObserver* global_obs; // pointer to this surface's global observer + uint32_t nstrips; // how many strips are there for strip_types + std::bitset<32> feedback; // What is fed back? strips/meters/timecode/bar_beat/global + int gainmode; // what kind of faders do we have Gain db or position 0 to 1? + PBD::Controllable::GroupControlDisposition usegroup; // current group disposition + Sorted strips; // list of stripables for this surface + // strips uint32_t bank; // current bank uint32_t bank_size; // size of banks for this surface + std::vector observers; // route observers for this surface + std::bitset<32> strip_types;// what strip types are a part of this bank + //select + OSCSelectObserver* sel_obs; // So we can sync select feedback with selected channel + uint32_t expand; // Used by /select/select + bool expand_enable; // use expand instead of select + boost::shared_ptr select; // stripable this surface uses (maybe expand strip) int plug_page; // current plugin page uint32_t plug_page_size; // plugin page size (number of controls) int plugin_id; // id of current plugin @@ -138,18 +153,11 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int send_page; // current send page uint32_t send_page_size; // send page size in channels PBD::ScopedConnection proc_connection; // for processor signal monitoring - std::bitset<32> strip_types;// what strip types are a part of this bank - uint32_t nstrips; // how many strips are there for strip_types - std::bitset<32> feedback; // What is fed back? strips/meters/timecode/bar_beat/global - int gainmode; // what kind of faders do we have Gain db or position 0 to 1? - PBD::Controllable::GroupControlDisposition usegroup; // current group disposition - uint32_t expand; // Used by /select/select - bool expand_enable; // use expand instead of select - OSCSelectObserver* sel_obs; // So we can sync select feedback with selected channel - Sorted strips; // list of stripables for this surface + // cue bool cue; // is this a cue surface uint32_t aux; // aux index for this cue surface Sorted sends; // list of sends for cue aux + OSCCueObserver* cue_obs; // pointer to this surface's cue observer }; /* * feedback bits: @@ -248,7 +256,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int check_surface (lo_message msg); uint32_t get_sid (boost::shared_ptr strip, lo_address addr); boost::shared_ptr get_strip (uint32_t ssid, lo_address addr); - void global_feedback (OSCSurface sur, lo_address addr); + void global_feedback (OSCSurface* sur, lo_address addr); + void strip_feedback (OSCSurface* sur); + void surface_destroy (OSCSurface* sur); void send_current_value (const char* path, lo_arg** argv, int argc, lo_message msg); void current_value_query (const char* path, size_t len, lo_arg **argv, int argc, lo_message msg); @@ -677,9 +687,6 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int sel_eq_shape (int id, float val, lo_message msg); 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 (void); void route_name_changed (const PBD::PropertyChange&, boost::weak_ptr r, lo_address addr); @@ -694,20 +701,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI PBD::ScopedConnectionList session_connections; PBD::ScopedConnectionList cueobserver_connections; - int route_send_fail (std::string path, uint32_t ssid, float val, lo_address addr); int sel_send_fail (std::string path, uint32_t id, float val, lo_address addr); int sel_fail (std::string path, float val, lo_address addr); - typedef std::list RouteObservers; - - RouteObservers route_observers; - - typedef std::list GlobalObservers; - GlobalObservers global_observers; - - typedef std::list CueObservers; - CueObservers cue_observers; - void debugmsg (const char *prefix, const char *path, const char* types, lo_arg **argv, int argc); static OSC* _instance; diff --git a/libs/surfaces/osc/osc_global_observer.cc b/libs/surfaces/osc/osc_global_observer.cc index 00f1b26a30..31d9b60e4e 100644 --- a/libs/surfaces/osc/osc_global_observer.cc +++ b/libs/surfaces/osc/osc_global_observer.cc @@ -36,8 +36,9 @@ using namespace PBD; using namespace ARDOUR; using namespace ArdourSurface; -OSCGlobalObserver::OSCGlobalObserver (Session& s, ArdourSurface::OSC::OSCSurface* su) - : sur (su) +OSCGlobalObserver::OSCGlobalObserver (OSC& o, Session& s, ArdourSurface::OSC::OSCSurface* su) + : _osc (o) + ,sur (su) ,_init (true) ,_last_master_gain (0.0) ,_last_master_trim (0.0) @@ -59,7 +60,7 @@ OSCGlobalObserver::OSCGlobalObserver (Session& s, ArdourSurface::OSC::OSCSurface */ // Master channel first - text_message (X_("/master/name"), "Master"); + _osc.text_message (X_("/master/name"), "Master", addr); boost::shared_ptr strip = session->master_out(); boost::shared_ptr mute_controllable = boost::dynamic_pointer_cast(strip->mute_control()); @@ -83,7 +84,7 @@ OSCGlobalObserver::OSCGlobalObserver (Session& s, ArdourSurface::OSC::OSCSurface // monitor stuff next strip = session->monitor_out(); if (strip) { - text_message (X_("/monitor/name"), "Monitor"); + _osc.text_message (X_("/monitor/name"), "Monitor", addr); boost::shared_ptr mon_mute_cont = strip->monitor_control()->cut_control(); mon_mute_cont->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_change_message, this, X_("/monitor/mute"), mon_mute_cont), OSC::instance()); @@ -114,8 +115,8 @@ OSCGlobalObserver::OSCGlobalObserver (Session& s, ArdourSurface::OSC::OSCSurface send_record_state_changed (); // session feedback - session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::text_message, this, X_("/session_name"), _1), OSC::instance()); - text_message (X_("/session_name"), session->snap_name()); + session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::session_name, this, X_("/session_name"), _1), OSC::instance()); + session_name (X_("/session_name"), session->snap_name()); session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::solo_active, this, _1), OSC::instance()); solo_active (session->soloing() || session->listening()); @@ -137,6 +138,61 @@ OSCGlobalObserver::~OSCGlobalObserver () lo_address_free (addr); } +void +OSCGlobalObserver::clear_observer () +{ + strip_connections.drop_connections (); + session_connections.drop_connections (); + _osc.text_message (X_("/master/name"), " ", addr); + _osc.text_message (X_("/monitor/name"), " ", addr); + _osc.text_message (X_("/session_name"), " ", addr); + if (feedback[6]) { // timecode enabled + _osc.text_message (X_("/position/smpte"), " ", addr); + } + if (feedback[5]) { // Bar beat enabled + _osc.text_message (X_("/position/bbt"), " ", addr); + } + if (feedback[11]) { // minutes/seconds enabled + _osc.text_message (X_("/position/time"), " ", addr); + } + if (feedback[10]) { // samples + _osc.text_message (X_("/position/samples"), " ", addr); + } + if (feedback[3]) { //heart beat enabled + _osc.float_message (X_("/heartbeat"), 0.0, addr); + } + if (feedback[7] || feedback[8]) { // meters enabled + float meter = 0; + if (feedback[7] && !gainmode) { + meter = -193; + } + _osc.float_message (X_("/master/meter"), meter, addr); + } + if (feedback[9]) { + _osc.float_message (X_("/master/signal"), 0, addr); + } + _osc.float_message ("/master/fader", 0, addr); + _osc.float_message ("/monitor/fader", 0, addr); + _osc.float_message ("/master/gain", -193, addr); + _osc.float_message ("/monitor/gain", -193, addr); + _osc.float_message (X_("/master/trimdB"), 0, addr); + _osc.float_message ("/master/mute", 0, addr); + _osc.float_message ("/master/pan_stereo_position", 0.5, addr); + _osc.float_message ("/monitor/mute", 0, addr); + _osc.float_message ("/monitor/dim", 0, addr); + _osc.float_message ("/monitor/mono", 0, addr); + _osc.float_message (X_("/loop_toggle"), 0, addr); + _osc.float_message (X_("/transport_play"), 0, addr); + _osc.float_message (X_("/transport_stop"), 0, addr); + _osc.float_message (X_("/rewind"), 0, addr); + _osc.float_message (X_("/ffwd"), 0, addr); + _osc.float_message (X_("/record_tally"), 0, addr); + _osc.float_message (X_("/rec_enable_toggle"), 0, addr); + _osc.float_message (X_("/cancel_all_solos"), 0, addr); + + +} + void OSCGlobalObserver::tick () { @@ -159,7 +215,7 @@ OSCGlobalObserver::tick () os << ':'; os << setw(2) << setfill('0') << timecode.frames; - text_message ("/position/smpte", os.str()); + _osc.text_message ("/position/smpte", os.str(), addr); } if (feedback[5]) { // Bar beat enabled Timecode::BBT_Time bbt_time; @@ -175,7 +231,7 @@ OSCGlobalObserver::tick () os << '|'; os << setw(4) << setfill('0') << bbt_time.ticks; - text_message ("/position/bbt", os.str()); + _osc.text_message ("/position/bbt", os.str(), addr); } if (feedback[11]) { // minutes/seconds enabled samplepos_t left = now_sample; @@ -197,21 +253,21 @@ OSCGlobalObserver::tick () os << '.'; os << setw(3) << setfill('0') << millisecs; - text_message ("/position/time", os.str()); + _osc.text_message ("/position/time", os.str(), addr); } if (feedback[10]) { // samples ostringstream os; os << now_sample; - text_message ("/position/samples", os.str()); + _osc.text_message ("/position/samples", os.str(), addr); } _last_sample = now_sample; } if (feedback[3]) { //heart beat enabled if (_heartbeat == 10) { - float_message (X_("/heartbeat"), 1.0); + _osc.float_message (X_("/heartbeat"), 1.0, addr); } if (!_heartbeat) { - float_message (X_("/heartbeat"), 0.0); + _osc.float_message (X_("/heartbeat"), 0.0, addr); } _heartbeat++; if (_heartbeat > 20) _heartbeat = 0; @@ -224,13 +280,13 @@ OSCGlobalObserver::tick () if (feedback[7] || feedback[8]) { if (gainmode && feedback[7]) { // change from db to 0-1 - float_message (X_("/master/meter"), ((now_meter + 94) / 100)); + _osc.float_message (X_("/master/meter"), ((now_meter + 94) / 100), addr); } else if ((!gainmode) && feedback[7]) { - float_message (X_("/master/meter"), now_meter); + _osc.float_message (X_("/master/meter"), now_meter, addr); } else if (feedback[8]) { uint32_t ledlvl = (uint32_t)(((now_meter + 54) / 3.75)-1); uint32_t ledbits = ~(0xfff< controllable) { - float_message (path, (float) controllable->get_value()); + _osc.float_message (path, (float) controllable->get_value(), addr); +} + +void +OSCGlobalObserver::session_name (string path, string name) +{ + _osc.text_message (path, name, addr); } void @@ -287,8 +349,8 @@ OSCGlobalObserver::send_gain_message (string path, boost::shared_ptrinternal_to_interface (controllable->get_value())); - text_message (string_compose ("%1name", path), string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value()))); + _osc.float_message (string_compose ("%1fader", path), controllable->internal_to_interface (controllable->get_value()), addr); + _osc.text_message (string_compose ("%1name", path), string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), addr); if (ismaster) { master_timeout = 8; } else { @@ -297,9 +359,9 @@ OSCGlobalObserver::send_gain_message (string path, boost::shared_ptrget_value() < 1e-15) { - float_message (string_compose ("%1gain",path), -200); + _osc.float_message (string_compose ("%1gain",path), -200, addr); } else { - float_message (string_compose ("%1gain",path), accurate_coefficient_to_dB (controllable->get_value())); + _osc.float_message (string_compose ("%1gain",path), accurate_coefficient_to_dB (controllable->get_value()), addr); } } } @@ -312,67 +374,34 @@ OSCGlobalObserver::send_trim_message (string path, boost::shared_ptrget_value())); + _osc.float_message (X_("/master/trimdB"), (float) accurate_coefficient_to_dB (controllable->get_value()), addr); } void OSCGlobalObserver::send_transport_state_changed() { - int_message (X_("/loop_toggle"), session->get_play_loop()); - int_message (X_("/transport_play"), session->transport_speed() == 1.0); - int_message (X_("/transport_stop"), session->transport_stopped()); - int_message (X_("/rewind"), session->transport_speed() < 0.0); - int_message (X_("/ffwd"), (session->transport_speed() != 1.0 && session->transport_speed() > 0.0)); + _osc.float_message (X_("/loop_toggle"), session->get_play_loop(), addr); + _osc.float_message (X_("/transport_play"), session->transport_speed() == 1.0, addr); + _osc.float_message (X_("/transport_stop"), session->transport_stopped(), addr); + _osc.float_message (X_("/rewind"), session->transport_speed() < 0.0, addr); + _osc.float_message (X_("/ffwd"), (session->transport_speed() != 1.0 && session->transport_speed() > 0.0), addr); } void OSCGlobalObserver::send_record_state_changed () { - int_message (X_("/rec_enable_toggle"), (int)session->get_record_enabled ()); + _osc.float_message (X_("/rec_enable_toggle"), (int)session->get_record_enabled (), addr); if (session->have_rec_enabled_track ()) { - int_message (X_("/record_tally"), 1); + _osc.float_message (X_("/record_tally"), 1, addr); } else { - int_message (X_("/record_tally"), 0); + _osc.float_message (X_("/record_tally"), 0, addr); } } void OSCGlobalObserver::solo_active (bool active) { - float_message (X_("/cancel_all_solos"), (float) active); -} - -void -OSCGlobalObserver::text_message (string path, std::string text) -{ - lo_message msg = lo_message_new (); - - lo_message_add_string (msg, text.c_str()); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); -} - -void -OSCGlobalObserver::float_message (string path, float value) -{ - lo_message msg = lo_message_new (); - - lo_message_add_float (msg, value); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); -} - -void -OSCGlobalObserver::int_message (string path, uint32_t value) -{ - lo_message msg = lo_message_new (); - - lo_message_add_int32 (msg, value); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); + _osc.float_message (X_("/cancel_all_solos"), (float) active, addr); } diff --git a/libs/surfaces/osc/osc_global_observer.h b/libs/surfaces/osc/osc_global_observer.h index 86832a54e8..4c071cdf0c 100644 --- a/libs/surfaces/osc/osc_global_observer.h +++ b/libs/surfaces/osc/osc_global_observer.h @@ -33,13 +33,15 @@ class OSCGlobalObserver { public: - OSCGlobalObserver (ARDOUR::Session& s, ArdourSurface::OSC::OSCSurface* su); + OSCGlobalObserver (ArdourSurface::OSC& o, ARDOUR::Session& s, ArdourSurface::OSC::OSCSurface* su); ~OSCGlobalObserver (); lo_address address() const { return addr; }; void tick (void); + void clear_observer (void); private: + ArdourSurface::OSC& _osc; PBD::ScopedConnectionList strip_connections; PBD::ScopedConnectionList session_connections; @@ -71,9 +73,7 @@ class OSCGlobalObserver void send_transport_state_changed (void); void send_record_state_changed (void); void solo_active (bool active); - void text_message (std::string path, std::string text); - void float_message (std::string path, float value); - void int_message (std::string path, uint32_t value); + void session_name (std::string path, std::string name); }; #endif /* __osc_oscglobalobserver_h__ */ diff --git a/libs/surfaces/osc/osc_route_observer.cc b/libs/surfaces/osc/osc_route_observer.cc index a960cf0003..6ce80ab789 100644 --- a/libs/surfaces/osc/osc_route_observer.cc +++ b/libs/surfaces/osc/osc_route_observer.cc @@ -59,12 +59,67 @@ OSCRouteObserver::~OSCRouteObserver () lo_address_free (addr); } +void +OSCRouteObserver::no_strip () +{ + // This gets called on drop references + _init = true; + + 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 OSCRouteObserver::refresh_strip (bool force) { _init = true; + uint32_t sid = sur->bank + ssid - 2; + if (sid >= sur->strips.size ()) { + // this _should_ only occure if the number of strips is less than banksize + clear_strip (); + return; + } + // future + /*if (sur->linkset) { + //to be added with linkset stuff + if (_osc.linksets[sur->linkset]->not_ready) + clear_strip (); + switch (ssid) { + case 1: + _osc.text_message_with_id ("/strip/name", ssid, "Device", addr); + break; + case 2: + _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1", not_ready), addr); + break; + case 3: + _osc.text_message_with_id ("/strip/name", ssid, "Missing", addr); + break; + case 4: + _osc.text_message_with_id ("/strip/name", ssid, "from", addr); + break; + case 5: + _osc.text_message_with_id ("/strip/name", ssid, "Linkset", addr); + break; + default: + break; + } + return; + } + }*/ - _strip = sur->strips[sur->bank + ssid - 2]; + boost::shared_ptr new_strip = sur->strips[sur->bank + ssid - 2]; + if (_strip && (new_strip == _strip) && !force) { + _init = false; + return; + } + + _strip = new_strip; + _strip->DropReferences.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCRouteObserver::no_strip, this), OSC::instance()); as = ARDOUR::Off; if (sur->feedback[0]) { // buttons are separate feedback @@ -130,6 +185,50 @@ OSCRouteObserver::refresh_strip (bool force) } +void +OSCRouteObserver::clear_strip () +{ + _init = true; + + strip_connections.drop_connections (); + + // all strip buttons should be off and faders 0 and etc. + _osc.float_message_with_id ("/strip/expand", ssid, 0, addr); + if (sur->feedback[0]) { // buttons are separate feedback + _osc.text_message_with_id ("/strip/name", ssid, " ", addr); + _osc.float_message_with_id ("/strip/mute", ssid, 0, addr); + _osc.float_message_with_id ("/strip/solo", ssid, 0, addr); + _osc.float_message_with_id ("/strip/recenable", ssid, 0, addr); + _osc.float_message_with_id ("/strip/record_safe", ssid, 0, addr); + _osc.float_message_with_id ("/strip/monitor_input", ssid, 0, addr); + _osc.float_message_with_id ("/strip/monitor_disk", ssid, 0, addr); + _osc.float_message_with_id ("/strip/gui_select", ssid, 0, addr); + _osc.float_message_with_id ("/strip/select", ssid, 0, addr); + } + if (sur->feedback[1]) { // level controls + if (sur->gainmode) { + _osc.float_message_with_id ("/strip/fader", ssid, 0, addr); + } else { + _osc.float_message_with_id ("/strip/gain", ssid, -193, addr); + } + _osc.float_message_with_id ("/strip/trimdB", ssid, 0, addr); + _osc.float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, addr); + } + if (sur->feedback[9]) { + _osc.float_message_with_id ("/strip/signal", ssid, 0, addr); + } + if (sur->feedback[7]) { + if (sur->gainmode) { + _osc.float_message_with_id ("/strip/meter", ssid, 0, addr); + } else { + _osc.float_message_with_id ("/strip/meter", ssid, -193, addr); + } + }else if (sur->feedback[8]) { + _osc.float_message_with_id ("/strip/meter", ssid, 0, addr); + } +} + + void OSCRouteObserver::tick () { diff --git a/libs/surfaces/osc/osc_route_observer.h b/libs/surfaces/osc/osc_route_observer.h index be7dd27a4e..2beefa0166 100644 --- a/libs/surfaces/osc/osc_route_observer.h +++ b/libs/surfaces/osc/osc_route_observer.h @@ -40,10 +40,12 @@ class OSCRouteObserver ~OSCRouteObserver (); boost::shared_ptr strip () const { return _strip; } - lo_address address() const { return addr; }; + uint32_t strip_id () const { return ssid; } + lo_address address () const { return addr; }; void tick (void); void send_select_status (const PBD::PropertyChange&); void refresh_strip (bool force); + void clear_strip (); private: boost::shared_ptr _strip; @@ -70,6 +72,7 @@ class OSCRouteObserver void send_gain_message (); void gain_automation (); void send_trim_message (); + void no_strip (); }; #endif /* __osc_oscrouteobserver_h__ */ diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc index 1889b04c26..eb0b57e7eb 100644 --- a/libs/surfaces/osc/osc_select_observer.cc +++ b/libs/surfaces/osc/osc_select_observer.cc @@ -49,8 +49,8 @@ using namespace PBD; using namespace ARDOUR; using namespace ArdourSurface; -OSCSelectObserver::OSCSelectObserver (boost::shared_ptr s, lo_address a, ArdourSurface::OSC::OSCSurface* su) - : _strip (s) +OSCSelectObserver::OSCSelectObserver (OSC& o, ArdourSurface::OSC::OSCSurface* su) + : _osc (o) ,sur (su) ,nsends (0) ,_last_gain (-1.0) @@ -58,12 +58,56 @@ OSCSelectObserver::OSCSelectObserver (boost::shared_ptr s, lo_address ,_init (true) { addr = lo_address_new_from_url (sur->remote_url.c_str()); + std::cout << "select observer created\n"; + refresh_strip (true); +} + +OSCSelectObserver::~OSCSelectObserver () +{ + _init = true; + no_strip (); + lo_address_free (addr); +} + +void +OSCSelectObserver::no_strip () +{ + // This gets called on drop references + _init = true; + + 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 +OSCSelectObserver::refresh_strip (bool force) +{ + _init = true; + + boost::shared_ptr new_strip = sur->select; + if (_strip && (new_strip == _strip) && !force) { + _init = false; + return; + } + std::cout << string_compose ("new select: %1\n", new_strip->name()); + + _strip = new_strip; + _strip->DropReferences.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::no_strip, this), OSC::instance()); + as = ARDOUR::Off; gainmode = sur->gainmode; feedback = sur->feedback; as = ARDOUR::Off; send_size = 0; plug_size = 0; _comp_redux = 1; + nsends = 0; + _last_gain = -1.0; + _last_trim = -1.0; _strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::name_changed, this, boost::lambda::_1), OSC::instance()); name_changed (ARDOUR::Properties::name); @@ -180,58 +224,56 @@ OSCSelectObserver::OSCSelectObserver (boost::shared_ptr s, lo_address tick(); } -OSCSelectObserver::~OSCSelectObserver () +void +OSCSelectObserver::clear_observer () { - _init = true; strip_connections.drop_connections (); // all strip buttons should be off and faders 0 and etc. - send_float ("/select/expand", 0); - text_message ("/select/name", " "); - text_message ("/select/comment", " "); - send_float ("/select/mute", 0); - send_float ("/select/solo", 0); - send_float ("/select/recenable", 0); - send_float ("/select/record_safe", 0); - send_float ("/select/monitor_input", 0); - send_float ("/select/monitor_disk", 0); - send_float ("/select/polarity", 0); - send_float ("/select/n_inputs", 0); - send_float ("/select/n_outputs", 0); + _osc.float_message ("/select/expand", 0, addr); + _osc.text_message ("/select/name", " ", addr); + _osc.text_message ("/select/comment", " ", addr); + _osc.float_message ("/select/mute", 0, addr); + _osc.float_message ("/select/solo", 0, addr); + _osc.float_message ("/select/recenable", 0, addr); + _osc.float_message ("/select/record_safe", 0, addr); + _osc.float_message ("/select/monitor_input", 0, addr); + _osc.float_message ("/select/monitor_disk", 0, addr); + _osc.float_message ("/select/polarity", 0, addr); + _osc.float_message ("/select/n_inputs", 0, addr); + _osc.float_message ("/select/n_outputs", 0, addr); if (gainmode) { - send_float ("/select/fader", 0); + _osc.float_message ("/select/fader", 0, addr); } else { - send_float ("/select/gain", -193); + _osc.float_message ("/select/gain", -193, addr); } - send_float ("/select/trimdB", 0); - send_float ("/select/pan_stereo_position", 0.5); - send_float ("/select/pan_stereo_width", 1); + _osc.float_message ("/select/trimdB", 0, addr); + _osc.float_message ("/select/pan_stereo_position", 0.5, addr); + _osc.float_message ("/select/pan_stereo_width", 1, addr); if (feedback[9]) { - send_float ("/select/signal", 0); + _osc.float_message ("/select/signal", 0, addr); } if (feedback[7]) { if (gainmode) { - send_float ("/select/meter", 0); + _osc.float_message ("/select/meter", 0, addr); } else { - send_float ("/select/meter", -193); + _osc.float_message ("/select/meter", -193, addr); } }else if (feedback[8]) { - send_float ("/select/meter", 0); + _osc.float_message ("/select/meter", 0, addr); } - send_float ("/select/pan_elevation_position", 0); - send_float ("/select/pan_frontback_position", .5); - send_float ("/select/pan_lfe_control", 0); - send_float ("/select/comp_enable", 0); - send_float ("/select/comp_threshold", 0); - send_float ("/select/comp_speed", 0); - send_float ("/select/comp_mode", 0); - text_message ("/select/comp_mode_name", " "); - text_message ("/select/comp_speed_name", " "); - send_float ("/select/comp_makeup", 0); + _osc.float_message ("/select/pan_elevation_position", 0, addr); + _osc.float_message ("/select/pan_frontback_position", .5, addr); + _osc.float_message ("/select/pan_lfe_control", 0, addr); + _osc.float_message ("/select/comp_enable", 0, addr); + _osc.float_message ("/select/comp_threshold", 0, addr); + _osc.float_message ("/select/comp_speed", 0, addr); + _osc.float_message ("/select/comp_mode", 0, addr); + _osc.text_message ("/select/comp_mode_name", " ", addr); + _osc.text_message ("/select/comp_speed_name", " ", addr); + _osc.float_message ("/select/comp_makeup", 0, addr); send_end(); plugin_end(); eq_end(); - - lo_address_free (addr); } void @@ -300,17 +342,17 @@ OSCSelectObserver::send_init() boost::shared_ptr r = boost::dynamic_pointer_cast (_strip); if (!r) { // should never get here - send_float_with_id ("/select/send_enable", c, 0); + _osc.float_message_with_id ("/select/send_enable", c, 0, addr); } boost::shared_ptr snd = boost::dynamic_pointer_cast (r->nth_send(s)); if (snd) { boost::shared_ptr proc = boost::dynamic_pointer_cast (snd); proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), c, proc), OSC::instance()); - send_float_with_id ("/select/send_enable", c, proc->enabled()); + _osc.float_message_with_id ("/select/send_enable", c, proc->enabled(), addr); } } if (!gainmode && send_valid) { - text_with_id ("/select/send_name", c, _strip->send_name(s)); + _osc.text_message_with_id ("/select/send_name", c, _strip->send_name(s), addr); } } } @@ -343,7 +385,7 @@ OSCSelectObserver::plugin_init() if (sur->plug_page_size) { plug_size = sur->plug_page_size; } - text_message ("/select/plugin/name", pip->name()); + _osc.text_message ("/select/plugin/name", pip->name(), addr); uint32_t page_end = nplug_params; uint32_t max_page = 1; if (plug_size && nplug_params) { @@ -362,8 +404,8 @@ OSCSelectObserver::plugin_init() int pid = 1; for ( uint32_t ppi = page_start; ppi < page_end; ++ppi, ++pid) { if (ppi >= nplug_params) { - text_with_id ("/select/plugin/parameter/name", pid, " "); - send_float_with_id ("/select/plugin/parameter", pid, 0); + _osc.text_message_with_id ("/select/plugin/parameter/name", pid, " ", addr); + _osc.float_message_with_id ("/select/plugin/parameter", pid, 0, addr); continue; } @@ -373,7 +415,7 @@ OSCSelectObserver::plugin_init() } ParameterDescriptor pd; pip->get_parameter_descriptor(controlid, pd); - text_with_id ("/select/plugin/parameter/name", pid, pd.label); + _osc.text_message_with_id ("/select/plugin/parameter/name", pid, pd.label, addr); if ( pip->parameter_is_input(controlid)) { boost::shared_ptr c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid)); if (c) { @@ -394,14 +436,14 @@ OSCSelectObserver::send_end () send_connections.drop_connections (); for (uint32_t i = 1; i <= send_size; i++) { if (gainmode) { - send_float_with_id ("/select/send_fader", i, 0); + _osc.float_message_with_id ("/select/send_fader", i, 0, addr); } else { - send_float_with_id ("/select/send_gain", i, -193); + _osc.float_message_with_id ("/select/send_gain", i, -193, addr); } // next enable - send_float_with_id ("/select/send_enable", i, 0); + _osc.float_message_with_id ("/select/send_enable", i, 0, addr); // next name - text_with_id ("/select/send_name", i, " "); + _osc.text_message_with_id ("/select/send_name", i, " ", addr); } // need to delete or clear send_timeout send_timeout.clear(); @@ -422,11 +464,11 @@ void OSCSelectObserver::plugin_end () { plugin_connections.drop_connections (); - text_message ("/select/plugin/name", " "); + _osc.text_message ("/select/plugin/name", " ", addr); for (uint32_t i = 1; i <= plug_size; i++) { - send_float_with_id ("/select/plugin/parameter", i, 0); + _osc.float_message_with_id ("/select/plugin/parameter", i, 0, addr); // next name - text_with_id ("/select/plugin/parameter/name", i, " "); + _osc.text_message_with_id ("/select/plugin/parameter/name", i, " ", addr); } nplug_params = 0; } @@ -448,33 +490,25 @@ OSCSelectObserver::tick () if (_last_meter != now_meter) { if (feedback[7] || feedback[8]) { string path = "/select/meter"; - lo_message msg = lo_message_new (); if (gainmode && feedback[7]) { - lo_message_add_float (msg, ((now_meter + 94) / 100)); - lo_send_message (addr, path.c_str(), msg); + _osc.float_message (path, ((now_meter + 94) / 100), addr); } else if ((!gainmode) && feedback[7]) { - lo_message_add_float (msg, now_meter); - lo_send_message (addr, path.c_str(), msg); + _osc.float_message (path, now_meter, addr); } else if (feedback[8]) { uint32_t ledlvl = (uint32_t)(((now_meter + 54) / 3.75)-1); uint16_t ledbits = ~(0xfff<name()); + _osc.text_message ("/select/name", _strip->name(), addr); } gain_timeout--; } @@ -496,7 +530,7 @@ OSCSelectObserver::tick () if (_strip->comp_redux_controllable() && _strip->comp_enable_controllable() && _strip->comp_enable_controllable()->get_value()) { float new_value = _strip->comp_redux_controllable()->get_parameter(); if (_comp_redux != new_value) { - send_float ("/select/comp_redux", new_value); + _osc.float_message ("/select/comp_redux", new_value, addr); _comp_redux = new_value; } } @@ -504,7 +538,7 @@ OSCSelectObserver::tick () if (send_timeout[i]) { if (send_timeout[i] == 1) { uint32_t pg_offset = (sur->send_page - 1) * sur->send_page_size; - text_with_id ("/select/send_name", i, _strip->send_name(pg_offset + i - 1)); + _osc.text_message_with_id ("/select/send_name", i, _strip->send_name(pg_offset + i - 1), addr); } send_timeout[i]--; } @@ -522,28 +556,24 @@ OSCSelectObserver::name_changed (const PBD::PropertyChange& what_changed) return; } - text_message ("/select/name", _strip->name()); + _osc.text_message ("/select/name", _strip->name(), addr); boost::shared_ptr route = boost::dynamic_pointer_cast (_strip); if (route) { //spit out the comment at the same time - text_message ("/select/comment", route->comment()); + _osc.text_message ("/select/comment", route->comment(), addr); // lets tell the surface how many inputs this strip has - send_float ("/select/n_inputs", (float) route->n_inputs().n_total()); + _osc.float_message ("/select/n_inputs", (float) route->n_inputs().n_total(), addr); // lets tell the surface how many outputs this strip has - send_float ("/select/n_outputs", (float) route->n_outputs().n_total()); + _osc.float_message ("/select/n_outputs", (float) route->n_outputs().n_total(), addr); } } void OSCSelectObserver::change_message (string path, boost::shared_ptr controllable) { - lo_message msg = lo_message_new (); 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 @@ -551,9 +581,9 @@ OSCSelectObserver::enable_message (string path, boost::shared_ptr { float val = controllable->get_value(); if (val) { - send_float (path, 1); + _osc.float_message (path, 1, addr); } else { - send_float (path, 0); + _osc.float_message (path, 0, addr); } } @@ -561,18 +591,9 @@ OSCSelectObserver::enable_message (string path, boost::shared_ptr void OSCSelectObserver::change_message_with_id (string path, uint32_t id, boost::shared_ptr controllable) { - lo_message msg = lo_message_new (); float val = controllable->get_value(); - if (feedback[2]) { - path = set_path (path, id); - } else { - lo_message_add_int32 (msg, id); - } - 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_with_id (path, id, (float) controllable->internal_to_interface (val), addr); } void @@ -580,23 +601,12 @@ OSCSelectObserver::enable_message_with_id (string path, uint32_t id, boost::shar { float val = controllable->get_value(); if (val) { - send_float_with_id (path, id, 1); + _osc.float_message_with_id (path, id, 1, addr); } else { - send_float_with_id (path, id, 0); + _osc.float_message_with_id (path, id, 0, addr); } } -void -OSCSelectObserver::text_message (string path, std::string text) -{ - lo_message msg = lo_message_new (); - - lo_message_add_string (msg, text.c_str()); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); -} - void OSCSelectObserver::monitor_status (boost::shared_ptr controllable) { @@ -616,8 +626,8 @@ OSCSelectObserver::monitor_status (boost::shared_ptr controllable) input = 0; } - send_float ("/select/monitor_input", (float) input); - send_float ("/select/monitor_disk", (float) disk); + _osc.float_message ("/select/monitor_input", (float) input, addr); + _osc.float_message ("/select/monitor_disk", (float) disk, addr); } void @@ -628,12 +638,8 @@ OSCSelectObserver::trim_message (string path, boost::shared_ptr co } else { return; } - lo_message msg = lo_message_new (); - lo_message_add_float (msg, (float) accurate_coefficient_to_dB (controllable->get_value())); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); + _osc.float_message (path, (float) accurate_coefficient_to_dB (controllable->get_value()), addr); } void @@ -647,14 +653,14 @@ OSCSelectObserver::gain_message () } if (gainmode) { - text_message ("/select/name", string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (value))); + _osc.text_message ("/select/name", string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (value)), addr); gain_timeout = 8; - send_float ("/select/fader", _strip->gain_control()->internal_to_interface (value)); + _osc.float_message ("/select/fader", _strip->gain_control()->internal_to_interface (value), addr); } else { if (value < 1e-15) { - send_float ("/select/gain", -200); + _osc.float_message ("/select/gain", -200, addr); } else { - send_float ("/select/gain", accurate_coefficient_to_dB (value)); + _osc.float_message ("/select/gain", accurate_coefficient_to_dB (value), addr); } } } @@ -687,11 +693,11 @@ OSCSelectObserver::gain_automation () } if (gainmode) { - send_float ("/select/fader/automation", output); - text_message ("/select/fader/automation_name", auto_name); + _osc.float_message ("/select/fader/automation", output, addr); + _osc.text_message ("/select/fader/automation_name", auto_name, addr); } else { - send_float ("/select/gain/automation", output); - text_message ("/select/gain/automation_name", auto_name); + _osc.float_message ("/select/gain/automation", output, addr); + _osc.text_message ("/select/gain/automation_name", auto_name, addr); } gain_message (); @@ -705,7 +711,6 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr } else { return; } - lo_message msg = lo_message_new (); string path; float value; float db; @@ -722,7 +727,7 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr if (gainmode) { path = "/select/send_fader"; value = controllable->internal_to_interface (controllable->get_value()); - text_with_id ("/select/send_name" , id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db)); + _osc.text_message_with_id ("/select/send_name" , id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db), addr); if (send_timeout.size() > id) { send_timeout[id] = 8; } @@ -731,15 +736,7 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr value = db; } - if (feedback[2]) { - path = set_path (path, id); - } else { - lo_message_add_int32 (msg, id); - } - - lo_message_add_float (msg, value); - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); + _osc.float_message_with_id (path, id, value, addr); } void @@ -748,31 +745,15 @@ OSCSelectObserver::send_enable (string path, uint32_t id, boost::shared_ptrenabled()); -} - -void -OSCSelectObserver::text_with_id (string path, uint32_t id, string name) -{ - lo_message msg = lo_message_new (); - if (feedback[2]) { - path = set_path (path, id); - } else { - lo_message_add_int32 (msg, id); - } - - lo_message_add_string (msg, name.c_str()); - - lo_send_message (addr, path.c_str(), msg); - lo_message_free (msg); + _osc.float_message_with_id ("/select/send_enable", id, proc->enabled(), addr); } void OSCSelectObserver::comp_mode () { change_message ("/select/comp_mode", _strip->comp_mode_controllable()); - text_message ("/select/comp_mode_name", _strip->comp_mode_name(_strip->comp_mode_controllable()->get_value())); - text_message ("/select/comp_speed_name", _strip->comp_speed_name(_strip->comp_mode_controllable()->get_value())); + _osc.text_message ("/select/comp_mode_name", _strip->comp_mode_name(_strip->comp_mode_controllable()->get_value()), addr); + _osc.text_message ("/select/comp_speed_name", _strip->comp_speed_name(_strip->comp_mode_controllable()->get_value()), addr); } void @@ -821,7 +802,7 @@ OSCSelectObserver::eq_init() for (uint32_t i = 0; i < eq_bands; i++) { if (_strip->eq_band_name(i).size()) { - text_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i)); + _osc.text_message_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i), addr); } if (_strip->eq_gain_controllable (i)) { _strip->eq_gain_controllable(i)->Changed.connect (eq_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::change_message_with_id, this, X_("/select/eq_gain"), i + 1, _strip->eq_gain_controllable(i)), OSC::instance()); @@ -847,18 +828,18 @@ OSCSelectObserver::eq_end () { eq_connections.drop_connections (); if (_strip->filter_freq_controllable (true)) { - send_float ("/select/eq_hpf", 0); + _osc.float_message ("/select/eq_hpf", 0, addr); } if (_strip->eq_enable_controllable ()) { - send_float ("/select/eq_enable", 0); + _osc.float_message ("/select/eq_enable", 0, addr); } for (uint32_t i = 1; i <= _strip->eq_band_cnt (); i++) { - text_with_id ("/select/eq_band_name", i, " "); - send_float_with_id ("/select/eq_gain", i, 0); - send_float_with_id ("/select/eq_freq", i, 0); - send_float_with_id ("/select/eq_q", i, 0); - send_float_with_id ("/select/eq_shape", i, 0); + _osc.text_message_with_id ("/select/eq_band_name", i, " ", addr); + _osc.float_message_with_id ("/select/eq_gain", i, 0, addr); + _osc.float_message_with_id ("/select/eq_freq", i, 0, addr); + _osc.float_message_with_id ("/select/eq_q", i, 0, addr); + _osc.float_message_with_id ("/select/eq_shape", i, 0, addr); } @@ -879,32 +860,3 @@ OSCSelectObserver::set_path (string path, uint32_t id) } return path; } - -void -OSCSelectObserver::send_float (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); - -} - -void -OSCSelectObserver::send_float_with_id (string path, uint32_t id, float val) -{ - lo_message msg = lo_message_new (); - if (feedback[2]) { - path = set_path (path, id); - } else { - lo_message_add_int32 (msg, id); - } - - 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_select_observer.h b/libs/surfaces/osc/osc_select_observer.h index 393a19dc70..218dce3735 100644 --- a/libs/surfaces/osc/osc_select_observer.h +++ b/libs/surfaces/osc/osc_select_observer.h @@ -37,7 +37,7 @@ class OSCSelectObserver { public: - OSCSelectObserver (boost::shared_ptr, lo_address addr, ArdourSurface::OSC::OSCSurface* sur); + OSCSelectObserver (ArdourSurface::OSC& o, ArdourSurface::OSC::OSCSurface* sur); ~OSCSelectObserver (); boost::shared_ptr strip () const { return _strip; } @@ -46,10 +46,14 @@ class OSCSelectObserver void renew_sends (void); void renew_plugin (void); void eq_restart (int); + void clear_observer (void); + void refresh_strip (bool force); + void no_strip (); private: boost::shared_ptr _strip; - + ArdourSurface::OSC& _osc; + PBD::ScopedConnectionList strip_connections; // sends, plugins and eq need their own PBD::ScopedConnectionList send_connections; @@ -81,8 +85,6 @@ class OSCSelectObserver void comp_mode (void); void change_message_with_id (std::string path, uint32_t id, boost::shared_ptr controllable); void enable_message_with_id (std::string path, uint32_t id, boost::shared_ptr controllable); - void text_message (std::string path, std::string text); - void text_with_id (std::string path, uint32_t id, std::string name); void monitor_status (boost::shared_ptr controllable); void gain_message (); void gain_automation (); @@ -98,8 +100,6 @@ class OSCSelectObserver void eq_init (void); void eq_end (void); std::string set_path (std::string path, uint32_t id); - void send_float (std::string path, float val); - void send_float_with_id (std::string path, uint32_t id, float val); }; #endif /* __osc_oscselectobserver_h__ */