diff options
author | Len Ovens <len@ovenwerks.net> | 2017-10-22 21:21:57 -0700 |
---|---|---|
committer | Len Ovens <len@ovenwerks.net> | 2017-10-22 21:25:30 -0700 |
commit | de9ae19d8c390ee07fe21559b0088d9ab3907828 (patch) | |
tree | 3be98d4fac191e6b3751ca55673f970627c535f4 | |
parent | 434c94174ff48c57b49dbebeda615721b9b3e431 (diff) |
OSC: fix various crash points
-rw-r--r-- | libs/surfaces/osc/osc.cc | 418 | ||||
-rw-r--r-- | libs/surfaces/osc/osc.h | 15 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_cue_observer.cc | 12 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_gui.cc | 1 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_route_observer.cc | 102 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_route_observer.h | 4 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_select_observer.cc | 84 | ||||
-rw-r--r-- | libs/surfaces/osc/osc_select_observer.h | 2 |
8 files changed, 372 insertions, 266 deletions
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index f6117c671a..c57576e32d 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -105,6 +105,7 @@ OSC::OSC (Session& s, uint32_t port) , default_plugin_size (0) , tick (true) , bank_dirty (false) + , observer_busy (true) , scrub_speed (0) , gui (0) { @@ -236,6 +237,7 @@ OSC::start () } } + observer_busy = false; register_callbacks(); session_loaded (*session); @@ -260,7 +262,10 @@ OSC::start () // order changed PresentationInfo::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); - _select = boost::shared_ptr<Stripable>(); + _select = ControlProtocol::first_selected_stripable(); + if(!_select) { + _select = session->master_out (); + } return 0; } @@ -298,19 +303,18 @@ OSC::thread_init () int OSC::stop () { - /* stop main loop */ + periodic_connection.disconnect (); + session_connections.drop_connections (); // clear surfaces - for (uint32_t it = 0; it < _surface.size(); ++it) { + observer_busy = true; + for (uint32_t it = 0; it < _surface.size (); ++it) { OSCSurface* sur = &_surface[it]; surface_destroy (sur); } _surface.clear(); - periodic_connection.disconnect (); - session_connections.drop_connections (); - cueobserver_connections.drop_connections (); - + /* stop main loop */ if (local_server) { g_source_destroy (local_server); g_source_unref (local_server); @@ -349,26 +353,38 @@ OSC::stop () void OSC::surface_destroy (OSCSurface* sur) { - if (sur->sel_obs) { - sur->sel_obs->clear_observer (); - delete sur->sel_obs; + OSCSelectObserver* so; + if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) { + so->clear_observer (); + delete so; sur->sel_obs = 0; + PBD::ScopedConnection pc = sur->proc_connection; + pc.disconnect (); } - if (sur->cue_obs) { - sur->cue_obs->clear_observer (); - delete sur->cue_obs; + + OSCCueObserver* co; + if ((co = dynamic_cast<OSCCueObserver*>(sur->cue_obs)) != 0) { + co->clear_observer (); + delete co; sur->cue_obs = 0; } - if (sur->global_obs) { - sur->global_obs->clear_observer (); - delete sur->global_obs; + + OSCGlobalObserver* go; + if ((go = dynamic_cast<OSCGlobalObserver*>(sur->global_obs)) != 0) { + go->clear_observer (); + delete go; sur->global_obs = 0; } - for (uint32_t i = 0; i < sur->observers.size(); i++) { - sur->observers[i]->clear_strip (); - delete sur->observers[i]; - } + uint32_t st_end = sur->observers.size (); + for (uint32_t i = 0; i < st_end; i++) { + OSCRouteObserver* ro; + if ((ro = dynamic_cast<OSCRouteObserver*>(sur->observers[i])) != 0) { + ro->clear_strip (); + delete ro; + ro = 0; + } + } sur->observers.clear(); } @@ -775,7 +791,10 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_ /* 15 for /#current_value plus 2 for /<path> */ len = strlen (path); + /* + * not needed until /strip/listen/ignore fixed OSCSurface *sur = get_surface(get_address (msg)); + */ if (strstr (path, "/automation")) { ret = set_automation (path, types, argv, argc, msg); @@ -1130,8 +1149,7 @@ OSC::routes_list (lo_message msg) if (!session) { return; } - OSCSurface *sur = get_surface(get_address (msg)); - sur->no_clear = true; + OSCSurface *sur = get_surface(get_address (msg), true); for (int n = 0; n < (int) sur->nstrips; ++n) { @@ -1192,13 +1210,6 @@ OSC::routes_list (lo_message msg) if (s->rec_enable_control()) { lo_message_add_int32 (reply, s->rec_enable_control()->get_value()); } - - /* - * 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); } else { @@ -1228,6 +1239,16 @@ OSC::routes_list (lo_message msg) } lo_message_free (reply); + // send feedback for newly created control surface + strip_feedback (sur, true); + global_feedback (sur); + // need to add select start + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } + } int @@ -1253,7 +1274,7 @@ OSC::get_address (lo_message msg) int OSC::refresh_surface (lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + OSCSurface *s = get_surface(get_address (msg), true); surface_destroy (s); // restart all observers set_surface (s->bank_size, (uint32_t) s->strip_types.to_ulong(), (uint32_t) s->feedback.to_ulong(), \ @@ -1265,13 +1286,18 @@ void OSC::clear_devices () { tick = false; - + observer_busy = true; + session_connections.drop_connections (); // clear out surfaces for (uint32_t it = 0; it < _surface.size(); ++it) { OSCSurface* sur = &_surface[it]; surface_destroy (sur); } _surface.clear(); + + PresentationInfo::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); + + observer_busy = false; tick = true; } @@ -1279,7 +1305,7 @@ int OSC::surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg) { int ret = 1; /* unhandled */ - OSCSurface *sur = get_surface(get_address (msg)); + OSCSurface *sur = get_surface(get_address (msg), true); int pi_page = sur->plug_page_size; int se_page = sur->send_page_size; int fadermode = sur->gainmode; @@ -1453,7 +1479,10 @@ OSC::surface_parse (const char *path, const char* types, lo_arg **argv, int argc int OSC::set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gm, uint32_t se_size, uint32_t pi_size, lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + if (observer_busy) { + return -1; + } + OSCSurface *s = get_surface(get_address (msg), true); s->bank_size = b_size; s->strip_types = strips; s->feedback = fb; @@ -1466,9 +1495,14 @@ 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 - strip_feedback(s); + strip_feedback(s, true); - global_feedback (s, get_address (msg)); + global_feedback (s); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } sel_send_pagesize (se_size, msg); sel_plug_pagesize (pi_size, msg); return 0; @@ -1477,19 +1511,30 @@ OSC::set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gm, ui int OSC::set_surface_bank_size (uint32_t bs, lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + if (observer_busy) { + return -1; + } + OSCSurface *s = get_surface(get_address (msg), true); s->bank_size = bs; s->bank = 1; // set bank and strip feedback - strip_feedback (s); + strip_feedback (s, true); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } return 0; } int OSC::set_surface_strip_types (uint32_t st, lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + if (observer_busy) { + return -1; + } + OSCSurface *s = get_surface(get_address (msg), true); s->strip_types = st; if (s->strip_types[10]) { s->usegroup = PBD::Controllable::UseGroup; @@ -1499,7 +1544,12 @@ OSC::set_surface_strip_types (uint32_t st, lo_message msg) // set bank and strip feedback s->bank = 1; - strip_feedback (s); + strip_feedback (s, true); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } return 0; } @@ -1507,28 +1557,44 @@ OSC::set_surface_strip_types (uint32_t st, lo_message msg) int OSC::set_surface_feedback (uint32_t fb, lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + if (observer_busy) { + return -1; + } + OSCSurface *s = get_surface(get_address (msg), true); s->feedback = fb; // set strip feedback - strip_feedback (s); + strip_feedback (s, false); // Set global/master feedback - global_feedback (s, get_address (msg)); + global_feedback (s); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } return 0; } int OSC::set_surface_gainmode (uint32_t gm, lo_message msg) { - OSCSurface *s = get_surface(get_address (msg)); + if (observer_busy) { + return -1; + } + OSCSurface *s = get_surface(get_address (msg), true); s->gainmode = gm; // set strip feedback - strip_feedback (s); + strip_feedback (s, false); // Set global/master feedback - global_feedback (s, get_address (msg)); + global_feedback (s); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), get_address (msg)); + } else { + _strip_select (session->master_out (), get_address (msg)); + } return 0; } @@ -1543,7 +1609,7 @@ OSC::check_surface (lo_message msg) } OSC::OSCSurface * -OSC::get_surface (lo_address addr) +OSC::get_surface (lo_address addr , bool quiet) { string r_url; char * rurl; @@ -1596,26 +1662,29 @@ OSC::get_surface (lo_address addr) { _surface.push_back (s); } - // moved this down here as selection may need s.<anything to do with select> set - if (!_select || (_select != ControlProtocol::first_selected_stripable())) { - gui_selection_changed(); - } - // set bank and strip feedback - strip_feedback (&s); + if (!quiet) { + // set bank and strip feedback - // Set global/master feedback - global_feedback (&s, addr); + strip_feedback (&s, true); + + // Set global/master feedback + global_feedback (&s); + if(ControlProtocol::first_selected_stripable()) { + _strip_select (ControlProtocol::first_selected_stripable(), addr); + } else { + _strip_select (session->master_out (), addr); + } + } 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) { - std::bitset<32> feedback = sur->feedback; - if (feedback[4] || feedback[3] || feedback[5] || feedback[6]) { + if (sur->feedback[4] || sur->feedback[3] || sur->feedback[5] || sur->feedback[6]) { // create a new Global Observer for this surface OSCGlobalObserver* o = new OSCGlobalObserver (*this, *session, sur); @@ -1624,29 +1693,40 @@ OSC::global_feedback (OSCSurface* sur, lo_address addr) } void -OSC::strip_feedback (OSCSurface* sur) +OSC::strip_feedback (OSCSurface* sur, bool new_bank_size) { - // 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(); + if (new_bank_size || (!sur->feedback[0] && !sur->feedback[1])) { + // delete old observers + for (uint32_t i = 0; i < sur->observers.size(); i++) { + if (!sur->bank_size) { + sur->observers[i]->clear_strip (); + } + delete sur->observers[i]; + } + sur->observers.clear(); - // 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; - } + // 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 (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); + 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); + } + } + } else { + if (sur->feedback[0] || sur->feedback[1]) { + for (uint32_t i = 0; i < sur->observers.size(); i++) { + sur->observers[i]->refresh_strip(true); + } } } + bank_leds (sur); } void @@ -1673,10 +1753,25 @@ OSC::recalcbanks () void OSC::_recalcbanks () { + if (observer_busy) { + return; + } if (!_select || (_select != ControlProtocol::first_selected_stripable())) { _select = ControlProtocol::first_selected_stripable(); gui_selection_changed (); } + /* + * We have two different ways of working here: + * 1) banked: The controller has a bank of strips and only can deal + * with banksize strips. We start banksize observers which run until + * either banksize is changed or Ardour exits. + * + * 2) banksize is 0 or unlimited and so is the same size as the number + * of strips. For a recalc, We want to tear down all strips but not send + * a reset value for any of the controls and then rebuild all observers. + * this is easier than detecting change in "bank" size and deleting or + * adding just a few. + */ // refresh each surface we know about. for (uint32_t it = 0; it < _surface.size(); ++it) { @@ -1685,18 +1780,17 @@ OSC::_recalcbanks () lo_address addr = lo_address_new_from_url (sur->remote_url.c_str()); if (sur->cue) { _cue_set (sur->aux, addr); - } else { - for (uint32_t i = 0; i < sur->observers.size(); i++) { - sur->observers[i]->refresh_strip (false); - } - } - - if (!sur->bank_size) { + } else if (!sur->bank_size) { + strip_feedback (sur, true); // This surface uses /strip/list tell it routes have changed lo_message reply; reply = lo_message_new (); lo_send_message (addr, "/strip/list", reply); lo_message_free (reply); + } else { + for (uint32_t i = 0; i < sur->observers.size(); i++) { + sur->observers[i]->refresh_strip (false); + } } } } @@ -1754,7 +1848,17 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr) s->observers[i]->refresh_strip (false); } } + bank_leds (s); + bank_dirty = false; + tick = true; + return 0; +} + +void +OSC::bank_leds (OSCSurface* s) +{ // light bankup or bankdown buttons if it is possible to bank in that direction + lo_address addr = lo_address_new_from_url (s->remote_url.c_str()); if (s->feedback[4] && !s->no_clear) { lo_message reply; reply = lo_message_new (); @@ -1774,9 +1878,6 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr) lo_send_message (addr, "/bank_down", reply); lo_message_free (reply); } - bank_dirty = false; - tick = true; - return 0; } int @@ -2761,7 +2862,7 @@ OSC::route_mute (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/mute", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/mute", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2796,7 +2897,7 @@ OSC::route_solo (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/solo", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2813,7 +2914,7 @@ OSC::route_solo_iso (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/solo_iso", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo_iso", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2830,7 +2931,7 @@ OSC::route_solo_safe (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/solo_safe", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/solo_safe", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2925,7 +3026,7 @@ OSC::route_recenable (int ssid, int yn, lo_message msg) } } } - return float_message_with_id ("/strip/recenable", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/recenable", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2978,7 +3079,7 @@ OSC::route_recsafe (int ssid, int yn, lo_message msg) } } } - return float_message_with_id ("/strip/record_safe", ssid, 0,get_address (msg)); + return float_message_with_id ("/strip/record_safe", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -2998,7 +3099,7 @@ OSC::route_monitor_input (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/monitor_input", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/monitor_input", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -3040,7 +3141,7 @@ OSC::route_monitor_disk (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/monitor_disk", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/monitor_disk", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -3080,7 +3181,7 @@ OSC::strip_phase (int ssid, int yn, lo_message msg) } } - return float_message_with_id ("/strip/polarity", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/polarity", ssid, 0, sur->feedback[2], get_address (msg)); } int @@ -3124,32 +3225,36 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr) if (!session) { return -1; } - OSCSurface *sur = get_surface(addr); - if (sur->sel_obs) { - delete sur->sel_obs; - sur->sel_obs = 0; - } - bool feedback_on = sur->feedback[13]; - if (s && feedback_on) { + OSCSurface *sur = get_surface(addr, true); + if (s) { 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) { // expand doesn't point to a stripable, turn it off and use select sur->expand = 0; sur->expand_enable = false; - if (_select && feedback_on) { + if (_select) { s = _select; sur->select = s; + } + } + + OSCSelectObserver* so = 0; + if (sur->feedback[13]) { + if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) { + so->refresh_strip (false); + } else { 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) { - float_message_with_id ("/strip/select", sur->expand, 0 , addr); + } else { + if (so != 0) { + delete so; + sur->sel_obs = 0; + } } - // need to set monitor for processor changed signal + + // need to set monitor for processor changed signal (for paging) // detecting processor changes requires cast to route boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s); if (r) { @@ -3157,52 +3262,12 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr) processor_changed (addr); } - if (!feedback_on) { - return 0; - } - //update buttons on surface - int b_s = sur->bank_size; - if (!b_s) { // bank size 0 means we need to know how many strips there are. - b_s = sur->nstrips; - } - for (int i = 1; i <= b_s; i++) { - string path = "expand"; - - if ((i == (int) sur->expand) && sur->expand_enable) { - lo_message reply = lo_message_new (); - if (sur->feedback[2]) { - ostringstream os; - os << "/strip/" << path << "/" << i; - path = os.str(); - } else { - ostringstream os; - os << "/strip/" << path; - path = os.str(); - lo_message_add_int32 (reply, i); - } - lo_message_add_float (reply, (float) 1); - - lo_send_message (addr, path.c_str(), reply); - lo_message_free (reply); - reply = lo_message_new (); - lo_message_add_float (reply, 1.0); - lo_send_message (addr, "/select/expand", reply); - lo_message_free (reply); - - } else { - lo_message reply = lo_message_new (); - lo_message_add_int32 (reply, i); - lo_message_add_float (reply, 0.0); - lo_send_message (addr, "/strip/expand", reply); - lo_message_free (reply); + for (uint32_t i = 0; i < sur->observers.size(); i++) { + OSCRouteObserver* ro; + if ((ro = dynamic_cast<OSCRouteObserver*>(sur->observers[i])) != 0) { + ro->refresh_strip (false); } } - if (!sur->expand_enable) { - lo_message reply = lo_message_new (); - lo_message_add_float (reply, 0.0); - lo_send_message (addr, "/select/expand", reply); - lo_message_free (reply); - } return 0; } @@ -3235,7 +3300,7 @@ OSC::strip_gui_select (int ssid, int yn, lo_message msg) SetStripableSelection (s); } else { if ((int) (sur->feedback.to_ulong())) { - float_message_with_id ("/strip/select", ssid, 0, get_address (msg)); + float_message_with_id ("/strip/select", ssid, 0, sur->feedback[2], get_address (msg)); } } @@ -3284,6 +3349,7 @@ OSC::route_set_gain_dB (int ssid, float dB, lo_message msg) if (!session) { return -1; } + OSCSurface *sur = get_surface(get_address (msg)); int ret; if (dB < -192) { ret = route_set_gain_abs (ssid, 0.0, msg); @@ -3291,7 +3357,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 float_message_with_id ("/strip/gain", ssid, -193, get_address (msg)); + return float_message_with_id ("/strip/gain", ssid, -193, sur->feedback[2], get_address (msg)); } return 0; } @@ -3371,10 +3437,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 float_message_with_id ("/strip/fader", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/fader", ssid, 0, sur->feedback[2], get_address (msg)); } } else { - return float_message_with_id ("/strip/fader", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/fader", ssid, 0, sur->feedback[2], get_address (msg)); } return 0; } @@ -3444,10 +3510,11 @@ OSC::route_set_trim_abs (int ssid, float level, lo_message msg) int OSC::route_set_trim_dB (int ssid, float dB, lo_message msg) { + OSCSurface *sur = get_surface(get_address (msg)); int ret; ret = route_set_trim_abs(ssid, dB_to_coefficient (dB), msg); if (ret != 0) { - return float_message_with_id ("/strip/trimdB", ssid, 0, get_address (msg)); + return float_message_with_id ("/strip/trimdB", ssid, 0, sur->feedback[2], get_address (msg)); } return 0; @@ -3524,7 +3591,7 @@ OSC::route_set_pan_stereo_position (int ssid, float pos, lo_message msg) } } - return float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, get_address (msg)); + return float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, sur->feedback[2], get_address (msg)); } int @@ -3541,7 +3608,7 @@ OSC::route_set_pan_stereo_width (int ssid, float pos, lo_message msg) } } - return float_message_with_id ("/strip/pan_stereo_width", ssid, 1, get_address (msg)); + return float_message_with_id ("/strip/pan_stereo_width", ssid, 1, sur->feedback[2], get_address (msg)); } int @@ -4670,15 +4737,15 @@ OSC::gui_selection_changed () bool OSC::periodic (void) { - // XXXX tick turned off for testing - // return true; // no crash with this enabled :P + if (observer_busy) { + return true; + } if (!tick) { Glib::usleep(100); // let flurry of signals subside if (global_init) { 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); } global_init = false; tick = true; @@ -4688,8 +4755,8 @@ OSC::periodic (void) bank_dirty = false; tick = true; } + return true; } - //return true; if (scrub_speed != 0) { // for those jog wheels that don't have 0 on release (touch), time out. @@ -4717,7 +4784,10 @@ OSC::periodic (void) go->tick (); } for (uint32_t i = 0; i < sur->observers.size(); i++) { - sur->observers[i]->tick (); + OSCRouteObserver* ro; + if ((ro = dynamic_cast<OSCRouteObserver*>(sur->observers[i])) != 0) { + ro->tick (); + } } } @@ -4990,8 +5060,6 @@ OSC::_cue_set (uint32_t aux, lo_address addr) } s->aux = aux; - //cueobserver_connections.drop_connections (); - // get a list of Auxes for (uint32_t n = 0; n < s->nstrips; ++n) { boost::shared_ptr<Stripable> stp = s->strips[n]; @@ -5160,11 +5228,10 @@ OSC::float_message (string path, float val, lo_address addr) } int -OSC::float_message_with_id (std::string path, uint32_t ssid, float value, lo_address addr) +OSC::float_message_with_id (std::string path, uint32_t ssid, float value, bool in_line, lo_address addr) { - OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->cue || sur->feedback[2]) { + if (in_line) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); @@ -5177,11 +5244,10 @@ OSC::float_message_with_id (std::string path, uint32_t ssid, float value, lo_add } int -OSC::int_message_with_id (std::string path, uint32_t ssid, int value, lo_address addr) +OSC::int_message_with_id (std::string path, uint32_t ssid, int value, bool in_line, lo_address addr) { - OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->cue || sur->feedback[2]) { + if (in_line) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); @@ -5208,11 +5274,10 @@ OSC::text_message (string path, string val, lo_address addr) } int -OSC::text_message_with_id (std::string path, uint32_t ssid, std::string val, lo_address addr) +OSC::text_message_with_id (std::string path, uint32_t ssid, std::string val, bool in_line, lo_address addr) { - OSCSurface *sur = get_surface(addr); lo_message msg = lo_message_new (); - if (sur->cue || sur->feedback[2]) { + if (in_line) { path = string_compose ("%1/%2", path, ssid); } else { lo_message_add_int32 (msg, ssid); @@ -5231,7 +5296,6 @@ OSC::Sorted OSC::cue_get_sorted_stripables(boost::shared_ptr<Stripable> aux, uint32_t id, lo_message msg) { Sorted sorted; - cueobserver_connections.drop_connections (); // fetch all stripables StripableList stripables; diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index 111b537be3..8ad9ec0307 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -91,9 +91,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest> int float_message (std::string, float value, lo_address addr); int text_message (std::string path, std::string val, lo_address addr); - int float_message_with_id (std::string, uint32_t ssid, float value, lo_address addr); - int int_message_with_id (std::string, uint32_t ssid, int value, lo_address addr); - int text_message_with_id (std::string path, uint32_t ssid, std::string val, lo_address addr); + int float_message_with_id (std::string, uint32_t ssid, float value, bool in_line, lo_address addr); + int int_message_with_id (std::string, uint32_t ssid, int value, bool in_line, lo_address addr); + int text_message_with_id (std::string path, uint32_t ssid, std::string val, bool in_line, lo_address addr); int start (); int stop (); @@ -234,6 +234,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest> uint32_t default_plugin_size; bool tick; bool bank_dirty; + bool observer_busy; float scrub_speed; // Current scrub speed double scrub_place; // place of play head at latest jog/scrub wheel tick int64_t scrub_time; // when did the wheel move last? @@ -252,13 +253,14 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest> std::string get_unix_server_url (); lo_address get_address (lo_message msg); - OSCSurface * get_surface (lo_address addr); + OSCSurface * get_surface (lo_address addr, bool quiet = false); int check_surface (lo_message msg); uint32_t get_sid (boost::shared_ptr<ARDOUR::Stripable> strip, lo_address addr); boost::shared_ptr<ARDOUR::Stripable> get_strip (uint32_t ssid, lo_address addr); - void global_feedback (OSCSurface* sur, lo_address addr); - void strip_feedback (OSCSurface* sur); + void global_feedback (OSCSurface* sur); + void strip_feedback (OSCSurface* sur, bool new_bank_size); void surface_destroy (OSCSurface* sur); + void bank_leds (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); @@ -699,7 +701,6 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest> bool periodic (void); sigc::connection periodic_connection; PBD::ScopedConnectionList session_connections; - PBD::ScopedConnectionList cueobserver_connections; 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); diff --git a/libs/surfaces/osc/osc_cue_observer.cc b/libs/surfaces/osc/osc_cue_observer.cc index 6cdc50e11e..bd310abdc5 100644 --- a/libs/surfaces/osc/osc_cue_observer.cc +++ b/libs/surfaces/osc/osc_cue_observer.cc @@ -59,7 +59,7 @@ OSCCueObserver::clear_observer () 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.text_message_with_id ("/cue/name", 0, " ", true, addr); _osc.float_message ("/cue/mute", 0, addr); _osc.float_message ("/cue/fader", 0, addr); _osc.float_message ("/cue/signal", 0, addr); @@ -195,7 +195,7 @@ OSCCueObserver::send_end () for (uint32_t i = 1; i <= sends.size(); 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); + _osc.text_message_with_id ("/cue/send/name", i, " ", true, addr); } gain_timeout.clear (); _last_gain.clear (); @@ -221,7 +221,7 @@ OSCCueObserver::name_changed (const PBD::PropertyChange& what_changed, uint32_t return; } if (id) { - _osc.text_message_with_id ("/cue/send/name", id, sends[id - 1]->name(), addr); + _osc.text_message_with_id ("/cue/send/name", id, sends[id - 1]->name(), true, addr); } else { _osc.text_message ("/cue/name", _strip->name(), addr); } @@ -247,8 +247,8 @@ OSCCueObserver::send_gain_message (uint32_t id, boost::shared_ptr<Controllable> return; } if (id) { - _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); + _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())), true, addr); + _osc.float_message_with_id ("/cue/send/fader", id, controllable->internal_to_interface (controllable->get_value()), true, 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); @@ -261,7 +261,7 @@ void OSCCueObserver::send_enabled_message (std::string path, uint32_t id, boost::shared_ptr<ARDOUR::Processor> proc) { if (id) { - _osc.float_message_with_id (path, id, (float) proc->enabled(), addr); + _osc.float_message_with_id (path, id, (float) proc->enabled(), true, addr); } else { _osc.float_message (path, (float) proc->enabled(), addr); } diff --git a/libs/surfaces/osc/osc_gui.cc b/libs/surfaces/osc/osc_gui.cc index 57fe2aa682..e1ae8bdea5 100644 --- a/libs/surfaces/osc/osc_gui.cc +++ b/libs/surfaces/osc/osc_gui.cc @@ -980,6 +980,7 @@ OSC_GUI::load_preset (std::string preset) gainmode_combo.set_active (atoi (prop->value().c_str())); } cp.gui_changed(); + clear_device (); } } diff --git a/libs/surfaces/osc/osc_route_observer.cc b/libs/surfaces/osc/osc_route_observer.cc index 6ce80ab789..1d3921066c 100644 --- a/libs/surfaces/osc/osc_route_observer.cc +++ b/libs/surfaces/osc/osc_route_observer.cc @@ -45,6 +45,7 @@ OSCRouteObserver::OSCRouteObserver (OSC& o, uint32_t ss, ArdourSurface::OSC::OSC ,_last_gain (-1.0) ,_last_trim (-1.0) ,_init (true) + ,_expand (false) { addr = lo_address_new_from_url (sur->remote_url.c_str()); refresh_strip (true); @@ -53,7 +54,6 @@ OSCRouteObserver::OSCRouteObserver (OSC& o, uint32_t ss, ArdourSurface::OSC::OSC OSCRouteObserver::~OSCRouteObserver () { _init = true; - strip_connections.drop_connections (); lo_address_free (addr); @@ -78,6 +78,9 @@ void OSCRouteObserver::refresh_strip (bool force) { _init = true; + gainmode = sur->gainmode; + feedback = sur->feedback; + in_line = feedback[2]; 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 @@ -112,17 +115,34 @@ OSCRouteObserver::refresh_strip (bool force) } }*/ + // this has to be done first because expand may change with no strip change + bool new_expand; + if (sur->expand_enable && sur->expand == ssid) { + new_expand = true; + } else { + new_expand = false; + } + if (new_expand != _expand) { + _expand = new_expand; + if (_expand) { + _osc.float_message_with_id ("/strip/expand", ssid, 1.0, in_line, addr); + } else { + _osc.float_message_with_id ("/strip/expand", ssid, 0.0, in_line, addr); + } + } + send_select_status (ARDOUR::Properties::selected); + boost::shared_ptr<ARDOUR::Stripable> new_strip = sur->strips[sur->bank + ssid - 2]; if (_strip && (new_strip == _strip) && !force) { _init = false; return; } - + strip_connections.drop_connections (); _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 + if (feedback[0]) { // buttons are separate feedback _strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCRouteObserver::name_changed, this, boost::lambda::_1), OSC::instance()); name_changed (ARDOUR::Properties::name); @@ -162,7 +182,7 @@ OSCRouteObserver::refresh_strip (bool force) send_select_status (ARDOUR::Properties::selected); } - if (sur->feedback[1]) { // level controls + if (feedback[1]) { // level controls boost::shared_ptr<GainControl> gain_cont = _strip->gain_control(); gain_cont->alist()->automation_state_changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCRouteObserver::gain_automation, this), OSC::instance()); gain_cont->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCRouteObserver::send_gain_message, this), OSC::instance()); @@ -193,38 +213,38 @@ OSCRouteObserver::clear_strip () 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); + _osc.float_message_with_id ("/strip/expand", ssid, 0, in_line, 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); + _osc.text_message_with_id ("/strip/name", ssid, " ", in_line, addr); + _osc.float_message_with_id ("/strip/mute", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/solo", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/recenable", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/record_safe", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/monitor_input", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/monitor_disk", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/gui_select", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/select", ssid, 0, in_line, addr); } if (sur->feedback[1]) { // level controls if (sur->gainmode) { - _osc.float_message_with_id ("/strip/fader", ssid, 0, addr); + _osc.float_message_with_id ("/strip/fader", ssid, 0, in_line, addr); } else { - _osc.float_message_with_id ("/strip/gain", ssid, -193, addr); + _osc.float_message_with_id ("/strip/gain", ssid, -193, in_line, addr); } - _osc.float_message_with_id ("/strip/trimdB", ssid, 0, addr); - _osc.float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, addr); + _osc.float_message_with_id ("/strip/trimdB", ssid, 0, in_line, addr); + _osc.float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, in_line, addr); } if (sur->feedback[9]) { - _osc.float_message_with_id ("/strip/signal", ssid, 0, addr); + _osc.float_message_with_id ("/strip/signal", ssid, 0, in_line, addr); } if (sur->feedback[7]) { if (sur->gainmode) { - _osc.float_message_with_id ("/strip/meter", ssid, 0, addr); + _osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr); } else { - _osc.float_message_with_id ("/strip/meter", ssid, -193, addr); + _osc.float_message_with_id ("/strip/meter", ssid, -193, in_line, addr); } }else if (sur->feedback[8]) { - _osc.float_message_with_id ("/strip/meter", ssid, 0, addr); + _osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr); } } @@ -247,13 +267,13 @@ OSCRouteObserver::tick () if (_last_meter != now_meter) { if (sur->feedback[7] || sur->feedback[8]) { if (sur->gainmode && sur->feedback[7]) { - _osc.float_message_with_id ("/strip/meter", ssid, ((now_meter + 94) / 100), addr); + _osc.float_message_with_id ("/strip/meter", ssid, ((now_meter + 94) / 100), in_line, addr); } else if ((!sur->gainmode) && sur->feedback[7]) { - _osc.float_message_with_id ("/strip/meter", ssid, now_meter, addr); + _osc.float_message_with_id ("/strip/meter", ssid, now_meter, in_line, addr); } else if (sur->feedback[8]) { uint32_t ledlvl = (uint32_t)(((now_meter + 54) / 3.75)-1); uint16_t ledbits = ~(0xfff<<ledlvl); - _osc.int_message_with_id ("/strip/meter", ssid, ledbits, addr); + _osc.int_message_with_id ("/strip/meter", ssid, ledbits, in_line, addr); } } if (sur->feedback[9]) { @@ -263,7 +283,7 @@ OSCRouteObserver::tick () } else { signal = 1; } - _osc.float_message_with_id ("/strip/signal", ssid, signal, addr); + _osc.float_message_with_id ("/strip/signal", ssid, signal, in_line, addr); } } _last_meter = now_meter; @@ -272,13 +292,13 @@ OSCRouteObserver::tick () if (sur->feedback[1]) { if (gain_timeout) { if (gain_timeout == 1) { - _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), addr); + _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), in_line, addr); } gain_timeout--; } if (trim_timeout) { if (trim_timeout == 1) { - _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), addr); + _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), in_line, addr); } trim_timeout--; } @@ -300,7 +320,7 @@ OSCRouteObserver::name_changed (const PBD::PropertyChange& what_changed) } if (_strip) { - _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), addr); + _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), in_line, addr); } } @@ -308,7 +328,7 @@ void OSCRouteObserver::send_change_message (string path, boost::shared_ptr<Controllable> controllable) { float val = controllable->get_value(); - _osc.float_message_with_id (path, ssid, (float) controllable->internal_to_interface (val), addr); + _osc.float_message_with_id (path, ssid, (float) controllable->internal_to_interface (val), in_line, addr); } void @@ -333,8 +353,8 @@ OSCRouteObserver::send_monitor_status (boost::shared_ptr<Controllable> controlla disk = 0; input = 0; } - _osc.int_message_with_id ("/strip/monitor_input", ssid, input, addr); - _osc.int_message_with_id ("/strip/monitor_disk", ssid, disk, addr); + _osc.int_message_with_id ("/strip/monitor_input", ssid, input, in_line, addr); + _osc.int_message_with_id ("/strip/monitor_disk", ssid, disk, in_line, addr); } @@ -347,11 +367,11 @@ OSCRouteObserver::send_trim_message () return; } if (sur->gainmode) { - _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (_last_trim)), addr); + _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (_last_trim)), in_line, addr); trim_timeout = 8; } - _osc.float_message_with_id ("/strip/trimdB", ssid, (float) accurate_coefficient_to_dB (_last_trim), addr); + _osc.float_message_with_id ("/strip/trimdB", ssid, (float) accurate_coefficient_to_dB (_last_trim), in_line, addr); } void @@ -365,14 +385,14 @@ OSCRouteObserver::send_gain_message () } if (sur->gainmode) { - _osc.float_message_with_id ("/strip/fader", ssid, controllable->internal_to_interface (_last_gain), addr); - _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), addr); + _osc.float_message_with_id ("/strip/fader", ssid, controllable->internal_to_interface (_last_gain), in_line, addr); + _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), in_line, addr); gain_timeout = 8; } else { if (controllable->get_value() < 1e-15) { - _osc.float_message_with_id ("/strip/gain", ssid, -200, addr); + _osc.float_message_with_id ("/strip/gain", ssid, -200, in_line, addr); } else { - _osc.float_message_with_id ("/strip/gain", ssid, accurate_coefficient_to_dB (_last_gain), addr); + _osc.float_message_with_id ("/strip/gain", ssid, accurate_coefficient_to_dB (_last_gain), in_line, addr); } } } @@ -412,8 +432,8 @@ OSCRouteObserver::gain_automation () default: break; } - _osc.float_message_with_id (string_compose ("%1/automation", path), ssid, output, addr); - _osc.text_message_with_id (string_compose ("%1/automation_name", path), ssid, auto_name, addr); + _osc.float_message_with_id (string_compose ("%1/automation", path), ssid, output, in_line, addr); + _osc.text_message_with_id (string_compose ("%1/automation_name", path), ssid, auto_name, in_line, addr); } void @@ -421,7 +441,7 @@ OSCRouteObserver::send_select_status (const PropertyChange& what) { if (what == PropertyChange(ARDOUR::Properties::selected)) { if (_strip) { - _osc.float_message_with_id ("/strip/select", ssid, _strip->is_selected(), addr); + _osc.float_message_with_id ("/strip/select", ssid, _strip->is_selected(), in_line, addr); } } } diff --git a/libs/surfaces/osc/osc_route_observer.h b/libs/surfaces/osc/osc_route_observer.h index 2beefa0166..e2781571e3 100644 --- a/libs/surfaces/osc/osc_route_observer.h +++ b/libs/surfaces/osc/osc_route_observer.h @@ -55,6 +55,8 @@ class OSCRouteObserver ArdourSurface::OSC& _osc; lo_address addr; std::string path; + uint32_t gainmode; + std::bitset<32> feedback; uint32_t ssid; ArdourSurface::OSC::OSCSurface* sur; float _last_meter; @@ -63,6 +65,8 @@ class OSCRouteObserver float _last_gain; float _last_trim; bool _init; + bool _expand; + bool in_line; ARDOUR::AutoState as; diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc index 1c96220df4..c60603b0df 100644 --- a/libs/surfaces/osc/osc_select_observer.cc +++ b/libs/surfaces/osc/osc_select_observer.cc @@ -58,7 +58,6 @@ OSCSelectObserver::OSCSelectObserver (OSC& o, ArdourSurface::OSC::OSCSurface* su ,_init (true) { addr = lo_address_new_from_url (sur->remote_url.c_str()); - std::cout << "select observer created\n"; refresh_strip (true); } @@ -76,6 +75,9 @@ OSCSelectObserver::no_strip () _init = true; strip_connections.drop_connections (); + send_connections.drop_connections (); + plugin_connections.drop_connections (); + eq_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 @@ -89,18 +91,30 @@ OSCSelectObserver::refresh_strip (bool force) { _init = true; + // this has to be done first because expand may change with no strip change + if (sur->expand_enable) { + _osc.float_message ("/select/expand", 1.0, addr); + } else { + _osc.float_message ("/select/expand", 0.0, addr); + } + boost::shared_ptr<ARDOUR::Stripable> 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; + if (!_strip) { + clear_observer (); + return; + } + _strip->DropReferences.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::no_strip, this), OSC::instance()); as = ARDOUR::Off; gainmode = sur->gainmode; feedback = sur->feedback; + in_line = feedback[2]; as = ARDOUR::Off; send_size = 0; plug_size = 0; @@ -218,7 +232,9 @@ OSCSelectObserver::refresh_strip (bool force) _strip->comp_makeup_controllable ()->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::change_message, this, X_("/select/comp_makeup"), _strip->comp_makeup_controllable()), OSC::instance()); change_message ("/select/comp_makeup", _strip->comp_makeup_controllable()); } - + renew_sends (); + renew_plugin (); + eq_restart(0); _init = false; tick(); @@ -227,6 +243,7 @@ OSCSelectObserver::refresh_strip (bool force) void OSCSelectObserver::clear_observer () { + _init = true; strip_connections.drop_connections (); // all strip buttons should be off and faders 0 and etc. _osc.float_message ("/select/expand", 0, addr); @@ -271,6 +288,7 @@ OSCSelectObserver::clear_observer () _osc.text_message ("/select/comp_mode_name", " ", addr); _osc.text_message ("/select/comp_speed_name", " ", addr); _osc.float_message ("/select/comp_makeup", 0, addr); + _osc.float_message ("/select/expand", 0.0, addr); send_end(); plugin_end(); eq_end(); @@ -342,17 +360,17 @@ OSCSelectObserver::send_init() boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_strip); if (!r) { // should never get here - _osc.float_message_with_id ("/select/send_enable", c, 0, addr); + _osc.float_message_with_id ("/select/send_enable", c, 0, in_line, addr); } boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(s)); if (snd) { boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (snd); proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), c, proc), OSC::instance()); - _osc.float_message_with_id ("/select/send_enable", c, proc->enabled(), addr); + _osc.float_message_with_id ("/select/send_enable", c, proc->enabled(), in_line, addr); } } if (!gainmode && send_valid) { - _osc.text_message_with_id ("/select/send_name", c, _strip->send_name(s), addr); + _osc.text_message_with_id ("/select/send_name", c, _strip->send_name(s), in_line, addr); } } } @@ -360,7 +378,7 @@ OSCSelectObserver::send_init() void OSCSelectObserver::plugin_init() { - if (!sur->plugin_id) { + if (!sur->plugin_id || !sur->plugins.size ()) { return; } @@ -404,8 +422,8 @@ OSCSelectObserver::plugin_init() int pid = 1; for ( uint32_t ppi = page_start; ppi < page_end; ++ppi, ++pid) { if (ppi >= nplug_params) { - _osc.text_message_with_id ("/select/plugin/parameter/name", pid, " ", addr); - _osc.float_message_with_id ("/select/plugin/parameter", pid, 0, addr); + _osc.text_message_with_id ("/select/plugin/parameter/name", pid, " ", in_line, addr); + _osc.float_message_with_id ("/select/plugin/parameter", pid, 0, in_line, addr); continue; } @@ -415,7 +433,7 @@ OSCSelectObserver::plugin_init() } ParameterDescriptor pd; pip->get_parameter_descriptor(controlid, pd); - _osc.text_message_with_id ("/select/plugin/parameter/name", pid, pd.label, addr); + _osc.text_message_with_id ("/select/plugin/parameter/name", pid, pd.label, in_line, addr); if ( pip->parameter_is_input(controlid)) { boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid)); if (c) { @@ -436,14 +454,14 @@ OSCSelectObserver::send_end () send_connections.drop_connections (); for (uint32_t i = 1; i <= send_size; i++) { if (gainmode) { - _osc.float_message_with_id ("/select/send_fader", i, 0, addr); + _osc.float_message_with_id ("/select/send_fader", i, 0, in_line, addr); } else { - _osc.float_message_with_id ("/select/send_gain", i, -193, addr); + _osc.float_message_with_id ("/select/send_gain", i, -193, in_line, addr); } // next enable - _osc.float_message_with_id ("/select/send_enable", i, 0, addr); + _osc.float_message_with_id ("/select/send_enable", i, 0, in_line, addr); // next name - _osc.text_message_with_id ("/select/send_name", i, " ", addr); + _osc.text_message_with_id ("/select/send_name", i, " ", in_line, addr); } // need to delete or clear send_timeout send_timeout.clear(); @@ -466,9 +484,9 @@ OSCSelectObserver::plugin_end () plugin_connections.drop_connections (); _osc.text_message ("/select/plugin/name", " ", addr); for (uint32_t i = 1; i <= plug_size; i++) { - _osc.float_message_with_id ("/select/plugin/parameter", i, 0, addr); + _osc.float_message_with_id ("/select/plugin/parameter", i, 0, in_line, addr); // next name - _osc.text_message_with_id ("/select/plugin/parameter/name", i, " ", addr); + _osc.text_message_with_id ("/select/plugin/parameter/name", i, " ", in_line, addr); } nplug_params = 0; } @@ -538,7 +556,7 @@ OSCSelectObserver::tick () if (send_timeout[i]) { if (send_timeout[i] == 1) { uint32_t pg_offset = (sur->send_page - 1) * sur->send_page_size; - _osc.text_message_with_id ("/select/send_name", i, _strip->send_name(pg_offset + i - 1), addr); + _osc.text_message_with_id ("/select/send_name", i, _strip->send_name(pg_offset + i - 1), in_line, addr); } send_timeout[i]--; } @@ -593,7 +611,7 @@ OSCSelectObserver::change_message_with_id (string path, uint32_t id, boost::shar { float val = controllable->get_value(); - _osc.float_message_with_id (path, id, (float) controllable->internal_to_interface (val), addr); + _osc.float_message_with_id (path, id, (float) controllable->internal_to_interface (val), in_line, addr); } void @@ -601,9 +619,9 @@ OSCSelectObserver::enable_message_with_id (string path, uint32_t id, boost::shar { float val = controllable->get_value(); if (val) { - _osc.float_message_with_id (path, id, 1, addr); + _osc.float_message_with_id (path, id, 1, in_line, addr); } else { - _osc.float_message_with_id (path, id, 0, addr); + _osc.float_message_with_id (path, id, 0, in_line, addr); } } @@ -727,7 +745,7 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr<PBD::Controllable> if (gainmode) { path = "/select/send_fader"; value = controllable->internal_to_interface (controllable->get_value()); - _osc.text_message_with_id ("/select/send_name" , id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db), addr); + _osc.text_message_with_id ("/select/send_name" , id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db), in_line, addr); if (send_timeout.size() > id) { send_timeout[id] = 8; } @@ -736,7 +754,7 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr<PBD::Controllable> value = db; } - _osc.float_message_with_id (path, id, value, addr); + _osc.float_message_with_id (path, id, value, in_line, addr); } void @@ -745,7 +763,7 @@ OSCSelectObserver::send_enable (string path, uint32_t id, boost::shared_ptr<Proc // with no delay value is wrong Glib::usleep(10); - _osc.float_message_with_id ("/select/send_enable", id, proc->enabled(), addr); + _osc.float_message_with_id ("/select/send_enable", id, proc->enabled(), in_line, addr); } void @@ -795,14 +813,14 @@ OSCSelectObserver::eq_init() enable_message ("/select/eq_enable", _strip->eq_enable_controllable()); } - uint32_t eq_bands = _strip->eq_band_cnt (); + eq_bands = _strip->eq_band_cnt (); if (!eq_bands) { return; } for (uint32_t i = 0; i < eq_bands; i++) { if (_strip->eq_band_name(i).size()) { - _osc.text_message_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i), addr); + _osc.text_message_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i), in_line, 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()); @@ -827,19 +845,15 @@ void OSCSelectObserver::eq_end () { eq_connections.drop_connections (); - if (_strip->filter_freq_controllable (true)) { _osc.float_message ("/select/eq_hpf", 0, addr); - } - if (_strip->eq_enable_controllable ()) { _osc.float_message ("/select/eq_enable", 0, addr); - } - for (uint32_t i = 1; i <= _strip->eq_band_cnt (); i++) { - _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); + for (uint32_t i = 1; i <= eq_bands; i++) { + _osc.text_message_with_id ("/select/eq_band_name", i, " ", in_line, addr); + _osc.float_message_with_id ("/select/eq_gain", i, 0, in_line, addr); + _osc.float_message_with_id ("/select/eq_freq", i, 0, in_line, addr); + _osc.float_message_with_id ("/select/eq_q", i, 0, in_line, addr); + _osc.float_message_with_id ("/select/eq_shape", i, 0, in_line, addr); } diff --git a/libs/surfaces/osc/osc_select_observer.h b/libs/surfaces/osc/osc_select_observer.h index 2dbf824419..c4a06517c6 100644 --- a/libs/surfaces/osc/osc_select_observer.h +++ b/libs/surfaces/osc/osc_select_observer.h @@ -63,6 +63,7 @@ class OSCSelectObserver std::string path; uint32_t gainmode; std::bitset<32> feedback; + bool in_line; ArdourSurface::OSC::OSCSurface* sur; std::vector<int> send_timeout; uint32_t gain_timeout; @@ -77,6 +78,7 @@ class OSCSelectObserver uint32_t send_size; uint32_t nplug_params; uint32_t plug_size; + uint32_t eq_bands; void name_changed (const PBD::PropertyChange& what_changed); void change_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable); |