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 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
244 if (i->type() == PluginAutomation) {
246 Evoral::Parameter param(*i);
248 ParameterDescriptor desc;
249 _plugins.front()->get_parameter_descriptor(i->id(), desc);
251 can_automate (param);
252 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
253 add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
254 } else if (i->type() == PluginPropertyAutomation) {
255 Evoral::Parameter param(*i);
256 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
257 if (desc.datatype != Variant::NOTHING) {
258 boost::shared_ptr<AutomationList> list;
259 if (Variant::type_is_numeric(desc.datatype)) {
260 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
262 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
269 PluginInsert::parameter_changed (uint32_t which, float val)
271 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
276 Plugins::iterator i = _plugins.begin();
278 /* don't set the first plugin, just all the slaves */
280 if (i != _plugins.end()) {
282 for (; i != _plugins.end(); ++i) {
283 (*i)->set_parameter (which, val);
290 PluginInsert::set_block_size (pframes_t nframes)
293 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
294 if ((*i)->set_block_size (nframes) != 0) {
302 PluginInsert::activate ()
304 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
308 Processor::activate ();
312 PluginInsert::deactivate ()
314 Processor::deactivate ();
316 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
322 PluginInsert::flush ()
324 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
330 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
332 // Calculate if, and how many frames we need to collect for analysis
333 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
334 _signal_analysis_collected_nframes);
335 if (nframes < collect_signal_nframes) { // we might not get all frames now
336 collect_signal_nframes = nframes;
339 ChanCount const in_streams = input_streams ();
340 ChanCount const out_streams = output_streams ();
342 ChanMapping in_map (in_streams);
343 ChanMapping out_map (out_streams);
345 if (_match.method == Split) {
346 /* fix the input mapping so that we have maps for each of the plugin's inputs */
347 in_map = ChanMapping (natural_input_streams ());
349 /* copy the first stream's buffer contents to the others */
350 /* XXX: audio only */
351 uint32_t first_idx = in_map.get (DataType::AUDIO, 0, &valid);
353 for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
354 bufs.get_audio(in_map.get (DataType::AUDIO, i, &valid)).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
359 bufs.set_count(ChanCount::max(bufs.count(), in_streams));
360 bufs.set_count(ChanCount::max(bufs.count(), out_streams));
362 /* Note that we've already required that plugins
363 be able to handle in-place processing.
370 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
372 boost::shared_ptr<AutomationControl> c
373 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
375 if (c->list() && c->automation_playback()) {
378 const float val = c->list()->rt_safe_eval (now, valid);
388 if (collect_signal_nframes > 0) {
390 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
391 //std::cerr << " streams " << input_streams().n_audio() << std::endl;
392 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
394 _signal_analysis_inputs.set_count(input_streams());
396 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
397 _signal_analysis_inputs.get_audio(i).read_from(
399 collect_signal_nframes,
400 _signal_analysis_collected_nframes); // offset is for target buffer
405 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
406 (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
407 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
408 in_map.offset_to(*t, natural_input_streams().get(*t));
409 out_map.offset_to(*t, natural_output_streams().get(*t));
413 if (collect_signal_nframes > 0) {
415 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
416 //std::cerr << " streams " << output_streams().n_audio() << std::endl;
418 _signal_analysis_outputs.set_count(output_streams());
420 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
421 _signal_analysis_outputs.get_audio(i).read_from(
423 collect_signal_nframes,
424 _signal_analysis_collected_nframes); // offset is for target buffer
427 _signal_analysis_collected_nframes += collect_signal_nframes;
428 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
430 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
431 _signal_analysis_collect_nframes_max = 0;
432 _signal_analysis_collected_nframes = 0;
434 AnalysisDataGathered(&_signal_analysis_inputs,
435 &_signal_analysis_outputs);
438 /* leave remaining channel buffers alone */
442 PluginInsert::silence (framecnt_t nframes)
448 ChanMapping in_map(input_streams());
449 ChanMapping out_map(output_streams());
451 if (_match.method == Split) {
452 /* fix the input mapping so that we have maps for each of the plugin's inputs */
453 in_map = ChanMapping (natural_input_streams ());
456 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
457 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
462 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
464 if (_pending_active) {
465 /* run as normal if we are active or moving from inactive to active */
467 if (_session.transport_rolling() || _session.bounce_processing()) {
468 automation_run (bufs, start_frame, nframes);
470 connect_and_run (bufs, nframes, 0, false);
474 uint32_t in = input_streams ().n_audio ();
475 uint32_t out = output_streams().n_audio ();
477 if (has_no_audio_inputs() || in == 0) {
479 /* silence all (audio) outputs. Should really declick
480 * at the transitions of "active"
483 for (uint32_t n = 0; n < out; ++n) {
484 bufs.get_audio (n).silence (nframes);
487 } else if (out > in) {
489 /* not active, but something has make up for any channel count increase */
491 // TODO: option round-robin (n % in) or silence additional buffers ??
492 // for now , simply replicate last buffer
493 for (uint32_t n = in; n < out; ++n) {
494 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
498 bufs.count().set_audio (out);
501 _active = _pending_active;
503 /* we have no idea whether the plugin generated silence or not, so mark
504 * all buffers appropriately.
510 PluginInsert::set_parameter (Evoral::Parameter param, float val)
512 if (param.type() != PluginAutomation) {
516 /* the others will be set from the event triggered by this */
518 _plugins[0]->set_parameter (param.id(), val);
520 boost::shared_ptr<AutomationControl> ac
521 = boost::dynamic_pointer_cast<AutomationControl>(control(param));
526 warning << "set_parameter called for nonexistant parameter "
527 << EventTypeMap::instance().to_symbol(param) << endmsg;
530 _session.set_dirty();
534 PluginInsert::get_parameter (Evoral::Parameter param)
536 if (param.type() != PluginAutomation) {
539 assert (!_plugins.empty ());
540 return _plugins[0]->get_parameter (param.id());
545 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
547 Evoral::ControlEvent next_event (0, 0.0f);
548 framepos_t now = start;
549 framepos_t end = now + nframes;
550 framecnt_t offset = 0;
552 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
555 connect_and_run (bufs, nframes, offset, false);
559 if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
561 /* no events have a time within the relevant range */
563 connect_and_run (bufs, nframes, offset, true, now);
569 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
571 connect_and_run (bufs, cnt, offset, true, now);
577 if (!find_next_event (now, end, next_event)) {
582 /* cleanup anything that is left to do */
585 connect_and_run (bufs, nframes, offset, true, now);
590 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
592 if (param.type() != PluginAutomation)
595 if (_plugins.empty()) {
596 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
598 abort(); /*NOTREACHED*/
601 return _plugins[0]->default_value (param.id());
606 PluginInsert::can_reset_all_parameters ()
610 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
612 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
614 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
618 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
624 if (ac->automation_state() & Play) {
629 return all && (params > 0);
633 PluginInsert::reset_parameters_to_default ()
637 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
639 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
641 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
645 const float dflt = _plugins[0]->default_value (cid);
646 const float curr = _plugins[0]->get_parameter (cid);
652 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
657 if (ac->automation_state() & Play) {
662 ac->set_value (dflt);
667 boost::shared_ptr<Plugin>
668 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
670 boost::shared_ptr<LadspaPlugin> lp;
672 boost::shared_ptr<LV2Plugin> lv2p;
674 #ifdef WINDOWS_VST_SUPPORT
675 boost::shared_ptr<WindowsVSTPlugin> vp;
678 boost::shared_ptr<LXVSTPlugin> lxvp;
680 #ifdef AUDIOUNIT_SUPPORT
681 boost::shared_ptr<AUPlugin> ap;
684 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
685 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
687 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
688 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
690 #ifdef WINDOWS_VST_SUPPORT
691 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
692 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
695 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
696 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
698 #ifdef AUDIOUNIT_SUPPORT
699 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
700 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
704 fatal << string_compose (_("programming error: %1"),
705 X_("unknown plugin type in PluginInsert::plugin_factory"))
707 abort(); /*NOTREACHED*/
708 return boost::shared_ptr<Plugin> ((Plugin*) 0);
712 PluginInsert::configure_io (ChanCount in, ChanCount out)
714 Match old_match = _match;
715 ChanCount old_in = input_streams ();
716 ChanCount old_out = output_streams ();
718 /* set the matching method and number of plugins that we will use to meet this configuration */
719 _match = private_can_support_io_configuration (in, out);
720 if (set_count (_match.plugins) == false) {
724 if ( (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
729 PluginIoReConfigure (); /* EMIT SIGNAL */
732 /* configure plugins */
733 switch (_match.method) {
736 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
742 if (_plugins.front()->configure_io (in, out) == false) {
748 // we don't know the analysis window size, so we must work with the
749 // current buffer size here. each request for data fills in these
750 // buffers and the analyser makes sure it gets enough data for the
752 session().ensure_buffer_set (_signal_analysis_inputs, in);
753 //_signal_analysis_inputs.set_count (in);
755 session().ensure_buffer_set (_signal_analysis_outputs, out);
756 //_signal_analysis_outputs.set_count (out);
758 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
760 return Processor::configure_io (in, out);
763 /** Decide whether this PluginInsert can support a given IO configuration.
764 * To do this, we run through a set of possible solutions in rough order of
767 * @param in Required input channel count.
768 * @param out Filled in with the output channel count if we return true.
769 * @return true if the given IO configuration can be supported.
772 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
774 return private_can_support_io_configuration (in, out).method != Impossible;
777 /** A private version of can_support_io_configuration which returns the method
778 * by which the configuration can be matched, rather than just whether or not
782 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
784 if (_plugins.empty()) {
788 PluginInfoPtr info = _plugins.front()->get_info();
789 ChanCount in; in += inx;
792 if (info->reconfigurable_io()) {
793 /* Plugin has flexible I/O, so delegate to it */
794 bool const r = _plugins.front()->can_support_io_configuration (in, out);
796 return Match (Impossible, 0);
799 return Match (Delegate, 1);
802 ChanCount inputs = info->n_inputs;
803 ChanCount outputs = info->n_outputs;
805 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
806 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
807 midi_bypass.set(DataType::MIDI, 1);
809 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
810 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
811 in.set(DataType::MIDI, 0);
814 bool no_inputs = true;
815 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
816 if (inputs.get (*t) != 0) {
823 /* no inputs so we can take any input configuration since we throw it away */
824 out = outputs + midi_bypass;
825 return Match (NoInputs, 1);
828 /* Plugin inputs match requested inputs exactly */
830 out = outputs + midi_bypass;
831 return Match (ExactMatch, 1);
834 /* We may be able to run more than one copy of the plugin within this insert
835 to cope with the insert having more inputs than the plugin.
836 We allow replication only for plugins with either zero or 1 inputs and outputs
837 for every valid data type.
841 bool can_replicate = true;
842 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
844 uint32_t nin = inputs.get (*t);
846 // No inputs of this type
847 if (nin == 0 && in.get(*t) == 0) {
851 if (nin != 1 || outputs.get (*t) != 1) {
852 can_replicate = false;
856 // Potential factor not set yet
858 f = in.get(*t) / nin;
861 // Factor for this type does not match another type, can not replicate
862 if (f != (in.get(*t) / nin)) {
863 can_replicate = false;
869 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
870 out.set (*t, outputs.get(*t) * f);
873 return Match (Replicate, f);
876 /* If the processor has exactly one input of a given type, and
877 the plugin has more, we can feed the single processor input
878 to some or all of the plugin inputs. This is rather
879 special-case-y, but the 1-to-many case is by far the
880 simplest. How do I split thy 2 processor inputs to 3
881 plugin inputs? Let me count the ways ...
884 bool can_split = true;
885 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
887 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
888 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
890 if (!can_split_type && !nothing_to_do_for_type) {
896 out = outputs + midi_bypass;
897 return Match (Split, 1);
900 /* If the plugin has more inputs than we want, we can `hide' some of them
901 by feeding them silence.
904 bool could_hide = false;
905 bool cannot_hide = false;
906 ChanCount hide_channels;
908 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
909 if (inputs.get(*t) > in.get(*t)) {
910 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
911 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
913 } else if (inputs.get(*t) < in.get(*t)) {
914 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
919 if (could_hide && !cannot_hide) {
920 out = outputs + midi_bypass;
921 return Match (Hide, 1, hide_channels);
925 return Match (Impossible, 0);
929 PluginInsert::get_state ()
935 PluginInsert::state (bool full)
937 XMLNode& node = Processor::state (full);
939 node.add_property("type", _plugins[0]->state_node_name());
940 node.add_property("unique-id", _plugins[0]->unique_id());
941 node.add_property("count", string_compose("%1", _plugins.size()));
942 node.add_child_nocopy (_plugins[0]->get_state());
944 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
945 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
947 node.add_child_nocopy (ac->get_state());
955 PluginInsert::set_control_ids (const XMLNode& node, int version)
957 const XMLNodeList& nlist = node.children();
958 XMLNodeConstIterator iter;
959 set<Evoral::Parameter>::const_iterator p;
961 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
962 if ((*iter)->name() == Controllable::xml_node_name) {
963 const XMLProperty* prop;
965 if ((prop = (*iter)->property (X_("parameter"))) != 0) {
966 uint32_t p = atoi (prop->value());
968 /* this may create the new controllable */
970 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
972 #ifndef NO_PLUGIN_STATE
976 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
978 ac->set_state (**iter, version);
987 PluginInsert::set_state(const XMLNode& node, int version)
989 XMLNodeList nlist = node.children();
990 XMLNodeIterator niter;
991 XMLPropertyList plist;
992 const XMLProperty *prop;
993 ARDOUR::PluginType type;
995 if ((prop = node.property ("type")) == 0) {
996 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1000 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1001 type = ARDOUR::LADSPA;
1002 } else if (prop->value() == X_("lv2")) {
1004 } else if (prop->value() == X_("windows-vst")) {
1005 type = ARDOUR::Windows_VST;
1006 } else if (prop->value() == X_("lxvst")) {
1007 type = ARDOUR::LXVST;
1008 } else if (prop->value() == X_("audiounit")) {
1009 type = ARDOUR::AudioUnit;
1011 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1017 prop = node.property ("unique-id");
1020 #ifdef WINDOWS_VST_SUPPORT
1021 /* older sessions contain VST plugins with only an "id" field.
1024 if (type == ARDOUR::Windows_VST) {
1025 prop = node.property ("id");
1029 #ifdef LXVST_SUPPORT
1030 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1032 if (type == ARDOUR::LXVST) {
1033 prop = node.property ("id");
1039 error << _("Plugin has no unique ID field") << endmsg;
1044 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1046 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1047 * allow to move sessions windows <> linux */
1048 #ifdef LXVST_SUPPORT
1049 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1050 type = ARDOUR::LXVST;
1051 plugin = find_plugin (_session, prop->value(), type);
1055 #ifdef WINDOWS_VST_SUPPORT
1056 if (plugin == 0 && type == ARDOUR::LXVST) {
1057 type = ARDOUR::Windows_VST;
1058 plugin = find_plugin (_session, prop->value(), type);
1063 error << string_compose(
1064 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1065 "Perhaps it was removed or moved since it was last used."),
1071 // The name of the PluginInsert comes from the plugin, nothing else
1072 _name = plugin->get_info()->name;
1076 // Processor::set_state() will set this, but too late
1077 // for it to be available when setting up plugin
1078 // state. We can't call Processor::set_state() until
1079 // the plugins themselves are created and added.
1083 if (_plugins.empty()) {
1084 /* if we are adding the first plugin, we will need to set
1085 up automatable controls.
1087 add_plugin (plugin);
1088 create_automatable_parameters ();
1089 set_control_ids (node, version);
1092 if ((prop = node.property ("count")) != 0) {
1093 sscanf (prop->value().c_str(), "%u", &count);
1096 if (_plugins.size() != count) {
1097 for (uint32_t n = 1; n < count; ++n) {
1098 add_plugin (plugin_factory (plugin));
1102 Processor::set_state (node, version);
1104 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1106 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1107 and set all plugins to the same state.
1110 if ((*niter)->name() == plugin->state_node_name()) {
1112 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1113 (*i)->set_state (**niter, version);
1120 if (version < 3000) {
1122 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1123 this is all handled by Automatable
1126 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1127 if ((*niter)->name() == "Redirect") {
1128 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1129 Processor::set_state (**niter, version);
1134 set_parameter_state_2X (node, version);
1137 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1141 (*i)->deactivate ();
1149 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1151 XMLNodeList nlist = node.children();
1152 XMLNodeIterator niter;
1154 /* look for port automation node */
1156 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1158 if ((*niter)->name() != port_automation_node_name) {
1164 XMLNodeConstIterator iter;
1169 cnodes = (*niter)->children ("port");
1171 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1175 if ((cprop = child->property("number")) != 0) {
1176 port = cprop->value().c_str();
1178 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1182 sscanf (port, "%" PRIu32, &port_id);
1184 if (port_id >= _plugins[0]->parameter_count()) {
1185 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1189 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1190 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1192 if (c && c->alist()) {
1193 if (!child->children().empty()) {
1194 c->alist()->set_state (*child->children().front(), version);
1196 /* In some cases 2.X saves lists with min_yval and max_yval
1197 being FLT_MIN and FLT_MAX respectively. This causes problems
1198 in A3 because these min/max values are used to compute
1199 where GUI control points should be drawn. If we see such
1200 values, `correct' them to the min/max of the appropriate
1204 float min_y = c->alist()->get_min_y ();
1205 float max_y = c->alist()->get_max_y ();
1207 ParameterDescriptor desc;
1208 _plugins.front()->get_parameter_descriptor (port_id, desc);
1210 if (min_y == FLT_MIN) {
1214 if (max_y == FLT_MAX) {
1218 c->alist()->set_yrange (min_y, max_y);
1221 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1233 PluginInsert::describe_parameter (Evoral::Parameter param)
1235 if (param.type() == PluginAutomation) {
1236 return _plugins[0]->describe_parameter (param);
1237 } else if (param.type() == PluginPropertyAutomation) {
1238 boost::shared_ptr<AutomationControl> c(automation_control(param));
1239 if (c && !c->desc().label.empty()) {
1240 return c->desc().label;
1243 return Automatable::describe_parameter(param);
1247 PluginInsert::signal_latency() const
1249 if (_user_latency) {
1250 return _user_latency;
1253 return _plugins[0]->signal_latency ();
1257 PluginInsert::type ()
1259 return plugin()->get_info()->type;
1262 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1263 const Evoral::Parameter& param,
1264 const ParameterDescriptor& desc,
1265 boost::shared_ptr<AutomationList> list)
1266 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1270 alist()->reset_default (desc.normal);
1272 list->set_interpolation(Evoral::ControlList::Discrete);
1277 set_flags(Controllable::Toggle);
1281 /** @param val `user' value */
1283 PluginInsert::PluginControl::set_value (double user_val)
1285 /* FIXME: probably should be taking out some lock here.. */
1287 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1288 (*i)->set_parameter (_list->parameter().id(), user_val);
1291 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1293 iasp->set_parameter (_list->parameter().id(), user_val);
1296 AutomationControl::set_value (user_val);
1300 PluginInsert::PluginControl::get_state ()
1304 XMLNode& node (AutomationControl::get_state());
1305 ss << parameter().id();
1306 node.add_property (X_("parameter"), ss.str());
1311 /** @return `user' val */
1313 PluginInsert::PluginControl::get_value () const
1315 /* FIXME: probably should be taking out some lock here.. */
1316 return _plugin->get_parameter (_list->parameter());
1319 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1320 const Evoral::Parameter& param,
1321 const ParameterDescriptor& desc,
1322 boost::shared_ptr<AutomationList> list)
1323 : AutomationControl (p->session(), param, desc, list)
1327 alist()->set_yrange (desc.lower, desc.upper);
1328 alist()->reset_default (desc.normal);
1332 set_flags(Controllable::Toggle);
1337 PluginInsert::PluginPropertyControl::set_value (double user_val)
1339 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1340 This is lossy, but better than nothing until Ardour's automation system
1341 can handle various datatypes all the way down. */
1342 const Variant value(_desc.datatype, user_val);
1343 if (value.type() == Variant::NOTHING) {
1344 error << "set_value(double) called for non-numeric property" << endmsg;
1348 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1349 (*i)->set_property(_list->parameter().id(), value);
1353 AutomationControl::set_value(user_val);
1357 PluginInsert::PluginPropertyControl::get_state ()
1361 XMLNode& node (AutomationControl::get_state());
1362 ss << parameter().id();
1363 node.add_property (X_("property"), ss.str());
1364 node.remove_property (X_("value"));
1370 PluginInsert::PluginPropertyControl::get_value () const
1372 return _value.to_double();
1375 boost::shared_ptr<Plugin>
1376 PluginInsert::get_impulse_analysis_plugin()
1378 boost::shared_ptr<Plugin> ret;
1379 if (_impulseAnalysisPlugin.expired()) {
1380 ret = plugin_factory(_plugins[0]);
1381 _impulseAnalysisPlugin = ret;
1383 ret = _impulseAnalysisPlugin.lock();
1390 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1392 // called from outside the audio thread, so this should be safe
1393 // only do audio as analysis is (currently) only for audio plugins
1394 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1395 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1397 _signal_analysis_collected_nframes = 0;
1398 _signal_analysis_collect_nframes_max = nframes;
1401 /** Add a plugin to our list */
1403 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1405 plugin->set_insert_id (this->id());
1407 if (_plugins.empty()) {
1408 /* first (and probably only) plugin instance - connect to relevant signals
1411 plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
1412 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1413 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1416 _plugins.push_back (plugin);
1420 PluginInsert::realtime_handle_transport_stopped ()
1422 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1423 (*i)->realtime_handle_transport_stopped ();
1428 PluginInsert::realtime_locate ()
1430 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1431 (*i)->realtime_locate ();
1436 PluginInsert::monitoring_changed ()
1438 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1439 (*i)->monitoring_changed ();
1444 PluginInsert::start_touch (uint32_t param_id)
1446 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1448 ac->start_touch (session().audible_frame());
1453 PluginInsert::end_touch (uint32_t param_id)
1455 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1457 ac->stop_touch (true, session().audible_frame());