diff --git a/libs/ardour/ardour/io_plug.h b/libs/ardour/ardour/io_plug.h index 22a05331dc..40458577ff 100644 --- a/libs/ardour/ardour/io_plug.h +++ b/libs/ardour/ardour/io_plug.h @@ -108,37 +108,6 @@ public: protected: std::string describe_parameter (Evoral::Parameter); - /** A control that manipulates a plugin parameter (control port). */ - struct PluginControl : public AutomationControl - { - PluginControl (IOPlug* p, - Evoral::Parameter const& param, - ParameterDescriptor const& desc); - - double get_value () const; - void catch_up_with_external_value (double val); - XMLNode& get_state() const; - std::string get_user_string() const; - private: - void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); - IOPlug* _iop; - }; - - /** A control that manipulates a plugin property (message). */ - struct PluginPropertyControl : public AutomationControl - { - PluginPropertyControl (IOPlug* p, - Evoral::Parameter const& param, - ParameterDescriptor const& desc); - - double get_value () const; - XMLNode& get_state() const; - private: - void actually_set_value (double value, PBD::Controllable::GroupControlDisposition); - IOPlug* _iop; - Variant _value; - }; - private: /* disallow copy construction */ IOPlug (IOPlug const&); diff --git a/libs/ardour/ardour/plug_insert_base.h b/libs/ardour/ardour/plug_insert_base.h index 229cdfb7d0..4832791c2f 100644 --- a/libs/ardour/ardour/plug_insert_base.h +++ b/libs/ardour/ardour/plug_insert_base.h @@ -24,15 +24,16 @@ #include "evoral/ControlSet.h" #include "ardour/ardour.h" +#include "ardour/automation_control.h" #include "ardour/plugin.h" #include "ardour/plugin_types.h" namespace ARDOUR { -class Session; +class Plugin; class ReadOnlyControl; class Route; -class Plugin; +class Session; class LIBARDOUR_API PlugInsertBase : virtual public Evoral::ControlSet, virtual public PBD::Destructible { @@ -61,10 +62,47 @@ public: virtual bool can_reset_all_parameters () = 0; virtual bool reset_parameters_to_default () = 0; + virtual std::string describe_parameter (Evoral::Parameter param) = 0; + virtual bool provides_stats () const = 0; virtual bool get_stats (PBD::microseconds_t&, PBD::microseconds_t&, double&, double&) const = 0; virtual void clear_stats () = 0; + /** A control that manipulates a plugin parameter (control port). */ + struct PluginControl : public AutomationControl { + PluginControl (Session& s, + PlugInsertBase* p, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + std::shared_ptr list = std::shared_ptr ()); + + double get_value (void) const; + void catch_up_with_external_value (double val); + XMLNode& get_state () const; + std::string get_user_string () const; + + protected: + virtual void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); + PlugInsertBase* _pib; + }; + + /** A control that manipulates a plugin property (message). */ + struct PluginPropertyControl : public AutomationControl { + PluginPropertyControl (Session& s, + PlugInsertBase* p, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + std::shared_ptr list = std::shared_ptr ()); + + double get_value (void) const; + XMLNode& get_state () const; + + protected: + virtual void actually_set_value (double value, PBD::Controllable::GroupControlDisposition); + PlugInsertBase* _pib; + Variant _value; + }; + protected: bool parse_plugin_type (XMLNode const&, PluginType&, std::string&) const; std::shared_ptr find_and_load_plugin (Session&, XMLNode const&, PluginType&, std::string const&, bool& any_vst); diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 8e1bc0aaea..9b6dbb8d06 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -53,6 +53,7 @@ class AudioEngine; class Session; class BufferSet; class IOPlug; +class PlugInsertBase; class PluginInsert; class Plugin; class PluginInfo; @@ -373,8 +374,8 @@ public: PBD::Signal1 EndTouch; protected: - friend class IOPlug; friend class PluginInsert; + friend class PlugInsertBase; friend class Session; /* Called when a parameter of the plugin is changed outside of this diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 57d11d00c3..2c76b3ce16 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -44,7 +44,6 @@ #include "ardour/processor.h" #include "ardour/readonly_control.h" #include "ardour/sidechain.h" -#include "ardour/automation_control.h" class XMLNode; @@ -209,42 +208,18 @@ public: bool get_stats (PBD::microseconds_t& min, PBD::microseconds_t& max, double& avg, double& dev) const; void clear_stats (); - /** A control that manipulates a plugin parameter (control port). */ - struct PluginControl : public AutomationControl + struct PIControl : public PluginControl { - PluginControl (PluginInsert* p, - const Evoral::Parameter& param, - const ParameterDescriptor& desc, - std::shared_ptr list=std::shared_ptr()); - - double get_value (void) const; - void catch_up_with_external_value (double val); - XMLNode& get_state() const; - std::string get_user_string() const; - + PIControl (Session& s, + PlugInsertBase* p, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + std::shared_ptr list = std::shared_ptr()) + : PluginControl (s, p, param, desc, list) {} private: - PluginInsert* _plugin; void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); }; - /** A control that manipulates a plugin property (message). */ - struct PluginPropertyControl : public AutomationControl - { - PluginPropertyControl (PluginInsert* p, - const Evoral::Parameter& param, - const ParameterDescriptor& desc, - std::shared_ptr list=std::shared_ptr()); - - double get_value (void) const; - XMLNode& get_state() const; - protected: - void actually_set_value (double value, PBD::Controllable::GroupControlDisposition); - - private: - PluginInsert* _plugin; - Variant _value; - }; - std::shared_ptr plugin(uint32_t num=0) const { if (num < _plugins.size()) { return _plugins[num]; diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 1788423fea..c058f48325 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -569,7 +569,7 @@ Automatable::control_factory(const Evoral::Parameter& param) PluginInsert* pi = dynamic_cast(this); if (pi) { pi->plugin(0)->get_parameter_descriptor(param.id(), desc); - control = new PluginInsert::PluginControl(pi, param, desc); + control = new PluginInsert::PIControl (_a_session, pi, param, desc); } else { warning << "PluginAutomation for non-Plugin" << endl; } @@ -583,7 +583,7 @@ Automatable::control_factory(const Evoral::Parameter& param) } else { list = std::shared_ptr(new AutomationList(param, desc, Temporal::TimeDomainProvider (Temporal::AudioTime))); } - control = new PluginInsert::PluginPropertyControl(pi, param, desc, list); + control = new PluginInsert::PluginPropertyControl (_a_session, pi, param, desc, list); } } else { warning << "PluginPropertyAutomation for non-Plugin" << endl; diff --git a/libs/ardour/io_plug.cc b/libs/ardour/io_plug.cc index ed7c3ca37b..4b1e685a8b 100644 --- a/libs/ardour/io_plug.cc +++ b/libs/ardour/io_plug.cc @@ -336,7 +336,7 @@ IOPlug::create_parameters () Evoral::Parameter param (PluginAutomation, 0, i); - std::shared_ptr c (new PluginControl(this, param, desc)); + std::shared_ptr c (new PluginControl (_session, this, param, desc)); c->set_flag (Controllable::NotAutomatable); add_control (c); @@ -351,7 +351,7 @@ IOPlug::create_parameters () if (desc.datatype == Variant::NOTHING) { continue; } - std::shared_ptr c (new PluginPropertyControl (this, param, desc)); + std::shared_ptr c (new PluginPropertyControl (_session, this, param, desc)); c->set_flag (Controllable::NotAutomatable); add_control (c); } @@ -655,104 +655,3 @@ IOPlug::reset_parameters_to_default () } return all; } - -/* ****************************************************************************/ - -IOPlug::PluginControl::PluginControl (IOPlug* p, - Evoral::Parameter const& param, - ParameterDescriptor const& desc) - : AutomationControl (p->session (), param, desc, std::shared_ptr (), p->describe_parameter (param)) - , _iop (p) -{ -} - -void -IOPlug::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override) -{ - _iop->plugin ()->set_parameter (parameter().id(), user_val, 0); - - AutomationControl::actually_set_value (user_val, group_override); -} - -void -IOPlug::PluginControl::catch_up_with_external_value (double user_val) -{ - AutomationControl::actually_set_value (user_val, Controllable::NoGroup); -} - -XMLNode& -IOPlug::PluginControl::get_state () const -{ - XMLNode& node (AutomationControl::get_state()); - node.set_property ("parameter", parameter().id()); - - std::shared_ptr lv2plugin = std::dynamic_pointer_cast (_iop->plugin ()); - if (lv2plugin) { - node.set_property ("symbol", lv2plugin->port_symbol (parameter().id())); - } - - return node; -} - -double -IOPlug::PluginControl::get_value () const -{ - std::shared_ptr plugin = _iop->plugin (); - - if (!plugin) { - return 0.0; - } - - return plugin->get_parameter (parameter().id()); -} - -std::string -IOPlug::PluginControl::get_user_string () const -{ - std::shared_ptr plugin = _iop->plugin (0); - if (plugin) { - std::string pp; - if (plugin->print_parameter (parameter().id(), pp) && pp.size () > 0) { - return pp; - } - } - return AutomationControl::get_user_string (); -} - -IOPlug::PluginPropertyControl::PluginPropertyControl (IOPlug* p, - Evoral::Parameter const& param, - ParameterDescriptor const& desc) - : AutomationControl (p->session(), param, desc ) - , _iop (p) -{ -} - -void -IOPlug::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd) -{ - const Variant value(_desc.datatype, user_val); - if (value.type() == Variant::NOTHING) { - return; - } - - _iop->plugin ()->set_property (parameter().id(), value); - - _value = value; - - AutomationControl::actually_set_value (user_val, gcd); -} - -XMLNode& -IOPlug::PluginPropertyControl::get_state () const -{ - XMLNode& node (AutomationControl::get_state()); - node.set_property ("property", parameter ().id ()); - node.remove_property ("value"); - return node; -} - -double -IOPlug::PluginPropertyControl::get_value () const -{ - return _value.to_double(); -} diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 8ddeda107c..637bb48447 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -2168,7 +2168,13 @@ LuaBindings::common (lua_State* L) .addFunction ("delay", &DelayLine::delay) .endClass () - .deriveWSPtrClass ("PluginControl") + .deriveWSPtrClass ("PluginControl") + .endClass () + + .deriveWSPtrClass ("PluginPropertyControl") + .endClass () + + .deriveWSPtrClass ("PIControl") .endClass () .beginClass ("RawMidiParser") diff --git a/libs/ardour/plug_insert_base.cc b/libs/ardour/plug_insert_base.cc index 047db3835c..24c9e893bb 100644 --- a/libs/ardour/plug_insert_base.cc +++ b/libs/ardour/plug_insert_base.cc @@ -16,11 +16,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "ardour/plug_insert_base.h" #include "ardour/ardour.h" #include "ardour/automation_control.h" -#include "ardour/lv2_plugin.h" #include "ardour/luaproc.h" -#include "ardour/plug_insert_base.h" +#include "ardour/lv2_plugin.h" #include "pbd/i18n.h" @@ -198,3 +198,125 @@ PlugInsertBase::preset_load_set_value (uint32_t p, float v) ac->set_value (v, Controllable::NoGroup); ac->stop_touch (timepos_t (ac->session ().audible_sample())); } + +/* ****************************************************************************/ + +PlugInsertBase::PluginControl::PluginControl (Session& s, + PlugInsertBase* p, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + std::shared_ptr list) + : AutomationControl (s, param, desc, list, p->describe_parameter (param)) + , _pib (p) +{ + if (alist ()) { + if (desc.toggled) { + list->set_interpolation (Evoral::ControlList::Discrete); + } + } +} + +/** @param val `user' value */ + +void +PlugInsertBase::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override) +{ + for (uint32_t i = 0; i < _pib->get_count (); ++i) { + _pib->plugin (i)->set_parameter (parameter ().id (), user_val, 0); + } + + AutomationControl::actually_set_value (user_val, group_override); +} + +void +PlugInsertBase::PluginControl::catch_up_with_external_value (double user_val) +{ + AutomationControl::actually_set_value (user_val, Controllable::NoGroup); +} + +XMLNode& +PlugInsertBase::PluginControl::get_state () const +{ + XMLNode& node (AutomationControl::get_state ()); + node.set_property (X_("parameter"), parameter ().id ()); + + std::shared_ptr lv2plugin = std::dynamic_pointer_cast (_pib->plugin (0)); + if (lv2plugin) { + node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter ().id ())); + } + + return node; +} + +/** @return `user' val */ +double +PlugInsertBase::PluginControl::get_value () const +{ + std::shared_ptr plugin = _pib->plugin (); + + if (!plugin) { + return 0.0; + } + + return plugin->get_parameter (parameter ().id ()); +} + +std::string +PlugInsertBase::PluginControl::get_user_string () const +{ + std::shared_ptr plugin = _pib->plugin (); + if (plugin) { + std::string pp; + if (plugin->print_parameter (parameter ().id (), pp) && pp.size () > 0) { + return pp; + } + } + return AutomationControl::get_user_string (); +} + +PlugInsertBase::PluginPropertyControl::PluginPropertyControl (Session& s, + PlugInsertBase* p, + const Evoral::Parameter& param, + const ParameterDescriptor& desc, + std::shared_ptr list) + : AutomationControl (s, param, desc, list) + , _pib (p) +{ +} + +void +PlugInsertBase::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd) +{ + /* Old numeric set_value(), coerce to appropriate datatype if possible. + * This is lossy, but better than nothing until Ardour's automation system + * can handle various datatypes all the way down. + */ + const Variant value (_desc.datatype, user_val); + if (value.type () == Variant::NOTHING) { + error << "set_value(double) called for non-numeric property" << endmsg; + return; + } + + for (uint32_t i = 0; i < _pib->get_count (); ++i) { + _pib->plugin (i)->set_property (parameter ().id (), value); + } + + _value = value; + + AutomationControl::actually_set_value (user_val, gcd); +} + +XMLNode& +PlugInsertBase::PluginPropertyControl::get_state () const +{ + XMLNode& node (AutomationControl::get_state ()); + node.set_property (X_("property"), parameter ().id ()); + node.remove_property (X_("value")); + return node; +} + +double +PlugInsertBase::PluginPropertyControl::get_value () const +{ + return _value.to_double (); +} diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index e794a58dc4..5d01cb90e0 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -569,7 +569,7 @@ PluginInsert::create_automatable_parameters () const bool automatable = a.find(param) != a.end(); std::shared_ptr list(new AutomationList(param, desc, *this)); - std::shared_ptr c (new PluginControl(this, param, desc, list)); + std::shared_ptr c (new PIControl(_session, this, param, desc, list)); if (!automatable || (limit_automatables > 0 && what_can_be_automated ().size() > limit_automatables)) { c->set_flag (Controllable::NotAutomatable); } @@ -590,7 +590,7 @@ PluginInsert::create_automatable_parameters () if (Variant::type_is_numeric(desc.datatype)) { list = std::shared_ptr(new AutomationList(param, desc, *this)); } - std::shared_ptr c (new PluginPropertyControl(this, param, desc, list)); + std::shared_ptr c (new PluginPropertyControl(_session, this, param, desc, list)); if (!Variant::type_is_numeric(desc.datatype)) { c->set_flag (Controllable::NotAutomatable); } @@ -612,7 +612,7 @@ PluginInsert::create_automatable_parameters () desc.upper = 1; std::shared_ptr list(new AutomationList(param, desc, *this)); - std::shared_ptr c (new PluginControl(this, param, desc, list)); + std::shared_ptr c (new PluginControl(_session, this, param, desc, list)); add_control (c); } @@ -3069,129 +3069,15 @@ PluginInsert::type () const return plugin()->get_info()->type; } -PluginInsert::PluginControl::PluginControl (PluginInsert* p, - const Evoral::Parameter& param, - const ParameterDescriptor& desc, - std::shared_ptr list) - : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param)) - , _plugin (p) -{ - if (alist()) { - if (desc.toggled) { - list->set_interpolation(Evoral::ControlList::Discrete); - } - } -} - -/** @param val `user' value */ - void -PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override) +PluginInsert::PIControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override) { - /* FIXME: probably should be taking out some lock here.. */ - - for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) { - (*i)->set_parameter (_list->parameter().id(), user_val, 0); - } - - std::shared_ptr iasp = _plugin->_impulseAnalysisPlugin.lock(); + std::shared_ptr iasp = dynamic_cast(_pib)->_impulseAnalysisPlugin.lock(); if (iasp) { iasp->set_parameter (_list->parameter().id(), user_val, 0); } - AutomationControl::actually_set_value (user_val, group_override); -} - -void -PluginInsert::PluginControl::catch_up_with_external_value (double user_val) -{ - AutomationControl::actually_set_value (user_val, Controllable::NoGroup); -} - -XMLNode& -PluginInsert::PluginControl::get_state () const -{ - XMLNode& node (AutomationControl::get_state()); - node.set_property (X_("parameter"), parameter().id()); - - std::shared_ptr lv2plugin = std::dynamic_pointer_cast (_plugin->_plugins[0]); - if (lv2plugin) { - node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id())); - } - - return node; -} - -/** @return `user' val */ -double -PluginInsert::PluginControl::get_value () const -{ - std::shared_ptr plugin = _plugin->plugin (0); - - if (!plugin) { - return 0.0; - } - - return plugin->get_parameter (_list->parameter().id()); -} - -std::string -PluginInsert::PluginControl::get_user_string () const -{ - std::shared_ptr plugin = _plugin->plugin (0); - if (plugin) { - std::string pp; - if (plugin->print_parameter (parameter().id(), pp) && pp.size () > 0) { - return pp; - } - } - return AutomationControl::get_user_string (); -} - -PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p, - const Evoral::Parameter& param, - const ParameterDescriptor& desc, - std::shared_ptr list) - : AutomationControl (p->session(), param, desc, list) - , _plugin (p) -{ -} - -void -PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd) -{ - /* Old numeric set_value(), coerce to appropriate datatype if possible. - This is lossy, but better than nothing until Ardour's automation system - can handle various datatypes all the way down. */ - const Variant value(_desc.datatype, user_val); - if (value.type() == Variant::NOTHING) { - error << "set_value(double) called for non-numeric property" << endmsg; - return; - } - - for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) { - (*i)->set_property(_list->parameter().id(), value); - } - - _value = value; - - AutomationControl::actually_set_value (user_val, gcd); -} - -XMLNode& -PluginInsert::PluginPropertyControl::get_state () const -{ - XMLNode& node (AutomationControl::get_state()); - node.set_property (X_("property"), parameter().id()); - node.remove_property (X_("value")); - - return node; -} - -double -PluginInsert::PluginPropertyControl::get_value () const -{ - return _value.to_double(); + PluginControl::actually_set_value (user_val, group_override); } std::shared_ptr