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/luaproc.h"
37 #include "ardour/plugin.h"
38 #include "ardour/plugin_insert.h"
41 #include "ardour/lv2_plugin.h"
44 #ifdef WINDOWS_VST_SUPPORT
45 #include "ardour/windows_vst_plugin.h"
49 #include "ardour/lxvst_plugin.h"
52 #ifdef AUDIOUNIT_SUPPORT
53 #include "ardour/audio_unit.h"
56 #include "ardour/session.h"
57 #include "ardour/types.h"
62 using namespace ARDOUR;
65 const string PluginInsert::port_automation_node_name = "PortAutomation";
67 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
68 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
69 , _signal_analysis_collected_nframes(0)
70 , _signal_analysis_collect_nframes_max(0)
75 , _pending_no_inplace (false)
77 /* the first is the master */
81 create_automatable_parameters ();
85 PluginInsert::~PluginInsert ()
90 PluginInsert::set_count (uint32_t num)
92 bool require_state = !_plugins.empty();
94 /* this is a bad idea.... we shouldn't do this while active.
95 only a route holding their redirect_lock should be calling this
100 } else if (num > _plugins.size()) {
101 uint32_t diff = num - _plugins.size();
103 for (uint32_t n = 0; n < diff; ++n) {
104 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
111 /* XXX do something */
115 } else if (num < _plugins.size()) {
116 uint32_t diff = _plugins.size() - num;
117 for (uint32_t n= 0; n < diff; ++n) {
127 PluginInsert::set_outputs (const ChanCount& c)
133 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
135 if (which.type() != PluginAutomation)
138 boost::shared_ptr<AutomationControl> c
139 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
142 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
147 PluginInsert::output_streams() const
149 assert (_configured);
150 return _configured_out;
154 PluginInsert::input_streams() const
156 assert (_configured);
157 return _configured_in;
161 PluginInsert::internal_output_streams() const
163 assert (!_plugins.empty());
165 PluginInfoPtr info = _plugins.front()->get_info();
167 if (info->reconfigurable_io()) {
168 ChanCount out = _plugins.front()->output_streams ();
169 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
172 ChanCount out = info->n_outputs;
173 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
174 out.set_audio (out.n_audio() * _plugins.size());
175 out.set_midi (out.n_midi() * _plugins.size());
181 PluginInsert::internal_input_streams() const
183 assert (!_plugins.empty());
187 PluginInfoPtr info = _plugins.front()->get_info();
189 if (info->reconfigurable_io()) {
190 assert (_plugins.size() == 1);
191 in = _plugins.front()->input_streams();
196 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
198 if (_match.method == Split) {
200 /* we are splitting 1 processor input to multiple plugin inputs,
201 so we have a maximum of 1 stream of each type.
203 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
204 if (in.get (*t) > 1) {
210 } else if (_match.method == Hide) {
212 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
213 in.set (*t, in.get (*t) - _match.hide.get (*t));
219 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
220 in.set (*t, in.get (*t) * _plugins.size ());
228 PluginInsert::natural_output_streams() const
230 return _plugins[0]->get_info()->n_outputs;
234 PluginInsert::natural_input_streams() const
236 return _plugins[0]->get_info()->n_inputs;
240 PluginInsert::has_no_inputs() const
242 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
246 PluginInsert::has_no_audio_inputs() const
248 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
252 PluginInsert::is_midi_instrument() const
254 /* XXX more finesse is possible here. VST plugins have a
255 a specific "instrument" flag, for example.
257 PluginInfoPtr pi = _plugins[0]->get_info();
259 return pi->n_inputs.n_midi() != 0 &&
260 pi->n_outputs.n_audio() > 0;
264 PluginInsert::create_automatable_parameters ()
266 assert (!_plugins.empty());
268 set<Evoral::Parameter> a = _plugins.front()->automatable ();
270 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
271 if (i->type() == PluginAutomation) {
273 Evoral::Parameter param(*i);
275 ParameterDescriptor desc;
276 _plugins.front()->get_parameter_descriptor(i->id(), desc);
278 can_automate (param);
279 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
280 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
282 _plugins.front()->set_automation_control (i->id(), c);
283 } else if (i->type() == PluginPropertyAutomation) {
284 Evoral::Parameter param(*i);
285 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
286 if (desc.datatype != Variant::NOTHING) {
287 boost::shared_ptr<AutomationList> list;
288 if (Variant::type_is_numeric(desc.datatype)) {
289 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
291 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
296 /** Called when something outside of this host has modified a plugin
297 * parameter. Responsible for propagating the change to two places:
299 * 1) anything listening to the Control itself
300 * 2) any replicated plugins that make up this PluginInsert.
302 * The PluginInsert is connected to the ParameterChangedExternally signal for
303 * the first (primary) plugin, and here broadcasts that change to any others.
305 * XXX We should probably drop this whole replication idea (Paul, October 2015)
306 * since it isn't used by sensible plugin APIs (AU, LV2).
309 PluginInsert::parameter_changed_externally (uint32_t which, float val)
311 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
313 /* First propagation: alter the underlying value of the control,
314 * without telling the plugin(s) that own/use it to set it.
321 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
324 pc->catch_up_with_external_value (val);
327 /* Second propagation: tell all plugins except the first to
328 update the value of this parameter. For sane plugin APIs,
329 there are no other plugins, so this is a no-op in those
333 Plugins::iterator i = _plugins.begin();
335 /* don't set the first plugin, just all the slaves */
337 if (i != _plugins.end()) {
339 for (; i != _plugins.end(); ++i) {
340 (*i)->set_parameter (which, val);
346 PluginInsert::set_block_size (pframes_t nframes)
349 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
350 if ((*i)->set_block_size (nframes) != 0) {
358 PluginInsert::activate ()
360 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
364 Processor::activate ();
368 PluginInsert::deactivate ()
370 Processor::deactivate ();
372 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
378 PluginInsert::flush ()
380 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
386 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
388 PinMappings in_map (_in_map);
389 PinMappings out_map (_out_map);
392 // auto-detect if inplace processing is possible
393 // TODO: do this once. during configure_io and every time the
394 // plugin-count or mapping changes.
395 bool inplace_ok = true;
396 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
397 if (!in_map[pc].is_monotonic ()) {
400 if (!out_map[pc].is_monotonic ()) {
405 if (_pending_no_inplace != !inplace_ok) {
406 #ifndef NDEBUG // this 'cerr' needs to go ASAP.
407 cerr << name () << " automatically set : " << (inplace_ok ? "Use Inplace" : "No Inplace") << "\n"; // XXX
409 _pending_no_inplace = !inplace_ok;
413 _no_inplace = _pending_no_inplace || _plugins.front()->inplace_broken ();
417 // TODO optimize special case.
418 // Currently this never triggers because the in_map for "Split" triggeres no_inplace.
419 if (_match.method == Split && !_no_inplace) {
420 assert (in_map.size () == 1);
421 in_map[0] = ChanMapping (max (natural_input_streams (), _configured_in));
422 ChanCount const in_streams = internal_input_streams ();
423 /* copy the first stream's audio buffer contents to the others */
425 uint32_t first_idx = in_map[0].get (DataType::AUDIO, 0, &valid);
427 for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
428 uint32_t idx = in_map[0].get (DataType::AUDIO, i, &valid);
430 bufs.get_audio(idx).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
437 bufs.set_count(ChanCount::max(bufs.count(), _configured_in));
438 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
444 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
446 boost::shared_ptr<AutomationControl> c
447 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
449 if (c->list() && c->automation_playback()) {
452 const float val = c->list()->rt_safe_eval (now, valid);
455 /* This is the ONLY place where we are
457 * AutomationControl::set_value_unchecked(). We
458 * know that the control is in
459 * automation playback mode, so no
460 * check on writable() is required
461 * (which must be done in AutomationControl::set_value()
464 c->set_value_unchecked(val);
471 /* Calculate if, and how many frames we need to collect for analysis */
472 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
473 _signal_analysis_collected_nframes);
474 if (nframes < collect_signal_nframes) { // we might not get all frames now
475 collect_signal_nframes = nframes;
478 if (collect_signal_nframes > 0) {
480 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
481 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
482 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
484 _signal_analysis_inputs.set_count(internal_input_streams());
486 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
487 _signal_analysis_inputs.get_audio(i).read_from(
489 collect_signal_nframes,
490 _signal_analysis_collected_nframes); // offset is for target buffer
496 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
497 ARDOUR::ChanMapping used_outputs;
500 // TODO optimize this flow. prepare during configure_io()
501 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
503 ARDOUR::ChanMapping i_in_map (natural_input_streams());
504 ARDOUR::ChanMapping i_out_map;
505 ARDOUR::ChanCount mapped;
506 ARDOUR::ChanCount backmap;
508 // map inputs sequentially
509 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
510 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
512 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
513 uint32_t m = mapped.get (*t);
515 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
517 inplace_bufs.get (*t, m).silence (nframes, offset);
519 mapped.set (*t, m + 1);
523 // TODO use map_offset_to() instead ??
527 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
528 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
529 uint32_t m = mapped.get (*t);
530 inplace_bufs.get (*t, m).silence (nframes, offset);
531 i_out_map.set (*t, out, m);
532 mapped.set (*t, m + 1);
536 if ((*i)->connect_and_run(inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
541 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
542 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
543 uint32_t m = backmap.get (*t);
545 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
547 bufs.get (*t, out_idx).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
548 used_outputs.set (*t, out_idx, 1); // mark as used
550 backmap.set (*t, m + 1);
554 /* all instances have completed, now clear outputs that have not been written to.
555 * (except midi bypass)
557 if (bufs.count().n_midi() == 1 && natural_output_streams().get(DataType::MIDI) == 0) {
558 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
560 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
561 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
563 used_outputs.get (*t, out, &valid);
564 if (valid) { continue; }
565 bufs.get (*t, out).silence (nframes, offset);
571 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
572 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
577 // TODO optimize: store "unconnected" in a fixed set.
578 // it only changes on reconfiguration.
579 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
580 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
582 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
583 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
585 uint32_t idx = out_map[pc].get (*t, o, &valid);
586 if (valid && idx == out) {
593 bufs.get (*t, out).silence (nframes, offset);
599 if (collect_signal_nframes > 0) {
601 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
602 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
604 _signal_analysis_outputs.set_count(internal_output_streams());
606 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
607 _signal_analysis_outputs.get_audio(i).read_from(
609 collect_signal_nframes,
610 _signal_analysis_collected_nframes); // offset is for target buffer
613 _signal_analysis_collected_nframes += collect_signal_nframes;
614 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
616 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
617 _signal_analysis_collect_nframes_max = 0;
618 _signal_analysis_collected_nframes = 0;
620 AnalysisDataGathered(&_signal_analysis_inputs,
621 &_signal_analysis_outputs);
627 PluginInsert::silence (framecnt_t nframes)
633 ChanMapping in_map (natural_input_streams ());
634 ChanMapping out_map (natural_output_streams ());
636 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
637 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
642 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
644 if (_pending_active) {
645 /* run as normal if we are active or moving from inactive to active */
647 if (_session.transport_rolling() || _session.bounce_processing()) {
648 automation_run (bufs, start_frame, nframes);
650 connect_and_run (bufs, nframes, 0, false);
654 // TODO use mapping in bypassed mode ?!
655 // -> do we bypass the processor or the plugin
657 uint32_t in = input_streams ().n_audio ();
658 uint32_t out = output_streams().n_audio ();
660 if (has_no_audio_inputs() || in == 0) {
662 /* silence all (audio) outputs. Should really declick
663 * at the transitions of "active"
666 for (uint32_t n = 0; n < out; ++n) {
667 bufs.get_audio (n).silence (nframes);
670 } else if (out > in) {
672 /* not active, but something has make up for any channel count increase
673 * for now , simply replicate last buffer
675 for (uint32_t n = in; n < out; ++n) {
676 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
680 bufs.count().set_audio (out);
683 _active = _pending_active;
685 /* we have no idea whether the plugin generated silence or not, so mark
686 * all buffers appropriately.
691 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
693 Evoral::ControlEvent next_event (0, 0.0f);
694 framepos_t now = start;
695 framepos_t end = now + nframes;
696 framecnt_t offset = 0;
698 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
701 connect_and_run (bufs, nframes, offset, false);
705 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
707 /* no events have a time within the relevant range */
709 connect_and_run (bufs, nframes, offset, true, now);
715 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
717 connect_and_run (bufs, cnt, offset, true, now);
723 if (!find_next_event (now, end, next_event)) {
728 /* cleanup anything that is left to do */
731 connect_and_run (bufs, nframes, offset, true, now);
736 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
738 if (param.type() != PluginAutomation)
741 if (_plugins.empty()) {
742 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
744 abort(); /*NOTREACHED*/
747 return _plugins[0]->default_value (param.id());
752 PluginInsert::can_reset_all_parameters ()
756 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
758 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
760 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
764 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
770 if (ac->automation_state() & Play) {
775 return all && (params > 0);
779 PluginInsert::reset_parameters_to_default ()
783 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
785 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
787 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
791 const float dflt = _plugins[0]->default_value (cid);
792 const float curr = _plugins[0]->get_parameter (cid);
798 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
803 if (ac->automation_state() & Play) {
808 ac->set_value (dflt, Controllable::NoGroup);
813 boost::shared_ptr<Plugin>
814 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
816 boost::shared_ptr<LadspaPlugin> lp;
817 boost::shared_ptr<LuaProc> lua;
819 boost::shared_ptr<LV2Plugin> lv2p;
821 #ifdef WINDOWS_VST_SUPPORT
822 boost::shared_ptr<WindowsVSTPlugin> vp;
825 boost::shared_ptr<LXVSTPlugin> lxvp;
827 #ifdef AUDIOUNIT_SUPPORT
828 boost::shared_ptr<AUPlugin> ap;
831 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
832 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
833 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
834 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
836 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
837 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
839 #ifdef WINDOWS_VST_SUPPORT
840 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
841 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
844 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
845 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
847 #ifdef AUDIOUNIT_SUPPORT
848 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
849 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
853 fatal << string_compose (_("programming error: %1"),
854 X_("unknown plugin type in PluginInsert::plugin_factory"))
856 abort(); /*NOTREACHED*/
857 return boost::shared_ptr<Plugin> ((Plugin*) 0);
861 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
862 if (num < _in_map.size()) {
863 bool changed = _in_map[num] != m;
866 PluginMapChanged (); /* EMIT SIGNAL */
872 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
873 if (num < _out_map.size()) {
874 bool changed = _out_map[num] != m;
877 PluginMapChanged (); /* EMIT SIGNAL */
883 PluginInsert::configure_io (ChanCount in, ChanCount out)
885 Match old_match = _match;
890 old_in = _configured_in;
891 old_out = _configured_out;
895 _configured_out = out;
897 /* get plugin configuration */
898 _match = private_can_support_io_configuration (in, out);
900 /* set the matching method and number of plugins that we will use to meet this configuration */
901 if (set_count (_match.plugins) == false) {
902 PluginIoReConfigure (); /* EMIT SIGNAL */
907 /* configure plugins */
908 switch (_match.method) {
911 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
912 PluginIoReConfigure (); /* EMIT SIGNAL */
921 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
923 assert (_match.strict_io || dout.n_audio() == out.n_audio()); // sans midi bypass
924 if (useins.n_audio() == 0) {
927 if (_plugins.front()->configure_io (useins, dout) == false) {
928 PluginIoReConfigure (); /* EMIT SIGNAL */
935 if (_plugins.front()->configure_io (in, out) == false) {
936 PluginIoReConfigure (); /* EMIT SIGNAL */
943 bool mapping_changed = false;
944 if (old_in == in && old_out == out && _configured
945 && old_match.method == _match.method
946 && _in_map.size() == _out_map.size()
947 && _in_map.size() == get_count ()
949 /* If the configuraton has not changed, keep the mapping */
950 } else if (_match.custom_cfg && _configured) {
951 /* strip dead wood */
952 for (uint32_t pc = 0; pc < get_count(); ++pc) {
955 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
956 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
958 uint32_t idx = _in_map[pc].get (*t, i, &valid);
959 if (valid && idx <= in.get (*t)) {
960 new_in.set (*t, i, idx);
963 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
965 uint32_t idx = _out_map[pc].get (*t, o, &valid);
966 if (valid && idx <= out.get (*t)) {
967 new_out.set (*t, o, idx);
971 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
972 mapping_changed = true;
974 _in_map[pc] = new_in;
975 _out_map[pc] = new_out;
978 /* generate a new mapping */
982 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
983 if (_match.method == Split) {
984 _in_map[pc] = ChanMapping ();
985 /* connect inputs in round-robin fashion */
986 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
987 const uint32_t cend = _configured_in.get (*t);
988 if (cend == 0) { continue; }
990 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
991 _in_map[pc].set (*t, in, c);
996 _in_map[pc] = ChanMapping (min (natural_input_streams (), in));
998 _out_map[pc] = ChanMapping (min (natural_output_streams(), out));
1000 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1001 _in_map[pc].offset_to(*t, pc * natural_input_streams().get(*t));
1002 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1004 mapping_changed = true;
1008 if (mapping_changed) {
1009 PluginMapChanged (); /* EMIT SIGNAL */
1012 cout << "----<<----\n";
1013 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1014 cout << "Channel Map for " << name() << " plugin " << pc << "\n";
1015 cout << " * Inputs:\n" << _in_map[pc];
1016 cout << " * Outputs:\n" << _out_map[pc];
1018 cout << "---->>----\n";
1022 if (old_in != in || old_out != out
1023 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1025 PluginIoReConfigure (); /* EMIT SIGNAL */
1028 // we don't know the analysis window size, so we must work with the
1029 // current buffer size here. each request for data fills in these
1030 // buffers and the analyser makes sure it gets enough data for the
1032 session().ensure_buffer_set (_signal_analysis_inputs, in);
1033 //_signal_analysis_inputs.set_count (in);
1035 session().ensure_buffer_set (_signal_analysis_outputs, out);
1036 //_signal_analysis_outputs.set_count (out);
1038 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1041 return Processor::configure_io (in, out);
1044 /** Decide whether this PluginInsert can support a given IO configuration.
1045 * To do this, we run through a set of possible solutions in rough order of
1048 * @param in Required input channel count.
1049 * @param out Filled in with the output channel count if we return true.
1050 * @return true if the given IO configuration can be supported.
1053 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1055 return private_can_support_io_configuration (in, out).method != Impossible;
1058 /** A private version of can_support_io_configuration which returns the method
1059 * by which the configuration can be matched, rather than just whether or not
1063 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1065 if (_plugins.empty()) {
1069 /* if a user specified a custom cfg, so be it. */
1072 return Match (ExactMatch, get_count(), false, true); // XXX
1075 /* try automatic configuration next */
1076 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1079 PluginInfoPtr info = _plugins.front()->get_info();
1080 ChanCount inputs = info->n_inputs;
1081 ChanCount outputs = info->n_outputs;
1082 ChanCount midi_bypass;
1084 /* handle case strict-i/o */
1085 if (_strict_io && m.method != Impossible) {
1088 /* special case MIDI instruments */
1089 if (is_midi_instrument()) {
1090 // output = midi-bypass + at most master-out channels.
1091 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1092 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1093 out = min (out, max_out);
1100 /* replicate processor to match output count (generators and such)
1101 * at least enough to feed every output port. */
1102 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1103 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1104 uint32_t nin = inputs.get (*t);
1105 if (nin == 0 || inx.get(*t) == 0) { continue; }
1106 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1109 return Match (Replicate, f);
1117 if (inx == out) { return m; }
1120 if (inx.get(DataType::MIDI) == 1
1121 && out.get (DataType::MIDI) == 0
1122 && outputs.get(DataType::MIDI) == 0) {
1123 out += ChanCount (DataType::MIDI, 1);
1128 if (m.method != Impossible) {
1132 if (info->reconfigurable_io()) {
1134 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1136 // houston, we have a problem.
1137 return Match (Impossible, 0);
1139 return Match (Delegate, 1);
1142 // add at least as many plugins so that output count matches input count
1144 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1145 uint32_t nin = inputs.get (*t);
1146 uint32_t nout = outputs.get (*t);
1147 if (nin == 0 || inx.get(*t) == 0) { continue; }
1148 // prefer floor() so the count won't overly increase IFF (nin < nout)
1149 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1151 if (f > 0 && outputs * f >= _configured_out) {
1153 return Match (Replicate, f);
1156 // add at least as many plugins needed to connect all inputs
1158 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1159 uint32_t nin = inputs.get (*t);
1160 if (nin == 0 || inx.get(*t) == 0) { continue; }
1161 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1164 return Match (Replicate, f);
1167 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1169 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1171 if (_plugins.empty()) {
1175 PluginInfoPtr info = _plugins.front()->get_info();
1176 ChanCount in; in += inx;
1177 ChanCount midi_bypass;
1179 if (info->reconfigurable_io()) {
1180 /* Plugin has flexible I/O, so delegate to it */
1181 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1183 return Match (Impossible, 0);
1185 return Match (Delegate, 1);
1188 ChanCount inputs = info->n_inputs;
1189 ChanCount outputs = info->n_outputs;
1191 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1192 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
1193 midi_bypass.set(DataType::MIDI, 1);
1195 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1196 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
1197 in.set(DataType::MIDI, 0);
1200 bool no_inputs = true;
1201 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1202 if (inputs.get (*t) != 0) {
1209 /* no inputs so we can take any input configuration since we throw it away */
1210 out = outputs + midi_bypass;
1211 return Match (NoInputs, 1);
1214 /* Plugin inputs match requested inputs exactly */
1216 out = outputs + midi_bypass;
1217 return Match (ExactMatch, 1);
1220 /* We may be able to run more than one copy of the plugin within this insert
1221 to cope with the insert having more inputs than the plugin.
1222 We allow replication only for plugins with either zero or 1 inputs and outputs
1223 for every valid data type.
1227 bool can_replicate = true;
1228 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1230 uint32_t nin = inputs.get (*t);
1232 // No inputs of this type
1233 if (nin == 0 && in.get(*t) == 0) {
1237 if (nin != 1 || outputs.get (*t) != 1) {
1238 can_replicate = false;
1242 // Potential factor not set yet
1244 f = in.get(*t) / nin;
1247 // Factor for this type does not match another type, can not replicate
1248 if (f != (in.get(*t) / nin)) {
1249 can_replicate = false;
1254 if (can_replicate) {
1255 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1256 out.set (*t, outputs.get(*t) * f);
1259 return Match (Replicate, f);
1262 /* If the processor has exactly one input of a given type, and
1263 the plugin has more, we can feed the single processor input
1264 to some or all of the plugin inputs. This is rather
1265 special-case-y, but the 1-to-many case is by far the
1266 simplest. How do I split thy 2 processor inputs to 3
1267 plugin inputs? Let me count the ways ...
1270 bool can_split = true;
1271 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1273 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
1274 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1276 if (!can_split_type && !nothing_to_do_for_type) {
1282 out = outputs + midi_bypass;
1283 return Match (Split, 1);
1286 /* If the plugin has more inputs than we want, we can `hide' some of them
1287 by feeding them silence.
1290 bool could_hide = false;
1291 bool cannot_hide = false;
1292 ChanCount hide_channels;
1294 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1295 if (inputs.get(*t) > in.get(*t)) {
1296 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1297 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1299 } else if (inputs.get(*t) < in.get(*t)) {
1300 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1305 if (could_hide && !cannot_hide) {
1306 out = outputs + midi_bypass;
1307 return Match (Hide, 1, false, false, hide_channels);
1310 midi_bypass.reset();
1311 return Match (Impossible, 0);
1316 PluginInsert::get_state ()
1318 return state (true);
1322 PluginInsert::state (bool full)
1324 XMLNode& node = Processor::state (full);
1326 node.add_property("type", _plugins[0]->state_node_name());
1327 node.add_property("unique-id", _plugins[0]->unique_id());
1328 node.add_property("count", string_compose("%1", _plugins.size()));
1330 /* remember actual i/o configuration (for later placeholder
1331 * in case the plugin goes missing) */
1332 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1333 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1335 /* save custom i/o config */
1336 node.add_property("custom", _custom_cfg ? "yes" : "no");
1338 assert (_custom_out == _configured_out); // redundant
1339 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1340 // TODO save _in_map[pc], _out_map[pc]
1344 _plugins[0]->set_insert_id(this->id());
1345 node.add_child_nocopy (_plugins[0]->get_state());
1347 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1348 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1350 node.add_child_nocopy (ac->get_state());
1358 PluginInsert::set_control_ids (const XMLNode& node, int version)
1360 const XMLNodeList& nlist = node.children();
1361 XMLNodeConstIterator iter;
1362 set<Evoral::Parameter>::const_iterator p;
1364 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1365 if ((*iter)->name() == Controllable::xml_node_name) {
1366 const XMLProperty* prop;
1368 uint32_t p = (uint32_t)-1;
1370 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1371 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1373 p = lv2plugin->port_index(prop->value().c_str());
1377 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1378 p = atoi (prop->value());
1381 if (p != (uint32_t)-1) {
1383 /* this may create the new controllable */
1385 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1387 #ifndef NO_PLUGIN_STATE
1391 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1393 ac->set_state (**iter, version);
1402 PluginInsert::set_state(const XMLNode& node, int version)
1404 XMLNodeList nlist = node.children();
1405 XMLNodeIterator niter;
1406 XMLPropertyList plist;
1407 const XMLProperty *prop;
1408 ARDOUR::PluginType type;
1410 if ((prop = node.property ("type")) == 0) {
1411 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1415 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1416 type = ARDOUR::LADSPA;
1417 } else if (prop->value() == X_("lv2")) {
1419 } else if (prop->value() == X_("windows-vst")) {
1420 type = ARDOUR::Windows_VST;
1421 } else if (prop->value() == X_("lxvst")) {
1422 type = ARDOUR::LXVST;
1423 } else if (prop->value() == X_("audiounit")) {
1424 type = ARDOUR::AudioUnit;
1425 } else if (prop->value() == X_("luaproc")) {
1428 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1434 prop = node.property ("unique-id");
1437 #ifdef WINDOWS_VST_SUPPORT
1438 /* older sessions contain VST plugins with only an "id" field.
1441 if (type == ARDOUR::Windows_VST) {
1442 prop = node.property ("id");
1446 #ifdef LXVST_SUPPORT
1447 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1449 if (type == ARDOUR::LXVST) {
1450 prop = node.property ("id");
1456 error << _("Plugin has no unique ID field") << endmsg;
1461 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1463 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1464 * allow to move sessions windows <> linux */
1465 #ifdef LXVST_SUPPORT
1466 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1467 type = ARDOUR::LXVST;
1468 plugin = find_plugin (_session, prop->value(), type);
1472 #ifdef WINDOWS_VST_SUPPORT
1473 if (plugin == 0 && type == ARDOUR::LXVST) {
1474 type = ARDOUR::Windows_VST;
1475 plugin = find_plugin (_session, prop->value(), type);
1480 error << string_compose(
1481 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1482 "Perhaps it was removed or moved since it was last used."),
1488 if (type == ARDOUR::Lua) {
1489 XMLNode *ls = node.child (plugin->state_node_name().c_str());
1490 // we need to load the script to set the name and parameters.
1491 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
1493 lp->set_script_from_state (*ls);
1497 // The name of the PluginInsert comes from the plugin, nothing else
1498 _name = plugin->get_info()->name;
1502 // Processor::set_state() will set this, but too late
1503 // for it to be available when setting up plugin
1504 // state. We can't call Processor::set_state() until
1505 // the plugins themselves are created and added.
1509 if (_plugins.empty()) {
1510 /* if we are adding the first plugin, we will need to set
1511 up automatable controls.
1513 add_plugin (plugin);
1514 create_automatable_parameters ();
1515 set_control_ids (node, version);
1518 if ((prop = node.property ("count")) != 0) {
1519 sscanf (prop->value().c_str(), "%u", &count);
1522 if (_plugins.size() != count) {
1523 for (uint32_t n = 1; n < count; ++n) {
1524 add_plugin (plugin_factory (plugin));
1528 Processor::set_state (node, version);
1530 PBD::ID new_id = this->id();
1531 PBD::ID old_id = this->id();
1533 if ((prop = node.property ("id")) != 0) {
1534 old_id = prop->value ();
1537 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1539 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1540 and set all plugins to the same state.
1543 if ((*niter)->name() == plugin->state_node_name()) {
1545 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1546 /* Plugin state can include external files which are named after the ID.
1548 * If regenerate_xml_or_string_ids() is set, the ID will already have
1549 * been changed, so we need to use the old ID from the XML to load the
1550 * state and then update the ID.
1552 * When copying a plugin-state, route_ui takes care of of updating the ID,
1553 * but we need to call set_insert_id() to clear the cached plugin-state
1554 * and force a change.
1556 if (!regenerate_xml_or_string_ids ()) {
1557 (*i)->set_insert_id (new_id);
1559 (*i)->set_insert_id (old_id);
1562 (*i)->set_state (**niter, version);
1564 if (regenerate_xml_or_string_ids ()) {
1565 (*i)->set_insert_id (new_id);
1573 if (version < 3000) {
1575 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1576 this is all handled by Automatable
1579 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1580 if ((*niter)->name() == "Redirect") {
1581 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1582 Processor::set_state (**niter, version);
1587 set_parameter_state_2X (node, version);
1590 if ((prop = node.property (X_("custom"))) != 0) {
1591 _custom_cfg = string_is_affirmative (prop->value());
1594 XMLNodeList kids = node.children ();
1595 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
1596 if ((*i)->name() == X_("ConfiguredOutput")) {
1597 _custom_out = ChanCount(**i);
1599 // TODO restore mappings for all 0 .. count.
1604 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1608 (*i)->deactivate ();
1616 PluginInsert::update_id (PBD::ID id)
1619 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1620 (*i)->set_insert_id (id);
1625 PluginInsert::set_state_dir (const std::string& d)
1627 // state() only saves the state of the first plugin
1628 _plugins[0]->set_state_dir (d);
1632 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1634 XMLNodeList nlist = node.children();
1635 XMLNodeIterator niter;
1637 /* look for port automation node */
1639 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1641 if ((*niter)->name() != port_automation_node_name) {
1647 XMLNodeConstIterator iter;
1652 cnodes = (*niter)->children ("port");
1654 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1658 if ((cprop = child->property("number")) != 0) {
1659 port = cprop->value().c_str();
1661 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1665 sscanf (port, "%" PRIu32, &port_id);
1667 if (port_id >= _plugins[0]->parameter_count()) {
1668 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1672 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1673 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1675 if (c && c->alist()) {
1676 if (!child->children().empty()) {
1677 c->alist()->set_state (*child->children().front(), version);
1679 /* In some cases 2.X saves lists with min_yval and max_yval
1680 being FLT_MIN and FLT_MAX respectively. This causes problems
1681 in A3 because these min/max values are used to compute
1682 where GUI control points should be drawn. If we see such
1683 values, `correct' them to the min/max of the appropriate
1687 float min_y = c->alist()->get_min_y ();
1688 float max_y = c->alist()->get_max_y ();
1690 ParameterDescriptor desc;
1691 _plugins.front()->get_parameter_descriptor (port_id, desc);
1693 if (min_y == FLT_MIN) {
1697 if (max_y == FLT_MAX) {
1701 c->alist()->set_yrange (min_y, max_y);
1704 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1716 PluginInsert::describe_parameter (Evoral::Parameter param)
1718 if (param.type() == PluginAutomation) {
1719 return _plugins[0]->describe_parameter (param);
1720 } else if (param.type() == PluginPropertyAutomation) {
1721 boost::shared_ptr<AutomationControl> c(automation_control(param));
1722 if (c && !c->desc().label.empty()) {
1723 return c->desc().label;
1726 return Automatable::describe_parameter(param);
1730 PluginInsert::signal_latency() const
1732 if (_user_latency) {
1733 return _user_latency;
1736 return _plugins[0]->signal_latency ();
1740 PluginInsert::type ()
1742 return plugin()->get_info()->type;
1745 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1746 const Evoral::Parameter& param,
1747 const ParameterDescriptor& desc,
1748 boost::shared_ptr<AutomationList> list)
1749 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1753 alist()->reset_default (desc.normal);
1755 list->set_interpolation(Evoral::ControlList::Discrete);
1760 set_flags(Controllable::Toggle);
1764 /** @param val `user' value */
1766 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1769 _set_value (user_val, group_override);
1773 PluginInsert::PluginControl::set_value_unchecked (double user_val)
1775 /* used only by automation playback */
1776 _set_value (user_val, Controllable::NoGroup);
1780 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1782 /* FIXME: probably should be taking out some lock here.. */
1784 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1785 (*i)->set_parameter (_list->parameter().id(), user_val);
1788 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1790 iasp->set_parameter (_list->parameter().id(), user_val);
1793 AutomationControl::set_value (user_val, group_override);
1797 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
1799 AutomationControl::set_value (user_val, Controllable::NoGroup);
1803 PluginInsert::PluginControl::get_state ()
1807 XMLNode& node (AutomationControl::get_state());
1808 ss << parameter().id();
1809 node.add_property (X_("parameter"), ss.str());
1811 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
1813 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
1820 /** @return `user' val */
1822 PluginInsert::PluginControl::get_value () const
1824 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
1830 return plugin->get_parameter (_list->parameter().id());
1833 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1834 const Evoral::Parameter& param,
1835 const ParameterDescriptor& desc,
1836 boost::shared_ptr<AutomationList> list)
1837 : AutomationControl (p->session(), param, desc, list)
1841 alist()->set_yrange (desc.lower, desc.upper);
1842 alist()->reset_default (desc.normal);
1846 set_flags(Controllable::Toggle);
1851 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
1854 set_value_unchecked (user_val);
1859 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
1861 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1862 This is lossy, but better than nothing until Ardour's automation system
1863 can handle various datatypes all the way down. */
1864 const Variant value(_desc.datatype, user_val);
1865 if (value.type() == Variant::NOTHING) {
1866 error << "set_value(double) called for non-numeric property" << endmsg;
1870 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1871 (*i)->set_property(_list->parameter().id(), value);
1875 AutomationControl::set_value (user_val, Controllable::NoGroup);
1879 PluginInsert::PluginPropertyControl::get_state ()
1883 XMLNode& node (AutomationControl::get_state());
1884 ss << parameter().id();
1885 node.add_property (X_("property"), ss.str());
1886 node.remove_property (X_("value"));
1892 PluginInsert::PluginPropertyControl::get_value () const
1894 return _value.to_double();
1897 boost::shared_ptr<Plugin>
1898 PluginInsert::get_impulse_analysis_plugin()
1900 boost::shared_ptr<Plugin> ret;
1901 if (_impulseAnalysisPlugin.expired()) {
1902 ret = plugin_factory(_plugins[0]);
1903 ret->configure_io (internal_input_streams (), internal_output_streams ());
1904 _impulseAnalysisPlugin = ret;
1906 ret = _impulseAnalysisPlugin.lock();
1913 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1915 // called from outside the audio thread, so this should be safe
1916 // only do audio as analysis is (currently) only for audio plugins
1917 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
1918 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
1920 _signal_analysis_collected_nframes = 0;
1921 _signal_analysis_collect_nframes_max = nframes;
1924 /** Add a plugin to our list */
1926 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1928 plugin->set_insert_id (this->id());
1930 if (_plugins.empty()) {
1931 /* first (and probably only) plugin instance - connect to relevant signals
1934 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
1935 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1936 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1939 _plugins.push_back (plugin);
1943 PluginInsert::realtime_handle_transport_stopped ()
1945 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1946 (*i)->realtime_handle_transport_stopped ();
1951 PluginInsert::realtime_locate ()
1953 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1954 (*i)->realtime_locate ();
1959 PluginInsert::monitoring_changed ()
1961 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1962 (*i)->monitoring_changed ();
1967 PluginInsert::start_touch (uint32_t param_id)
1969 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1971 ac->start_touch (session().audible_frame());
1976 PluginInsert::end_touch (uint32_t param_id)
1978 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1980 ac->stop_touch (true, session().audible_frame());