diff --git a/libs/surfaces/websockets/dispatcher.cc b/libs/surfaces/websockets/dispatcher.cc index 816e1e4a3d..583cb9cacb 100644 --- a/libs/surfaces/websockets/dispatcher.cc +++ b/libs/surfaces/websockets/dispatcher.cc @@ -55,8 +55,9 @@ WebsocketsDispatcher::dispatch (Client client, const NodeStateMessage& msg) void WebsocketsDispatcher::update_all_nodes (Client client) { - for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - ArdourMixerStrip &strip = mixer ().nth_strip (strip_n); + for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) { + uint32_t strip_n = it->first; + ArdourMixerStrip& strip = it->second; bool is_vca = strip.stripable ()->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA; @@ -83,23 +84,23 @@ WebsocketsDispatcher::update_all_nodes (Client client) update (client, Node::strip_pan, strip_n, strip.pan ()); - for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = strip.nth_plugin (plugin_n).insert (); - if (!insert) { - break; - } + for (ArdourMixerStrip::PluginMap::iterator it = strip.plugins ().begin (); it != strip.plugins ().end (); ++it) { + uint32_t plugin_n = it->first; + boost::shared_ptr insert = it->second.insert (); + boost::shared_ptr plugin = insert->plugin (); - boost::shared_ptr plugin = insert->plugin (); update (client, Node::strip_plugin_description, strip_n, plugin_n, static_cast (plugin->name ())); update (client, Node::strip_plugin_enable, strip_n, plugin_n, - strip.nth_plugin (plugin_n).enabled ()); + strip.plugin (plugin_n).enabled ()); for (uint32_t param_n = 0; param_n < plugin->parameter_count (); ++param_n) { - boost::shared_ptr a_ctrl = - strip.nth_plugin (plugin_n).param_control (param_n); - if (!a_ctrl) { + boost::shared_ptr a_ctrl; + + try { + a_ctrl = strip.plugin (plugin_n).param_control (param_n); + } catch (ArdourMixerNotFoundException) { continue; } @@ -129,7 +130,7 @@ WebsocketsDispatcher::update_all_nodes (Client client) update (client, Node::strip_plugin_param_description, addr, val); - TypedValue value = strip.nth_plugin (plugin_n).param_value (param_n); + TypedValue value = strip.plugin (plugin_n).param_value (param_n); update (client, Node::strip_plugin_param_value, strip_n, plugin_n, param_n, value); } } @@ -189,9 +190,9 @@ WebsocketsDispatcher::strip_gain_handler (Client client, const NodeStateMessage& uint32_t strip_id = state.nth_addr (0); if (msg.is_write () && (state.n_val () > 0)) { - mixer ().nth_strip (strip_id).set_gain (state.nth_val (0)); + mixer ().strip (strip_id).set_gain (state.nth_val (0)); } else { - update (client, Node::strip_gain, strip_id, mixer ().nth_strip (strip_id).gain ()); + update (client, Node::strip_gain, strip_id, mixer ().strip (strip_id).gain ()); } } @@ -207,9 +208,9 @@ WebsocketsDispatcher::strip_pan_handler (Client client, const NodeStateMessage& uint32_t strip_id = state.nth_addr (0); if (msg.is_write () && (state.n_val () > 0)) { - mixer ().nth_strip (strip_id).set_pan (state.nth_val (0)); + mixer ().strip (strip_id).set_pan (state.nth_val (0)); } else { - update (client, Node::strip_pan, strip_id, mixer ().nth_strip (strip_id).pan ()); + update (client, Node::strip_pan, strip_id, mixer ().strip (strip_id).pan ()); } } @@ -225,9 +226,9 @@ WebsocketsDispatcher::strip_mute_handler (Client client, const NodeStateMessage& uint32_t strip_id = state.nth_addr (0); if (msg.is_write () && (state.n_val () > 0)) { - mixer ().nth_strip (strip_id).set_mute (state.nth_val (0)); + mixer ().strip (strip_id).set_mute (state.nth_val (0)); } else { - update (client, Node::strip_mute, strip_id, mixer ().nth_strip (strip_id).mute ()); + update (client, Node::strip_mute, strip_id, mixer ().strip (strip_id).mute ()); } } @@ -244,10 +245,10 @@ WebsocketsDispatcher::strip_plugin_enable_handler (Client client, const NodeStat uint32_t plugin_id = state.nth_addr (1); if (msg.is_write () && (state.n_val () > 0)) { - mixer ().nth_strip (strip_id).nth_plugin (plugin_id).set_enabled (state.nth_val (0)); + mixer ().strip (strip_id).plugin (plugin_id).set_enabled (state.nth_val (0)); } else { update (client, Node::strip_plugin_enable, strip_id, plugin_id, - mixer ().nth_strip (strip_id).nth_plugin (plugin_id).enabled ()); + mixer ().strip (strip_id).plugin (plugin_id).enabled ()); } } @@ -265,10 +266,10 @@ WebsocketsDispatcher::strip_plugin_param_value_handler (Client client, const Nod uint32_t param_id = state.nth_addr (2); if (msg.is_write () && (state.n_val () > 0)) { - mixer ().nth_strip (strip_id).nth_plugin (plugin_id).set_param_value (param_id, + mixer ().strip (strip_id).plugin (plugin_id).set_param_value (param_id, state.nth_val (0)); } else { - TypedValue value = mixer ().nth_strip (strip_id).nth_plugin (plugin_id).param_value (param_id); + TypedValue value = mixer ().strip (strip_id).plugin (plugin_id).param_value (param_id); update (client, Node::strip_plugin_param_value, strip_id, plugin_id, param_id, value); } } diff --git a/libs/surfaces/websockets/feedback.cc b/libs/surfaces/websockets/feedback.cc index e3e08c35a1..ab26d58d48 100644 --- a/libs/surfaces/websockets/feedback.cc +++ b/libs/surfaces/websockets/feedback.cc @@ -24,7 +24,6 @@ #include "transport.h" #include "server.h" #include "state.h" -#include "mixer.h" // TO DO: make this configurable #define POLL_INTERVAL_MS 100 @@ -56,21 +55,21 @@ struct StripGainObserver { void operator() (ArdourFeedback* p, uint32_t strip_n) { // fires multiple times (4x as of ardour 6.0) - p->update_all (Node::strip_gain, strip_n, p->mixer ().nth_strip (strip_n).gain ()); + p->update_all (Node::strip_gain, strip_n, p->mixer ().strip (strip_n).gain ()); } }; struct StripPanObserver { void operator() (ArdourFeedback* p, uint32_t strip_n) { - p->update_all (Node::strip_pan, strip_n, p->mixer ().nth_strip (strip_n).pan ()); + p->update_all (Node::strip_pan, strip_n, p->mixer ().strip (strip_n).pan ()); } }; struct StripMuteObserver { void operator() (ArdourFeedback* p, uint32_t strip_n) { - p->update_all (Node::strip_mute, strip_n, p->mixer ().nth_strip (strip_n).mute ()); + p->update_all (Node::strip_mute, strip_n, p->mixer ().strip (strip_n).mute ()); } }; @@ -78,7 +77,7 @@ struct PluginBypassObserver { void operator() (ArdourFeedback* p, uint32_t strip_n, uint32_t plugin_n) { p->update_all (Node::strip_plugin_enable, strip_n, plugin_n, - p->mixer ().nth_strip (strip_n).nth_plugin (plugin_n).enabled ()); + p->mixer ().strip (strip_n).plugin (plugin_n).enabled ()); } }; @@ -87,9 +86,11 @@ struct PluginParamValueObserver { uint32_t param_n, boost::weak_ptr ctrl) { boost::shared_ptr control = ctrl.lock (); + if (!control) { return; } + p->update_all (Node::strip_plugin_param_value, strip_n, plugin_n, param_n, ArdourMixerPlugin::param_value (control)); } @@ -101,7 +102,7 @@ ArdourFeedback::start () observe_transport (); observe_mixer (); - // some things need polling like the strip meters + // some values need polling like the strip meters Glib::RefPtr periodic_timeout = Glib::TimeoutSource::create (POLL_INTERVAL_MS); _periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &ArdourFeedback::poll)); @@ -179,9 +180,9 @@ ArdourFeedback::poll () const { update_all (Node::transport_time, transport ().time ()); - for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - float db = mixer ().nth_strip (strip_n).meter_level_db (); - update_all (Node::strip_meter, strip_n, static_cast (db)); + for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) { + float db = it->second.meter_level_db (); + update_all (Node::strip_meter, it->first, static_cast (db)); } return true; @@ -202,9 +203,12 @@ ArdourFeedback::observe_transport () void ArdourFeedback::observe_mixer () { - for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - boost::shared_ptr stripable = mixer ().nth_strip (strip_n).stripable (); - boost::shared_ptr connections = mixer().nth_strip (strip_n).connections (); + for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) { + uint32_t strip_n = it->first; + ArdourMixerStrip& strip = it->second; + + boost::shared_ptr stripable = strip.stripable (); + boost::shared_ptr connections = it->second.connections (); stripable->gain_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, boost::bind (StripGainObserver (), this, strip_n), event_loop ()); @@ -217,23 +221,20 @@ ArdourFeedback::observe_mixer () stripable->mute_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, boost::bind (StripMuteObserver (), this, strip_n), event_loop ()); - observe_strip_plugins (strip_n, stripable); + observe_strip_plugins (strip_n, strip.plugins ()); } } void -ArdourFeedback::observe_strip_plugins (uint32_t strip_n, boost::shared_ptr strip) +ArdourFeedback::observe_strip_plugins (uint32_t strip_n, ArdourMixerStrip::PluginMap& plugins) { - for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).insert (); - if (!insert) { - break; - } - - uint32_t bypass = insert->plugin ()->designated_bypass_port (); - Evoral::Parameter param = Evoral::Parameter (PluginAutomation, 0, bypass); - boost::shared_ptr control = insert->automation_control (param); - std::unique_ptr connections (new PBD::ScopedConnectionList()); + for (ArdourMixerStrip::PluginMap::iterator it = plugins.begin(); it != plugins.end(); ++it) { + uint32_t plugin_n = it->first; + boost::shared_ptr insert = it->second.insert (); + boost::shared_ptr connections = it->second.connections (); + uint32_t bypass = insert->plugin ()->designated_bypass_port (); + Evoral::Parameter param = Evoral::Parameter (PluginAutomation, 0, bypass); + boost::shared_ptr control = insert->automation_control (param); if (control) { control->Changed.connect (*connections, MISSING_INVALIDATOR, @@ -257,17 +258,17 @@ ArdourFeedback::observe_strip_plugin_param_values (uint32_t strip_n, boost::shared_ptr plugin = insert->plugin (); for (uint32_t param_n = 0; param_n < plugin->parameter_count (); ++param_n) { - boost::shared_ptr control = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).param_control (param_n); + try { + boost::shared_ptr control = mixer ().strip (strip_n).plugin (plugin_n).param_control (param_n); - if (!control) { - continue; + /*PBD::ScopedConnectionList *connections = _plugin_connections[(strip_n << 16) | plugin_n].get(); + + control->Changed.connect (*connections, MISSING_INVALIDATOR, + boost::bind (PluginParamValueObserver (), this, strip_n, plugin_n, param_n, + boost::weak_ptr(control)), + event_loop ());*/ + } catch (ArdourMixerNotFoundException) { + /* ignore */ } - - /*PBD::ScopedConnectionList *connections = _plugin_connections[(strip_n << 16) | plugin_n].get(); - - control->Changed.connect (*connections, MISSING_INVALIDATOR, - boost::bind (PluginParamValueObserver (), this, strip_n, plugin_n, param_n, - boost::weak_ptr(control)), - event_loop ());*/ } } diff --git a/libs/surfaces/websockets/feedback.h b/libs/surfaces/websockets/feedback.h index de14481719..4fac978e56 100644 --- a/libs/surfaces/websockets/feedback.h +++ b/libs/surfaces/websockets/feedback.h @@ -25,6 +25,7 @@ #include "component.h" #include "typed_value.h" +#include "mixer.h" class ArdourFeedback : public SurfaceComponent { @@ -50,9 +51,8 @@ private: void observe_transport (); void observe_mixer (); - void observe_strip_plugins (uint32_t, boost::shared_ptr); - void observe_strip_plugin_param_values (uint32_t, uint32_t, - boost::shared_ptr); + void observe_strip_plugins (uint32_t, ArdourMixerStrip::PluginMap&); + void observe_strip_plugin_param_values (uint32_t, uint32_t, boost::shared_ptr); }; #endif // _ardour_surface_websockets_feedback_h_ diff --git a/libs/surfaces/websockets/mixer.cc b/libs/surfaces/websockets/mixer.cc index 2d794fdb7e..7cdccf05e2 100644 --- a/libs/surfaces/websockets/mixer.cc +++ b/libs/surfaces/websockets/mixer.cc @@ -39,10 +39,16 @@ ArdourMixerPlugin::insert () const return _insert; } +boost::shared_ptr +ArdourMixerPlugin::connections () const +{ + return _connections; +} + bool ArdourMixerPlugin::enabled () const { - insert ()->enabled (); + return insert ()->enabled (); } void @@ -55,18 +61,15 @@ TypedValue ArdourMixerPlugin::param_value (uint32_t param_n) { boost::shared_ptr control = param_control (param_n); - TypedValue value = TypedValue (); + ParameterDescriptor pd = control->desc (); + TypedValue value = TypedValue (); - if (control) { - ParameterDescriptor pd = control->desc (); - - if (pd.toggled) { - value = TypedValue (static_cast (control->get_value ())); - } else if (pd.enumeration || pd.integer_step) { - value = TypedValue (static_cast (control->get_value ())); - } else { - value = TypedValue (control->get_value ()); - } + if (pd.toggled) { + value = TypedValue (static_cast (control->get_value ())); + } else if (pd.enumeration || pd.integer_step) { + value = TypedValue (static_cast (control->get_value ())); + } else { + value = TypedValue (control->get_value ()); } return value; @@ -76,21 +79,18 @@ void ArdourMixerPlugin::set_param_value (uint32_t param_n, TypedValue value) { boost::shared_ptr control = param_control (param_n); + ParameterDescriptor pd = control->desc (); + double dbl_val; - if (control) { - ParameterDescriptor pd = control->desc (); - double dbl_val; - - if (pd.toggled) { - dbl_val = static_cast (static_cast (value)); - } else if (pd.enumeration || pd.integer_step) { - dbl_val = static_cast (static_cast (value)); - } else { - dbl_val = static_cast (value); - } - - control->set_value (dbl_val, PBD::Controllable::NoGroup); + if (pd.toggled) { + dbl_val = static_cast (static_cast (value)); + } else if (pd.enumeration || pd.integer_step) { + dbl_val = static_cast (static_cast (value)); + } else { + dbl_val = static_cast (value); } + + control->set_value (dbl_val, PBD::Controllable::NoGroup); } boost::shared_ptr @@ -113,6 +113,7 @@ ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripab , _connections (boost::shared_ptr (new PBD::ScopedConnectionList())) { if (_stripable->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA) { + /* no plugins to handle */ return; } @@ -125,13 +126,15 @@ ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripab for (uint32_t plugin_n = 0;; ++plugin_n) { boost::shared_ptr processor = route->nth_plugin (plugin_n); - if (processor) { - boost::shared_ptr insert = boost::static_pointer_cast (processor); + if (!processor) { + break; + } - if (insert) { - ArdourMixerPlugin plugin (insert); - _plugins.push_back (plugin); - } + boost::shared_ptr insert = boost::static_pointer_cast (processor); + + if (insert) { + ArdourMixerPlugin plugin (insert); + _plugins.emplace (plugin_n, plugin); } } } @@ -148,20 +151,20 @@ ArdourMixerStrip::connections () const return _connections; } -int -ArdourMixerStrip::plugin_count () const -{ - return _plugins.size (); -} - ArdourMixerPlugin& -ArdourMixerStrip::nth_plugin (uint32_t plugin_n) +ArdourMixerStrip::plugin (uint32_t plugin_n) { - if (plugin_n < _plugins.size ()) { - return _plugins[plugin_n]; + if (_plugins.find (plugin_n) == _plugins.end ()) { + throw ArdourMixerNotFoundException ("plugin id = " + boost::lexical_cast(plugin_n) + " not found"); } - throw ArdourMixerNotFoundException ("plugin id = " + boost::lexical_cast(plugin_n) + " not found"); + return _plugins.at (plugin_n); +} + +ArdourMixerStrip::PluginMap& +ArdourMixerStrip::plugins () +{ + return _plugins; } double @@ -180,9 +183,11 @@ double ArdourMixerStrip::pan () const { boost::shared_ptr ac = _stripable->pan_azimuth_control (); + if (!ac) { throw ArdourMixerNotFoundException ("strip has no panner"); } + return ac->internal_to_interface (ac->get_value ()); } @@ -190,9 +195,11 @@ void ArdourMixerStrip::set_pan (double value) { boost::shared_ptr ac = _stripable->pan_azimuth_control (); + if (!ac) { return; } + ac->set_value (ac->interface_to_internal (value), PBD::Controllable::NoGroup); } @@ -265,8 +272,7 @@ ArdourMixer::start () ArdourMixerStrip strip (*it); //(*it)->DropReferences.connect (_connections, MISSING_INVALIDATOR, // boost::bind (&ArdourMixer::on_drop_strip, this, strip_n), event_loop ()); - _strips.push_back (strip); - strip_n++; + _strips.emplace (strip_n++, strip); } return 0; @@ -279,20 +285,21 @@ ArdourMixer::stop () return 0; } -uint32_t -ArdourMixer::strip_count () const +ArdourMixer::StripMap& +ArdourMixer::strips () { - return _strips.size (); + return _strips; } + ArdourMixerStrip& -ArdourMixer::nth_strip (uint32_t strip_n) +ArdourMixer::strip (uint32_t strip_n) { - if (strip_n < _strips.size ()) { - return _strips[strip_n]; + if (_strips.find (strip_n) == _strips.end ()) { + throw ArdourMixerNotFoundException ("strip id = " + boost::lexical_cast(strip_n) + " not found"); } - throw ArdourMixerNotFoundException ("strip id = " + boost::lexical_cast(strip_id) + " not found"); + return _strips.at (strip_n); } void diff --git a/libs/surfaces/websockets/mixer.h b/libs/surfaces/websockets/mixer.h index c2ee9f87ae..274f73236d 100644 --- a/libs/surfaces/websockets/mixer.h +++ b/libs/surfaces/websockets/mixer.h @@ -33,7 +33,8 @@ public: ArdourMixerPlugin (boost::shared_ptr); boost::shared_ptr insert () const; - + boost::shared_ptr connections () const; + bool enabled () const; void set_enabled (bool); @@ -58,8 +59,10 @@ public: boost::shared_ptr stripable () const; boost::shared_ptr connections () const; - int plugin_count () const; - ArdourMixerPlugin& nth_plugin (uint32_t); + typedef std::map PluginMap; + + PluginMap& plugins (); + ArdourMixerPlugin& plugin (uint32_t); double gain () const; void set_gain (double); @@ -80,7 +83,8 @@ public: private: boost::shared_ptr _stripable; boost::shared_ptr _connections; - std::vector _plugins; + + PluginMap _plugins; void on_drop_plugin (uint32_t); @@ -96,13 +100,14 @@ public: int start (); int stop (); - uint32_t strip_count () const; - ArdourMixerStrip& nth_strip (uint32_t); + typedef std::map StripMap; + + StripMap& strips (); + ArdourMixerStrip& strip (uint32_t); void on_drop_strip (uint32_t); private: - typedef std::vector StripsVector; - StripsVector _strips; + StripMap _strips; }; #endif // _ardour_surface_websockets_mixer_h_