WS: prepare for handling object disconnections

Use maps instead of vectors for holding strips and plugins
This allows to deal with "holes" after objects are removed

Also paves the way for a future improved way of identifying
individual strips and plugins
This commit is contained in:
Luciano Iam 2020-08-29 20:06:00 +02:00 committed by Robin Gareus
parent 7521d8ab6f
commit a8f917e7e2
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
5 changed files with 132 additions and 118 deletions

View file

@ -55,8 +55,9 @@ WebsocketsDispatcher::dispatch (Client client, const NodeStateMessage& msg)
void void
WebsocketsDispatcher::update_all_nodes (Client client) WebsocketsDispatcher::update_all_nodes (Client client)
{ {
for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) {
ArdourMixerStrip &strip = mixer ().nth_strip (strip_n); uint32_t strip_n = it->first;
ArdourMixerStrip& strip = it->second;
bool is_vca = strip.stripable ()->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA; 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 ()); update (client, Node::strip_pan, strip_n, strip.pan ());
for (uint32_t plugin_n = 0;; ++plugin_n) { for (ArdourMixerStrip::PluginMap::iterator it = strip.plugins ().begin (); it != strip.plugins ().end (); ++it) {
boost::shared_ptr<PluginInsert> insert = strip.nth_plugin (plugin_n).insert (); uint32_t plugin_n = it->first;
if (!insert) { boost::shared_ptr<PluginInsert> insert = it->second.insert ();
break; boost::shared_ptr<Plugin> plugin = insert->plugin ();
}
boost::shared_ptr<Plugin> plugin = insert->plugin ();
update (client, Node::strip_plugin_description, strip_n, plugin_n, update (client, Node::strip_plugin_description, strip_n, plugin_n,
static_cast<std::string> (plugin->name ())); static_cast<std::string> (plugin->name ()));
update (client, Node::strip_plugin_enable, strip_n, plugin_n, 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) { for (uint32_t param_n = 0; param_n < plugin->parameter_count (); ++param_n) {
boost::shared_ptr<AutomationControl> a_ctrl = boost::shared_ptr<AutomationControl> a_ctrl;
strip.nth_plugin (plugin_n).param_control (param_n);
if (!a_ctrl) { try {
a_ctrl = strip.plugin (plugin_n).param_control (param_n);
} catch (ArdourMixerNotFoundException) {
continue; continue;
} }
@ -129,7 +130,7 @@ WebsocketsDispatcher::update_all_nodes (Client client)
update (client, Node::strip_plugin_param_description, addr, val); 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); 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); uint32_t strip_id = state.nth_addr (0);
if (msg.is_write () && (state.n_val () > 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 { } 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); uint32_t strip_id = state.nth_addr (0);
if (msg.is_write () && (state.n_val () > 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 { } 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); uint32_t strip_id = state.nth_addr (0);
if (msg.is_write () && (state.n_val () > 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 { } 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); uint32_t plugin_id = state.nth_addr (1);
if (msg.is_write () && (state.n_val () > 0)) { 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 { } else {
update (client, Node::strip_plugin_enable, strip_id, plugin_id, 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); uint32_t param_id = state.nth_addr (2);
if (msg.is_write () && (state.n_val () > 0)) { 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)); state.nth_val (0));
} else { } 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); update (client, Node::strip_plugin_param_value, strip_id, plugin_id, param_id, value);
} }
} }

View file

@ -24,7 +24,6 @@
#include "transport.h" #include "transport.h"
#include "server.h" #include "server.h"
#include "state.h" #include "state.h"
#include "mixer.h"
// TO DO: make this configurable // TO DO: make this configurable
#define POLL_INTERVAL_MS 100 #define POLL_INTERVAL_MS 100
@ -56,21 +55,21 @@ struct StripGainObserver {
void operator() (ArdourFeedback* p, uint32_t strip_n) void operator() (ArdourFeedback* p, uint32_t strip_n)
{ {
// fires multiple times (4x as of ardour 6.0) // 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 { struct StripPanObserver {
void operator() (ArdourFeedback* p, uint32_t strip_n) 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 { struct StripMuteObserver {
void operator() (ArdourFeedback* p, uint32_t strip_n) 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) void operator() (ArdourFeedback* p, uint32_t strip_n, uint32_t plugin_n)
{ {
p->update_all (Node::strip_plugin_enable, strip_n, 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<AutomationControl> ctrl) uint32_t param_n, boost::weak_ptr<AutomationControl> ctrl)
{ {
boost::shared_ptr<AutomationControl> control = ctrl.lock (); boost::shared_ptr<AutomationControl> control = ctrl.lock ();
if (!control) { if (!control) {
return; return;
} }
p->update_all (Node::strip_plugin_param_value, strip_n, plugin_n, param_n, p->update_all (Node::strip_plugin_param_value, strip_n, plugin_n, param_n,
ArdourMixerPlugin::param_value (control)); ArdourMixerPlugin::param_value (control));
} }
@ -101,7 +102,7 @@ ArdourFeedback::start ()
observe_transport (); observe_transport ();
observe_mixer (); observe_mixer ();
// some things need polling like the strip meters // some values need polling like the strip meters
Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (POLL_INTERVAL_MS); Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (POLL_INTERVAL_MS);
_periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, _periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this,
&ArdourFeedback::poll)); &ArdourFeedback::poll));
@ -179,9 +180,9 @@ ArdourFeedback::poll () const
{ {
update_all (Node::transport_time, transport ().time ()); update_all (Node::transport_time, transport ().time ());
for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) {
float db = mixer ().nth_strip (strip_n).meter_level_db (); float db = it->second.meter_level_db ();
update_all (Node::strip_meter, strip_n, static_cast<double> (db)); update_all (Node::strip_meter, it->first, static_cast<double> (db));
} }
return true; return true;
@ -202,9 +203,12 @@ ArdourFeedback::observe_transport ()
void void
ArdourFeedback::observe_mixer () ArdourFeedback::observe_mixer ()
{ {
for (uint32_t strip_n = 0; strip_n < mixer ().strip_count (); ++strip_n) { for (ArdourMixer::StripMap::iterator it = mixer().strips().begin(); it != mixer().strips().end(); ++it) {
boost::shared_ptr<Stripable> stripable = mixer ().nth_strip (strip_n).stripable (); uint32_t strip_n = it->first;
boost::shared_ptr<PBD::ScopedConnectionList> connections = mixer().nth_strip (strip_n).connections (); ArdourMixerStrip& strip = it->second;
boost::shared_ptr<Stripable> stripable = strip.stripable ();
boost::shared_ptr<PBD::ScopedConnectionList> connections = it->second.connections ();
stripable->gain_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, stripable->gain_control ()->Changed.connect (*connections, MISSING_INVALIDATOR,
boost::bind<void> (StripGainObserver (), this, strip_n), event_loop ()); boost::bind<void> (StripGainObserver (), this, strip_n), event_loop ());
@ -217,23 +221,20 @@ ArdourFeedback::observe_mixer ()
stripable->mute_control ()->Changed.connect (*connections, MISSING_INVALIDATOR, stripable->mute_control ()->Changed.connect (*connections, MISSING_INVALIDATOR,
boost::bind<void> (StripMuteObserver (), this, strip_n), event_loop ()); boost::bind<void> (StripMuteObserver (), this, strip_n), event_loop ());
observe_strip_plugins (strip_n, stripable); observe_strip_plugins (strip_n, strip.plugins ());
} }
} }
void void
ArdourFeedback::observe_strip_plugins (uint32_t strip_n, boost::shared_ptr<ARDOUR::Stripable> strip) ArdourFeedback::observe_strip_plugins (uint32_t strip_n, ArdourMixerStrip::PluginMap& plugins)
{ {
for (uint32_t plugin_n = 0;; ++plugin_n) { for (ArdourMixerStrip::PluginMap::iterator it = plugins.begin(); it != plugins.end(); ++it) {
boost::shared_ptr<PluginInsert> insert = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).insert (); uint32_t plugin_n = it->first;
if (!insert) { boost::shared_ptr<PluginInsert> insert = it->second.insert ();
break; boost::shared_ptr<PBD::ScopedConnectionList> connections = it->second.connections ();
} uint32_t bypass = insert->plugin ()->designated_bypass_port ();
Evoral::Parameter param = Evoral::Parameter (PluginAutomation, 0, bypass);
uint32_t bypass = insert->plugin ()->designated_bypass_port (); boost::shared_ptr<AutomationControl> control = insert->automation_control (param);
Evoral::Parameter param = Evoral::Parameter (PluginAutomation, 0, bypass);
boost::shared_ptr<AutomationControl> control = insert->automation_control (param);
std::unique_ptr<PBD::ScopedConnectionList> connections (new PBD::ScopedConnectionList());
if (control) { if (control) {
control->Changed.connect (*connections, MISSING_INVALIDATOR, control->Changed.connect (*connections, MISSING_INVALIDATOR,
@ -257,17 +258,17 @@ ArdourFeedback::observe_strip_plugin_param_values (uint32_t strip_n,
boost::shared_ptr<Plugin> plugin = insert->plugin (); boost::shared_ptr<Plugin> 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->parameter_count (); ++param_n) {
boost::shared_ptr<AutomationControl> control = mixer ().nth_strip (strip_n).nth_plugin (plugin_n).param_control (param_n); try {
boost::shared_ptr<AutomationControl> control = mixer ().strip (strip_n).plugin (plugin_n).param_control (param_n);
if (!control) { /*PBD::ScopedConnectionList *connections = _plugin_connections[(strip_n << 16) | plugin_n].get();
continue;
control->Changed.connect (*connections, MISSING_INVALIDATOR,
boost::bind<void> (PluginParamValueObserver (), this, strip_n, plugin_n, param_n,
boost::weak_ptr<AutomationControl>(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<void> (PluginParamValueObserver (), this, strip_n, plugin_n, param_n,
boost::weak_ptr<AutomationControl>(control)),
event_loop ());*/
} }
} }

View file

@ -25,6 +25,7 @@
#include "component.h" #include "component.h"
#include "typed_value.h" #include "typed_value.h"
#include "mixer.h"
class ArdourFeedback : public SurfaceComponent class ArdourFeedback : public SurfaceComponent
{ {
@ -50,9 +51,8 @@ private:
void observe_transport (); void observe_transport ();
void observe_mixer (); void observe_mixer ();
void observe_strip_plugins (uint32_t, boost::shared_ptr<ARDOUR::Stripable>); void observe_strip_plugins (uint32_t, ArdourMixerStrip::PluginMap&);
void observe_strip_plugin_param_values (uint32_t, uint32_t, void observe_strip_plugin_param_values (uint32_t, uint32_t, boost::shared_ptr<ARDOUR::PluginInsert>);
boost::shared_ptr<ARDOUR::PluginInsert>);
}; };
#endif // _ardour_surface_websockets_feedback_h_ #endif // _ardour_surface_websockets_feedback_h_

View file

@ -39,10 +39,16 @@ ArdourMixerPlugin::insert () const
return _insert; return _insert;
} }
boost::shared_ptr<PBD::ScopedConnectionList>
ArdourMixerPlugin::connections () const
{
return _connections;
}
bool bool
ArdourMixerPlugin::enabled () const ArdourMixerPlugin::enabled () const
{ {
insert ()->enabled (); return insert ()->enabled ();
} }
void void
@ -55,18 +61,15 @@ TypedValue
ArdourMixerPlugin::param_value (uint32_t param_n) ArdourMixerPlugin::param_value (uint32_t param_n)
{ {
boost::shared_ptr<ARDOUR::AutomationControl> control = param_control (param_n); boost::shared_ptr<ARDOUR::AutomationControl> control = param_control (param_n);
TypedValue value = TypedValue (); ParameterDescriptor pd = control->desc ();
TypedValue value = TypedValue ();
if (control) { if (pd.toggled) {
ParameterDescriptor pd = control->desc (); value = TypedValue (static_cast<bool> (control->get_value ()));
} else if (pd.enumeration || pd.integer_step) {
if (pd.toggled) { value = TypedValue (static_cast<int> (control->get_value ()));
value = TypedValue (static_cast<bool> (control->get_value ())); } else {
} else if (pd.enumeration || pd.integer_step) { value = TypedValue (control->get_value ());
value = TypedValue (static_cast<int> (control->get_value ()));
} else {
value = TypedValue (control->get_value ());
}
} }
return value; return value;
@ -76,21 +79,18 @@ void
ArdourMixerPlugin::set_param_value (uint32_t param_n, TypedValue value) ArdourMixerPlugin::set_param_value (uint32_t param_n, TypedValue value)
{ {
boost::shared_ptr<AutomationControl> control = param_control (param_n); boost::shared_ptr<AutomationControl> control = param_control (param_n);
ParameterDescriptor pd = control->desc ();
double dbl_val;
if (control) { if (pd.toggled) {
ParameterDescriptor pd = control->desc (); dbl_val = static_cast<double> (static_cast<bool> (value));
double dbl_val; } else if (pd.enumeration || pd.integer_step) {
dbl_val = static_cast<double> (static_cast<int> (value));
if (pd.toggled) { } else {
dbl_val = static_cast<double> (static_cast<bool> (value)); dbl_val = static_cast<double> (value);
} else if (pd.enumeration || pd.integer_step) {
dbl_val = static_cast<double> (static_cast<int> (value));
} else {
dbl_val = static_cast<double> (value);
}
control->set_value (dbl_val, PBD::Controllable::NoGroup);
} }
control->set_value (dbl_val, PBD::Controllable::NoGroup);
} }
boost::shared_ptr<ARDOUR::AutomationControl> boost::shared_ptr<ARDOUR::AutomationControl>
@ -113,6 +113,7 @@ ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr<ARDOUR::Stripable> stripab
, _connections (boost::shared_ptr<PBD::ScopedConnectionList> (new PBD::ScopedConnectionList())) , _connections (boost::shared_ptr<PBD::ScopedConnectionList> (new PBD::ScopedConnectionList()))
{ {
if (_stripable->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA) { if (_stripable->presentation_info ().flags () & ARDOUR::PresentationInfo::VCA) {
/* no plugins to handle */
return; return;
} }
@ -125,13 +126,15 @@ ArdourMixerStrip::ArdourMixerStrip (boost::shared_ptr<ARDOUR::Stripable> stripab
for (uint32_t plugin_n = 0;; ++plugin_n) { for (uint32_t plugin_n = 0;; ++plugin_n) {
boost::shared_ptr<Processor> processor = route->nth_plugin (plugin_n); boost::shared_ptr<Processor> processor = route->nth_plugin (plugin_n);
if (processor) { if (!processor) {
boost::shared_ptr<PluginInsert> insert = boost::static_pointer_cast<PluginInsert> (processor); break;
}
if (insert) { boost::shared_ptr<PluginInsert> insert = boost::static_pointer_cast<PluginInsert> (processor);
ArdourMixerPlugin plugin (insert);
_plugins.push_back (plugin); if (insert) {
} ArdourMixerPlugin plugin (insert);
_plugins.emplace (plugin_n, plugin);
} }
} }
} }
@ -148,20 +151,20 @@ ArdourMixerStrip::connections () const
return _connections; return _connections;
} }
int
ArdourMixerStrip::plugin_count () const
{
return _plugins.size ();
}
ArdourMixerPlugin& ArdourMixerPlugin&
ArdourMixerStrip::nth_plugin (uint32_t plugin_n) ArdourMixerStrip::plugin (uint32_t plugin_n)
{ {
if (plugin_n < _plugins.size ()) { if (_plugins.find (plugin_n) == _plugins.end ()) {
return _plugins[plugin_n]; throw ArdourMixerNotFoundException ("plugin id = " + boost::lexical_cast<std::string>(plugin_n) + " not found");
} }
throw ArdourMixerNotFoundException ("plugin id = " + boost::lexical_cast<std::string>(plugin_n) + " not found"); return _plugins.at (plugin_n);
}
ArdourMixerStrip::PluginMap&
ArdourMixerStrip::plugins ()
{
return _plugins;
} }
double double
@ -180,9 +183,11 @@ double
ArdourMixerStrip::pan () const ArdourMixerStrip::pan () const
{ {
boost::shared_ptr<AutomationControl> ac = _stripable->pan_azimuth_control (); boost::shared_ptr<AutomationControl> ac = _stripable->pan_azimuth_control ();
if (!ac) { if (!ac) {
throw ArdourMixerNotFoundException ("strip has no panner"); throw ArdourMixerNotFoundException ("strip has no panner");
} }
return ac->internal_to_interface (ac->get_value ()); return ac->internal_to_interface (ac->get_value ());
} }
@ -190,9 +195,11 @@ void
ArdourMixerStrip::set_pan (double value) ArdourMixerStrip::set_pan (double value)
{ {
boost::shared_ptr<AutomationControl> ac = _stripable->pan_azimuth_control (); boost::shared_ptr<AutomationControl> ac = _stripable->pan_azimuth_control ();
if (!ac) { if (!ac) {
return; return;
} }
ac->set_value (ac->interface_to_internal (value), PBD::Controllable::NoGroup); ac->set_value (ac->interface_to_internal (value), PBD::Controllable::NoGroup);
} }
@ -265,8 +272,7 @@ ArdourMixer::start ()
ArdourMixerStrip strip (*it); ArdourMixerStrip strip (*it);
//(*it)->DropReferences.connect (_connections, MISSING_INVALIDATOR, //(*it)->DropReferences.connect (_connections, MISSING_INVALIDATOR,
// boost::bind (&ArdourMixer::on_drop_strip, this, strip_n), event_loop ()); // boost::bind (&ArdourMixer::on_drop_strip, this, strip_n), event_loop ());
_strips.push_back (strip); _strips.emplace (strip_n++, strip);
strip_n++;
} }
return 0; return 0;
@ -279,20 +285,21 @@ ArdourMixer::stop ()
return 0; return 0;
} }
uint32_t ArdourMixer::StripMap&
ArdourMixer::strip_count () const ArdourMixer::strips ()
{ {
return _strips.size (); return _strips;
} }
ArdourMixerStrip& ArdourMixerStrip&
ArdourMixer::nth_strip (uint32_t strip_n) ArdourMixer::strip (uint32_t strip_n)
{ {
if (strip_n < _strips.size ()) { if (_strips.find (strip_n) == _strips.end ()) {
return _strips[strip_n]; throw ArdourMixerNotFoundException ("strip id = " + boost::lexical_cast<std::string>(strip_n) + " not found");
} }
throw ArdourMixerNotFoundException ("strip id = " + boost::lexical_cast<std::string>(strip_id) + " not found"); return _strips.at (strip_n);
} }
void void

View file

@ -33,7 +33,8 @@ public:
ArdourMixerPlugin (boost::shared_ptr<ARDOUR::PluginInsert>); ArdourMixerPlugin (boost::shared_ptr<ARDOUR::PluginInsert>);
boost::shared_ptr<ARDOUR::PluginInsert> insert () const; boost::shared_ptr<ARDOUR::PluginInsert> insert () const;
boost::shared_ptr<PBD::ScopedConnectionList> connections () const;
bool enabled () const; bool enabled () const;
void set_enabled (bool); void set_enabled (bool);
@ -58,8 +59,10 @@ public:
boost::shared_ptr<ARDOUR::Stripable> stripable () const; boost::shared_ptr<ARDOUR::Stripable> stripable () const;
boost::shared_ptr<PBD::ScopedConnectionList> connections () const; boost::shared_ptr<PBD::ScopedConnectionList> connections () const;
int plugin_count () const; typedef std::map<uint32_t, ArdourMixerPlugin> PluginMap;
ArdourMixerPlugin& nth_plugin (uint32_t);
PluginMap& plugins ();
ArdourMixerPlugin& plugin (uint32_t);
double gain () const; double gain () const;
void set_gain (double); void set_gain (double);
@ -80,7 +83,8 @@ public:
private: private:
boost::shared_ptr<ARDOUR::Stripable> _stripable; boost::shared_ptr<ARDOUR::Stripable> _stripable;
boost::shared_ptr<PBD::ScopedConnectionList> _connections; boost::shared_ptr<PBD::ScopedConnectionList> _connections;
std::vector<ArdourMixerPlugin> _plugins;
PluginMap _plugins;
void on_drop_plugin (uint32_t); void on_drop_plugin (uint32_t);
@ -96,13 +100,14 @@ public:
int start (); int start ();
int stop (); int stop ();
uint32_t strip_count () const; typedef std::map<uint32_t, ArdourMixerStrip> StripMap;
ArdourMixerStrip& nth_strip (uint32_t);
StripMap& strips ();
ArdourMixerStrip& strip (uint32_t);
void on_drop_strip (uint32_t); void on_drop_strip (uint32_t);
private: private:
typedef std::vector<ArdourMixerStrip> StripsVector; StripMap _strips;
StripsVector _strips;
}; };
#endif // _ardour_surface_websockets_mixer_h_ #endif // _ardour_surface_websockets_mixer_h_