diff --git a/libs/surfaces/websockets/component.h b/libs/surfaces/websockets/component.h index bb407d76ef..d90c4b4627 100644 --- a/libs/surfaces/websockets/component.h +++ b/libs/surfaces/websockets/component.h @@ -57,7 +57,7 @@ public: PBD::EventLoop* event_loop () const; Glib::RefPtr main_loop () const; ARDOUR::Session& session () const; - ArdourMixer& mixer () const; + ArdourMixer& mixer () const; ArdourTransport& transport () const; WebsocketsServer& server () const; WebsocketsDispatcher& dispatcher () const; diff --git a/libs/surfaces/websockets/feedback.cc b/libs/surfaces/websockets/feedback.cc index ab26d58d48..866a9aae7d 100644 --- a/libs/surfaces/websockets/feedback.cc +++ b/libs/surfaces/websockets/feedback.cc @@ -180,7 +180,9 @@ ArdourFeedback::poll () const { update_all (Node::transport_time, transport ().time ()); - for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) { + Glib::Threads::Mutex::Lock lock (mixer ().mutex ()); + + 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)); } @@ -230,8 +232,9 @@ ArdourFeedback::observe_strip_plugins (uint32_t strip_n, ArdourMixerStrip::Plugi { 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 (); + ArdourMixerPlugin& plugin = it->second; + boost::shared_ptr insert = plugin.insert (); + boost::shared_ptr connections = plugin.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); @@ -241,32 +244,22 @@ ArdourFeedback::observe_strip_plugins (uint32_t strip_n, ArdourMixerStrip::Plugi boost::bind (PluginBypassObserver (), this, strip_n, plugin_n), event_loop ()); } - //insert->DropReferences.connect (*connections, MISSING_INVALIDATOR, - // boost::bind (&ArdourFeedback::on_drop_plugin, this, strip_n, plugin_n), event_loop ()); - - // assume each strip can hold up to 65535 plugins - //_plugin_connections[(strip_n << 16) | plugin_n] = std::move (connections); - - observe_strip_plugin_param_values (strip_n, plugin_n, insert); + observe_strip_plugin_param_values (strip_n, plugin_n, plugin); } } void ArdourFeedback::observe_strip_plugin_param_values (uint32_t strip_n, - uint32_t plugin_n, boost::shared_ptr insert) + uint32_t plugin_n, ArdourMixerPlugin& plugin) { - boost::shared_ptr plugin = insert->plugin (); - - for (uint32_t param_n = 0; param_n < plugin->parameter_count (); ++param_n) { + for (uint32_t param_n = 0; param_n < plugin.param_count (); ++param_n) { try { - boost::shared_ptr control = mixer ().strip (strip_n).plugin (plugin_n).param_control (param_n); + boost::shared_ptr control = plugin.param_control (param_n); - /*PBD::ScopedConnectionList *connections = _plugin_connections[(strip_n << 16) | plugin_n].get(); - - control->Changed.connect (*connections, MISSING_INVALIDATOR, + control->Changed.connect (*plugin.connections (), MISSING_INVALIDATOR, boost::bind (PluginParamValueObserver (), this, strip_n, plugin_n, param_n, boost::weak_ptr(control)), - event_loop ());*/ + event_loop ()); } catch (ArdourMixerNotFoundException) { /* ignore */ } diff --git a/libs/surfaces/websockets/feedback.h b/libs/surfaces/websockets/feedback.h index 4fac978e56..0359b548bf 100644 --- a/libs/surfaces/websockets/feedback.h +++ b/libs/surfaces/websockets/feedback.h @@ -52,7 +52,7 @@ private: void observe_transport (); void observe_mixer (); void observe_strip_plugins (uint32_t, ArdourMixerStrip::PluginMap&); - void observe_strip_plugin_param_values (uint32_t, uint32_t, boost::shared_ptr); + void observe_strip_plugin_param_values (uint32_t, uint32_t, ArdourMixerPlugin&); }; #endif // _ardour_surface_websockets_feedback_h_ diff --git a/libs/surfaces/websockets/mixer.cc b/libs/surfaces/websockets/mixer.cc index 7cdccf05e2..d9139ac557 100644 --- a/libs/surfaces/websockets/mixer.cc +++ b/libs/surfaces/websockets/mixer.cc @@ -33,6 +33,11 @@ ArdourMixerPlugin::ArdourMixerPlugin (boost::shared_ptr in , _connections (boost::shared_ptr (new PBD::ScopedConnectionList())) {} +ArdourMixerPlugin::~ArdourMixerPlugin () +{ + _connections->drop_connections (); +} + boost::shared_ptr ArdourMixerPlugin::insert () const { @@ -57,22 +62,16 @@ ArdourMixerPlugin::set_enabled (bool enabled) insert ()->enable (enabled); } +uint32_t +ArdourMixerPlugin::param_count () const +{ + return _insert->plugin ()->parameter_count (); +} + TypedValue ArdourMixerPlugin::param_value (uint32_t param_n) { - boost::shared_ptr control = param_control (param_n); - ParameterDescriptor pd = control->desc (); - TypedValue value = TypedValue (); - - 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; + return param_value (param_control (param_n)); } void @@ -108,7 +107,24 @@ ArdourMixerPlugin::param_control (uint32_t param_n) const return _insert->automation_control (Evoral::Parameter (PluginAutomation, 0, control_id)); } -ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripable) +TypedValue +ArdourMixerPlugin::param_value (boost::shared_ptr control) +{ + ParameterDescriptor pd = control->desc (); + TypedValue value = TypedValue (); + + 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; +} + +ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripable, PBD::EventLoop* event_loop) : _stripable (stripable) , _connections (boost::shared_ptr (new PBD::ScopedConnectionList())) { @@ -134,11 +150,18 @@ ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripab if (insert) { ArdourMixerPlugin plugin (insert); + plugin.insert ()->DropReferences.connect (*plugin.connections (), MISSING_INVALIDATOR, + boost::bind (&ArdourMixerStrip::on_drop_plugin, this, plugin_n), event_loop); _plugins.emplace (plugin_n, plugin); } } } +ArdourMixerStrip::~ArdourMixerStrip () +{ + _connections->drop_connections (); +} + boost::shared_ptr ArdourMixerStrip::stripable () const { @@ -229,11 +252,9 @@ ArdourMixerStrip::name () const } void -ArdourMixerStrip::on_drop_plugin (uint32_t) +ArdourMixerStrip::on_drop_plugin (uint32_t plugin_n) { - //uint32_t key = (strip_n << 16) | plugin_n; - //_plugin_connections[key]->drop_connections (); - //_plugin_connections.erase (key); + _plugins.erase (plugin_n); } double @@ -263,16 +284,17 @@ ArdourMixerStrip::from_db (double db) int ArdourMixer::start () { - /* take an indexed snapshot of current strips */ + /* take a snapshot of current strips */ StripableList strips; session ().get_stripables (strips, PresentationInfo::AllStripables); uint32_t strip_n = 0; for (StripableList::iterator it = strips.begin (); it != strips.end (); ++it) { - ArdourMixerStrip strip (*it); - //(*it)->DropReferences.connect (_connections, MISSING_INVALIDATOR, - // boost::bind (&ArdourMixer::on_drop_strip, this, strip_n), event_loop ()); - _strips.emplace (strip_n++, strip); + ArdourMixerStrip strip (*it, event_loop ()); + strip.stripable ()->DropReferences.connect (*strip.connections (), MISSING_INVALIDATOR, + boost::bind (&ArdourMixer::on_drop_strip, this, strip_n), event_loop ()); + _strips.emplace (strip_n, strip); + strip_n++; } return 0; @@ -281,6 +303,7 @@ ArdourMixer::start () int ArdourMixer::stop () { + Glib::Threads::Mutex::Lock lock (mixer ().mutex ()); _strips.clear (); return 0; } @@ -305,15 +328,12 @@ ArdourMixer::strip (uint32_t strip_n) void ArdourMixer::on_drop_strip (uint32_t strip_n) { - /*for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = strip_plugin_insert (strip_n, plugin_n); - if (!insert) { - break; - } - - on_drop_plugin (strip_n, plugin_n); - }*/ - - //_strip_connections[strip_n]->drop_connections (); - //_strip_connections.erase (strip_n); + Glib::Threads::Mutex::Lock lock (_mutex); + _strips.erase (strip_n); +} + +Glib::Threads::Mutex& +ArdourMixer::mutex () +{ + return _mutex; } diff --git a/libs/surfaces/websockets/mixer.h b/libs/surfaces/websockets/mixer.h index 274f73236d..fd3f1d3f3a 100644 --- a/libs/surfaces/websockets/mixer.h +++ b/libs/surfaces/websockets/mixer.h @@ -19,6 +19,8 @@ #ifndef _ardour_surface_websockets_mixer_h_ #define _ardour_surface_websockets_mixer_h_ +#include + #include "component.h" #include "typed_value.h" @@ -31,13 +33,15 @@ class ArdourMixerPlugin { public: ArdourMixerPlugin (boost::shared_ptr); + ~ArdourMixerPlugin (); - boost::shared_ptr insert () const; + boost::shared_ptr insert () const; boost::shared_ptr connections () const; bool enabled () const; void set_enabled (bool); + uint32_t param_count () const; TypedValue param_value (uint32_t); void set_param_value (uint32_t, TypedValue); @@ -54,9 +58,10 @@ private: class ArdourMixerStrip { public: - ArdourMixerStrip (boost::shared_ptr); - - boost::shared_ptr stripable () const; + ArdourMixerStrip (boost::shared_ptr, PBD::EventLoop*); + ~ArdourMixerStrip (); + + boost::shared_ptr stripable () const; boost::shared_ptr connections () const; typedef std::map PluginMap; @@ -106,8 +111,11 @@ public: ArdourMixerStrip& strip (uint32_t); void on_drop_strip (uint32_t); + Glib::Threads::Mutex& mutex (); + private: - StripMap _strips; + StripMap _strips; + Glib::Threads::Mutex _mutex; }; #endif // _ardour_surface_websockets_mixer_h_