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 , _maps_from_state (false)
77 /* the first is the master */
81 create_automatable_parameters ();
82 const ChanCount& sc (sidechain_input_pins ());
83 if (sc.n_audio () > 0) {
84 add_sidechain (sc.n_audio ());
89 PluginInsert::~PluginInsert ()
94 PluginInsert::set_strict_io (bool b)
96 bool changed = _strict_io != b;
99 PluginConfigChanged (); /* EMIT SIGNAL */
104 PluginInsert::set_count (uint32_t num)
106 bool require_state = !_plugins.empty();
108 /* this is a bad idea.... we shouldn't do this while active.
109 only a route holding their redirect_lock should be calling this
114 } else if (num > _plugins.size()) {
115 uint32_t diff = num - _plugins.size();
117 for (uint32_t n = 0; n < diff; ++n) {
118 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
125 /* XXX do something */
128 PluginConfigChanged (); /* EMIT SIGNAL */
130 } else if (num < _plugins.size()) {
131 uint32_t diff = _plugins.size() - num;
132 for (uint32_t n= 0; n < diff; ++n) {
135 PluginConfigChanged (); /* EMIT SIGNAL */
143 PluginInsert::set_outputs (const ChanCount& c)
145 bool changed = (_custom_out != c) && _custom_cfg;
148 PluginConfigChanged (); /* EMIT SIGNAL */
153 PluginInsert::set_custom_cfg (bool b)
155 bool changed = _custom_cfg != b;
158 PluginConfigChanged (); /* EMIT SIGNAL */
163 PluginInsert::set_preset_out (const ChanCount& c)
165 bool changed = _preset_out != c;
167 if (changed && !_custom_cfg) {
168 PluginConfigChanged (); /* EMIT SIGNAL */
174 PluginInsert::add_sidechain (uint32_t n_audio)
176 // caller must hold process lock
180 std::ostringstream n;
182 n << "Sidechain " << Session::next_name_id ();
184 n << "TO BE RESET FROM XML";
186 SideChain *sc = new SideChain (_session, n.str ());
187 _sidechain = boost::shared_ptr<SideChain> (sc);
188 _sidechain->activate ();
189 for (uint32_t n = 0; n < n_audio; ++n) {
190 _sidechain->input()->add_port ("", owner()); // add a port, don't connect.
192 PluginConfigChanged (); /* EMIT SIGNAL */
197 PluginInsert::del_sidechain ()
203 PluginConfigChanged (); /* EMIT SIGNAL */
208 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
210 if (which.type() != PluginAutomation)
213 boost::shared_ptr<AutomationControl> c
214 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
217 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
222 PluginInsert::output_streams() const
224 assert (_configured);
225 return _configured_out;
229 PluginInsert::input_streams() const
231 assert (_configured);
232 return _configured_in;
236 PluginInsert::internal_streams() const
238 assert (_configured);
239 return _configured_internal;
243 PluginInsert::internal_output_streams() const
245 assert (!_plugins.empty());
247 PluginInfoPtr info = _plugins.front()->get_info();
249 if (info->reconfigurable_io()) {
250 ChanCount out = _plugins.front()->output_streams ();
251 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
254 ChanCount out = info->n_outputs;
255 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
256 out.set_audio (out.n_audio() * _plugins.size());
257 out.set_midi (out.n_midi() * _plugins.size());
263 PluginInsert::internal_input_streams() const
265 assert (!_plugins.empty());
269 PluginInfoPtr info = _plugins.front()->get_info();
271 if (info->reconfigurable_io()) {
272 in = _plugins.front()->input_streams();
277 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
279 if (_match.method == Split) {
281 /* we are splitting 1 processor input to multiple plugin inputs,
282 so we have a maximum of 1 stream of each type.
284 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
285 if (in.get (*t) > 1) {
291 } else if (_match.method == Hide) {
293 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
294 in.set (*t, in.get (*t) - _match.hide.get (*t));
300 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
301 in.set (*t, in.get (*t) * _plugins.size ());
309 PluginInsert::natural_output_streams() const
312 if (is_channelstrip ()) {
313 return _configured_out;
316 return _plugins[0]->get_info()->n_outputs;
320 PluginInsert::natural_input_streams() const
323 if (is_channelstrip ()) {
324 return _configured_in;
327 return _plugins[0]->get_info()->n_inputs;
331 PluginInsert::sidechain_input_pins() const
333 return _cached_sidechain_pins;
337 PluginInsert::has_no_inputs() const
339 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
343 PluginInsert::has_no_audio_inputs() const
345 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
349 PluginInsert::plugin_latency () const {
350 return _plugins.front()->signal_latency ();
354 PluginInsert::needs_midi_input() const
356 PluginInfoPtr pip = _plugins[0]->get_info();
357 if (pip->needs_midi_input ()) {
360 return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
364 PluginInsert::create_automatable_parameters ()
366 assert (!_plugins.empty());
368 set<Evoral::Parameter> a = _plugins.front()->automatable ();
370 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
371 if (i->type() == PluginAutomation) {
373 Evoral::Parameter param(*i);
375 ParameterDescriptor desc;
376 _plugins.front()->get_parameter_descriptor(i->id(), desc);
378 can_automate (param);
379 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
380 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
382 _plugins.front()->set_automation_control (i->id(), c);
383 } else if (i->type() == PluginPropertyAutomation) {
384 Evoral::Parameter param(*i);
385 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
386 if (desc.datatype != Variant::NOTHING) {
387 boost::shared_ptr<AutomationList> list;
388 if (Variant::type_is_numeric(desc.datatype)) {
389 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
391 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
396 /** Called when something outside of this host has modified a plugin
397 * parameter. Responsible for propagating the change to two places:
399 * 1) anything listening to the Control itself
400 * 2) any replicated plugins that make up this PluginInsert.
402 * The PluginInsert is connected to the ParameterChangedExternally signal for
403 * the first (primary) plugin, and here broadcasts that change to any others.
405 * XXX We should probably drop this whole replication idea (Paul, October 2015)
406 * since it isn't used by sensible plugin APIs (AU, LV2).
409 PluginInsert::parameter_changed_externally (uint32_t which, float val)
411 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
413 /* First propagation: alter the underlying value of the control,
414 * without telling the plugin(s) that own/use it to set it.
421 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
424 pc->catch_up_with_external_value (val);
427 /* Second propagation: tell all plugins except the first to
428 update the value of this parameter. For sane plugin APIs,
429 there are no other plugins, so this is a no-op in those
433 Plugins::iterator i = _plugins.begin();
435 /* don't set the first plugin, just all the slaves */
437 if (i != _plugins.end()) {
439 for (; i != _plugins.end(); ++i) {
440 (*i)->set_parameter (which, val);
446 PluginInsert::set_block_size (pframes_t nframes)
449 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
450 if ((*i)->set_block_size (nframes) != 0) {
458 PluginInsert::activate ()
460 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
464 Processor::activate ();
468 PluginInsert::deactivate ()
470 Processor::deactivate ();
472 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
478 PluginInsert::flush ()
480 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
486 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
488 // TODO: atomically copy maps & _no_inplace
489 PinMappings in_map (_in_map);
490 PinMappings out_map (_out_map);
491 ChanMapping thru_map (_thru_map);
492 if (_mapping_changed) { // ToDo use a counters, increment until match.
493 _no_inplace = check_inplace ();
494 _mapping_changed = false;
497 if (_latency_changed) {
498 /* delaylines are configured with the max possible latency (as reported by the plugin)
499 * so this won't allocate memory (unless the plugin lied about its max latency)
500 * It may still 'click' though, since the fixed delaylines are not de-clicked.
501 * Then again plugin-latency changes are not click-free to begin with.
503 * This is also worst case, there is currently no concept of per-stream latency.
505 * e.g. Two identical latent plugins:
506 * 1st plugin: process left (latent), bypass right.
507 * 2nd plugin: bypass left, process right (latent).
508 * -> currently this yields 2 times latency of the plugin,
510 _latency_changed = false;
511 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
514 if (_match.method == Split && !_no_inplace) {
515 // TODO: also use this optimization if one source-buffer
516 // feeds _all_ *connected* inputs.
517 // currently this is *first* buffer to all only --
518 // see PluginInsert::check_inplace
519 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
520 if (_configured_internal.get (*t) == 0) {
524 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
525 assert (valid && first_idx == 0); // check_inplace ensures this
526 /* copy the first stream's buffer contents to the others */
527 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
528 uint32_t idx = in_map[0].get (*t, i, &valid);
531 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
535 /* the copy operation produces a linear monotonic input map */
536 in_map[0] = ChanMapping (natural_input_streams ());
539 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
540 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
546 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
548 boost::shared_ptr<AutomationControl> c
549 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
551 if (c->list() && c->automation_playback()) {
554 const float val = c->list()->rt_safe_eval (now, valid);
557 /* This is the ONLY place where we are
559 * AutomationControl::set_value_unchecked(). We
560 * know that the control is in
561 * automation playback mode, so no
562 * check on writable() is required
563 * (which must be done in AutomationControl::set_value()
566 c->set_value_unchecked(val);
573 /* Calculate if, and how many frames we need to collect for analysis */
574 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
575 _signal_analysis_collected_nframes);
576 if (nframes < collect_signal_nframes) { // we might not get all frames now
577 collect_signal_nframes = nframes;
580 if (collect_signal_nframes > 0) {
582 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
583 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
584 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
586 _signal_analysis_inputs.set_count(internal_input_streams());
588 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
589 _signal_analysis_inputs.get_audio(i).read_from(
591 collect_signal_nframes,
592 _signal_analysis_collected_nframes); // offset is for target buffer
597 if (is_channelstrip ()) {
598 if (_configured_in.n_audio() > 0) {
599 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
600 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
602 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
604 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
605 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
611 // TODO optimize -- build maps once.
613 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
614 ARDOUR::ChanMapping used_outputs;
616 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
618 /* build used-output map */
619 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
620 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
621 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
623 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
625 used_outputs.set (*t, out_idx, 1); // mark as used
630 /* copy thru data to outputs before processing in-place */
631 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
632 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
634 uint32_t in_idx = thru_map.get (*t, out, &valid);
636 uint32_t m = out + natural_input_streams ().get (*t);
637 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
638 used_outputs.set (*t, out, 1); // mark as used
644 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
646 ARDOUR::ChanMapping i_in_map (natural_input_streams());
647 ARDOUR::ChanMapping i_out_map (out_map[pc]);
648 ARDOUR::ChanCount mapped;
650 /* map inputs sequentially */
651 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
652 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
654 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
655 uint32_t m = mapped.get (*t);
657 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
659 inplace_bufs.get (*t, m).silence (nframes, offset);
661 mapped.set (*t, m + 1);
665 /* outputs are mapped to inplace_bufs after the inputs */
666 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
667 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
670 if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
675 /* all instances have completed, now copy data that was written
676 * and zero unconnected buffers */
677 ARDOUR::ChanMapping nonzero_out (used_outputs);
678 if (has_midi_bypass ()) {
679 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
681 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
682 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
684 used_outputs.get (*t, out, &valid);
686 nonzero_out.get (*t, out, &valid);
688 bufs.get (*t, out).silence (nframes, offset);
691 uint32_t m = out + natural_input_streams ().get (*t);
692 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
697 /* in-place processing */
699 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
700 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
705 // TODO optimize: store "unconnected" in a fixed set.
706 // it only changes on reconfiguration.
707 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
708 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
710 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
711 mapped = true; // in-place Midi bypass
713 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
714 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
716 uint32_t idx = out_map[pc].get (*t, o, &valid);
717 if (valid && idx == out) {
724 bufs.get (*t, out).silence (nframes, offset);
730 if (collect_signal_nframes > 0) {
732 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
733 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
735 _signal_analysis_outputs.set_count(internal_output_streams());
737 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
738 _signal_analysis_outputs.get_audio(i).read_from(
740 collect_signal_nframes,
741 _signal_analysis_collected_nframes); // offset is for target buffer
744 _signal_analysis_collected_nframes += collect_signal_nframes;
745 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
747 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
748 _signal_analysis_collect_nframes_max = 0;
749 _signal_analysis_collected_nframes = 0;
751 AnalysisDataGathered(&_signal_analysis_inputs,
752 &_signal_analysis_outputs);
758 PluginInsert::silence (framecnt_t nframes)
764 ChanMapping in_map (natural_input_streams ());
765 ChanMapping out_map (natural_output_streams ());
767 // TODO run sidechain (delaylines)
768 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
769 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
774 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
776 if (_pending_active) {
777 /* run as normal if we are active or moving from inactive to active */
780 // collect sidechain input for complete cycle (!)
781 // TODO we need delaylines here for latency compensation
782 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
785 if (_session.transport_rolling() || _session.bounce_processing()) {
786 automation_run (bufs, start_frame, nframes);
788 connect_and_run (bufs, nframes, 0, false);
792 // TODO use mapping in bypassed mode ?!
793 // -> do we bypass the processor or the plugin
795 // TODO include sidechain??
797 uint32_t in = input_streams ().n_audio ();
798 uint32_t out = output_streams().n_audio ();
800 if (has_no_audio_inputs() || in == 0) {
802 /* silence all (audio) outputs. Should really declick
803 * at the transitions of "active"
806 for (uint32_t n = 0; n < out; ++n) {
807 bufs.get_audio (n).silence (nframes);
810 } else if (out > in) {
812 /* not active, but something has make up for any channel count increase
813 * for now , simply replicate last buffer
815 for (uint32_t n = in; n < out; ++n) {
816 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
820 bufs.count().set_audio (out);
823 _active = _pending_active;
825 /* we have no idea whether the plugin generated silence or not, so mark
826 * all buffers appropriately.
831 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
833 Evoral::ControlEvent next_event (0, 0.0f);
834 framepos_t now = start;
835 framepos_t end = now + nframes;
836 framecnt_t offset = 0;
838 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
841 connect_and_run (bufs, nframes, offset, false);
845 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
847 /* no events have a time within the relevant range */
849 connect_and_run (bufs, nframes, offset, true, now);
855 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
857 connect_and_run (bufs, cnt, offset, true, now);
863 if (!find_next_event (now, end, next_event)) {
868 /* cleanup anything that is left to do */
871 connect_and_run (bufs, nframes, offset, true, now);
876 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
878 if (param.type() != PluginAutomation)
881 if (_plugins.empty()) {
882 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
884 abort(); /*NOTREACHED*/
887 return _plugins[0]->default_value (param.id());
892 PluginInsert::can_reset_all_parameters ()
896 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
898 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
900 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
904 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
910 if (ac->automation_state() & Play) {
915 return all && (params > 0);
919 PluginInsert::reset_parameters_to_default ()
923 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
925 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
927 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
931 const float dflt = _plugins[0]->default_value (cid);
932 const float curr = _plugins[0]->get_parameter (cid);
938 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
943 if (ac->automation_state() & Play) {
948 ac->set_value (dflt, Controllable::NoGroup);
953 boost::shared_ptr<Plugin>
954 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
956 boost::shared_ptr<LadspaPlugin> lp;
957 boost::shared_ptr<LuaProc> lua;
959 boost::shared_ptr<LV2Plugin> lv2p;
961 #ifdef WINDOWS_VST_SUPPORT
962 boost::shared_ptr<WindowsVSTPlugin> vp;
965 boost::shared_ptr<LXVSTPlugin> lxvp;
967 #ifdef AUDIOUNIT_SUPPORT
968 boost::shared_ptr<AUPlugin> ap;
971 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
972 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
973 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
974 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
976 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
977 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
979 #ifdef WINDOWS_VST_SUPPORT
980 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
981 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
984 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
985 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
987 #ifdef AUDIOUNIT_SUPPORT
988 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
989 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
993 fatal << string_compose (_("programming error: %1"),
994 X_("unknown plugin type in PluginInsert::plugin_factory"))
996 abort(); /*NOTREACHED*/
997 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1001 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1002 if (num < _in_map.size()) {
1003 bool changed = _in_map[num] != m;
1005 changed |= sanitize_maps ();
1007 PluginMapChanged (); /* EMIT SIGNAL */
1008 _mapping_changed = true;
1009 _session.set_dirty();
1015 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1016 if (num < _out_map.size()) {
1017 bool changed = _out_map[num] != m;
1019 changed |= sanitize_maps ();
1021 PluginMapChanged (); /* EMIT SIGNAL */
1022 _mapping_changed = true;
1023 _session.set_dirty();
1029 PluginInsert::set_thru_map (ChanMapping m) {
1030 bool changed = _thru_map != m;
1032 changed |= sanitize_maps ();
1034 PluginMapChanged (); /* EMIT SIGNAL */
1035 _mapping_changed = true;
1036 _session.set_dirty();
1041 PluginInsert::input_map () const
1045 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1046 ChanMapping m (i->second);
1047 const ChanMapping::Mappings& mp ((*i).second.mappings());
1048 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1049 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1050 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1058 PluginInsert::output_map () const
1062 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1063 ChanMapping m (i->second);
1064 const ChanMapping::Mappings& mp ((*i).second.mappings());
1065 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1066 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1067 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1071 if (has_midi_bypass ()) {
1072 rv.set (DataType::MIDI, 0, 0);
1079 PluginInsert::has_midi_bypass () const
1081 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1082 && natural_output_streams ().n_midi () == 0) {
1089 PluginInsert::has_midi_thru () const
1091 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1092 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1100 PluginInsert::is_channelstrip () const {
1101 return _plugins.front()->is_channelstrip();
1106 PluginInsert::check_inplace ()
1108 bool inplace_ok = !_plugins.front()->inplace_broken ();
1110 if (_thru_map.n_total () > 0) {
1111 // TODO once midi-bypass is part of the mapping, ignore it
1115 if (_match.method == Split && inplace_ok) {
1116 assert (get_count() == 1);
1117 assert (_in_map.size () == 1);
1118 if (!_out_map[0].is_monotonic ()) {
1121 if (_configured_internal != _configured_in) {
1122 /* no sidechain -- TODO we could allow this with
1123 * some more logic in PluginInsert::connect_and_run().
1125 * PluginInsert::reset_map() already maps it.
1130 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1131 if (_configured_internal.get (*t) == 0) {
1135 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1136 if (!valid || first_idx != 0) {
1137 // so far only allow to copy the *first* stream's buffer to others
1140 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1141 uint32_t idx = _in_map[0].get (*t, i, &valid);
1142 if (valid && idx != first_idx) {
1151 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1156 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1157 if (!_in_map[pc].is_monotonic ()) {
1160 if (!_out_map[pc].is_monotonic ()) {
1164 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1165 return !inplace_ok; // no-inplace
1169 PluginInsert::sanitize_maps ()
1171 bool changed = false;
1172 /* strip dead wood */
1173 PinMappings new_ins;
1174 PinMappings new_outs;
1175 ChanMapping new_thru;
1177 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1179 ChanMapping new_out;
1180 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1181 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1183 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1184 if (valid && idx < _configured_internal.get (*t)) {
1185 new_in.set (*t, i, idx);
1188 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1190 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1191 if (valid && idx < _configured_out.get (*t)) {
1192 new_out.set (*t, o, idx);
1196 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1199 new_ins[pc] = new_in;
1200 new_outs[pc] = new_out;
1203 /* prevent dup output assignments */
1204 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1205 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1206 bool mapped = false;
1207 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1209 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1210 if (valid && mapped) {
1211 new_outs[pc].unset (*t, idx);
1219 /* remove excess thru */
1220 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1221 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1223 uint32_t idx = _thru_map.get (*t, o, &valid);
1224 if (valid && idx < _configured_internal.get (*t)) {
1225 new_thru.set (*t, o, idx);
1230 /* prevent out + thru, existing plugin outputs override thru */
1231 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1232 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1233 bool mapped = false;
1235 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1236 new_outs[pc].get_src (*t, o, &mapped);
1237 if (mapped) { break; }
1239 if (!mapped) { continue; }
1240 uint32_t idx = new_thru.get (*t, o, &valid);
1242 new_thru.unset (*t, idx);
1247 if (has_midi_bypass ()) {
1248 // TODO: include midi-bypass in the thru set,
1249 // remove dedicated handling.
1250 new_thru.unset (DataType::MIDI, 0);
1253 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1257 _out_map = new_outs;
1258 _thru_map = new_thru;
1264 PluginInsert::reset_map (bool emit)
1266 const PinMappings old_in (_in_map);
1267 const PinMappings old_out (_out_map);
1271 _thru_map = ChanMapping ();
1273 /* build input map */
1274 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1275 uint32_t sc = 0; // side-chain round-robin (all instances)
1277 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1278 const uint32_t nis = natural_input_streams ().get(*t);
1279 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1281 /* SC inputs are last in the plugin-insert.. */
1282 const uint32_t sc_start = _configured_in.get (*t);
1283 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1284 /* ...but may not be at the end of the plugin ports.
1285 * in case the side-chain is not the last port, shift connections back.
1286 * and connect to side-chain
1289 uint32_t ic = 0; // split inputs
1290 const uint32_t cend = _configured_in.get (*t);
1292 for (uint32_t in = 0; in < nis; ++in) {
1293 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1294 if (iod.is_sidechain) {
1295 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1296 if (sc_len > 0) {// side-chain may be hidden
1297 _in_map[pc].set (*t, in, sc_start + sc);
1298 sc = (sc + 1) % sc_len;
1302 if (_match.method == Split) {
1303 if (cend == 0) { continue; }
1304 if (_strict_io && ic + stride * pc >= cend) {
1307 /* connect *no* sidechain sinks in round-robin fashion */
1308 _in_map[pc].set (*t, in, ic + stride * pc);
1309 if (_strict_io && (ic + 1) == cend) {
1312 ic = (ic + 1) % cend;
1314 uint32_t s = in - shift;
1315 if (stride * pc + s < cend) {
1316 _in_map[pc].set (*t, in, s + stride * pc);
1324 /* build output map */
1326 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1327 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1328 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1329 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1334 if (old_in == _in_map && old_out == _out_map) {
1338 PluginMapChanged (); /* EMIT SIGNAL */
1339 _mapping_changed = true;
1340 _session.set_dirty();
1346 PluginInsert::configure_io (ChanCount in, ChanCount out)
1348 Match old_match = _match;
1350 ChanCount old_internal;
1354 old_in = _configured_in;
1355 old_internal = _configured_internal;
1356 old_out = _configured_out;
1359 _configured_in = in;
1360 _configured_internal = in;
1361 _configured_out = out;
1364 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1365 * (currently _sidechain->configure_io always succeeds
1366 * since Processor::configure_io() succeeds)
1368 if (!_sidechain->configure_io (in, out)) {
1369 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1372 _configured_internal += _sidechain->input()->n_ports();
1375 /* get plugin configuration */
1376 _match = private_can_support_io_configuration (in, out);
1378 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1380 DEBUG_STR_APPEND(a, string_compose ("Match '%1': ", name()));
1381 DEBUG_STR_APPEND(a, _match);
1382 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1386 /* set the matching method and number of plugins that we will use to meet this configuration */
1387 if (set_count (_match.plugins) == false) {
1388 PluginIoReConfigure (); /* EMIT SIGNAL */
1389 _configured = false;
1393 /* configure plugins */
1394 switch (_match.method) {
1397 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1398 PluginIoReConfigure (); /* EMIT SIGNAL */
1399 _configured = false;
1405 ChanCount dout (in); // hint
1408 } else if (_preset_out.n_audio () > 0) {
1409 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1410 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1411 dout.set (DataType::AUDIO, 2);
1413 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1415 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
1417 if (useins.n_audio() == 0) {
1420 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("Delegate configuration: %1 %2 %3\n", name(), useins, dout));
1422 if (_plugins.front()->configure_io (useins, dout) == false) {
1423 PluginIoReConfigure (); /* EMIT SIGNAL */
1424 _configured = false;
1430 if (_plugins.front()->configure_io (in, out) == false) {
1431 PluginIoReConfigure (); /* EMIT SIGNAL */
1432 _configured = false;
1438 bool mapping_changed = false;
1439 if (old_in == in && old_out == out
1441 && old_match.method == _match.method
1442 && _in_map.size() == _out_map.size()
1443 && _in_map.size() == get_count ()
1445 /* If the configuration has not changed, keep the mapping */
1446 if (old_internal != _configured_internal) {
1447 mapping_changed = sanitize_maps ();
1449 } else if (_match.custom_cfg && _configured) {
1450 mapping_changed = sanitize_maps ();
1453 if (is_channelstrip ()) { _maps_from_state = false; }
1455 if (_maps_from_state) {
1456 _maps_from_state = false;
1457 mapping_changed = true;
1460 /* generate a new mapping */
1461 mapping_changed = reset_map (false);
1465 if (mapping_changed) {
1466 PluginMapChanged (); /* EMIT SIGNAL */
1469 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1472 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1473 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1475 DEBUG_STR_APPEND(a, "----><----\n");
1477 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1478 DEBUG_STR_APPEND(a, " * Inputs:\n");
1479 DEBUG_STR_APPEND(a, _in_map[pc]);
1480 DEBUG_STR_APPEND(a, " * Outputs:\n");
1481 DEBUG_STR_APPEND(a, _out_map[pc]);
1483 DEBUG_STR_APPEND(a, " * Thru:\n");
1484 DEBUG_STR_APPEND(a, _thru_map);
1485 DEBUG_STR_APPEND(a, "-------->>--------\n");
1486 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1491 _no_inplace = check_inplace ();
1492 _mapping_changed = false;
1494 /* only the "noinplace_buffers" thread buffers need to be this large,
1495 * this can be optimized. other buffers are fine with
1496 * ChanCount::max (natural_input_streams (), natural_output_streams())
1497 * and route.cc's max (configured_in, configured_out)
1499 * no-inplace copies "thru" outputs (to emulate in-place) for
1500 * all outputs (to prevent overwrite) into a temporary space
1501 * which also holds input buffers (in case the plugin does process
1502 * in-place and overwrites those).
1504 * this buffers need to be at least as
1505 * natural_input_streams () + possible outputs.
1507 * sidechain inputs add a constraint on the input:
1508 * configured input + sidechain (=_configured_internal)
1510 _required_buffers =ChanCount::max (_configured_internal,
1511 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1513 if (old_in != in || old_out != out || old_internal != _configured_internal
1514 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1516 PluginIoReConfigure (); /* EMIT SIGNAL */
1519 _delaybuffers.configure (_configured_out, _plugins.front()->max_latency ());
1520 _latency_changed = true;
1522 // we don't know the analysis window size, so we must work with the
1523 // current buffer size here. each request for data fills in these
1524 // buffers and the analyser makes sure it gets enough data for the
1526 session().ensure_buffer_set (_signal_analysis_inputs, in);
1527 //_signal_analysis_inputs.set_count (in);
1529 session().ensure_buffer_set (_signal_analysis_outputs, out);
1530 //_signal_analysis_outputs.set_count (out);
1532 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1535 return Processor::configure_io (in, out);
1538 /** Decide whether this PluginInsert can support a given IO configuration.
1539 * To do this, we run through a set of possible solutions in rough order of
1542 * @param in Required input channel count.
1543 * @param out Filled in with the output channel count if we return true.
1544 * @return true if the given IO configuration can be supported.
1547 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1550 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1552 return private_can_support_io_configuration (in, out).method != Impossible;
1556 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1558 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1559 // preseed hint (for variable i/o)
1560 out.set (DataType::AUDIO, _preset_out.n_audio ());
1563 Match rv = internal_can_support_io_configuration (in, out);
1565 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1566 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("using output preset: %1 %2\n", name(), _preset_out));
1567 out.set (DataType::AUDIO, _preset_out.n_audio ());
1572 /** A private version of can_support_io_configuration which returns the method
1573 * by which the configuration can be matched, rather than just whether or not
1577 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1579 if (_plugins.empty()) {
1584 if (is_channelstrip ()) {
1586 return Match (ExactMatch, 1);
1590 /* if a user specified a custom cfg, so be it. */
1592 PluginInfoPtr info = _plugins.front()->get_info();
1594 if (info->reconfigurable_io()) {
1595 return Match (Delegate, get_count(), _strict_io, true);
1597 return Match (ExactMatch, get_count(), _strict_io, true);
1601 /* try automatic configuration */
1602 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1604 PluginInfoPtr info = _plugins.front()->get_info();
1605 ChanCount inputs = info->n_inputs;
1606 ChanCount outputs = info->n_outputs;
1608 /* handle case strict-i/o */
1609 if (_strict_io && m.method != Impossible) {
1612 /* special case MIDI instruments */
1613 if (needs_midi_input ()) {
1614 // output = midi-bypass + at most master-out channels.
1615 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1616 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1617 out = ChanCount::min (out, max_out);
1618 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o instrument: %1\n", name()));
1624 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1625 /* replicate processor to match output count (generators and such)
1626 * at least enough to feed every output port. */
1627 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1628 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1629 uint32_t nout = outputs.get (*t);
1630 if (nout == 0 || inx.get(*t) == 0) { continue; }
1631 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1634 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o generator: %1\n", name()));
1635 return Match (Replicate, f, _strict_io);
1646 if (m.method != Impossible) {
1650 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1652 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("resolving 'Impossible' match for %1\n", name()));
1654 if (info->reconfigurable_io()) {
1657 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1658 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1659 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1661 // houston, we have a problem.
1662 return Match (Impossible, 0);
1664 return Match (Delegate, 1, _strict_io);
1667 ChanCount midi_bypass;
1668 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1669 midi_bypass.set (DataType::MIDI, 1);
1672 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1674 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1675 uint32_t nin = ns_inputs.get (*t);
1676 uint32_t nout = outputs.get (*t);
1677 if (nin == 0 || inx.get(*t) == 0) { continue; }
1678 // prefer floor() so the count won't overly increase IFF (nin < nout)
1679 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1681 if (f > 0 && outputs * f >= _configured_out) {
1682 out = outputs * f + midi_bypass;
1683 return Match (Replicate, f, _strict_io);
1686 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1688 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1689 uint32_t nin = ns_inputs.get (*t);
1690 if (nin == 0 || inx.get(*t) == 0) { continue; }
1691 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1694 out = outputs * f + midi_bypass;
1695 return Match (Replicate, f, _strict_io);
1698 // add at least as many plugins needed to connect all inputs
1700 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1701 uint32_t nin = inputs.get (*t);
1702 if (nin == 0 || inx.get(*t) == 0) { continue; }
1703 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1705 out = outputs * f + midi_bypass;
1706 return Match (Replicate, f, _strict_io);
1709 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1711 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1713 if (_plugins.empty()) {
1717 PluginInfoPtr info = _plugins.front()->get_info();
1718 ChanCount in; in += inx;
1719 ChanCount midi_bypass;
1721 if (info->reconfigurable_io()) {
1722 /* Plugin has flexible I/O, so delegate to it
1723 * pre-seed outputs, plugin tries closest match
1726 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1727 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1728 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1730 return Match (Impossible, 0);
1732 return Match (Delegate, 1);
1735 ChanCount inputs = info->n_inputs;
1736 ChanCount outputs = info->n_outputs;
1737 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1739 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1740 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("bypassing midi-data around %1\n", name()));
1741 midi_bypass.set (DataType::MIDI, 1);
1743 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1744 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("hiding midi-port from plugin %1\n", name()));
1745 in.set(DataType::MIDI, 0);
1748 // add internally provided sidechain ports
1749 ChanCount insc = in + sidechain_input_ports ();
1751 bool no_inputs = true;
1752 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1753 if (inputs.get (*t) != 0) {
1760 /* no inputs so we can take any input configuration since we throw it away */
1761 out = outputs + midi_bypass;
1762 return Match (NoInputs, 1);
1765 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1766 if (inputs == insc) {
1767 out = outputs + midi_bypass;
1768 return Match (ExactMatch, 1);
1771 /* Plugin inputs matches without side-chain-pins */
1772 if (ns_inputs == in) {
1773 out = outputs + midi_bypass;
1774 return Match (ExactMatch, 1);
1777 /* We may be able to run more than one copy of the plugin within this insert
1778 to cope with the insert having more inputs than the plugin.
1779 We allow replication only for plugins with either zero or 1 inputs and outputs
1780 for every valid data type.
1784 bool can_replicate = true;
1785 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1787 // ignore side-chains
1788 uint32_t nin = ns_inputs.get (*t);
1790 // No inputs of this type
1791 if (nin == 0 && in.get(*t) == 0) {
1795 if (nin != 1 || outputs.get (*t) != 1) {
1796 can_replicate = false;
1800 // Potential factor not set yet
1802 f = in.get(*t) / nin;
1805 // Factor for this type does not match another type, can not replicate
1806 if (f != (in.get(*t) / nin)) {
1807 can_replicate = false;
1812 if (can_replicate && f > 0) {
1813 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1814 out.set (*t, outputs.get(*t) * f);
1817 return Match (Replicate, f);
1820 /* If the processor has exactly one input of a given type, and
1821 the plugin has more, we can feed the single processor input
1822 to some or all of the plugin inputs. This is rather
1823 special-case-y, but the 1-to-many case is by far the
1824 simplest. How do I split thy 2 processor inputs to 3
1825 plugin inputs? Let me count the ways ...
1828 bool can_split = true;
1829 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1831 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
1832 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1834 if (!can_split_type && !nothing_to_do_for_type) {
1840 out = outputs + midi_bypass;
1841 return Match (Split, 1);
1844 /* If the plugin has more inputs than we want, we can `hide' some of them
1845 by feeding them silence.
1848 bool could_hide = false;
1849 bool cannot_hide = false;
1850 ChanCount hide_channels;
1852 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1853 if (inputs.get(*t) > in.get(*t)) {
1854 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1855 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1857 } else if (inputs.get(*t) < in.get(*t)) {
1858 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1863 if (could_hide && !cannot_hide) {
1864 out = outputs + midi_bypass;
1865 return Match (Hide, 1, false, false, hide_channels);
1868 return Match (Impossible, 0);
1873 PluginInsert::get_state ()
1875 return state (true);
1879 PluginInsert::state (bool full)
1881 XMLNode& node = Processor::state (full);
1883 node.add_property("type", _plugins[0]->state_node_name());
1884 node.add_property("unique-id", _plugins[0]->unique_id());
1885 node.add_property("count", string_compose("%1", _plugins.size()));
1887 /* remember actual i/o configuration (for later placeholder
1888 * in case the plugin goes missing) */
1889 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1890 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1891 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
1893 /* save custom i/o config */
1894 node.add_property("custom", _custom_cfg ? "yes" : "no");
1895 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1897 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
1898 node.add_child_nocopy (* _in_map[pc].state (tmp));
1899 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
1900 node.add_child_nocopy (* _out_map[pc].state (tmp));
1902 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
1905 node.add_child_nocopy (_sidechain->state (full));
1908 _plugins[0]->set_insert_id(this->id());
1909 node.add_child_nocopy (_plugins[0]->get_state());
1911 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1912 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1914 node.add_child_nocopy (ac->get_state());
1922 PluginInsert::set_control_ids (const XMLNode& node, int version)
1924 const XMLNodeList& nlist = node.children();
1925 XMLNodeConstIterator iter;
1926 set<Evoral::Parameter>::const_iterator p;
1928 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1929 if ((*iter)->name() == Controllable::xml_node_name) {
1930 const XMLProperty* prop;
1932 uint32_t p = (uint32_t)-1;
1934 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1935 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1937 p = lv2plugin->port_index(prop->value().c_str());
1941 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1942 p = atoi (prop->value());
1945 if (p != (uint32_t)-1) {
1947 /* this may create the new controllable */
1949 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1951 #ifndef NO_PLUGIN_STATE
1955 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1957 ac->set_state (**iter, version);
1966 PluginInsert::set_state(const XMLNode& node, int version)
1968 XMLNodeList nlist = node.children();
1969 XMLNodeIterator niter;
1970 XMLPropertyList plist;
1971 const XMLProperty *prop;
1972 ARDOUR::PluginType type;
1974 if ((prop = node.property ("type")) == 0) {
1975 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1979 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1980 type = ARDOUR::LADSPA;
1981 } else if (prop->value() == X_("lv2")) {
1983 } else if (prop->value() == X_("windows-vst")) {
1984 type = ARDOUR::Windows_VST;
1985 } else if (prop->value() == X_("lxvst")) {
1986 type = ARDOUR::LXVST;
1987 } else if (prop->value() == X_("audiounit")) {
1988 type = ARDOUR::AudioUnit;
1989 } else if (prop->value() == X_("luaproc")) {
1992 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1998 prop = node.property ("unique-id");
2001 #ifdef WINDOWS_VST_SUPPORT
2002 /* older sessions contain VST plugins with only an "id" field.
2005 if (type == ARDOUR::Windows_VST) {
2006 prop = node.property ("id");
2010 #ifdef LXVST_SUPPORT
2011 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2013 if (type == ARDOUR::LXVST) {
2014 prop = node.property ("id");
2020 error << _("Plugin has no unique ID field") << endmsg;
2025 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2027 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2028 * allow to move sessions windows <> linux */
2029 #ifdef LXVST_SUPPORT
2030 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2031 type = ARDOUR::LXVST;
2032 plugin = find_plugin (_session, prop->value(), type);
2036 #ifdef WINDOWS_VST_SUPPORT
2037 if (plugin == 0 && type == ARDOUR::LXVST) {
2038 type = ARDOUR::Windows_VST;
2039 plugin = find_plugin (_session, prop->value(), type);
2044 error << string_compose(
2045 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2046 "Perhaps it was removed or moved since it was last used."),
2052 if (type == ARDOUR::Lua) {
2053 XMLNode *ls = node.child (plugin->state_node_name().c_str());
2054 // we need to load the script to set the name and parameters.
2055 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
2057 lp->set_script_from_state (*ls);
2061 // The name of the PluginInsert comes from the plugin, nothing else
2062 _name = plugin->get_info()->name;
2066 // Processor::set_state() will set this, but too late
2067 // for it to be available when setting up plugin
2068 // state. We can't call Processor::set_state() until
2069 // the plugins themselves are created and added.
2073 if (_plugins.empty()) {
2074 /* if we are adding the first plugin, we will need to set
2075 up automatable controls.
2077 add_plugin (plugin);
2078 create_automatable_parameters ();
2079 set_control_ids (node, version);
2082 if ((prop = node.property ("count")) != 0) {
2083 sscanf (prop->value().c_str(), "%u", &count);
2086 if (_plugins.size() != count) {
2087 for (uint32_t n = 1; n < count; ++n) {
2088 add_plugin (plugin_factory (plugin));
2092 Processor::set_state (node, version);
2094 PBD::ID new_id = this->id();
2095 PBD::ID old_id = this->id();
2097 if ((prop = node.property ("id")) != 0) {
2098 old_id = prop->value ();
2101 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2103 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2104 and set all plugins to the same state.
2107 if ((*niter)->name() == plugin->state_node_name()) {
2109 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2110 /* Plugin state can include external files which are named after the ID.
2112 * If regenerate_xml_or_string_ids() is set, the ID will already have
2113 * been changed, so we need to use the old ID from the XML to load the
2114 * state and then update the ID.
2116 * When copying a plugin-state, route_ui takes care of of updating the ID,
2117 * but we need to call set_insert_id() to clear the cached plugin-state
2118 * and force a change.
2120 if (!regenerate_xml_or_string_ids ()) {
2121 (*i)->set_insert_id (new_id);
2123 (*i)->set_insert_id (old_id);
2126 (*i)->set_state (**niter, version);
2128 if (regenerate_xml_or_string_ids ()) {
2129 (*i)->set_insert_id (new_id);
2137 if (version < 3000) {
2139 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2140 this is all handled by Automatable
2143 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2144 if ((*niter)->name() == "Redirect") {
2145 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2146 Processor::set_state (**niter, version);
2151 set_parameter_state_2X (node, version);
2154 if ((prop = node.property (X_("custom"))) != 0) {
2155 _custom_cfg = string_is_affirmative (prop->value());
2158 uint32_t in_maps = 0;
2159 uint32_t out_maps = 0;
2160 XMLNodeList kids = node.children ();
2161 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2162 if ((*i)->name() == X_("ConfiguredOutput")) {
2163 _custom_out = ChanCount(**i);
2165 if ((*i)->name() == X_("PresetOutput")) {
2166 _preset_out = ChanCount(**i);
2168 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2169 long pc = atol (&((*i)->name().c_str()[9]));
2170 if (pc >=0 && pc <= get_count()) {
2171 _in_map[pc] = ChanMapping (**i);
2175 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2176 long pc = atol (&((*i)->name().c_str()[10]));
2177 if (pc >=0 && pc <= get_count()) {
2178 _out_map[pc] = ChanMapping (**i);
2182 if ((*i)->name () == "ThruMap") {
2183 _thru_map = ChanMapping (**i);
2186 // sidechain is a Processor (IO)
2187 if ((*i)->name () == Processor::state_node_name) {
2191 _sidechain->set_state (**i, version);
2195 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2196 _maps_from_state = true;
2199 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2203 (*i)->deactivate ();
2207 PluginConfigChanged (); /* EMIT SIGNAL */
2212 PluginInsert::update_id (PBD::ID id)
2215 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2216 (*i)->set_insert_id (id);
2221 PluginInsert::set_state_dir (const std::string& d)
2223 // state() only saves the state of the first plugin
2224 _plugins[0]->set_state_dir (d);
2228 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2230 XMLNodeList nlist = node.children();
2231 XMLNodeIterator niter;
2233 /* look for port automation node */
2235 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2237 if ((*niter)->name() != port_automation_node_name) {
2243 XMLNodeConstIterator iter;
2248 cnodes = (*niter)->children ("port");
2250 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2254 if ((cprop = child->property("number")) != 0) {
2255 port = cprop->value().c_str();
2257 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2261 sscanf (port, "%" PRIu32, &port_id);
2263 if (port_id >= _plugins[0]->parameter_count()) {
2264 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2268 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2269 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2271 if (c && c->alist()) {
2272 if (!child->children().empty()) {
2273 c->alist()->set_state (*child->children().front(), version);
2275 /* In some cases 2.X saves lists with min_yval and max_yval
2276 being FLT_MIN and FLT_MAX respectively. This causes problems
2277 in A3 because these min/max values are used to compute
2278 where GUI control points should be drawn. If we see such
2279 values, `correct' them to the min/max of the appropriate
2283 float min_y = c->alist()->get_min_y ();
2284 float max_y = c->alist()->get_max_y ();
2286 ParameterDescriptor desc;
2287 _plugins.front()->get_parameter_descriptor (port_id, desc);
2289 if (min_y == FLT_MIN) {
2293 if (max_y == FLT_MAX) {
2297 c->alist()->set_yrange (min_y, max_y);
2300 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2312 PluginInsert::describe_parameter (Evoral::Parameter param)
2314 if (param.type() == PluginAutomation) {
2315 return _plugins[0]->describe_parameter (param);
2316 } else if (param.type() == PluginPropertyAutomation) {
2317 boost::shared_ptr<AutomationControl> c(automation_control(param));
2318 if (c && !c->desc().label.empty()) {
2319 return c->desc().label;
2322 return Automatable::describe_parameter(param);
2326 PluginInsert::signal_latency() const
2328 if (_user_latency) {
2329 return _user_latency;
2332 return _plugins[0]->signal_latency ();
2336 PluginInsert::type ()
2338 return plugin()->get_info()->type;
2341 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2342 const Evoral::Parameter& param,
2343 const ParameterDescriptor& desc,
2344 boost::shared_ptr<AutomationList> list)
2345 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2349 alist()->reset_default (desc.normal);
2351 list->set_interpolation(Evoral::ControlList::Discrete);
2356 set_flags(Controllable::Toggle);
2360 /** @param val `user' value */
2362 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2365 _set_value (user_val, group_override);
2369 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2371 /* used only by automation playback */
2372 _set_value (user_val, Controllable::NoGroup);
2376 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2378 /* FIXME: probably should be taking out some lock here.. */
2380 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2381 (*i)->set_parameter (_list->parameter().id(), user_val);
2384 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2386 iasp->set_parameter (_list->parameter().id(), user_val);
2389 AutomationControl::set_value (user_val, group_override);
2393 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2395 AutomationControl::set_value (user_val, Controllable::NoGroup);
2399 PluginInsert::PluginControl::get_state ()
2403 XMLNode& node (AutomationControl::get_state());
2404 ss << parameter().id();
2405 node.add_property (X_("parameter"), ss.str());
2407 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2409 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2416 /** @return `user' val */
2418 PluginInsert::PluginControl::get_value () const
2420 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2426 return plugin->get_parameter (_list->parameter().id());
2429 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2430 const Evoral::Parameter& param,
2431 const ParameterDescriptor& desc,
2432 boost::shared_ptr<AutomationList> list)
2433 : AutomationControl (p->session(), param, desc, list)
2437 alist()->set_yrange (desc.lower, desc.upper);
2438 alist()->reset_default (desc.normal);
2442 set_flags(Controllable::Toggle);
2447 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2450 set_value_unchecked (user_val);
2455 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2457 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2458 This is lossy, but better than nothing until Ardour's automation system
2459 can handle various datatypes all the way down. */
2460 const Variant value(_desc.datatype, user_val);
2461 if (value.type() == Variant::NOTHING) {
2462 error << "set_value(double) called for non-numeric property" << endmsg;
2466 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2467 (*i)->set_property(_list->parameter().id(), value);
2471 AutomationControl::set_value (user_val, Controllable::NoGroup);
2475 PluginInsert::PluginPropertyControl::get_state ()
2479 XMLNode& node (AutomationControl::get_state());
2480 ss << parameter().id();
2481 node.add_property (X_("property"), ss.str());
2482 node.remove_property (X_("value"));
2488 PluginInsert::PluginPropertyControl::get_value () const
2490 return _value.to_double();
2493 boost::shared_ptr<Plugin>
2494 PluginInsert::get_impulse_analysis_plugin()
2496 boost::shared_ptr<Plugin> ret;
2497 if (_impulseAnalysisPlugin.expired()) {
2498 ret = plugin_factory(_plugins[0]);
2499 ret->configure_io (internal_input_streams (), internal_output_streams ());
2500 _impulseAnalysisPlugin = ret;
2502 ret = _impulseAnalysisPlugin.lock();
2509 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2511 // called from outside the audio thread, so this should be safe
2512 // only do audio as analysis is (currently) only for audio plugins
2513 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2514 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2516 _signal_analysis_collected_nframes = 0;
2517 _signal_analysis_collect_nframes_max = nframes;
2520 /** Add a plugin to our list */
2522 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2524 plugin->set_insert_id (this->id());
2526 if (_plugins.empty()) {
2527 /* first (and probably only) plugin instance - connect to relevant signals */
2529 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2530 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2531 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2532 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2533 // cache sidechain port count
2534 _cached_sidechain_pins.reset ();
2535 const ChanCount& nis (plugin->get_info()->n_inputs);
2536 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2537 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2538 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2539 if (iod.is_sidechain) {
2540 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2545 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2546 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2548 vst->set_insert (this, _plugins.size ());
2551 _plugins.push_back (plugin);
2555 PluginInsert::realtime_handle_transport_stopped ()
2557 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2558 (*i)->realtime_handle_transport_stopped ();
2563 PluginInsert::realtime_locate ()
2565 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2566 (*i)->realtime_locate ();
2571 PluginInsert::monitoring_changed ()
2573 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2574 (*i)->monitoring_changed ();
2579 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2581 // this is called in RT context, LatencyChanged is emitted after run()
2582 _latency_changed = true;
2586 PluginInsert::start_touch (uint32_t param_id)
2588 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2590 ac->start_touch (session().audible_frame());
2595 PluginInsert::end_touch (uint32_t param_id)
2597 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2599 ac->stop_touch (true, session().audible_frame());
2603 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2606 case PluginInsert::Impossible: o << "Impossible"; break;
2607 case PluginInsert::Delegate: o << "Delegate"; break;
2608 case PluginInsert::NoInputs: o << "NoInputs"; break;
2609 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2610 case PluginInsert::Replicate: o << "Replicate"; break;
2611 case PluginInsert::Split: o << "Split"; break;
2612 case PluginInsert::Hide: o << "Hide"; break;
2614 o << " cnt: " << m.plugins
2615 << (m.strict_io ? " strict-io" : "")
2616 << (m.custom_cfg ? " custom-cfg" : "");
2617 if (m.method == PluginInsert::Hide) {
2618 o << " hide: " << m.hide;