From c4a4857b8710654e8b91aa354f602331ed8fc859 Mon Sep 17 00:00:00 2001 From: Len Ovens Date: Tue, 6 Jun 2017 07:35:24 -0700 Subject: OSC: add optional paging to sends in select. --- libs/surfaces/osc/osc.cc | 117 ++++++++++++++++++++++++++----- libs/surfaces/osc/osc.h | 15 +++- libs/surfaces/osc/osc_select_observer.cc | 91 +++++++++++++++++------- libs/surfaces/osc/osc_select_observer.h | 8 ++- 4 files changed, 183 insertions(+), 48 deletions(-) diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 4818f9340c..72d8010c3f 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -565,6 +565,11 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, "/select/send_gain", "if", sel_sendgain); REGISTER_CALLBACK (serv, "/select/send_fader", "if", sel_sendfader); REGISTER_CALLBACK (serv, "/select/send_enable", "if", sel_sendenable); + REGISTER_CALLBACK (serv, "/select/send_page", "f", sel_send_page); + REGISTER_CALLBACK (serv, "/select/send_page_size", "f", sel_send_pagesize); + REGISTER_CALLBACK (serv, "/select/plug_page", "f", sel_plug_page); + REGISTER_CALLBACK (serv, "/select/plug_page_size", "f", sel_plug_pagesize); + REGISTER_CALLBACK (serv, "/select/plugin", "f", sel_plugin); REGISTER_CALLBACK (serv, "/select/expand", "i", sel_expand); REGISTER_CALLBACK (serv, "/select/pan_elevation_position", "f", sel_pan_elevation); REGISTER_CALLBACK (serv, "/select/pan_frontback_position", "f", sel_pan_frontback); @@ -1394,7 +1399,6 @@ OSC::set_surface_feedback (uint32_t fb, lo_message msg) return 0; } - int OSC::set_surface_gainmode (uint32_t gm, lo_message msg) { @@ -1461,6 +1465,11 @@ OSC::get_surface (lo_address addr) s.cue = false; s.aux = 0; s.strips = get_sorted_stripables(s.strip_types, s.cue); + s.send_page = 1; + s.send_page_size = 0; + s.plug_page = 1; + s.plug_page_size = 0; + s.plugin = 1; s.nstrips = s.strips.size(); _surface.push_back (s); @@ -1727,6 +1736,57 @@ OSC::get_strip (uint32_t ssid, lo_address addr) return boost::shared_ptr(); } +// send and plugin paging commands +int +OSC::sel_send_pagesize (uint32_t size, lo_message msg) +{ + OSCSurface *s = get_surface(get_address (msg)); + if (size != s->send_page_size) { + s->send_page_size = size; + s->sel_obs->renew_sends(); + } + return 0; +} + +int +OSC::sel_send_page (int page, lo_message msg) +{ + OSCSurface *s = get_surface(get_address (msg)); + s->send_page = s->send_page + page; + s->sel_obs->renew_sends(); + return 0; +} + +int +OSC::sel_plug_pagesize (uint32_t size, lo_message msg) +{ + OSCSurface *s = get_surface(get_address (msg)); + if (size != s->plug_page_size) { + s->plug_page_size = size; + s->sel_obs->renew_plugin(); + } + return 0; +} + +int +OSC::sel_plug_page (int page, lo_message msg) +{ + OSCSurface *s = get_surface(get_address (msg)); + s->plug_page = s->plug_page + page; + s->sel_obs->renew_plugin(); + return 0; +} + +int +OSC::sel_plugin (uint32_t id, lo_message msg) +{ + OSCSurface *s = get_surface(get_address (msg)); + s->plugin = id; + s->plug_page = 1; + s->sel_obs->renew_plugin(); + return 0; +} + void OSC::transport_frame (lo_message msg) { @@ -2762,14 +2822,14 @@ OSC::_strip_select (boost::shared_ptr s, lo_address addr) } bool feedback_on = sur->feedback.to_ulong(); if (s && feedback_on) { - OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur->gainmode, sur->feedback); + OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur); s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); sur->sel_obs = sel_fb; } else if (sur->expand_enable) { sur->expand = 0; sur->expand_enable = false; if (_select && feedback_on) { - OSCSelectObserver* sel_fb = new OSCSelectObserver (_select, addr, sur->gainmode, sur->feedback); + OSCSelectObserver* sel_fb = new OSCSelectObserver (_select, addr, sur); _select->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); sur->sel_obs = sel_fb; } @@ -3144,6 +3204,9 @@ int OSC::sel_sendgain (int id, float val, lo_message msg) { OSCSurface *sur = get_surface(get_address (msg)); + if (sur->send_page_size && (id > (int)sur->send_page_size)) { + return sel_send_fail ("send_gain", id, -193, get_address (msg)); + } boost::shared_ptr s; if (sur->expand_enable) { s = get_strip (sur->expand, get_address (msg)); @@ -3151,9 +3214,10 @@ OSC::sel_sendgain (int id, float val, lo_message msg) s = _select; } float abs; + int send_id; if (s) { if (id > 0) { - --id; + send_id = id - 1; } #ifdef MIXBUS abs = val; @@ -3164,18 +3228,24 @@ OSC::sel_sendgain (int id, float val, lo_message msg) abs = dB_to_coefficient (val); } #endif - if (s->send_level_controllable (id)) { - s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup); + if (sur->send_page_size) { + send_id = send_id + ((sur->send_page - 1) * sur->send_page_size); + } + if (s->send_level_controllable (send_id)) { + s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup); return 0; } } - return sel_send_fail ("send_gain", id + 1, -193, get_address (msg)); + return sel_send_fail ("send_gain", id, -193, get_address (msg)); } int OSC::sel_sendfader (int id, float val, lo_message msg) { OSCSurface *sur = get_surface(get_address (msg)); + if (sur->send_page_size && (id > (int)sur->send_page_size)) { + return sel_send_fail ("send_fader", id, 0, get_address (msg)); + } boost::shared_ptr s; if (sur->expand_enable) { s = get_strip (sur->expand, get_address (msg)); @@ -3183,19 +3253,23 @@ OSC::sel_sendfader (int id, float val, lo_message msg) s = _select; } float abs; + int send_id; if (s) { if (id > 0) { - --id; + send_id = id - 1; + } + if (sur->send_page_size) { + send_id = send_id + ((sur->send_page - 1) * sur->send_page_size); } - if (s->send_level_controllable (id)) { + if (s->send_level_controllable (send_id)) { #ifdef MIXBUS - abs = s->send_level_controllable(id)->interface_to_internal (val); + abs = s->send_level_controllable(send_id)->interface_to_internal (val); #else abs = slider_position_to_gain_with_max (val, 2.0); #endif - s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup); + s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup); return 0; } } @@ -3248,27 +3322,34 @@ int OSC::sel_sendenable (int id, float val, lo_message msg) { OSCSurface *sur = get_surface(get_address (msg)); + if (sur->send_page_size && (id > (int)sur->send_page_size)) { + return sel_send_fail ("send_enable", id, 0, get_address (msg)); + } boost::shared_ptr s; if (sur->expand_enable) { s = get_strip (sur->expand, get_address (msg)); } else { s = _select; } + int send_id; if (s) { if (id > 0) { - --id; + send_id = id - 1; + } + if (sur->send_page_size) { + send_id = send_id + ((sur->send_page - 1) * sur->send_page_size); } - if (s->send_enable_controllable (id)) { - s->send_enable_controllable (id)->set_value (val, PBD::Controllable::NoGroup); + if (s->send_enable_controllable (send_id)) { + s->send_enable_controllable (send_id)->set_value (val, PBD::Controllable::NoGroup); return 0; } - if (s->send_level_controllable (id)) { + if (s->send_level_controllable (send_id)) { boost::shared_ptr r = boost::dynamic_pointer_cast (s); if (!r) { // should never get here - return sel_send_fail ("send_enable", id + 1, 0, get_address (msg)); + return sel_send_fail ("send_enable", id, 0, get_address (msg)); } - boost::shared_ptr snd = boost::dynamic_pointer_cast (r->nth_send(id)); + boost::shared_ptr snd = boost::dynamic_pointer_cast (r->nth_send(send_id)); if (snd) { if (val) { snd->activate(); @@ -3279,7 +3360,7 @@ OSC::sel_sendenable (int id, float val, lo_message msg) return 0; } } - return sel_send_fail ("send_enable", id + 1, 0, get_address (msg)); + return sel_send_fail ("send_enable", id, 0, get_address (msg)); } int diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index fb8a5e5365..5bb55113c0 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -121,9 +121,10 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI JogMode jogmode; // current jogmode uint32_t bank; // current bank uint32_t bank_size; // size of banks for this surface - uint32_t plug_page; // current plugin page + int plug_page; // current plugin page uint32_t plug_page_size; // plugin page size (number of controls) - uint32_t send_page; // current send page + uint32_t plugin; // id of current plugin + int send_page; // current send page uint32_t send_page_size; // send page size in channels 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 @@ -425,6 +426,11 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI PATH_CALLBACK1_MSG(sel_pan_elevation,f); PATH_CALLBACK1_MSG(sel_pan_frontback,f); PATH_CALLBACK1_MSG(sel_pan_lfe,f); + PATH_CALLBACK1_MSG(sel_send_page,f); + PATH_CALLBACK1_MSG(sel_send_pagesize,f); + PATH_CALLBACK1_MSG(sel_plug_page,f); + PATH_CALLBACK1_MSG(sel_plug_pagesize,f); + PATH_CALLBACK1_MSG(sel_plugin,f); PATH_CALLBACK1_MSG(sel_comp_enable,f); PATH_CALLBACK1_MSG(sel_comp_threshold,f); PATH_CALLBACK1_MSG(sel_comp_speed,f); @@ -581,6 +587,11 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int set_surface_feedback (uint32_t fb, lo_message msg); int set_surface_gainmode (uint32_t gm, lo_message msg); int refresh_surface (lo_message msg); + int sel_send_pagesize (uint32_t size, lo_message msg); + int sel_send_page (int page, lo_message msg); + int sel_plug_pagesize (uint32_t size, lo_message msg); + int sel_plug_page (int page, lo_message msg); + int sel_plugin (uint32_t id, lo_message msg); int scrub (float delta, lo_message msg); int jog (float delta, lo_message msg); diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc index 2071f0455d..c4a5eae09c 100644 --- a/libs/surfaces/osc/osc_select_observer.cc +++ b/libs/surfaces/osc/osc_select_observer.cc @@ -45,15 +45,17 @@ using namespace PBD; using namespace ARDOUR; using namespace ArdourSurface; -OSCSelectObserver::OSCSelectObserver (boost::shared_ptr s, lo_address a, uint32_t gm, std::bitset<32> fb) +OSCSelectObserver::OSCSelectObserver (boost::shared_ptr s, lo_address a, ArdourSurface::OSC::OSCSurface* su) : _strip (s) - ,gainmode (gm) - ,feedback (fb) + ,sur (su) ,nsends (0) ,_last_gain (0.0) { addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a)); + gainmode = sur->gainmode; + feedback = sur->feedback; as = ARDOUR::Off; + send_size = 0; if (feedback[0]) { // buttons are separate feedback _strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::name_changed, this, boost::lambda::_1), OSC::instance()); @@ -234,53 +236,86 @@ OSCSelectObserver::~OSCSelectObserver () lo_address_free (addr); } +void +OSCSelectObserver::renew_sends () { + send_end(); + send_init(); +} + +void +OSCSelectObserver::renew_plugin () { + // to be written :) +} + void OSCSelectObserver::send_init() { // we don't know how many there are, so find out. bool sends; + nsends = 0; do { sends = false; if (_strip->send_level_controllable (nsends)) { - _strip->send_level_controllable(nsends)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_gain, this, nsends, _strip->send_level_controllable(nsends)), OSC::instance()); - send_timeout.push_back (0); - send_gain (nsends, _strip->send_level_controllable(nsends)); sends = true; + nsends++; } + } while (sends); + if (!nsends) { + return; + } - if (_strip->send_enable_controllable (nsends)) { - _strip->send_enable_controllable(nsends)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::enable_message_with_id, this, X_("/select/send_enable"), nsends + 1, _strip->send_enable_controllable(nsends)), OSC::instance()); - enable_message_with_id ("/select/send_enable", nsends + 1, _strip->send_enable_controllable(nsends)); - sends = true; - } else if (sends) { + send_size = nsends; + if (sur->send_page_size) { + send_size = sur->send_page_size; + } + // check limits + uint32_t max_page = (uint32_t)(nsends / send_size) + 1; + if (sur->send_page < 1) { + sur->send_page = 1; + } else if ((uint32_t)sur->send_page > max_page) { + sur->send_page = max_page; + } + uint32_t page_start = ((sur->send_page - 1) * send_size); + uint32_t last_send = sur->send_page * send_size; + uint32_t c = 1; + + for (uint32_t s = page_start; s < last_send; ++s, ++c) { + + bool send_valid = false; + if (_strip->send_level_controllable (s)) { + _strip->send_level_controllable(s)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_gain, this, c, _strip->send_level_controllable(s)), OSC::instance()); + send_timeout.push_back (0); + send_gain (c, _strip->send_level_controllable(s)); + send_valid = true; + } + + if (_strip->send_enable_controllable (s)) { + _strip->send_enable_controllable(s)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::enable_message_with_id, this, X_("/select/send_enable"), c, _strip->send_enable_controllable(s)), OSC::instance()); + enable_message_with_id ("/select/send_enable", c, _strip->send_enable_controllable(s)); + } else if (send_valid) { boost::shared_ptr r = boost::dynamic_pointer_cast (_strip); if (!r) { // should never get here - send_float_with_id ("/select/send_enable", nsends + 1, 0); + send_float_with_id ("/select/send_enable", c, 0); } - boost::shared_ptr snd = boost::dynamic_pointer_cast (r->nth_send(nsends)); + 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"), nsends + 1, proc), OSC::instance()); - send_float_with_id ("/select/send_enable", nsends + 1, proc->enabled()); + 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()); } } - // this should get signalled by the route the send goes to, (TODO) - if (!gainmode && sends) { // if the gain control is there, this is too - text_with_id ("/select/send_name", nsends + 1, _strip->send_name(nsends)); + if (!gainmode && send_valid) { + text_with_id ("/select/send_name", c, _strip->send_name(s)); } - // Send numbers are 0 based, OSC is 1 based so this gets incremented at the end - if (sends) { - nsends++; - } - } while (sends); + } } void OSCSelectObserver::send_end () { send_connections.drop_connections (); - for (uint32_t i = 1; i <= nsends; i++) { + for (uint32_t i = 1; i <= send_size; i++) { if (gainmode) { send_float_with_id ("/select/send_fader", i, 0); } else { @@ -291,6 +326,8 @@ OSCSelectObserver::send_end () // next name text_with_id ("/select/send_name", i, " "); } + // need to delete or clear send_timeout + send_timeout.clear(); nsends = 0; } @@ -580,7 +617,7 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr #else value = gain_to_slider_position (controllable->get_value()); #endif - text_with_id ("/select/send_name" , id + 1, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db)); + text_with_id ("/select/send_name" , id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), db)); if (send_timeout.size() > id) { send_timeout[id] = 8; } @@ -590,9 +627,9 @@ OSCSelectObserver::send_gain (uint32_t id, boost::shared_ptr } if (feedback[2]) { - path = set_path (path, id + 1); + path = set_path (path, id); } else { - lo_message_add_int32 (msg, id + 1); + lo_message_add_int32 (msg, id); } lo_message_add_float (msg, value); diff --git a/libs/surfaces/osc/osc_select_observer.h b/libs/surfaces/osc/osc_select_observer.h index 6cd20a7769..5fdb976aca 100644 --- a/libs/surfaces/osc/osc_select_observer.h +++ b/libs/surfaces/osc/osc_select_observer.h @@ -31,16 +31,20 @@ #include "ardour/types.h" #include "ardour/processor.h" +#include "osc.h" + class OSCSelectObserver { public: - OSCSelectObserver (boost::shared_ptr, lo_address addr, uint32_t gainmode, std::bitset<32> feedback); + OSCSelectObserver (boost::shared_ptr, lo_address addr, ArdourSurface::OSC::OSCSurface* sur); ~OSCSelectObserver (); boost::shared_ptr strip () const { return _strip; } lo_address address() const { return addr; }; void tick (void); + void renew_sends (void); + void renew_plugin (void); private: boost::shared_ptr _strip; @@ -54,12 +58,14 @@ class OSCSelectObserver std::string path; uint32_t gainmode; std::bitset<32> feedback; + ArdourSurface::OSC::OSCSurface* sur; std::vector send_timeout; uint32_t gain_timeout; float _last_meter; uint32_t nsends; float _last_gain; ARDOUR::AutoState as; + uint32_t send_size; void name_changed (const PBD::PropertyChange& what_changed); void change_message (std::string path, boost::shared_ptr controllable); -- cgit v1.2.3