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"
40 #include "ardour/lv2_plugin.h"
43 #ifdef WINDOWS_VST_SUPPORT
44 #include "ardour/windows_vst_plugin.h"
48 #include "ardour/lxvst_plugin.h"
51 #ifdef AUDIOUNIT_SUPPORT
52 #include "ardour/audio_unit.h"
55 #include "ardour/session.h"
56 #include "ardour/types.h"
61 using namespace ARDOUR;
64 const string PluginInsert::port_automation_node_name = "PortAutomation";
66 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
67 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
68 , _signal_analysis_collected_nframes(0)
69 , _signal_analysis_collect_nframes_max(0)
71 /* the first is the master */
75 create_automatable_parameters ();
80 PluginInsert::set_count (uint32_t num)
82 bool require_state = !_plugins.empty();
84 /* this is a bad idea.... we shouldn't do this while active.
85 only a route holding their redirect_lock should be calling this
90 } else if (num > _plugins.size()) {
91 uint32_t diff = num - _plugins.size();
93 for (uint32_t n = 0; n < diff; ++n) {
94 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
101 /* XXX do something */
105 } else if (num < _plugins.size()) {
106 uint32_t diff = _plugins.size() - num;
107 for (uint32_t n= 0; n < diff; ++n) {
115 PluginInsert::~PluginInsert ()
120 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
122 if (which.type() != PluginAutomation)
125 boost::shared_ptr<AutomationControl> c
126 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
129 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
134 PluginInsert::output_streams() const
136 assert (!_plugins.empty());
138 PluginInfoPtr info = _plugins.front()->get_info();
140 if (info->reconfigurable_io()) {
141 ChanCount out = _plugins.front()->output_streams ();
142 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
145 ChanCount out = info->n_outputs;
146 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
147 out.set_audio (out.n_audio() * _plugins.size());
148 out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
154 PluginInsert::input_streams() const
156 assert (!_plugins.empty());
160 PluginInfoPtr info = _plugins.front()->get_info();
162 if (info->reconfigurable_io()) {
163 assert (_plugins.size() == 1);
164 in = _plugins.front()->input_streams();
169 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
171 if (_match.method == Split) {
173 /* we are splitting 1 processor input to multiple plugin inputs,
174 so we have a maximum of 1 stream of each type.
176 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
177 if (in.get (*t) > 1) {
183 } else if (_match.method == Hide) {
185 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
186 in.set (*t, in.get (*t) - _match.hide.get (*t));
192 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
193 in.set (*t, in.get (*t) * _plugins.size ());
201 PluginInsert::natural_output_streams() const
203 return _plugins[0]->get_info()->n_outputs;
207 PluginInsert::natural_input_streams() const
209 return _plugins[0]->get_info()->n_inputs;
213 PluginInsert::has_no_inputs() const
215 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
219 PluginInsert::has_no_audio_inputs() const
221 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
225 PluginInsert::is_midi_instrument() const
227 /* XXX more finesse is possible here. VST plugins have a
228 a specific "instrument" flag, for example.
230 PluginInfoPtr pi = _plugins[0]->get_info();
232 return pi->n_inputs.n_midi() != 0 &&
233 pi->n_outputs.n_audio() > 0;
237 PluginInsert::create_automatable_parameters ()
239 assert (!_plugins.empty());
241 set<Evoral::Parameter> a = _plugins.front()->automatable ();
243 ParameterDescriptor desc;
245 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
246 if (i->type() == PluginAutomation) {
248 Evoral::Parameter param(*i);
250 _plugins.front()->get_parameter_descriptor(i->id(), desc);
252 /* the Parameter belonging to the actual plugin doesn't have its range set
253 but we want the Controllable related to this Parameter to have those limits.
256 param.set_range (desc.lower, desc.upper, _plugins.front()->default_value(i->id()), desc.toggled);
257 can_automate (param);
258 boost::shared_ptr<AutomationList> list(new AutomationList(param));
259 add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
260 } else if (i->type() == PluginPropertyAutomation) {
261 Evoral::Parameter param(*i);
262 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
263 if (desc.datatype != Variant::VOID) {
264 boost::shared_ptr<AutomationList> list;
265 if (Variant::type_is_numeric(desc.datatype)) {
266 list = boost::shared_ptr<AutomationList>(new AutomationList(param));
268 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
275 PluginInsert::parameter_changed (uint32_t which, float val)
277 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
282 Plugins::iterator i = _plugins.begin();
284 /* don't set the first plugin, just all the slaves */
286 if (i != _plugins.end()) {
288 for (; i != _plugins.end(); ++i) {
289 (*i)->set_parameter (which, val);
296 PluginInsert::set_block_size (pframes_t nframes)
299 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
300 if ((*i)->set_block_size (nframes) != 0) {
308 PluginInsert::activate ()
310 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
314 Processor::activate ();
318 PluginInsert::deactivate ()
320 Processor::deactivate ();
322 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
328 PluginInsert::flush ()
330 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
336 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
338 // Calculate if, and how many frames we need to collect for analysis
339 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
340 _signal_analysis_collected_nframes);
341 if (nframes < collect_signal_nframes) { // we might not get all frames now
342 collect_signal_nframes = nframes;
345 ChanCount const in_streams = input_streams ();
346 ChanCount const out_streams = output_streams ();
348 ChanMapping in_map (in_streams);
349 ChanMapping out_map (out_streams);
351 if (_match.method == Split) {
352 /* fix the input mapping so that we have maps for each of the plugin's inputs */
353 in_map = ChanMapping (natural_input_streams ());
355 /* copy the first stream's buffer contents to the others */
356 /* XXX: audio only */
357 uint32_t first_idx = in_map.get (DataType::AUDIO, 0, &valid);
359 for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
360 bufs.get_audio(in_map.get (DataType::AUDIO, i, &valid)).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
365 bufs.set_count(ChanCount::max(bufs.count(), in_streams));
366 bufs.set_count(ChanCount::max(bufs.count(), out_streams));
368 /* Note that we've already required that plugins
369 be able to handle in-place processing.
376 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
378 boost::shared_ptr<AutomationControl> c
379 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
381 if (c->list() && c->automation_playback()) {
384 const float val = c->list()->rt_safe_eval (now, valid);
394 if (collect_signal_nframes > 0) {
396 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
397 //std::cerr << " streams " << input_streams().n_audio() << std::endl;
398 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
400 _signal_analysis_inputs.set_count(input_streams());
402 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
403 _signal_analysis_inputs.get_audio(i).read_from(
405 collect_signal_nframes,
406 _signal_analysis_collected_nframes); // offset is for target buffer
411 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
412 (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
413 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
414 in_map.offset_to(*t, natural_input_streams().get(*t));
415 out_map.offset_to(*t, natural_output_streams().get(*t));
419 if (collect_signal_nframes > 0) {
421 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
422 //std::cerr << " streams " << output_streams().n_audio() << std::endl;
424 _signal_analysis_outputs.set_count(output_streams());
426 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
427 _signal_analysis_outputs.get_audio(i).read_from(
429 collect_signal_nframes,
430 _signal_analysis_collected_nframes); // offset is for target buffer
433 _signal_analysis_collected_nframes += collect_signal_nframes;
434 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
436 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
437 _signal_analysis_collect_nframes_max = 0;
438 _signal_analysis_collected_nframes = 0;
440 AnalysisDataGathered(&_signal_analysis_inputs,
441 &_signal_analysis_outputs);
444 /* leave remaining channel buffers alone */
448 PluginInsert::silence (framecnt_t nframes)
454 ChanMapping in_map(input_streams());
455 ChanMapping out_map(output_streams());
457 if (_match.method == Split) {
458 /* fix the input mapping so that we have maps for each of the plugin's inputs */
459 in_map = ChanMapping (natural_input_streams ());
462 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
463 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
468 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
470 if (_pending_active) {
471 /* run as normal if we are active or moving from inactive to active */
473 if (_session.transport_rolling() || _session.bounce_processing()) {
474 automation_run (bufs, start_frame, nframes);
476 connect_and_run (bufs, nframes, 0, false);
480 uint32_t in = input_streams ().n_audio ();
481 uint32_t out = output_streams().n_audio ();
483 if (has_no_audio_inputs() || in == 0) {
485 /* silence all (audio) outputs. Should really declick
486 * at the transitions of "active"
489 for (uint32_t n = 0; n < out; ++n) {
490 bufs.get_audio (n).silence (nframes);
493 } else if (out > in) {
495 /* not active, but something has make up for any channel count increase */
497 // TODO: option round-robin (n % in) or silence additional buffers ??
498 // for now , simply replicate last buffer
499 for (uint32_t n = in; n < out; ++n) {
500 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
504 bufs.count().set_audio (out);
507 _active = _pending_active;
509 /* we have no idea whether the plugin generated silence or not, so mark
510 * all buffers appropriately.
516 PluginInsert::set_parameter (Evoral::Parameter param, float val)
518 if (param.type() != PluginAutomation) {
522 /* the others will be set from the event triggered by this */
524 _plugins[0]->set_parameter (param.id(), val);
526 boost::shared_ptr<AutomationControl> ac
527 = boost::dynamic_pointer_cast<AutomationControl>(control(param));
532 warning << "set_parameter called for nonexistant parameter "
533 << EventTypeMap::instance().to_symbol(param) << endmsg;
536 _session.set_dirty();
540 PluginInsert::get_parameter (Evoral::Parameter param)
542 if (param.type() != PluginAutomation) {
545 assert (!_plugins.empty ());
546 return _plugins[0]->get_parameter (param.id());
551 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
553 Evoral::ControlEvent next_event (0, 0.0f);
554 framepos_t now = start;
555 framepos_t end = now + nframes;
556 framecnt_t offset = 0;
558 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
561 connect_and_run (bufs, nframes, offset, false);
565 if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
567 /* no events have a time within the relevant range */
569 connect_and_run (bufs, nframes, offset, true, now);
575 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
577 connect_and_run (bufs, cnt, offset, true, now);
583 if (!find_next_event (now, end, next_event)) {
588 /* cleanup anything that is left to do */
591 connect_and_run (bufs, nframes, offset, true, now);
596 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
598 if (param.type() != PluginAutomation)
601 if (_plugins.empty()) {
602 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
607 return _plugins[0]->default_value (param.id());
610 boost::shared_ptr<Plugin>
611 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
613 boost::shared_ptr<LadspaPlugin> lp;
615 boost::shared_ptr<LV2Plugin> lv2p;
617 #ifdef WINDOWS_VST_SUPPORT
618 boost::shared_ptr<WindowsVSTPlugin> vp;
621 boost::shared_ptr<LXVSTPlugin> lxvp;
623 #ifdef AUDIOUNIT_SUPPORT
624 boost::shared_ptr<AUPlugin> ap;
627 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
628 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
630 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
631 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
633 #ifdef WINDOWS_VST_SUPPORT
634 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
635 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
638 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
639 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
641 #ifdef AUDIOUNIT_SUPPORT
642 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
643 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
647 fatal << string_compose (_("programming error: %1"),
648 X_("unknown plugin type in PluginInsert::plugin_factory"))
651 return boost::shared_ptr<Plugin> ((Plugin*) 0);
655 PluginInsert::configure_io (ChanCount in, ChanCount out)
657 Match old_match = _match;
658 ChanCount old_in = input_streams ();
659 ChanCount old_out = output_streams ();
661 /* set the matching method and number of plugins that we will use to meet this configuration */
662 _match = private_can_support_io_configuration (in, out);
663 if (set_count (_match.plugins) == false) {
667 if ( (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
672 PluginIoReConfigure (); /* EMIT SIGNAL */
675 /* configure plugins */
676 switch (_match.method) {
679 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
685 if (_plugins.front()->configure_io (in, out) == false) {
691 // we don't know the analysis window size, so we must work with the
692 // current buffer size here. each request for data fills in these
693 // buffers and the analyser makes sure it gets enough data for the
695 session().ensure_buffer_set (_signal_analysis_inputs, in);
696 //_signal_analysis_inputs.set_count (in);
698 session().ensure_buffer_set (_signal_analysis_outputs, out);
699 //_signal_analysis_outputs.set_count (out);
701 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
703 return Processor::configure_io (in, out);
706 /** Decide whether this PluginInsert can support a given IO configuration.
707 * To do this, we run through a set of possible solutions in rough order of
710 * @param in Required input channel count.
711 * @param out Filled in with the output channel count if we return true.
712 * @return true if the given IO configuration can be supported.
715 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
717 return private_can_support_io_configuration (in, out).method != Impossible;
720 /** A private version of can_support_io_configuration which returns the method
721 * by which the configuration can be matched, rather than just whether or not
725 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
727 if (_plugins.empty()) {
731 PluginInfoPtr info = _plugins.front()->get_info();
732 ChanCount in; in += inx;
735 if (info->reconfigurable_io()) {
736 /* Plugin has flexible I/O, so delegate to it */
737 bool const r = _plugins.front()->can_support_io_configuration (in, out);
739 return Match (Impossible, 0);
742 return Match (Delegate, 1);
745 ChanCount inputs = info->n_inputs;
746 ChanCount outputs = info->n_outputs;
748 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
749 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
750 midi_bypass.set(DataType::MIDI, 1);
752 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
753 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
754 in.set(DataType::MIDI, 0);
757 bool no_inputs = true;
758 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
759 if (inputs.get (*t) != 0) {
766 /* no inputs so we can take any input configuration since we throw it away */
767 out = outputs + midi_bypass;
768 return Match (NoInputs, 1);
771 /* Plugin inputs match requested inputs exactly */
773 out = outputs + midi_bypass;
774 return Match (ExactMatch, 1);
777 /* We may be able to run more than one copy of the plugin within this insert
778 to cope with the insert having more inputs than the plugin.
779 We allow replication only for plugins with either zero or 1 inputs and outputs
780 for every valid data type.
784 bool can_replicate = true;
785 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
787 uint32_t nin = inputs.get (*t);
789 // No inputs of this type
790 if (nin == 0 && in.get(*t) == 0) {
794 if (nin != 1 || outputs.get (*t) != 1) {
795 can_replicate = false;
799 // Potential factor not set yet
801 f = in.get(*t) / nin;
804 // Factor for this type does not match another type, can not replicate
805 if (f != (in.get(*t) / nin)) {
806 can_replicate = false;
812 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
813 out.set (*t, outputs.get(*t) * f);
816 return Match (Replicate, f);
819 /* If the processor has exactly one input of a given type, and
820 the plugin has more, we can feed the single processor input
821 to some or all of the plugin inputs. This is rather
822 special-case-y, but the 1-to-many case is by far the
823 simplest. How do I split thy 2 processor inputs to 3
824 plugin inputs? Let me count the ways ...
827 bool can_split = true;
828 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
830 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
831 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
833 if (!can_split_type && !nothing_to_do_for_type) {
839 out = outputs + midi_bypass;
840 return Match (Split, 1);
843 /* If the plugin has more inputs than we want, we can `hide' some of them
844 by feeding them silence.
847 bool could_hide = false;
848 bool cannot_hide = false;
849 ChanCount hide_channels;
851 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
852 if (inputs.get(*t) > in.get(*t)) {
853 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
854 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
856 } else if (inputs.get(*t) < in.get(*t)) {
857 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
862 if (could_hide && !cannot_hide) {
863 out = outputs + midi_bypass;
864 return Match (Hide, 1, hide_channels);
868 return Match (Impossible, 0);
872 PluginInsert::get_state ()
878 PluginInsert::state (bool full)
880 XMLNode& node = Processor::state (full);
882 node.add_property("type", _plugins[0]->state_node_name());
883 node.add_property("unique-id", _plugins[0]->unique_id());
884 node.add_property("count", string_compose("%1", _plugins.size()));
885 node.add_child_nocopy (_plugins[0]->get_state());
887 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
888 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
890 node.add_child_nocopy (ac->get_state());
898 PluginInsert::set_control_ids (const XMLNode& node, int version)
900 const XMLNodeList& nlist = node.children();
901 XMLNodeConstIterator iter;
902 set<Evoral::Parameter>::const_iterator p;
904 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
905 if ((*iter)->name() == Controllable::xml_node_name) {
906 const XMLProperty* prop;
908 if ((prop = (*iter)->property (X_("parameter"))) != 0) {
909 uint32_t p = atoi (prop->value());
911 /* this may create the new controllable */
913 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
915 #ifndef NO_PLUGIN_STATE
919 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
921 ac->set_state (**iter, version);
930 PluginInsert::set_state(const XMLNode& node, int version)
932 XMLNodeList nlist = node.children();
933 XMLNodeIterator niter;
934 XMLPropertyList plist;
935 const XMLProperty *prop;
936 ARDOUR::PluginType type;
938 if ((prop = node.property ("type")) == 0) {
939 error << _("XML node describing plugin is missing the `type' field") << endmsg;
943 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
944 type = ARDOUR::LADSPA;
945 } else if (prop->value() == X_("lv2")) {
947 } else if (prop->value() == X_("windows-vst")) {
948 type = ARDOUR::Windows_VST;
949 } else if (prop->value() == X_("lxvst")) {
950 type = ARDOUR::LXVST;
951 } else if (prop->value() == X_("audiounit")) {
952 type = ARDOUR::AudioUnit;
954 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
960 prop = node.property ("unique-id");
963 #ifdef WINDOWS_VST_SUPPORT
964 /* older sessions contain VST plugins with only an "id" field.
967 if (type == ARDOUR::Windows_VST) {
968 prop = node.property ("id");
973 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
975 if (type == ARDOUR::LXVST) {
976 prop = node.property ("id");
982 error << _("Plugin has no unique ID field") << endmsg;
987 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
989 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
990 * allow to move sessions windows <> linux */
992 if (plugin == 0 && type == ARDOUR::Windows_VST) {
993 type = ARDOUR::LXVST;
994 plugin = find_plugin (_session, prop->value(), type);
998 #ifdef WINDOWS_VST_SUPPORT
999 if (plugin == 0 && type == ARDOUR::LXVST) {
1000 type = ARDOUR::Windows_VST;
1001 plugin = find_plugin (_session, prop->value(), type);
1006 error << string_compose(
1007 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1008 "Perhaps it was removed or moved since it was last used."),
1014 // The name of the PluginInsert comes from the plugin, nothing else
1015 _name = plugin->get_info()->name;
1019 // Processor::set_state() will set this, but too late
1020 // for it to be available when setting up plugin
1021 // state. We can't call Processor::set_state() until
1022 // the plugins themselves are created and added.
1026 if (_plugins.empty()) {
1027 /* if we are adding the first plugin, we will need to set
1028 up automatable controls.
1030 add_plugin (plugin);
1031 create_automatable_parameters ();
1032 set_control_ids (node, version);
1035 if ((prop = node.property ("count")) != 0) {
1036 sscanf (prop->value().c_str(), "%u", &count);
1039 if (_plugins.size() != count) {
1040 for (uint32_t n = 1; n < count; ++n) {
1041 add_plugin (plugin_factory (plugin));
1045 Processor::set_state (node, version);
1047 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1049 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1050 and set all plugins to the same state.
1053 if ((*niter)->name() == plugin->state_node_name()) {
1055 plugin->set_state (**niter, version);
1057 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1058 (*i)->set_state (**niter, version);
1065 if (version < 3000) {
1067 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1068 this is all handled by Automatable
1071 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1072 if ((*niter)->name() == "Redirect") {
1073 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1074 Processor::set_state (**niter, version);
1079 set_parameter_state_2X (node, version);
1082 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1086 (*i)->deactivate ();
1094 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1096 XMLNodeList nlist = node.children();
1097 XMLNodeIterator niter;
1099 /* look for port automation node */
1101 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1103 if ((*niter)->name() != port_automation_node_name) {
1109 XMLNodeConstIterator iter;
1114 cnodes = (*niter)->children ("port");
1116 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1120 if ((cprop = child->property("number")) != 0) {
1121 port = cprop->value().c_str();
1123 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1127 sscanf (port, "%" PRIu32, &port_id);
1129 if (port_id >= _plugins[0]->parameter_count()) {
1130 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1134 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1135 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1138 if (!child->children().empty()) {
1139 c->alist()->set_state (*child->children().front(), version);
1141 /* In some cases 2.X saves lists with min_yval and max_yval
1142 being FLT_MIN and FLT_MAX respectively. This causes problems
1143 in A3 because these min/max values are used to compute
1144 where GUI control points should be drawn. If we see such
1145 values, `correct' them to the min/max of the appropriate
1149 float min_y = c->alist()->get_min_y ();
1150 float max_y = c->alist()->get_max_y ();
1152 ParameterDescriptor desc;
1153 _plugins.front()->get_parameter_descriptor (port_id, desc);
1155 if (min_y == FLT_MIN) {
1159 if (max_y == FLT_MAX) {
1163 c->alist()->set_yrange (min_y, max_y);
1166 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1178 PluginInsert::describe_parameter (Evoral::Parameter param)
1180 if (param.type() == PluginAutomation) {
1181 return _plugins[0]->describe_parameter (param);
1182 } else if (param.type() == PluginPropertyAutomation) {
1183 boost::shared_ptr<AutomationControl> c(automation_control(param));
1184 if (c && !c->desc().label.empty()) {
1185 return c->desc().label;
1188 return Automatable::describe_parameter(param);
1192 PluginInsert::signal_latency() const
1194 if (_user_latency) {
1195 return _user_latency;
1198 return _plugins[0]->signal_latency ();
1202 PluginInsert::type ()
1204 return plugin()->get_info()->type;
1207 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1208 const Evoral::Parameter& param,
1209 const ParameterDescriptor& desc,
1210 boost::shared_ptr<AutomationList> list)
1211 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1215 alist()->reset_default (desc.normal);
1219 set_flags(Controllable::Toggle);
1223 /** @param val `user' value */
1225 PluginInsert::PluginControl::set_value (double user_val)
1227 /* FIXME: probably should be taking out some lock here.. */
1229 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1230 (*i)->set_parameter (_list->parameter().id(), user_val);
1233 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1235 iasp->set_parameter (_list->parameter().id(), user_val);
1238 AutomationControl::set_value (user_val);
1242 PluginInsert::PluginControl::internal_to_interface (double val) const
1244 val = Controllable::internal_to_interface(val);
1246 if (_desc.logarithmic) {
1248 val = pow (val, 1/1.5);
1258 PluginInsert::PluginControl::interface_to_internal (double val) const
1260 if (_desc.logarithmic) {
1264 val = pow (val, 1.5);
1268 val = Controllable::interface_to_internal(val);
1274 PluginInsert::PluginControl::get_state ()
1278 XMLNode& node (AutomationControl::get_state());
1279 ss << parameter().id();
1280 node.add_property (X_("parameter"), ss.str());
1285 /** @return `user' val */
1287 PluginInsert::PluginControl::get_value () const
1289 /* FIXME: probably should be taking out some lock here.. */
1290 return _plugin->get_parameter (_list->parameter());
1293 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1294 const Evoral::Parameter& param,
1295 const ParameterDescriptor& desc,
1296 boost::shared_ptr<AutomationList> list)
1297 : AutomationControl (p->session(), param, desc, list)
1301 alist()->set_yrange (desc.lower, desc.upper);
1302 alist()->reset_default (desc.normal);
1306 set_flags(Controllable::Toggle);
1311 PluginInsert::PluginPropertyControl::set_value (double user_val)
1313 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1314 This is lossy, but better than nothing until Ardour's automation system
1315 can handle various datatypes all the way down. */
1316 const Variant value(_desc.datatype, user_val);
1317 if (value.type() == Variant::VOID) {
1318 error << "set_value(double) called for non-numeric property" << endmsg;
1322 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1323 (*i)->set_property(_list->parameter().id(), value);
1327 AutomationControl::set_value(user_val);
1331 PluginInsert::PluginPropertyControl::get_state ()
1335 XMLNode& node (AutomationControl::get_state());
1336 ss << parameter().id();
1337 node.add_property (X_("property"), ss.str());
1338 node.remove_property (X_("value"));
1344 PluginInsert::PluginPropertyControl::get_value () const
1346 return _value.to_double();
1349 boost::shared_ptr<Plugin>
1350 PluginInsert::get_impulse_analysis_plugin()
1352 boost::shared_ptr<Plugin> ret;
1353 if (_impulseAnalysisPlugin.expired()) {
1354 ret = plugin_factory(_plugins[0]);
1355 _impulseAnalysisPlugin = ret;
1357 ret = _impulseAnalysisPlugin.lock();
1364 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1366 // called from outside the audio thread, so this should be safe
1367 // only do audio as analysis is (currently) only for audio plugins
1368 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1369 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1371 _signal_analysis_collected_nframes = 0;
1372 _signal_analysis_collect_nframes_max = nframes;
1375 /** Add a plugin to our list */
1377 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1379 plugin->set_insert_info (this);
1381 if (_plugins.empty()) {
1382 /* first (and probably only) plugin instance - connect to relevant signals
1385 plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
1386 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1387 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1390 _plugins.push_back (plugin);
1394 PluginInsert::realtime_handle_transport_stopped ()
1396 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1397 (*i)->realtime_handle_transport_stopped ();
1402 PluginInsert::realtime_locate ()
1404 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1405 (*i)->realtime_locate ();
1410 PluginInsert::monitoring_changed ()
1412 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1413 (*i)->monitoring_changed ();
1418 PluginInsert::start_touch (uint32_t param_id)
1420 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1422 ac->start_touch (session().audible_frame());
1427 PluginInsert::end_touch (uint32_t param_id)
1429 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1431 ac->stop_touch (true, session().audible_frame());