diff --git a/libs/surfaces/websockets/dispatcher.cc b/libs/surfaces/websockets/dispatcher.cc index f8dd86f8f8..816e1e4a3d 100644 --- a/libs/surfaces/websockets/dispatcher.cc +++ b/libs/surfaces/websockets/dispatcher.cc @@ -56,36 +56,35 @@ void WebsocketsDispatcher::update_all_nodes (Client client) { for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - boost::shared_ptr strip = mixer ().nth_strip (strip_n); + ArdourMixerStrip &strip = mixer ().nth_strip (strip_n); - bool is_vca = strip->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA; + bool is_vca = strip.stripable ()->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA; AddressVector strip_addr = AddressVector (); strip_addr.push_back (strip_n); ValueVector strip_desc = ValueVector (); - strip_desc.push_back (strip->name ()); + strip_desc.push_back (strip.name ()); strip_desc.push_back (is_vca); update (client, Node::strip_description, strip_addr, strip_desc); - update (client, Node::strip_gain, strip_n, mixer ().strip_gain (strip_n)); - update (client, Node::strip_mute, strip_n, mixer ().strip_mute (strip_n)); + update (client, Node::strip_gain, strip_n, strip.gain ()); + update (client, Node::strip_mute, strip_n, strip.mute ()); // Pan and plugins not available in VCAs if (is_vca) { continue; } - boost::shared_ptr route = boost::dynamic_pointer_cast (strip); + boost::shared_ptr route = boost::dynamic_pointer_cast (strip.stripable ()); if (!route) { continue; } - update (client, Node::strip_pan, strip_n, mixer ().strip_pan (strip_n)); + update (client, Node::strip_pan, strip_n, strip.pan ()); for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = mixer () - .strip_plugin_insert (strip_n, plugin_n); + boost::shared_ptr insert = strip.nth_plugin (plugin_n).insert (); if (!insert) { break; } @@ -95,11 +94,11 @@ WebsocketsDispatcher::update_all_nodes (Client client) static_cast (plugin->name ())); update (client, Node::strip_plugin_enable, strip_n, plugin_n, - mixer ().strip_plugin_enabled (strip_n, plugin_n)); + strip.nth_plugin (plugin_n).enabled ()); for (uint32_t param_n = 0; param_n < plugin->parameter_count (); ++param_n) { boost::shared_ptr a_ctrl = - mixer ().strip_plugin_param_control (strip_n, plugin_n, param_n); + strip.nth_plugin (plugin_n).param_control (param_n); if (!a_ctrl) { continue; } @@ -130,7 +129,7 @@ WebsocketsDispatcher::update_all_nodes (Client client) update (client, Node::strip_plugin_param_description, addr, val); - TypedValue value = mixer ().strip_plugin_param_value (strip_n, plugin_n, param_n); + TypedValue value = strip.nth_plugin (plugin_n).param_value (param_n); update (client, Node::strip_plugin_param_value, strip_n, plugin_n, param_n, value); } } @@ -190,9 +189,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 ().set_strip_gain (strip_id, state.nth_val (0)); + mixer ().nth_strip (strip_id).set_gain (state.nth_val (0)); } else { - update (client, Node::strip_gain, strip_id, mixer ().strip_gain (strip_id)); + update (client, Node::strip_gain, strip_id, mixer ().nth_strip (strip_id).gain ()); } } @@ -208,9 +207,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 ().set_strip_pan (strip_id, state.nth_val (0)); + mixer ().nth_strip (strip_id).set_pan (state.nth_val (0)); } else { - update (client, Node::strip_pan, strip_id, mixer ().strip_pan (strip_id)); + update (client, Node::strip_pan, strip_id, mixer ().nth_strip (strip_id).pan ()); } } @@ -226,9 +225,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 ().set_strip_mute (strip_id, state.nth_val (0)); + mixer ().nth_strip (strip_id).set_mute (state.nth_val (0)); } else { - update (client, Node::strip_mute, strip_id, mixer ().strip_mute (strip_id)); + update (client, Node::strip_mute, strip_id, mixer ().nth_strip (strip_id).mute ()); } } @@ -245,10 +244,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 ().set_strip_plugin_enabled (strip_id, plugin_id, state.nth_val (0)); + mixer ().nth_strip (strip_id).nth_plugin (plugin_id).set_enabled (state.nth_val (0)); } else { update (client, Node::strip_plugin_enable, strip_id, plugin_id, - mixer ().strip_plugin_enabled (strip_id, plugin_id)); + mixer ().nth_strip (strip_id).nth_plugin (plugin_id).enabled ()); } } @@ -266,10 +265,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 ().set_strip_plugin_param_value (strip_id, plugin_id, param_id, + mixer ().nth_strip (strip_id).nth_plugin (plugin_id).set_param_value (param_id, state.nth_val (0)); } else { - TypedValue value = mixer ().strip_plugin_param_value (strip_id, plugin_id, param_id); + TypedValue value = mixer ().nth_strip (strip_id).nth_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 d124a341ee..e3e08c35a1 100644 --- a/libs/surfaces/websockets/feedback.cc +++ b/libs/surfaces/websockets/feedback.cc @@ -16,7 +16,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "ardour/meter.h" #include "ardour/plugin_insert.h" #include "ardour/session.h" #include "ardour/tempo.h" @@ -57,21 +56,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 ().strip_gain (strip_n)); + p->update_all (Node::strip_gain, strip_n, p->mixer ().nth_strip (strip_n).gain ()); } }; struct StripPanObserver { void operator() (ArdourFeedback* p, uint32_t strip_n) { - p->update_all (Node::strip_pan, strip_n, p->mixer ().strip_pan (strip_n)); + p->update_all (Node::strip_pan, strip_n, p->mixer ().nth_strip (strip_n).pan ()); } }; struct StripMuteObserver { void operator() (ArdourFeedback* p, uint32_t strip_n) { - p->update_all (Node::strip_mute, strip_n, p->mixer ().strip_mute (strip_n)); + p->update_all (Node::strip_mute, strip_n, p->mixer ().nth_strip (strip_n).mute ()); } }; @@ -79,7 +78,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 ().strip_plugin_enabled (strip_n, plugin_n)); + p->mixer ().nth_strip (strip_n).nth_plugin (plugin_n).enabled ()); } }; @@ -92,7 +91,7 @@ struct PluginParamValueObserver { return; } p->update_all (Node::strip_plugin_param_value, strip_n, plugin_n, param_n, - ArdourMixer::plugin_param_value (control)); + ArdourMixerPlugin::param_value (control)); } }; @@ -117,17 +116,17 @@ ArdourFeedback::stop () _periodic_connection.disconnect (); _transport_connections.drop_connections (); - for (StripConnectionMap::iterator it = _strip_connections.begin (); it != _strip_connections.end(); ++it) { + /*for (StripConnectionMap::iterator it = _strip_connections.begin (); it != _strip_connections.end(); ++it) { it->second->drop_connections (); } _strip_connections.clear(); - - for (PluginConnectionMap::iterator it = _plugin_connections.begin (); it != _plugin_connections.end(); ++it) { +*/ + /*for (PluginConnectionMap::iterator it = _plugin_connections.begin (); it != _plugin_connections.end(); ++it) { it->second->drop_connections (); } - _plugin_connections.clear(); + _plugin_connections.clear();*/ return 0; } @@ -181,10 +180,7 @@ ArdourFeedback::poll () const update_all (Node::transport_time, transport ().time ()); for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - // meters - boost::shared_ptr strip = mixer ().nth_strip (strip_n); - boost::shared_ptr meter = strip->peak_meter (); - float db = meter ? meter->meter_level (0, MeterMCP) : -193; + float db = mixer ().nth_strip (strip_n).meter_level_db (); update_all (Node::strip_meter, strip_n, static_cast (db)); } @@ -207,27 +203,21 @@ void ArdourFeedback::observe_mixer () { for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { - boost::shared_ptr strip = mixer ().nth_strip (strip_n); + boost::shared_ptr stripable = mixer ().nth_strip (strip_n).stripable (); + boost::shared_ptr connections = mixer().nth_strip (strip_n).connections (); - std::unique_ptr connections (new PBD::ScopedConnectionList()); - - strip->gain_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, + stripable->gain_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, boost::bind (StripGainObserver (), this, strip_n), event_loop ()); - if (strip->pan_azimuth_control ()) { - strip->pan_azimuth_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, + if (stripable->pan_azimuth_control ()) { + stripable->pan_azimuth_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, boost::bind (StripPanObserver (), this, strip_n), event_loop ()); } - strip->mute_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, + stripable->mute_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, boost::bind (StripMuteObserver (), this, strip_n), event_loop ()); - strip->DropReferences.connect (*connections, MISSING_INVALIDATOR, - boost::bind (&ArdourFeedback::on_drop_strip, this, strip_n), event_loop ()); - - _strip_connections[strip_n] = std::move (connections); - - observe_strip_plugins (strip_n, strip); + observe_strip_plugins (strip_n, stripable); } } @@ -235,7 +225,7 @@ void ArdourFeedback::observe_strip_plugins (uint32_t strip_n, boost::shared_ptr strip) { for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = mixer ().strip_plugin_insert (strip_n, plugin_n); + boost::shared_ptr insert = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).insert (); if (!insert) { break; } @@ -250,11 +240,11 @@ ArdourFeedback::observe_strip_plugins (uint32_t strip_n, boost::shared_ptr (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 ()); + //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); + //_plugin_connections[(strip_n << 16) | plugin_n] = std::move (connections); observe_strip_plugin_param_values (strip_n, plugin_n, insert); } @@ -267,42 +257,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 ().strip_plugin_param_control ( - strip_n, plugin_n, param_n); + boost::shared_ptr control = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).param_control (param_n); if (!control) { continue; } - PBD::ScopedConnectionList *connections = _plugin_connections[(strip_n << 16) | plugin_n].get(); + /*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 ()); + event_loop ());*/ } } - -void -ArdourFeedback::on_drop_strip (uint32_t strip_n) -{ - for (uint32_t plugin_n = 0;; ++plugin_n) { - boost::shared_ptr insert = mixer ().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); -} - -void -ArdourFeedback::on_drop_plugin (uint32_t strip_n, uint32_t plugin_n) -{ - uint32_t key = (strip_n << 16) | plugin_n; - _plugin_connections[key]->drop_connections (); - _plugin_connections.erase (key); -} diff --git a/libs/surfaces/websockets/feedback.h b/libs/surfaces/websockets/feedback.h index 200e2b534d..de14481719 100644 --- a/libs/surfaces/websockets/feedback.h +++ b/libs/surfaces/websockets/feedback.h @@ -46,12 +46,6 @@ private: PBD::ScopedConnectionList _transport_connections; sigc::connection _periodic_connection; - typedef boost::unordered_map> StripConnectionMap; - StripConnectionMap _strip_connections; - - typedef boost::unordered_map> PluginConnectionMap; - StripConnectionMap _plugin_connections; // also holds connections to parameters - bool poll () const; void observe_transport (); @@ -59,9 +53,6 @@ private: void observe_strip_plugins (uint32_t, boost::shared_ptr); void observe_strip_plugin_param_values (uint32_t, uint32_t, boost::shared_ptr); - - void on_drop_strip (uint32_t); - void on_drop_plugin (uint32_t, uint32_t); }; #endif // _ardour_surface_websockets_feedback_h_ diff --git a/libs/surfaces/websockets/mixer.cc b/libs/surfaces/websockets/mixer.cc index a39f860860..13cc3a32f4 100644 --- a/libs/surfaces/websockets/mixer.cc +++ b/libs/surfaces/websockets/mixer.cc @@ -17,6 +17,7 @@ */ #include "ardour/dB.h" +#include "ardour/meter.h" #include "ardour/plugin_insert.h" #include "ardour/session.h" #include "pbd/controllable.h" @@ -25,157 +26,33 @@ using namespace ARDOUR; -int -ArdourMixer::start () +ArdourMixerPlugin::ArdourMixerPlugin (boost::shared_ptr insert) + : _insert (insert) + , _connections (boost::shared_ptr (new PBD::ScopedConnectionList())) +{} + +boost::shared_ptr +ArdourMixerPlugin::insert () const { - /* take an indexed snapshot of current strips */ - StripableList strips; - session ().get_stripables (strips, PresentationInfo::AllStripables); - - for (StripableList::iterator strip = strips.begin (); strip != strips.end (); ++strip) { - _strips.push_back (*strip); - } - - return 0; -} - -int -ArdourMixer::stop () -{ - _strips.clear (); - return 0; -} - -double -ArdourMixer::to_db (double k) -{ - if (k == 0) { - return -std::numeric_limits::infinity (); - } - - float db = accurate_coefficient_to_dB (static_cast (k)); - - return static_cast (db); -} - -double -ArdourMixer::from_db (double db) -{ - if (db < -192) { - return 0; - } - - float k = dB_to_coefficient (static_cast (db)); - - return static_cast (k); -} - -double -ArdourMixer::strip_gain (uint32_t strip_n) const -{ - return to_db (nth_strip (strip_n)->gain_control ()->get_value ()); -} - -void -ArdourMixer::set_strip_gain (uint32_t strip_n, double db) -{ - nth_strip (strip_n)->gain_control ()->set_value (from_db (db), PBD::Controllable::NoGroup); -} - -double -ArdourMixer::strip_pan (uint32_t strip_n) const -{ - boost::shared_ptr ac = nth_strip (strip_n)->pan_azimuth_control (); - if (!ac) { - /* TODO: inform GUI that strip has no panner */ - return 0; - } - return ac->internal_to_interface (ac->get_value ()); -} - -void -ArdourMixer::set_strip_pan (uint32_t strip_n, double value) -{ - boost::shared_ptr ac = nth_strip (strip_n)->pan_azimuth_control (); - if (!ac) { - return; - } - ac->set_value (ac->interface_to_internal (value), PBD::Controllable::NoGroup); + return _insert; } bool -ArdourMixer::strip_mute (uint32_t strip_n) const +ArdourMixerPlugin::enabled () const { - return nth_strip (strip_n)->mute_control ()->muted (); + insert ()->enabled (); } void -ArdourMixer::set_strip_mute (uint32_t strip_n, bool mute) +ArdourMixerPlugin::set_enabled (bool enabled) { - nth_strip (strip_n)->mute_control ()->set_value (mute ? 1.0 : 0.0, PBD::Controllable::NoGroup); -} - -bool -ArdourMixer::strip_plugin_enabled (uint32_t strip_n, uint32_t plugin_n) const -{ - return strip_plugin_insert (strip_n, plugin_n)->enabled (); -} - -void -ArdourMixer::set_strip_plugin_enabled (uint32_t strip_n, uint32_t plugin_n, bool enabled) -{ - strip_plugin_insert (strip_n, plugin_n)->enable (enabled); + insert ()->enable (enabled); } TypedValue -ArdourMixer::strip_plugin_param_value (uint32_t strip_n, uint32_t plugin_n, - uint32_t param_n) const -{ - return plugin_param_value (strip_plugin_param_control (strip_n, plugin_n, param_n)); -} - -void -ArdourMixer::set_strip_plugin_param_value (uint32_t strip_n, uint32_t plugin_n, - uint32_t param_n, TypedValue value) -{ - boost::shared_ptr control = strip_plugin_param_control ( - strip_n, plugin_n, param_n); - - 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); - } -} - -uint32_t -ArdourMixer::strip_count () const -{ - return _strips.size (); -} - -boost::shared_ptr -ArdourMixer::nth_strip (uint32_t strip_n) const -{ - if (strip_n < _strips.size ()) { - return _strips[strip_n]; - } - - return boost::shared_ptr (); -} - -TypedValue -ArdourMixer::plugin_param_value (boost::shared_ptr control) +ArdourMixerPlugin::param_value (uint32_t param_n) { + boost::shared_ptr control = param_control (param_n); TypedValue value = TypedValue (); if (control) { @@ -193,48 +70,241 @@ ArdourMixer::plugin_param_value (boost::shared_ptr co return value; } -boost::shared_ptr -ArdourMixer::strip_plugin_insert (uint32_t strip_n, uint32_t plugin_n) const +void +ArdourMixerPlugin::set_param_value (uint32_t param_n, TypedValue value) { - boost::shared_ptr strip = nth_strip (strip_n); + boost::shared_ptr control = param_control (param_n); - if ((strip->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA) == 0) { - boost::shared_ptr route = boost::dynamic_pointer_cast (strip); + if (control) { + ParameterDescriptor pd = control->desc (); + double dbl_val; - if (route) { - boost::shared_ptr processor = route->nth_plugin (plugin_n); + 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); + } - if (processor) { - boost::shared_ptr insert = - boost::static_pointer_cast (processor); + control->set_value (dbl_val, PBD::Controllable::NoGroup); + } +} - if (insert) { - return insert; - } +boost::shared_ptr +ArdourMixerPlugin::param_control (uint32_t param_n) const +{ + bool ok = false; + boost::shared_ptr plugin = _insert->plugin (); + uint32_t control_id = plugin->nth_parameter (param_n, ok); + + if (!ok || !plugin->parameter_is_input (control_id)) { + throw ArdourMixerNotFoundException("invalid automation control"); + } + + return _insert->automation_control (Evoral::Parameter (PluginAutomation, 0, control_id)); +} + +ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr stripable) + : _stripable (stripable) + , _connections (boost::shared_ptr (new PBD::ScopedConnectionList())) +{ + if (_stripable->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA) { + return; + } + + boost::shared_ptr route = boost::dynamic_pointer_cast (_stripable); + + if (!route) { + return; + } + + 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 (insert) { + ArdourMixerPlugin plugin (insert); + _plugins.push_back (plugin); } } } - - return boost::shared_ptr (); } -boost::shared_ptr -ArdourMixer::strip_plugin_param_control (uint32_t strip_n, uint32_t plugin_n, - uint32_t param_n) const +boost::shared_ptr +ArdourMixerStrip::stripable () const { - boost::shared_ptr insert = strip_plugin_insert (strip_n, plugin_n); + return _stripable; +} - if (insert) { - bool ok = false; - boost::shared_ptr plugin = insert->plugin (); - uint32_t control_id = plugin->nth_parameter (param_n, ok); +boost::shared_ptr +ArdourMixerStrip::connections () const +{ + return _connections; +} - if (ok && plugin->parameter_is_input (control_id)) { - boost::shared_ptr control = - insert->automation_control (Evoral::Parameter (PluginAutomation, 0, control_id)); - return control; - } +int +ArdourMixerStrip::plugin_count () const +{ + return _plugins.size (); +} + +ArdourMixerPlugin& +ArdourMixerStrip::nth_plugin (uint32_t plugin_n) +{ + if (plugin_n < _plugins.size ()) { + return _plugins[plugin_n]; } - return boost::shared_ptr (); + throw ArdourMixerNotFoundException (""/*"Plugin with ID " + plugin_n + " not found"*/); +} + +double +ArdourMixerStrip::gain () const +{ + return to_db (_stripable->gain_control ()->get_value ()); +} + +void +ArdourMixerStrip::set_gain (double db) +{ + _stripable->gain_control ()->set_value (from_db (db), PBD::Controllable::NoGroup); +} + +double +ArdourMixerStrip::pan () const +{ + boost::shared_ptr ac = _stripable->pan_azimuth_control (); + if (!ac) { + /* TODO: inform GUI that strip has no panner */ + return 0; + } + return ac->internal_to_interface (ac->get_value ()); +} + +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); +} + +bool +ArdourMixerStrip::mute () const +{ + return _stripable->mute_control ()->muted (); +} + +void +ArdourMixerStrip::set_mute (bool mute) +{ + _stripable->mute_control ()->set_value (mute ? 1.0 : 0.0, PBD::Controllable::NoGroup); +} + +float +ArdourMixerStrip::meter_level_db () const +{ + boost::shared_ptr meter = _stripable->peak_meter (); + return meter ? meter->meter_level (0, MeterMCP) : -193; +} + +std::string +ArdourMixerStrip::name () const +{ + return _stripable->name (); +} + +void +ArdourMixerStrip::on_drop_plugin (uint32_t) +{ + //uint32_t key = (strip_n << 16) | plugin_n; + //_plugin_connections[key]->drop_connections (); + //_plugin_connections.erase (key); +} + +double +ArdourMixerStrip::to_db (double k) +{ + if (k == 0) { + return -std::numeric_limits::infinity (); + } + + float db = accurate_coefficient_to_dB (static_cast (k)); + + return static_cast (db); +} + +double +ArdourMixerStrip::from_db (double db) +{ + if (db < -192) { + return 0; + } + + float k = dB_to_coefficient (static_cast (db)); + + return static_cast (k); +} + +int +ArdourMixer::start () +{ + /* take an indexed 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.push_back (strip); + strip_n++; + } + + return 0; +} + +int +ArdourMixer::stop () +{ + _strips.clear (); + return 0; +} + +uint32_t +ArdourMixer::strip_count () const +{ + return _strips.size (); +} + +ArdourMixerStrip& +ArdourMixer::nth_strip (uint32_t strip_n) +{ + if (strip_n < _strips.size ()) { + return _strips[strip_n]; + } + + throw ArdourMixerNotFoundException (""/*"Strip with ID " + strip_n + " not found"*/); +} + +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); } diff --git a/libs/surfaces/websockets/mixer.h b/libs/surfaces/websockets/mixer.h index de63d9a12f..c2ee9f87ae 100644 --- a/libs/surfaces/websockets/mixer.h +++ b/libs/surfaces/websockets/mixer.h @@ -22,6 +22,70 @@ #include "component.h" #include "typed_value.h" +struct ArdourMixerNotFoundException : public virtual std::runtime_error +{ + using std::runtime_error::runtime_error; +}; + +class ArdourMixerPlugin +{ +public: + ArdourMixerPlugin (boost::shared_ptr); + + boost::shared_ptr insert () const; + + bool enabled () const; + void set_enabled (bool); + + TypedValue param_value (uint32_t); + void set_param_value (uint32_t, TypedValue); + + boost::shared_ptr param_control (uint32_t) const; + + static TypedValue param_value (boost::shared_ptr); + +private: + boost::shared_ptr _insert; + boost::shared_ptr _connections; + +}; + +class ArdourMixerStrip +{ +public: + ArdourMixerStrip (boost::shared_ptr); + + boost::shared_ptr stripable () const; + boost::shared_ptr connections () const; + + int plugin_count () const; + ArdourMixerPlugin& nth_plugin (uint32_t); + + double gain () const; + void set_gain (double); + + double pan () const; + void set_pan (double); + + bool mute () const; + void set_mute (bool); + + std::string name () const; + + float meter_level_db () const; + + static double to_db (double); + static double from_db (double); + +private: + boost::shared_ptr _stripable; + boost::shared_ptr _connections; + std::vector _plugins; + + void on_drop_plugin (uint32_t); + +}; + class ArdourMixer : public SurfaceComponent { public: @@ -32,37 +96,13 @@ public: int start (); int stop (); - static double to_db (double); - static double from_db (double); - - double strip_gain (uint32_t) const; - void set_strip_gain (uint32_t, double); - - double strip_pan (uint32_t) const; - void set_strip_pan (uint32_t, double); - - bool strip_mute (uint32_t) const; - void set_strip_mute (uint32_t, bool); - - bool strip_plugin_enabled (uint32_t, uint32_t) const; - void set_strip_plugin_enabled (uint32_t, uint32_t, bool); - - TypedValue strip_plugin_param_value (uint32_t, uint32_t, uint32_t) const; - void set_strip_plugin_param_value (uint32_t, uint32_t, uint32_t, TypedValue); - - uint32_t strip_count () const; - boost::shared_ptr nth_strip (uint32_t) const; - - boost::shared_ptr strip_plugin_insert (uint32_t, uint32_t) const; - - boost::shared_ptr strip_plugin_param_control ( - uint32_t, uint32_t, uint32_t) const; - - static TypedValue plugin_param_value (boost::shared_ptr); + uint32_t strip_count () const; + ArdourMixerStrip& nth_strip (uint32_t); + void on_drop_strip (uint32_t); private: - typedef std::vector > StripableVector; - StripableVector _strips; + typedef std::vector StripsVector; + StripsVector _strips; }; #endif // _ardour_surface_websockets_mixer_h_