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::update_id (PBD::ID id)
1152 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1153 (*i)->set_insert_id (id);
1158 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1160 XMLNodeList nlist = node.children();
1161 XMLNodeIterator niter;
1163 /* look for port automation node */
1165 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1167 if ((*niter)->name() != port_automation_node_name) {
1173 XMLNodeConstIterator iter;
1178 cnodes = (*niter)->children ("port");
1180 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1184 if ((cprop = child->property("number")) != 0) {
1185 port = cprop->value().c_str();
1187 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1191 sscanf (port, "%" PRIu32, &port_id);
1193 if (port_id >= _plugins[0]->parameter_count()) {
1194 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1198 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1199 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1201 if (c && c->alist()) {
1202 if (!child->children().empty()) {
1203 c->alist()->set_state (*child->children().front(), version);
1205 /* In some cases 2.X saves lists with min_yval and max_yval
1206 being FLT_MIN and FLT_MAX respectively. This causes problems
1207 in A3 because these min/max values are used to compute
1208 where GUI control points should be drawn. If we see such
1209 values, `correct' them to the min/max of the appropriate
1213 float min_y = c->alist()->get_min_y ();
1214 float max_y = c->alist()->get_max_y ();
1216 ParameterDescriptor desc;
1217 _plugins.front()->get_parameter_descriptor (port_id, desc);
1219 if (min_y == FLT_MIN) {
1223 if (max_y == FLT_MAX) {
1227 c->alist()->set_yrange (min_y, max_y);
1230 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1242 PluginInsert::describe_parameter (Evoral::Parameter param)
1244 if (param.type() == PluginAutomation) {
1245 return _plugins[0]->describe_parameter (param);
1246 } else if (param.type() == PluginPropertyAutomation) {
1247 boost::shared_ptr<AutomationControl> c(automation_control(param));
1248 if (c && !c->desc().label.empty()) {
1249 return c->desc().label;
1252 return Automatable::describe_parameter(param);
1256 PluginInsert::signal_latency() const
1258 if (_user_latency) {
1259 return _user_latency;
1262 return _plugins[0]->signal_latency ();
1266 PluginInsert::type ()
1268 return plugin()->get_info()->type;
1271 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1272 const Evoral::Parameter& param,
1273 const ParameterDescriptor& desc,
1274 boost::shared_ptr<AutomationList> list)
1275 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1279 alist()->reset_default (desc.normal);
1281 list->set_interpolation(Evoral::ControlList::Discrete);
1286 set_flags(Controllable::Toggle);
1290 /** @param val `user' value */
1292 PluginInsert::PluginControl::set_value (double user_val)
1294 /* FIXME: probably should be taking out some lock here.. */
1296 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1297 (*i)->set_parameter (_list->parameter().id(), user_val);
1300 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1302 iasp->set_parameter (_list->parameter().id(), user_val);
1305 AutomationControl::set_value (user_val);
1309 PluginInsert::PluginControl::get_state ()
1313 XMLNode& node (AutomationControl::get_state());
1314 ss << parameter().id();
1315 node.add_property (X_("parameter"), ss.str());
1320 /** @return `user' val */
1322 PluginInsert::PluginControl::get_value () const
1324 /* FIXME: probably should be taking out some lock here.. */
1325 return _plugin->get_parameter (_list->parameter());
1328 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1329 const Evoral::Parameter& param,
1330 const ParameterDescriptor& desc,
1331 boost::shared_ptr<AutomationList> list)
1332 : AutomationControl (p->session(), param, desc, list)
1336 alist()->set_yrange (desc.lower, desc.upper);
1337 alist()->reset_default (desc.normal);
1341 set_flags(Controllable::Toggle);
1346 PluginInsert::PluginPropertyControl::set_value (double user_val)
1348 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1349 This is lossy, but better than nothing until Ardour's automation system
1350 can handle various datatypes all the way down. */
1351 const Variant value(_desc.datatype, user_val);
1352 if (value.type() == Variant::NOTHING) {
1353 error << "set_value(double) called for non-numeric property" << endmsg;
1357 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1358 (*i)->set_property(_list->parameter().id(), value);
1362 AutomationControl::set_value(user_val);
1366 PluginInsert::PluginPropertyControl::get_state ()
1370 XMLNode& node (AutomationControl::get_state());
1371 ss << parameter().id();
1372 node.add_property (X_("property"), ss.str());
1373 node.remove_property (X_("value"));
1379 PluginInsert::PluginPropertyControl::get_value () const
1381 return _value.to_double();
1384 boost::shared_ptr<Plugin>
1385 PluginInsert::get_impulse_analysis_plugin()
1387 boost::shared_ptr<Plugin> ret;
1388 if (_impulseAnalysisPlugin.expired()) {
1389 ret = plugin_factory(_plugins[0]);
1390 _impulseAnalysisPlugin = ret;
1392 ret = _impulseAnalysisPlugin.lock();
1399 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1401 // called from outside the audio thread, so this should be safe
1402 // only do audio as analysis is (currently) only for audio plugins
1403 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1404 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1406 _signal_analysis_collected_nframes = 0;
1407 _signal_analysis_collect_nframes_max = nframes;
1410 /** Add a plugin to our list */
1412 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1414 plugin->set_insert_id (this->id());
1416 if (_plugins.empty()) {
1417 /* first (and probably only) plugin instance - connect to relevant signals
1420 plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
1421 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1422 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1425 _plugins.push_back (plugin);
1429 PluginInsert::realtime_handle_transport_stopped ()
1431 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1432 (*i)->realtime_handle_transport_stopped ();
1437 PluginInsert::realtime_locate ()
1439 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1440 (*i)->realtime_locate ();
1445 PluginInsert::monitoring_changed ()
1447 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1448 (*i)->monitoring_changed ();
1453 PluginInsert::start_touch (uint32_t param_id)
1455 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1457 ac->start_touch (session().audible_frame());
1462 PluginInsert::end_touch (uint32_t param_id)
1464 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1466 ac->stop_touch (true, session().audible_frame());