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 nonexistent 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 ();
719 _configured_out = out;
721 /* set the matching method and number of plugins that we will use to meet this configuration */
722 _match = private_can_support_io_configuration (in, out);
723 if (set_count (_match.plugins) == false) {
724 PluginIoReConfigure (); /* EMIT SIGNAL */
728 /* configure plugins */
729 switch (_match.method) {
732 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out) == false) {
733 PluginIoReConfigure (); /* EMIT SIGNAL */
739 if (_plugins.front()->configure_io (in, out) == false) {
740 PluginIoReConfigure (); /* EMIT SIGNAL */
746 if ( (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
751 PluginIoReConfigure (); /* EMIT SIGNAL */
754 // we don't know the analysis window size, so we must work with the
755 // current buffer size here. each request for data fills in these
756 // buffers and the analyser makes sure it gets enough data for the
758 session().ensure_buffer_set (_signal_analysis_inputs, in);
759 //_signal_analysis_inputs.set_count (in);
761 session().ensure_buffer_set (_signal_analysis_outputs, out);
762 //_signal_analysis_outputs.set_count (out);
764 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
766 return Processor::configure_io (in, out);
769 /** Decide whether this PluginInsert can support a given IO configuration.
770 * To do this, we run through a set of possible solutions in rough order of
773 * @param in Required input channel count.
774 * @param out Filled in with the output channel count if we return true.
775 * @return true if the given IO configuration can be supported.
778 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
780 return private_can_support_io_configuration (in, out).method != Impossible;
783 /** A private version of can_support_io_configuration which returns the method
784 * by which the configuration can be matched, rather than just whether or not
788 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
790 if (_plugins.empty()) {
794 PluginInfoPtr info = _plugins.front()->get_info();
795 ChanCount in; in += inx;
798 if (info->reconfigurable_io()) {
799 /* Plugin has flexible I/O, so delegate to it */
800 bool const r = _plugins.front()->can_support_io_configuration (in, out);
802 return Match (Impossible, 0);
805 return Match (Delegate, 1);
808 ChanCount inputs = info->n_inputs;
809 ChanCount outputs = info->n_outputs;
811 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
812 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
813 midi_bypass.set(DataType::MIDI, 1);
815 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
816 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
817 in.set(DataType::MIDI, 0);
820 bool no_inputs = true;
821 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
822 if (inputs.get (*t) != 0) {
829 /* no inputs so we can take any input configuration since we throw it away */
830 out = outputs + midi_bypass;
831 return Match (NoInputs, 1);
834 /* Plugin inputs match requested inputs exactly */
836 out = outputs + midi_bypass;
837 return Match (ExactMatch, 1);
840 /* We may be able to run more than one copy of the plugin within this insert
841 to cope with the insert having more inputs than the plugin.
842 We allow replication only for plugins with either zero or 1 inputs and outputs
843 for every valid data type.
847 bool can_replicate = true;
848 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
850 uint32_t nin = inputs.get (*t);
852 // No inputs of this type
853 if (nin == 0 && in.get(*t) == 0) {
857 if (nin != 1 || outputs.get (*t) != 1) {
858 can_replicate = false;
862 // Potential factor not set yet
864 f = in.get(*t) / nin;
867 // Factor for this type does not match another type, can not replicate
868 if (f != (in.get(*t) / nin)) {
869 can_replicate = false;
875 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
876 out.set (*t, outputs.get(*t) * f);
879 return Match (Replicate, f);
882 /* If the processor has exactly one input of a given type, and
883 the plugin has more, we can feed the single processor input
884 to some or all of the plugin inputs. This is rather
885 special-case-y, but the 1-to-many case is by far the
886 simplest. How do I split thy 2 processor inputs to 3
887 plugin inputs? Let me count the ways ...
890 bool can_split = true;
891 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
893 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
894 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
896 if (!can_split_type && !nothing_to_do_for_type) {
902 out = outputs + midi_bypass;
903 return Match (Split, 1);
906 /* If the plugin has more inputs than we want, we can `hide' some of them
907 by feeding them silence.
910 bool could_hide = false;
911 bool cannot_hide = false;
912 ChanCount hide_channels;
914 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
915 if (inputs.get(*t) > in.get(*t)) {
916 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
917 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
919 } else if (inputs.get(*t) < in.get(*t)) {
920 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
925 if (could_hide && !cannot_hide) {
926 out = outputs + midi_bypass;
927 return Match (Hide, 1, hide_channels);
931 return Match (Impossible, 0);
935 PluginInsert::get_state ()
941 PluginInsert::state (bool full)
943 XMLNode& node = Processor::state (full);
945 node.add_property("type", _plugins[0]->state_node_name());
946 node.add_property("unique-id", _plugins[0]->unique_id());
947 node.add_property("count", string_compose("%1", _plugins.size()));
949 /* remember actual i/o configuration (for later placeholder
950 * in case the plugin goes missing) */
951 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
952 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
954 node.add_child_nocopy (_plugins[0]->get_state());
956 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
957 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
959 node.add_child_nocopy (ac->get_state());
967 PluginInsert::set_control_ids (const XMLNode& node, int version)
969 const XMLNodeList& nlist = node.children();
970 XMLNodeConstIterator iter;
971 set<Evoral::Parameter>::const_iterator p;
973 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
974 if ((*iter)->name() == Controllable::xml_node_name) {
975 const XMLProperty* prop;
977 if ((prop = (*iter)->property (X_("parameter"))) != 0) {
978 uint32_t p = atoi (prop->value());
980 /* this may create the new controllable */
982 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
984 #ifndef NO_PLUGIN_STATE
988 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
990 ac->set_state (**iter, version);
999 PluginInsert::set_state(const XMLNode& node, int version)
1001 XMLNodeList nlist = node.children();
1002 XMLNodeIterator niter;
1003 XMLPropertyList plist;
1004 const XMLProperty *prop;
1005 ARDOUR::PluginType type;
1007 if ((prop = node.property ("type")) == 0) {
1008 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1012 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1013 type = ARDOUR::LADSPA;
1014 } else if (prop->value() == X_("lv2")) {
1016 } else if (prop->value() == X_("windows-vst")) {
1017 type = ARDOUR::Windows_VST;
1018 } else if (prop->value() == X_("lxvst")) {
1019 type = ARDOUR::LXVST;
1020 } else if (prop->value() == X_("audiounit")) {
1021 type = ARDOUR::AudioUnit;
1023 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1029 prop = node.property ("unique-id");
1032 #ifdef WINDOWS_VST_SUPPORT
1033 /* older sessions contain VST plugins with only an "id" field.
1036 if (type == ARDOUR::Windows_VST) {
1037 prop = node.property ("id");
1041 #ifdef LXVST_SUPPORT
1042 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1044 if (type == ARDOUR::LXVST) {
1045 prop = node.property ("id");
1051 error << _("Plugin has no unique ID field") << endmsg;
1056 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1058 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1059 * allow to move sessions windows <> linux */
1060 #ifdef LXVST_SUPPORT
1061 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1062 type = ARDOUR::LXVST;
1063 plugin = find_plugin (_session, prop->value(), type);
1067 #ifdef WINDOWS_VST_SUPPORT
1068 if (plugin == 0 && type == ARDOUR::LXVST) {
1069 type = ARDOUR::Windows_VST;
1070 plugin = find_plugin (_session, prop->value(), type);
1075 error << string_compose(
1076 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1077 "Perhaps it was removed or moved since it was last used."),
1083 // The name of the PluginInsert comes from the plugin, nothing else
1084 _name = plugin->get_info()->name;
1088 // Processor::set_state() will set this, but too late
1089 // for it to be available when setting up plugin
1090 // state. We can't call Processor::set_state() until
1091 // the plugins themselves are created and added.
1095 if (_plugins.empty()) {
1096 /* if we are adding the first plugin, we will need to set
1097 up automatable controls.
1099 add_plugin (plugin);
1100 create_automatable_parameters ();
1101 set_control_ids (node, version);
1104 if ((prop = node.property ("count")) != 0) {
1105 sscanf (prop->value().c_str(), "%u", &count);
1108 if (_plugins.size() != count) {
1109 for (uint32_t n = 1; n < count; ++n) {
1110 add_plugin (plugin_factory (plugin));
1114 Processor::set_state (node, version);
1116 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1118 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1119 and set all plugins to the same state.
1122 if ((*niter)->name() == plugin->state_node_name()) {
1124 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1125 (*i)->set_state (**niter, version);
1132 if (version < 3000) {
1134 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1135 this is all handled by Automatable
1138 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1139 if ((*niter)->name() == "Redirect") {
1140 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1141 Processor::set_state (**niter, version);
1146 set_parameter_state_2X (node, version);
1149 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1153 (*i)->deactivate ();
1161 PluginInsert::update_id (PBD::ID id)
1164 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1165 (*i)->set_insert_id (id);
1170 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1172 XMLNodeList nlist = node.children();
1173 XMLNodeIterator niter;
1175 /* look for port automation node */
1177 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1179 if ((*niter)->name() != port_automation_node_name) {
1185 XMLNodeConstIterator iter;
1190 cnodes = (*niter)->children ("port");
1192 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1196 if ((cprop = child->property("number")) != 0) {
1197 port = cprop->value().c_str();
1199 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1203 sscanf (port, "%" PRIu32, &port_id);
1205 if (port_id >= _plugins[0]->parameter_count()) {
1206 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1210 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1211 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1213 if (c && c->alist()) {
1214 if (!child->children().empty()) {
1215 c->alist()->set_state (*child->children().front(), version);
1217 /* In some cases 2.X saves lists with min_yval and max_yval
1218 being FLT_MIN and FLT_MAX respectively. This causes problems
1219 in A3 because these min/max values are used to compute
1220 where GUI control points should be drawn. If we see such
1221 values, `correct' them to the min/max of the appropriate
1225 float min_y = c->alist()->get_min_y ();
1226 float max_y = c->alist()->get_max_y ();
1228 ParameterDescriptor desc;
1229 _plugins.front()->get_parameter_descriptor (port_id, desc);
1231 if (min_y == FLT_MIN) {
1235 if (max_y == FLT_MAX) {
1239 c->alist()->set_yrange (min_y, max_y);
1242 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1254 PluginInsert::describe_parameter (Evoral::Parameter param)
1256 if (param.type() == PluginAutomation) {
1257 return _plugins[0]->describe_parameter (param);
1258 } else if (param.type() == PluginPropertyAutomation) {
1259 boost::shared_ptr<AutomationControl> c(automation_control(param));
1260 if (c && !c->desc().label.empty()) {
1261 return c->desc().label;
1264 return Automatable::describe_parameter(param);
1268 PluginInsert::signal_latency() const
1270 if (_user_latency) {
1271 return _user_latency;
1274 return _plugins[0]->signal_latency ();
1278 PluginInsert::type ()
1280 return plugin()->get_info()->type;
1283 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1284 const Evoral::Parameter& param,
1285 const ParameterDescriptor& desc,
1286 boost::shared_ptr<AutomationList> list)
1287 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1291 alist()->reset_default (desc.normal);
1293 list->set_interpolation(Evoral::ControlList::Discrete);
1298 set_flags(Controllable::Toggle);
1302 /** @param val `user' value */
1304 PluginInsert::PluginControl::set_value (double user_val)
1306 /* FIXME: probably should be taking out some lock here.. */
1308 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1309 (*i)->set_parameter (_list->parameter().id(), user_val);
1312 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1314 iasp->set_parameter (_list->parameter().id(), user_val);
1317 AutomationControl::set_value (user_val);
1321 PluginInsert::PluginControl::get_state ()
1325 XMLNode& node (AutomationControl::get_state());
1326 ss << parameter().id();
1327 node.add_property (X_("parameter"), ss.str());
1332 /** @return `user' val */
1334 PluginInsert::PluginControl::get_value () const
1336 /* FIXME: probably should be taking out some lock here.. */
1337 return _plugin->get_parameter (_list->parameter());
1340 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1341 const Evoral::Parameter& param,
1342 const ParameterDescriptor& desc,
1343 boost::shared_ptr<AutomationList> list)
1344 : AutomationControl (p->session(), param, desc, list)
1348 alist()->set_yrange (desc.lower, desc.upper);
1349 alist()->reset_default (desc.normal);
1353 set_flags(Controllable::Toggle);
1358 PluginInsert::PluginPropertyControl::set_value (double user_val)
1360 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1361 This is lossy, but better than nothing until Ardour's automation system
1362 can handle various datatypes all the way down. */
1363 const Variant value(_desc.datatype, user_val);
1364 if (value.type() == Variant::NOTHING) {
1365 error << "set_value(double) called for non-numeric property" << endmsg;
1369 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1370 (*i)->set_property(_list->parameter().id(), value);
1374 AutomationControl::set_value(user_val);
1378 PluginInsert::PluginPropertyControl::get_state ()
1382 XMLNode& node (AutomationControl::get_state());
1383 ss << parameter().id();
1384 node.add_property (X_("property"), ss.str());
1385 node.remove_property (X_("value"));
1391 PluginInsert::PluginPropertyControl::get_value () const
1393 return _value.to_double();
1396 boost::shared_ptr<Plugin>
1397 PluginInsert::get_impulse_analysis_plugin()
1399 boost::shared_ptr<Plugin> ret;
1400 if (_impulseAnalysisPlugin.expired()) {
1401 ret = plugin_factory(_plugins[0]);
1402 ret->configure_io (input_streams (), output_streams ());
1403 _impulseAnalysisPlugin = ret;
1405 ret = _impulseAnalysisPlugin.lock();
1412 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1414 // called from outside the audio thread, so this should be safe
1415 // only do audio as analysis is (currently) only for audio plugins
1416 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1417 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1419 _signal_analysis_collected_nframes = 0;
1420 _signal_analysis_collect_nframes_max = nframes;
1423 /** Add a plugin to our list */
1425 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1427 plugin->set_insert_id (this->id());
1429 if (_plugins.empty()) {
1430 /* first (and probably only) plugin instance - connect to relevant signals
1433 plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
1434 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1435 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1438 _plugins.push_back (plugin);
1442 PluginInsert::realtime_handle_transport_stopped ()
1444 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1445 (*i)->realtime_handle_transport_stopped ();
1450 PluginInsert::realtime_locate ()
1452 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1453 (*i)->realtime_locate ();
1458 PluginInsert::monitoring_changed ()
1460 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1461 (*i)->monitoring_changed ();
1466 PluginInsert::start_touch (uint32_t param_id)
1468 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1470 ac->start_touch (session().audible_frame());
1475 PluginInsert::end_touch (uint32_t param_id)
1477 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1479 ac->stop_touch (true, session().audible_frame());