2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "libardour-config.h"
26 #include "pbd/failed_constructor.h"
27 #include "pbd/xml++.h"
28 #include "pbd/convert.h"
30 #include "ardour/audio_buffer.h"
31 #include "ardour/automation_list.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/debug.h"
34 #include "ardour/event_type_map.h"
35 #include "ardour/ladspa_plugin.h"
36 #include "ardour/plugin.h"
37 #include "ardour/plugin_insert.h"
38 #include "ardour/port.h"
39 #include "ardour/route.h"
42 #include "ardour/lv2_plugin.h"
45 #ifdef WINDOWS_VST_SUPPORT
46 #include "ardour/windows_vst_plugin.h"
50 #include "ardour/lxvst_plugin.h"
53 #ifdef AUDIOUNIT_SUPPORT
54 #include "ardour/audio_unit.h"
57 #include "ardour/audioengine.h"
58 #include "ardour/session.h"
59 #include "ardour/types.h"
64 using namespace ARDOUR;
67 const string PluginInsert::port_automation_node_name = "PortAutomation";
69 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
70 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
71 , _signal_analysis_collected_nframes(0)
72 , _signal_analysis_collect_nframes_max(0)
74 /* the first is the master */
78 create_automatable_parameters ();
83 PluginInsert::set_count (uint32_t num)
85 bool require_state = !_plugins.empty();
87 /* this is a bad idea.... we shouldn't do this while active.
88 only a route holding their redirect_lock should be calling this
93 } else if (num > _plugins.size()) {
94 uint32_t diff = num - _plugins.size();
96 for (uint32_t n = 0; n < diff; ++n) {
97 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
104 /* XXX do something */
108 } else if (num < _plugins.size()) {
109 uint32_t diff = _plugins.size() - num;
110 for (uint32_t n= 0; n < diff; ++n) {
118 PluginInsert::~PluginInsert ()
123 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
125 if (which.type() != PluginAutomation)
128 boost::shared_ptr<AutomationControl> c
129 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
132 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
137 PluginInsert::output_streams() const
139 assert (!_plugins.empty());
141 if (_plugins.front()->reconfigurable_io()) {
142 ChanCount out = _plugins.front()->output_streams ();
143 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
146 ChanCount out = _plugins.front()->get_info()->n_outputs;
147 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
148 out.set_audio (out.n_audio() * _plugins.size());
149 out.set_midi (out.n_midi() * _plugins.size());
155 PluginInsert::input_streams() const
157 assert (!_plugins.empty());
161 if (_plugins.front()->reconfigurable_io()) {
162 assert (_plugins.size() == 1);
163 in = _plugins.front()->input_streams();
165 in = _plugins[0]->get_info()->n_inputs;
168 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
170 if (_match.method == Split) {
172 /* we are splitting 1 processor input to multiple plugin inputs,
173 so we have a maximum of 1 stream of each type.
175 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
176 if (in.get (*t) > 1) {
182 } else if (_match.method == Hide) {
184 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
185 in.set (*t, in.get (*t) - _match.hide.get (*t));
191 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
192 in.set (*t, in.get (*t) * _plugins.size ());
200 PluginInsert::natural_output_streams() const
202 return _plugins[0]->get_info()->n_outputs;
206 PluginInsert::natural_input_streams() const
208 return _plugins[0]->get_info()->n_inputs;
212 PluginInsert::has_no_inputs() const
214 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
218 PluginInsert::has_no_audio_inputs() const
220 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
224 PluginInsert::is_midi_instrument() const
226 /* XXX more finesse is possible here. VST plugins have a
227 a specific "instrument" flag, for example.
229 PluginInfoPtr pi = _plugins[0]->get_info();
231 return pi->n_inputs.n_midi() != 0 &&
232 pi->n_outputs.n_audio() > 0;
236 PluginInsert::create_automatable_parameters ()
238 assert (!_plugins.empty());
240 set<Evoral::Parameter> a = _plugins.front()->automatable ();
242 Plugin::ParameterDescriptor desc;
244 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
245 if (i->type() == PluginAutomation) {
247 Evoral::Parameter param(*i);
249 _plugins.front()->get_parameter_descriptor(i->id(), desc);
251 /* the Parameter belonging to the actual plugin doesn't have its range set
252 but we want the Controllable related to this Parameter to have those limits.
255 param.set_range (desc.lower, desc.upper, _plugins.front()->default_value(i->id()), desc.toggled);
256 can_automate (param);
257 boost::shared_ptr<AutomationList> list(new AutomationList(param));
258 add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, list)));
264 PluginInsert::parameter_changed (Evoral::Parameter which, float val)
266 if (which.type() != PluginAutomation)
269 Plugins::iterator i = _plugins.begin();
271 /* don't set the first plugin, just all the slaves */
273 if (i != _plugins.end()) {
275 for (; i != _plugins.end(); ++i) {
276 (*i)->set_parameter (which, val);
282 PluginInsert::set_block_size (pframes_t nframes)
285 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
286 if ((*i)->set_block_size (nframes) != 0) {
294 PluginInsert::activate ()
296 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
300 Processor::activate ();
304 PluginInsert::deactivate ()
306 Processor::deactivate ();
308 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
314 PluginInsert::flush ()
316 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
322 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
324 // Calculate if, and how many frames we need to collect for analysis
325 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
326 _signal_analysis_collected_nframes);
327 if (nframes < collect_signal_nframes) { // we might not get all frames now
328 collect_signal_nframes = nframes;
331 ChanCount const in_streams = input_streams ();
332 ChanCount const out_streams = output_streams ();
334 ChanMapping in_map (in_streams);
335 ChanMapping out_map (out_streams);
337 if (_match.method == Split) {
338 /* fix the input mapping so that we have maps for each of the plugin's inputs */
339 in_map = ChanMapping (natural_input_streams ());
341 /* copy the first stream's buffer contents to the others */
342 /* XXX: audio only */
343 Sample const * mono = bufs.get_audio (in_map.get (DataType::AUDIO, 0, &valid)).data (offset);
344 for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
345 memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i, &valid)).data (offset), mono, sizeof (Sample) * nframes);
349 /* Note that we've already required that plugins
350 be able to handle in-place processing.
357 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
359 boost::shared_ptr<AutomationControl> c
360 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
362 if (c->parameter().type() == PluginAutomation && c->automation_playback()) {
365 const float val = c->list()->rt_safe_eval (now, valid);
375 if (collect_signal_nframes > 0) {
377 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
378 //std::cerr << " streams " << input_streams().n_audio() << std::endl;
379 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
381 _signal_analysis_inputs.set_count(input_streams());
383 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
384 _signal_analysis_inputs.get_audio(i).read_from(
386 collect_signal_nframes,
387 _signal_analysis_collected_nframes); // offset is for target buffer
392 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
393 (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
394 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
395 in_map.offset_to(*t, natural_input_streams().get(*t));
396 out_map.offset_to(*t, natural_output_streams().get(*t));
400 if (collect_signal_nframes > 0) {
402 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
403 //std::cerr << " streams " << output_streams().n_audio() << std::endl;
405 _signal_analysis_outputs.set_count(output_streams());
407 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
408 _signal_analysis_outputs.get_audio(i).read_from(
410 collect_signal_nframes,
411 _signal_analysis_collected_nframes); // offset is for target buffer
414 _signal_analysis_collected_nframes += collect_signal_nframes;
415 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
417 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
418 _signal_analysis_collect_nframes_max = 0;
419 _signal_analysis_collected_nframes = 0;
421 AnalysisDataGathered(&_signal_analysis_inputs,
422 &_signal_analysis_outputs);
425 /* leave remaining channel buffers alone */
429 PluginInsert::silence (framecnt_t nframes)
435 ChanMapping in_map(input_streams());
436 ChanMapping out_map(output_streams());
438 if (_match.method == Split) {
439 /* fix the input mapping so that we have maps for each of the plugin's inputs */
440 in_map = ChanMapping (natural_input_streams ());
443 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
444 (*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
449 PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
451 if (_pending_active) {
452 /* run as normal if we are active or moving from inactive to active */
454 if (_session.transport_rolling()) {
455 automation_run (bufs, nframes);
457 connect_and_run (bufs, nframes, 0, false);
462 if (has_no_audio_inputs()) {
464 /* silence all (audio) outputs. Should really declick
465 * at the transitions of "active"
468 uint32_t out = output_streams().n_audio ();
470 for (uint32_t n = 0; n < out; ++n) {
471 bufs.get_audio (n).silence (nframes);
474 bufs.count().set_audio (out);
478 /* does this need to be done with MIDI? it appears not */
480 uint32_t in = input_streams ().n_audio ();
481 uint32_t out = output_streams().n_audio ();
485 /* not active, but something has make up for any channel count increase */
487 for (uint32_t n = out - in; n < out; ++n) {
488 memcpy (bufs.get_audio (n).data(), bufs.get_audio(in - 1).data(), sizeof (Sample) * nframes);
492 bufs.count().set_audio (out);
496 _active = _pending_active;
498 /* we have no idea whether the plugin generated silence or not, so mark
499 * all buffers appropriately.
502 bufs.set_is_silent (false);
506 PluginInsert::set_parameter (Evoral::Parameter param, float val)
508 if (param.type() != PluginAutomation) {
512 /* the others will be set from the event triggered by this */
514 _plugins[0]->set_parameter (param.id(), val);
516 boost::shared_ptr<AutomationControl> ac
517 = boost::dynamic_pointer_cast<AutomationControl>(control(param));
522 warning << "set_parameter called for nonexistant parameter "
523 << EventTypeMap::instance().to_symbol(param) << endmsg;
526 _session.set_dirty();
530 PluginInsert::get_parameter (Evoral::Parameter param)
532 if (param.type() != PluginAutomation) {
535 assert (!_plugins.empty ());
536 return _plugins[0]->get_parameter (param.id());
541 PluginInsert::automation_run (BufferSet& bufs, pframes_t nframes)
543 Evoral::ControlEvent next_event (0, 0.0f);
544 framepos_t now = _session.transport_frame ();
545 framepos_t end = now + nframes;
546 framecnt_t offset = 0;
548 Glib::Mutex::Lock lm (control_lock(), Glib::TRY_LOCK);
551 connect_and_run (bufs, nframes, offset, false);
555 if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
557 /* no events have a time within the relevant range */
559 connect_and_run (bufs, nframes, offset, true, now);
565 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
567 connect_and_run (bufs, cnt, offset, true, now);
573 if (!find_next_event (now, end, next_event)) {
578 /* cleanup anything that is left to do */
581 connect_and_run (bufs, nframes, offset, true, now);
586 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
588 if (param.type() != PluginAutomation)
591 if (_plugins.empty()) {
592 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
597 return _plugins[0]->default_value (param.id());
600 boost::shared_ptr<Plugin>
601 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
603 boost::shared_ptr<LadspaPlugin> lp;
605 boost::shared_ptr<LV2Plugin> lv2p;
607 #ifdef WINDOWS_VST_SUPPORT
608 boost::shared_ptr<WindowsVSTPlugin> vp;
611 boost::shared_ptr<LXVSTPlugin> lxvp;
613 #ifdef AUDIOUNIT_SUPPORT
614 boost::shared_ptr<AUPlugin> ap;
617 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
618 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
620 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
621 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
623 #ifdef WINDOWS_VST_SUPPORT
624 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
625 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
628 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
629 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
631 #ifdef AUDIOUNIT_SUPPORT
632 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
633 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
637 fatal << string_compose (_("programming error: %1"),
638 X_("unknown plugin type in PluginInsert::plugin_factory"))
641 return boost::shared_ptr<Plugin> ((Plugin*) 0);
645 PluginInsert::configure_io (ChanCount in, ChanCount out)
647 Match old_match = _match;
649 /* set the matching method and number of plugins that we will use to meet this configuration */
650 _match = private_can_support_io_configuration (in, out);
651 if (set_count (_match.plugins) == false) {
655 /* a signal needs emitting if we start or stop splitting */
656 if (old_match.method != _match.method && (old_match.method == Split || _match.method == Split)) {
657 SplittingChanged (); /* EMIT SIGNAL */
660 /* configure plugins */
661 switch (_match.method) {
664 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
670 if (_plugins.front()->configure_io (in, out) == false) {
676 // we don't know the analysis window size, so we must work with the
677 // current buffer size here. each request for data fills in these
678 // buffers and the analyser makes sure it gets enough data for the
680 session().ensure_buffer_set (_signal_analysis_inputs, in);
681 //_signal_analysis_inputs.set_count (in);
683 session().ensure_buffer_set (_signal_analysis_outputs, out);
684 //_signal_analysis_outputs.set_count (out);
686 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
688 return Processor::configure_io (in, out);
691 /** Decide whether this PluginInsert can support a given IO configuration.
692 * To do this, we run through a set of possible solutions in rough order of
695 * @param in Required input channel count.
696 * @param out Filled in with the output channel count if we return true.
697 * @return true if the given IO configuration can be supported.
700 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
702 return private_can_support_io_configuration (in, out).method != Impossible;
705 /** A private version of can_support_io_configuration which returns the method
706 * by which the configuration can be matched, rather than just whether or not
710 PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCount& out) const
712 if (_plugins.front()->reconfigurable_io()) {
713 /* Plugin has flexible I/O, so delegate to it */
714 bool const r = _plugins.front()->can_support_io_configuration (in, out);
716 return Match (Impossible, 0);
719 return Match (Delegate, 1);
722 ChanCount inputs = _plugins[0]->get_info()->n_inputs;
723 ChanCount outputs = _plugins[0]->get_info()->n_outputs;
725 bool no_inputs = true;
726 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
727 if (inputs.get (*t) != 0) {
734 /* no inputs so we can take any input configuration since we throw it away */
736 return Match (NoInputs, 1);
739 /* Plugin inputs match requested inputs exactly */
742 return Match (ExactMatch, 1);
745 /* We may be able to run more than one copy of the plugin within this insert
746 to cope with the insert having more inputs than the plugin.
747 We allow replication only for plugins with either zero or 1 inputs and outputs
748 for every valid data type.
752 bool can_replicate = true;
753 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
755 uint32_t nin = inputs.get (*t);
757 // No inputs of this type
758 if (nin == 0 && in.get(*t) == 0) {
762 if (nin != 1 || outputs.get (*t) != 1) {
763 can_replicate = false;
767 // Potential factor not set yet
769 f = in.get(*t) / nin;
772 // Factor for this type does not match another type, can not replicate
773 if (f != (in.get(*t) / nin)) {
774 can_replicate = false;
780 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
781 out.set (*t, outputs.get(*t) * f);
783 return Match (Replicate, f);
786 /* If the processor has exactly one input of a given type, and
787 the plugin has more, we can feed the single processor input
788 to some or all of the plugin inputs. This is rather
789 special-case-y, but the 1-to-many case is by far the
790 simplest. How do I split thy 2 processor inputs to 3
791 plugin inputs? Let me count the ways ...
794 bool can_split = true;
795 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
797 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
798 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
800 if (!can_split_type && !nothing_to_do_for_type) {
807 return Match (Split, 1);
810 /* If the plugin has more inputs than we want, we can `hide' some of them
811 by feeding them silence.
814 bool could_hide = false;
815 bool cannot_hide = false;
816 ChanCount hide_channels;
818 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
819 if (inputs.get(*t) > in.get(*t)) {
820 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
821 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
823 } else if (inputs.get(*t) < in.get(*t)) {
824 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
829 if (could_hide && !cannot_hide) {
831 return Match (Hide, 1, hide_channels);
834 return Match (Impossible, 0);
838 PluginInsert::get_state ()
844 PluginInsert::state (bool full)
846 XMLNode& node = Processor::state (full);
848 node.add_property("type", _plugins[0]->state_node_name());
849 node.add_property("unique-id", _plugins[0]->unique_id());
850 node.add_property("count", string_compose("%1", _plugins.size()));
851 node.add_child_nocopy (_plugins[0]->get_state());
853 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
854 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
856 node.add_child_nocopy (ac->get_state());
864 PluginInsert::set_control_ids (const XMLNode& node, int version)
866 const XMLNodeList& nlist = node.children();
867 XMLNodeConstIterator iter;
868 set<Evoral::Parameter>::const_iterator p;
870 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
871 if ((*iter)->name() == Controllable::xml_node_name) {
872 const XMLProperty* prop;
874 if ((prop = (*iter)->property (X_("parameter"))) != 0) {
875 uint32_t p = atoi (prop->value());
876 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
880 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
882 ac->set_state (**iter, version);
890 PluginInsert::set_state(const XMLNode& node, int version)
892 XMLNodeList nlist = node.children();
893 XMLNodeIterator niter;
894 XMLPropertyList plist;
895 const XMLProperty *prop;
896 ARDOUR::PluginType type;
898 if ((prop = node.property ("type")) == 0) {
899 error << _("XML node describing plugin is missing the `type' field") << endmsg;
903 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
904 type = ARDOUR::LADSPA;
905 } else if (prop->value() == X_("lv2")) {
907 } else if (prop->value() == X_("windows-vst")) {
908 type = ARDOUR::Windows_VST;
909 } else if (prop->value() == X_("lxvst")) {
910 type = ARDOUR::LXVST;
911 } else if (prop->value() == X_("audiounit")) {
912 type = ARDOUR::AudioUnit;
914 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
920 prop = node.property ("unique-id");
923 #ifdef WINDOWS_VST_SUPPORT
924 /* older sessions contain VST plugins with only an "id" field.
927 if (type == ARDOUR::Windows_VST) {
928 prop = node.property ("id");
933 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
935 if (type == ARDOUR::LXVST) {
936 prop = node.property ("id");
942 error << _("Plugin has no unique ID field") << endmsg;
947 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
950 error << string_compose(
951 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
952 "Perhaps it was removed or moved since it was last used."),
958 // The name of the PluginInsert comes from the plugin, nothing else
959 _name = plugin->get_info()->name;
963 // Processor::set_state() will set this, but too late
964 // for it to be available when setting up plugin
965 // state. We can't call Processor::set_state() until
966 // the plugins themselves are created and added.
970 if (_plugins.empty()) {
971 /* if we are adding the first plugin, we will need to set
972 up automatable controls.
975 create_automatable_parameters ();
976 set_control_ids (node, version);
979 if ((prop = node.property ("count")) != 0) {
980 sscanf (prop->value().c_str(), "%u", &count);
983 if (_plugins.size() != count) {
984 for (uint32_t n = 1; n < count; ++n) {
985 add_plugin (plugin_factory (plugin));
989 Processor::set_state (node, version);
991 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
993 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
994 and set all plugins to the same state.
997 if ((*niter)->name() == plugin->state_node_name()) {
999 plugin->set_state (**niter, version);
1001 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1002 (*i)->set_state (**niter, version);
1009 if (version < 3000) {
1011 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1012 this is all handled by Automatable
1015 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1016 if ((*niter)->name() == "Redirect") {
1017 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1018 Processor::set_state (**niter, version);
1023 set_parameter_state_2X (node, version);
1026 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1030 (*i)->deactivate ();
1038 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1040 XMLNodeList nlist = node.children();
1041 XMLNodeIterator niter;
1043 /* look for port automation node */
1045 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1047 if ((*niter)->name() != port_automation_node_name) {
1053 XMLNodeConstIterator iter;
1058 cnodes = (*niter)->children ("port");
1060 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1064 if ((cprop = child->property("number")) != 0) {
1065 port = cprop->value().c_str();
1067 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1071 sscanf (port, "%" PRIu32, &port_id);
1073 if (port_id >= _plugins[0]->parameter_count()) {
1074 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1078 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1079 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1082 if (!child->children().empty()) {
1083 c->alist()->set_state (*child->children().front(), version);
1085 /* In some cases 2.X saves lists with min_yval and max_yval
1086 being FLT_MIN and FLT_MAX respectively. This causes problems
1087 in A3 because these min/max values are used to compute
1088 where GUI control points should be drawn. If we see such
1089 values, `correct' them to the min/max of the appropriate
1093 float min_y = c->alist()->get_min_y ();
1094 float max_y = c->alist()->get_max_y ();
1096 Plugin::ParameterDescriptor desc;
1097 _plugins.front()->get_parameter_descriptor (port_id, desc);
1099 if (min_y == FLT_MIN) {
1103 if (max_y == FLT_MAX) {
1107 c->alist()->set_yrange (min_y, max_y);
1110 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1122 PluginInsert::describe_parameter (Evoral::Parameter param)
1124 if (param.type() != PluginAutomation) {
1125 return Automatable::describe_parameter(param);
1128 return _plugins[0]->describe_parameter (param);
1132 PluginInsert::signal_latency() const
1134 if (_user_latency) {
1135 return _user_latency;
1138 return _plugins[0]->signal_latency ();
1142 PluginInsert::type ()
1144 return plugin()->get_info()->type;
1147 PluginInsert::PluginControl::PluginControl (PluginInsert* p, const Evoral::Parameter ¶m, boost::shared_ptr<AutomationList> list)
1148 : AutomationControl (p->session(), param, list, p->describe_parameter(param))
1151 Plugin::ParameterDescriptor desc;
1152 p->plugin(0)->get_parameter_descriptor (param.id(), desc);
1153 _logarithmic = desc.logarithmic;
1154 _sr_dependent = desc.sr_dependent;
1155 _toggled = desc.toggled;
1158 /** @param val `user' value */
1160 PluginInsert::PluginControl::set_value (double user_val)
1162 /* FIXME: probably should be taking out some lock here.. */
1164 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1165 (*i)->set_parameter (_list->parameter().id(), user_val);
1168 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1170 iasp->set_parameter (_list->parameter().id(), user_val);
1173 AutomationControl::set_value (user_val);
1177 PluginInsert::PluginControl::internal_to_interface (double val) const
1191 PluginInsert::PluginControl::interface_to_internal (double val) const
1201 PluginInsert::PluginControl::get_state ()
1205 XMLNode& node (AutomationControl::get_state());
1206 ss << parameter().id();
1207 node.add_property (X_("parameter"), ss.str());
1212 /** @return `user' val */
1214 PluginInsert::PluginControl::get_value () const
1216 /* FIXME: probably should be taking out some lock here.. */
1217 return _plugin->get_parameter (_list->parameter());
1220 boost::shared_ptr<Plugin>
1221 PluginInsert::get_impulse_analysis_plugin()
1223 boost::shared_ptr<Plugin> ret;
1224 if (_impulseAnalysisPlugin.expired()) {
1225 ret = plugin_factory(_plugins[0]);
1226 _impulseAnalysisPlugin = ret;
1228 ret = _impulseAnalysisPlugin.lock();
1235 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1237 // called from outside the audio thread, so this should be safe
1238 // only do audio as analysis is (currently) only for audio plugins
1239 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1240 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1242 _signal_analysis_collected_nframes = 0;
1243 _signal_analysis_collect_nframes_max = nframes;
1246 /** Add a plugin to our list */
1248 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1250 plugin->set_insert_info (this);
1251 _plugins.push_back (plugin);
1255 PluginInsert::realtime_handle_transport_stopped ()
1257 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1258 (*i)->realtime_handle_transport_stopped ();
1263 PluginInsert::realtime_locate ()
1265 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1266 (*i)->realtime_locate ();
1271 PluginInsert::monitoring_changed ()
1273 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1274 (*i)->monitoring_changed ();