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]);
122 XMLNode& state = _plugins[0]->get_state ();
123 p->set_state (state, Stateful::loading_state_version);
130 PluginConfigChanged (); /* EMIT SIGNAL */
132 } else if (num < _plugins.size()) {
133 uint32_t diff = _plugins.size() - num;
134 for (uint32_t n= 0; n < diff; ++n) {
137 PluginConfigChanged (); /* EMIT SIGNAL */
145 PluginInsert::set_outputs (const ChanCount& c)
147 bool changed = (_custom_out != c) && _custom_cfg;
150 PluginConfigChanged (); /* EMIT SIGNAL */
155 PluginInsert::set_custom_cfg (bool b)
157 bool changed = _custom_cfg != b;
160 PluginConfigChanged (); /* EMIT SIGNAL */
165 PluginInsert::set_preset_out (const ChanCount& c)
167 bool changed = _preset_out != c;
169 if (changed && !_custom_cfg) {
170 PluginConfigChanged (); /* EMIT SIGNAL */
176 PluginInsert::add_sidechain (uint32_t n_audio)
178 // caller must hold process lock
182 std::ostringstream n;
184 n << "Sidechain " << Session::next_name_id ();
186 n << "TO BE RESET FROM XML";
188 SideChain *sc = new SideChain (_session, n.str ());
189 _sidechain = boost::shared_ptr<SideChain> (sc);
190 _sidechain->activate ();
191 for (uint32_t n = 0; n < n_audio; ++n) {
192 _sidechain->input()->add_port ("", owner()); // add a port, don't connect.
194 PluginConfigChanged (); /* EMIT SIGNAL */
199 PluginInsert::del_sidechain ()
205 PluginConfigChanged (); /* EMIT SIGNAL */
210 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
212 if (which.type() != PluginAutomation)
215 boost::shared_ptr<AutomationControl> c
216 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
219 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
224 PluginInsert::output_streams() const
226 assert (_configured);
227 return _configured_out;
231 PluginInsert::input_streams() const
233 assert (_configured);
234 return _configured_in;
238 PluginInsert::internal_streams() const
240 assert (_configured);
241 return _configured_internal;
245 PluginInsert::internal_output_streams() const
247 assert (!_plugins.empty());
249 PluginInfoPtr info = _plugins.front()->get_info();
251 if (info->reconfigurable_io()) {
252 ChanCount out = _plugins.front()->output_streams ();
253 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
256 ChanCount out = info->n_outputs;
257 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
258 out.set_audio (out.n_audio() * _plugins.size());
259 out.set_midi (out.n_midi() * _plugins.size());
265 PluginInsert::internal_input_streams() const
267 assert (!_plugins.empty());
271 PluginInfoPtr info = _plugins.front()->get_info();
273 if (info->reconfigurable_io()) {
274 in = _plugins.front()->input_streams();
279 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
281 if (_match.method == Split) {
283 /* we are splitting 1 processor input to multiple plugin inputs,
284 so we have a maximum of 1 stream of each type.
286 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
287 if (in.get (*t) > 1) {
293 } else if (_match.method == Hide) {
295 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
296 in.set (*t, in.get (*t) - _match.hide.get (*t));
302 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
303 in.set (*t, in.get (*t) * _plugins.size ());
311 PluginInsert::natural_output_streams() const
314 if (is_channelstrip ()) {
315 return _configured_out;
318 return _plugins[0]->get_info()->n_outputs;
322 PluginInsert::natural_input_streams() const
325 if (is_channelstrip ()) {
326 return _configured_in;
329 return _plugins[0]->get_info()->n_inputs;
333 PluginInsert::sidechain_input_pins() const
335 return _cached_sidechain_pins;
339 PluginInsert::has_no_inputs() const
341 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
345 PluginInsert::has_no_audio_inputs() const
347 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
351 PluginInsert::plugin_latency () const {
352 return _plugins.front()->signal_latency ();
356 PluginInsert::needs_midi_input() const
358 PluginInfoPtr pip = _plugins[0]->get_info();
359 if (pip->needs_midi_input ()) {
362 return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
366 PluginInsert::create_automatable_parameters ()
368 assert (!_plugins.empty());
370 set<Evoral::Parameter> a = _plugins.front()->automatable ();
372 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
373 if (i->type() == PluginAutomation) {
375 Evoral::Parameter param(*i);
377 ParameterDescriptor desc;
378 _plugins.front()->get_parameter_descriptor(i->id(), desc);
380 can_automate (param);
381 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
382 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
384 _plugins.front()->set_automation_control (i->id(), c);
385 } else if (i->type() == PluginPropertyAutomation) {
386 Evoral::Parameter param(*i);
387 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
388 if (desc.datatype != Variant::NOTHING) {
389 boost::shared_ptr<AutomationList> list;
390 if (Variant::type_is_numeric(desc.datatype)) {
391 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
393 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
398 /** Called when something outside of this host has modified a plugin
399 * parameter. Responsible for propagating the change to two places:
401 * 1) anything listening to the Control itself
402 * 2) any replicated plugins that make up this PluginInsert.
404 * The PluginInsert is connected to the ParameterChangedExternally signal for
405 * the first (primary) plugin, and here broadcasts that change to any others.
407 * XXX We should probably drop this whole replication idea (Paul, October 2015)
408 * since it isn't used by sensible plugin APIs (AU, LV2).
411 PluginInsert::parameter_changed_externally (uint32_t which, float val)
413 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
415 /* First propagation: alter the underlying value of the control,
416 * without telling the plugin(s) that own/use it to set it.
423 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
426 pc->catch_up_with_external_value (val);
429 /* Second propagation: tell all plugins except the first to
430 update the value of this parameter. For sane plugin APIs,
431 there are no other plugins, so this is a no-op in those
435 Plugins::iterator i = _plugins.begin();
437 /* don't set the first plugin, just all the slaves */
439 if (i != _plugins.end()) {
441 for (; i != _plugins.end(); ++i) {
442 (*i)->set_parameter (which, val);
448 PluginInsert::set_block_size (pframes_t nframes)
451 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
452 if ((*i)->set_block_size (nframes) != 0) {
460 PluginInsert::activate ()
462 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
466 Processor::activate ();
470 PluginInsert::deactivate ()
472 Processor::deactivate ();
474 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
480 PluginInsert::flush ()
482 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
488 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
490 // TODO: atomically copy maps & _no_inplace
491 PinMappings in_map (_in_map);
492 PinMappings out_map (_out_map);
493 ChanMapping thru_map (_thru_map);
494 if (_mapping_changed) { // ToDo use a counters, increment until match.
495 _no_inplace = check_inplace ();
496 _mapping_changed = false;
499 if (_latency_changed) {
500 /* delaylines are configured with the max possible latency (as reported by the plugin)
501 * so this won't allocate memory (unless the plugin lied about its max latency)
502 * It may still 'click' though, since the fixed delaylines are not de-clicked.
503 * Then again plugin-latency changes are not click-free to begin with.
505 * This is also worst case, there is currently no concept of per-stream latency.
507 * e.g. Two identical latent plugins:
508 * 1st plugin: process left (latent), bypass right.
509 * 2nd plugin: bypass left, process right (latent).
510 * -> currently this yields 2 times latency of the plugin,
512 _latency_changed = false;
513 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
516 if (_match.method == Split && !_no_inplace) {
517 // TODO: also use this optimization if one source-buffer
518 // feeds _all_ *connected* inputs.
519 // currently this is *first* buffer to all only --
520 // see PluginInsert::check_inplace
521 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
522 if (_configured_internal.get (*t) == 0) {
526 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
527 assert (valid && first_idx == 0); // check_inplace ensures this
528 /* copy the first stream's buffer contents to the others */
529 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
530 uint32_t idx = in_map[0].get (*t, i, &valid);
533 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
537 /* the copy operation produces a linear monotonic input map */
538 in_map[0] = ChanMapping (natural_input_streams ());
541 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
542 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
548 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
550 boost::shared_ptr<AutomationControl> c
551 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
553 if (c->list() && c->automation_playback()) {
556 const float val = c->list()->rt_safe_eval (now, valid);
559 /* This is the ONLY place where we are
561 * AutomationControl::set_value_unchecked(). We
562 * know that the control is in
563 * automation playback mode, so no
564 * check on writable() is required
565 * (which must be done in AutomationControl::set_value()
568 c->set_value_unchecked(val);
575 /* Calculate if, and how many frames we need to collect for analysis */
576 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
577 _signal_analysis_collected_nframes);
578 if (nframes < collect_signal_nframes) { // we might not get all frames now
579 collect_signal_nframes = nframes;
582 if (collect_signal_nframes > 0) {
584 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
585 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
586 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
588 _signal_analysis_inputs.set_count(internal_input_streams());
590 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
591 _signal_analysis_inputs.get_audio(i).read_from(
593 collect_signal_nframes,
594 _signal_analysis_collected_nframes); // offset is for target buffer
599 if (is_channelstrip ()) {
600 if (_configured_in.n_audio() > 0) {
601 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
602 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
604 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
606 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
607 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
613 // TODO optimize -- build maps once.
615 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
616 ARDOUR::ChanMapping used_outputs;
618 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
620 /* build used-output map */
621 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
622 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
623 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
625 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
627 used_outputs.set (*t, out_idx, 1); // mark as used
632 /* copy thru data to outputs before processing in-place */
633 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
634 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
636 uint32_t in_idx = thru_map.get (*t, out, &valid);
638 uint32_t m = out + natural_input_streams ().get (*t);
639 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
640 used_outputs.set (*t, out, 1); // mark as used
646 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
648 ARDOUR::ChanMapping i_in_map (natural_input_streams());
649 ARDOUR::ChanMapping i_out_map (out_map[pc]);
650 ARDOUR::ChanCount mapped;
652 /* map inputs sequentially */
653 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
654 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
656 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
657 uint32_t m = mapped.get (*t);
659 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
661 inplace_bufs.get (*t, m).silence (nframes, offset);
663 mapped.set (*t, m + 1);
667 /* outputs are mapped to inplace_bufs after the inputs */
668 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
669 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
672 if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
677 /* all instances have completed, now copy data that was written
678 * and zero unconnected buffers */
679 ARDOUR::ChanMapping nonzero_out (used_outputs);
680 if (has_midi_bypass ()) {
681 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
683 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
684 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
686 used_outputs.get (*t, out, &valid);
688 nonzero_out.get (*t, out, &valid);
690 bufs.get (*t, out).silence (nframes, offset);
693 uint32_t m = out + natural_input_streams ().get (*t);
694 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
699 /* in-place processing */
701 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
702 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
707 // TODO optimize: store "unconnected" in a fixed set.
708 // it only changes on reconfiguration.
709 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
710 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
712 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
713 mapped = true; // in-place Midi bypass
715 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
716 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
718 uint32_t idx = out_map[pc].get (*t, o, &valid);
719 if (valid && idx == out) {
726 bufs.get (*t, out).silence (nframes, offset);
732 if (collect_signal_nframes > 0) {
734 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
735 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
737 _signal_analysis_outputs.set_count(internal_output_streams());
739 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
740 _signal_analysis_outputs.get_audio(i).read_from(
742 collect_signal_nframes,
743 _signal_analysis_collected_nframes); // offset is for target buffer
746 _signal_analysis_collected_nframes += collect_signal_nframes;
747 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
749 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
750 _signal_analysis_collect_nframes_max = 0;
751 _signal_analysis_collected_nframes = 0;
753 AnalysisDataGathered(&_signal_analysis_inputs,
754 &_signal_analysis_outputs);
760 PluginInsert::silence (framecnt_t nframes)
766 ChanMapping in_map (natural_input_streams ());
767 ChanMapping out_map (natural_output_streams ());
769 // TODO run sidechain (delaylines)
770 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
771 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
776 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
778 if (_pending_active) {
779 /* run as normal if we are active or moving from inactive to active */
782 // collect sidechain input for complete cycle (!)
783 // TODO we need delaylines here for latency compensation
784 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
787 if (_session.transport_rolling() || _session.bounce_processing()) {
788 automation_run (bufs, start_frame, nframes);
790 connect_and_run (bufs, nframes, 0, false);
794 // TODO use mapping in bypassed mode ?!
795 // -> do we bypass the processor or the plugin
797 // TODO include sidechain??
799 uint32_t in = input_streams ().n_audio ();
800 uint32_t out = output_streams().n_audio ();
802 if (has_no_audio_inputs() || in == 0) {
804 /* silence all (audio) outputs. Should really declick
805 * at the transitions of "active"
808 for (uint32_t n = 0; n < out; ++n) {
809 bufs.get_audio (n).silence (nframes);
812 } else if (out > in) {
814 /* not active, but something has make up for any channel count increase
815 * for now , simply replicate last buffer
817 for (uint32_t n = in; n < out; ++n) {
818 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
822 bufs.count().set_audio (out);
825 _active = _pending_active;
827 /* we have no idea whether the plugin generated silence or not, so mark
828 * all buffers appropriately.
833 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
835 Evoral::ControlEvent next_event (0, 0.0f);
836 framepos_t now = start;
837 framepos_t end = now + nframes;
838 framecnt_t offset = 0;
840 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
843 connect_and_run (bufs, nframes, offset, false);
847 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
849 /* no events have a time within the relevant range */
851 connect_and_run (bufs, nframes, offset, true, now);
857 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
859 connect_and_run (bufs, cnt, offset, true, now);
865 if (!find_next_event (now, end, next_event)) {
870 /* cleanup anything that is left to do */
873 connect_and_run (bufs, nframes, offset, true, now);
878 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
880 if (param.type() != PluginAutomation)
883 if (_plugins.empty()) {
884 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
886 abort(); /*NOTREACHED*/
889 return _plugins[0]->default_value (param.id());
894 PluginInsert::can_reset_all_parameters ()
898 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
900 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
902 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
906 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
912 if (ac->automation_state() & Play) {
917 return all && (params > 0);
921 PluginInsert::reset_parameters_to_default ()
925 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
927 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
929 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
933 const float dflt = _plugins[0]->default_value (cid);
934 const float curr = _plugins[0]->get_parameter (cid);
940 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
945 if (ac->automation_state() & Play) {
950 ac->set_value (dflt, Controllable::NoGroup);
955 boost::shared_ptr<Plugin>
956 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
958 boost::shared_ptr<LadspaPlugin> lp;
959 boost::shared_ptr<LuaProc> lua;
961 boost::shared_ptr<LV2Plugin> lv2p;
963 #ifdef WINDOWS_VST_SUPPORT
964 boost::shared_ptr<WindowsVSTPlugin> vp;
967 boost::shared_ptr<LXVSTPlugin> lxvp;
969 #ifdef AUDIOUNIT_SUPPORT
970 boost::shared_ptr<AUPlugin> ap;
973 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
974 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
975 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
976 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
978 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
979 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
981 #ifdef WINDOWS_VST_SUPPORT
982 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
983 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
986 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
987 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
989 #ifdef AUDIOUNIT_SUPPORT
990 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
991 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
995 fatal << string_compose (_("programming error: %1"),
996 X_("unknown plugin type in PluginInsert::plugin_factory"))
998 abort(); /*NOTREACHED*/
999 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1003 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1004 if (num < _in_map.size()) {
1005 bool changed = _in_map[num] != m;
1007 changed |= sanitize_maps ();
1009 PluginMapChanged (); /* EMIT SIGNAL */
1010 _mapping_changed = true;
1011 _session.set_dirty();
1017 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1018 if (num < _out_map.size()) {
1019 bool changed = _out_map[num] != m;
1021 changed |= sanitize_maps ();
1023 PluginMapChanged (); /* EMIT SIGNAL */
1024 _mapping_changed = true;
1025 _session.set_dirty();
1031 PluginInsert::set_thru_map (ChanMapping m) {
1032 bool changed = _thru_map != m;
1034 changed |= sanitize_maps ();
1036 PluginMapChanged (); /* EMIT SIGNAL */
1037 _mapping_changed = true;
1038 _session.set_dirty();
1043 PluginInsert::input_map () const
1047 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1048 ChanMapping m (i->second);
1049 const ChanMapping::Mappings& mp ((*i).second.mappings());
1050 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1051 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1052 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1060 PluginInsert::output_map () const
1064 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1065 ChanMapping m (i->second);
1066 const ChanMapping::Mappings& mp ((*i).second.mappings());
1067 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1068 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1069 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1073 if (has_midi_bypass ()) {
1074 rv.set (DataType::MIDI, 0, 0);
1081 PluginInsert::has_midi_bypass () const
1083 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1084 && natural_output_streams ().n_midi () == 0) {
1091 PluginInsert::has_midi_thru () const
1093 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1094 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1102 PluginInsert::is_channelstrip () const {
1103 return _plugins.front()->is_channelstrip();
1108 PluginInsert::check_inplace ()
1110 bool inplace_ok = !_plugins.front()->inplace_broken ();
1112 if (_thru_map.n_total () > 0) {
1113 // TODO once midi-bypass is part of the mapping, ignore it
1117 if (_match.method == Split && inplace_ok) {
1118 assert (get_count() == 1);
1119 assert (_in_map.size () == 1);
1120 if (!_out_map[0].is_monotonic ()) {
1123 if (_configured_internal != _configured_in) {
1124 /* no sidechain -- TODO we could allow this with
1125 * some more logic in PluginInsert::connect_and_run().
1127 * PluginInsert::reset_map() already maps it.
1132 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1133 if (_configured_internal.get (*t) == 0) {
1137 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1138 if (!valid || first_idx != 0) {
1139 // so far only allow to copy the *first* stream's buffer to others
1142 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1143 uint32_t idx = _in_map[0].get (*t, i, &valid);
1144 if (valid && idx != first_idx) {
1153 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1158 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1159 if (!_in_map[pc].is_monotonic ()) {
1162 if (!_out_map[pc].is_monotonic ()) {
1166 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1167 return !inplace_ok; // no-inplace
1171 PluginInsert::sanitize_maps ()
1173 bool changed = false;
1174 /* strip dead wood */
1175 PinMappings new_ins;
1176 PinMappings new_outs;
1177 ChanMapping new_thru;
1179 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1181 ChanMapping new_out;
1182 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1183 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1185 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1186 if (valid && idx < _configured_internal.get (*t)) {
1187 new_in.set (*t, i, idx);
1190 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1192 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1193 if (valid && idx < _configured_out.get (*t)) {
1194 new_out.set (*t, o, idx);
1198 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1201 new_ins[pc] = new_in;
1202 new_outs[pc] = new_out;
1205 /* prevent dup output assignments */
1206 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1207 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1208 bool mapped = false;
1209 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1211 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1212 if (valid && mapped) {
1213 new_outs[pc].unset (*t, idx);
1221 /* remove excess thru */
1222 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1223 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1225 uint32_t idx = _thru_map.get (*t, o, &valid);
1226 if (valid && idx < _configured_internal.get (*t)) {
1227 new_thru.set (*t, o, idx);
1232 /* prevent out + thru, existing plugin outputs override thru */
1233 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1234 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1235 bool mapped = false;
1237 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1238 new_outs[pc].get_src (*t, o, &mapped);
1239 if (mapped) { break; }
1241 if (!mapped) { continue; }
1242 uint32_t idx = new_thru.get (*t, o, &valid);
1244 new_thru.unset (*t, idx);
1249 if (has_midi_bypass ()) {
1250 // TODO: include midi-bypass in the thru set,
1251 // remove dedicated handling.
1252 new_thru.unset (DataType::MIDI, 0);
1255 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1259 _out_map = new_outs;
1260 _thru_map = new_thru;
1266 PluginInsert::reset_map (bool emit)
1268 const PinMappings old_in (_in_map);
1269 const PinMappings old_out (_out_map);
1273 _thru_map = ChanMapping ();
1275 /* build input map */
1276 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1277 uint32_t sc = 0; // side-chain round-robin (all instances)
1279 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1280 const uint32_t nis = natural_input_streams ().get(*t);
1281 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1283 /* SC inputs are last in the plugin-insert.. */
1284 const uint32_t sc_start = _configured_in.get (*t);
1285 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1286 /* ...but may not be at the end of the plugin ports.
1287 * in case the side-chain is not the last port, shift connections back.
1288 * and connect to side-chain
1291 uint32_t ic = 0; // split inputs
1292 const uint32_t cend = _configured_in.get (*t);
1294 for (uint32_t in = 0; in < nis; ++in) {
1295 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1296 if (iod.is_sidechain) {
1297 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1298 if (sc_len > 0) {// side-chain may be hidden
1299 _in_map[pc].set (*t, in, sc_start + sc);
1300 sc = (sc + 1) % sc_len;
1304 if (_match.method == Split) {
1305 if (cend == 0) { continue; }
1306 if (_strict_io && ic + stride * pc >= cend) {
1309 /* connect *no* sidechain sinks in round-robin fashion */
1310 _in_map[pc].set (*t, in, ic + stride * pc);
1311 if (_strict_io && (ic + 1) == cend) {
1314 ic = (ic + 1) % cend;
1316 uint32_t s = in - shift;
1317 if (stride * pc + s < cend) {
1318 _in_map[pc].set (*t, in, s + stride * pc);
1326 /* build output map */
1328 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1329 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1330 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1331 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1336 if (old_in == _in_map && old_out == _out_map) {
1340 PluginMapChanged (); /* EMIT SIGNAL */
1341 _mapping_changed = true;
1342 _session.set_dirty();
1348 PluginInsert::configure_io (ChanCount in, ChanCount out)
1350 Match old_match = _match;
1352 ChanCount old_internal;
1356 old_in = _configured_in;
1357 old_internal = _configured_internal;
1358 old_out = _configured_out;
1361 _configured_in = in;
1362 _configured_internal = in;
1363 _configured_out = out;
1366 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1367 * (currently _sidechain->configure_io always succeeds
1368 * since Processor::configure_io() succeeds)
1370 if (!_sidechain->configure_io (in, out)) {
1371 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1374 _configured_internal += _sidechain->input()->n_ports();
1377 /* get plugin configuration */
1378 _match = private_can_support_io_configuration (in, out);
1380 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1382 DEBUG_STR_APPEND(a, string_compose ("Match '%1': ", name()));
1383 DEBUG_STR_APPEND(a, _match);
1384 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1388 /* set the matching method and number of plugins that we will use to meet this configuration */
1389 if (set_count (_match.plugins) == false) {
1390 PluginIoReConfigure (); /* EMIT SIGNAL */
1391 _configured = false;
1395 /* configure plugins */
1396 switch (_match.method) {
1399 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1400 PluginIoReConfigure (); /* EMIT SIGNAL */
1401 _configured = false;
1407 ChanCount dout (in); // hint
1410 } else if (_preset_out.n_audio () > 0) {
1411 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1412 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1413 dout.set (DataType::AUDIO, 2);
1415 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1417 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
1419 if (useins.n_audio() == 0) {
1422 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("Delegate configuration: %1 %2 %3\n", name(), useins, dout));
1424 if (_plugins.front()->configure_io (useins, dout) == false) {
1425 PluginIoReConfigure (); /* EMIT SIGNAL */
1426 _configured = false;
1432 if (_plugins.front()->configure_io (in, out) == false) {
1433 PluginIoReConfigure (); /* EMIT SIGNAL */
1434 _configured = false;
1440 bool mapping_changed = false;
1441 if (old_in == in && old_out == out
1443 && old_match.method == _match.method
1444 && _in_map.size() == _out_map.size()
1445 && _in_map.size() == get_count ()
1447 /* If the configuration has not changed, keep the mapping */
1448 if (old_internal != _configured_internal) {
1449 mapping_changed = sanitize_maps ();
1451 } else if (_match.custom_cfg && _configured) {
1452 mapping_changed = sanitize_maps ();
1455 if (is_channelstrip ()) { _maps_from_state = false; }
1457 if (_maps_from_state) {
1458 _maps_from_state = false;
1459 mapping_changed = true;
1462 /* generate a new mapping */
1463 mapping_changed = reset_map (false);
1467 if (mapping_changed) {
1468 PluginMapChanged (); /* EMIT SIGNAL */
1471 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1474 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1475 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1477 DEBUG_STR_APPEND(a, "----><----\n");
1479 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1480 DEBUG_STR_APPEND(a, " * Inputs:\n");
1481 DEBUG_STR_APPEND(a, _in_map[pc]);
1482 DEBUG_STR_APPEND(a, " * Outputs:\n");
1483 DEBUG_STR_APPEND(a, _out_map[pc]);
1485 DEBUG_STR_APPEND(a, " * Thru:\n");
1486 DEBUG_STR_APPEND(a, _thru_map);
1487 DEBUG_STR_APPEND(a, "-------->>--------\n");
1488 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1493 _no_inplace = check_inplace ();
1494 _mapping_changed = false;
1496 /* only the "noinplace_buffers" thread buffers need to be this large,
1497 * this can be optimized. other buffers are fine with
1498 * ChanCount::max (natural_input_streams (), natural_output_streams())
1499 * and route.cc's max (configured_in, configured_out)
1501 * no-inplace copies "thru" outputs (to emulate in-place) for
1502 * all outputs (to prevent overwrite) into a temporary space
1503 * which also holds input buffers (in case the plugin does process
1504 * in-place and overwrites those).
1506 * this buffers need to be at least as
1507 * natural_input_streams () + possible outputs.
1509 * sidechain inputs add a constraint on the input:
1510 * configured input + sidechain (=_configured_internal)
1512 _required_buffers =ChanCount::max (_configured_internal,
1513 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1515 if (old_in != in || old_out != out || old_internal != _configured_internal
1516 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1518 PluginIoReConfigure (); /* EMIT SIGNAL */
1521 _delaybuffers.configure (_configured_out, _plugins.front()->max_latency ());
1522 _latency_changed = true;
1524 // we don't know the analysis window size, so we must work with the
1525 // current buffer size here. each request for data fills in these
1526 // buffers and the analyser makes sure it gets enough data for the
1528 session().ensure_buffer_set (_signal_analysis_inputs, in);
1529 //_signal_analysis_inputs.set_count (in);
1531 session().ensure_buffer_set (_signal_analysis_outputs, out);
1532 //_signal_analysis_outputs.set_count (out);
1534 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1537 return Processor::configure_io (in, out);
1540 /** Decide whether this PluginInsert can support a given IO configuration.
1541 * To do this, we run through a set of possible solutions in rough order of
1544 * @param in Required input channel count.
1545 * @param out Filled in with the output channel count if we return true.
1546 * @return true if the given IO configuration can be supported.
1549 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1552 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1554 return private_can_support_io_configuration (in, out).method != Impossible;
1558 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1560 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1561 // preseed hint (for variable i/o)
1562 out.set (DataType::AUDIO, _preset_out.n_audio ());
1565 Match rv = internal_can_support_io_configuration (in, out);
1567 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1568 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("using output preset: %1 %2\n", name(), _preset_out));
1569 out.set (DataType::AUDIO, _preset_out.n_audio ());
1574 /** A private version of can_support_io_configuration which returns the method
1575 * by which the configuration can be matched, rather than just whether or not
1579 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1581 if (_plugins.empty()) {
1586 if (is_channelstrip ()) {
1588 return Match (ExactMatch, 1);
1592 /* if a user specified a custom cfg, so be it. */
1594 PluginInfoPtr info = _plugins.front()->get_info();
1596 if (info->reconfigurable_io()) {
1597 return Match (Delegate, get_count(), _strict_io, true);
1599 return Match (ExactMatch, get_count(), _strict_io, true);
1603 /* try automatic configuration */
1604 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1606 PluginInfoPtr info = _plugins.front()->get_info();
1607 ChanCount inputs = info->n_inputs;
1608 ChanCount outputs = info->n_outputs;
1610 /* handle case strict-i/o */
1611 if (_strict_io && m.method != Impossible) {
1614 /* special case MIDI instruments */
1615 if (needs_midi_input ()) {
1616 // output = midi-bypass + at most master-out channels.
1617 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1618 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1619 out = ChanCount::min (out, max_out);
1620 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o instrument: %1\n", name()));
1626 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1627 /* replicate processor to match output count (generators and such)
1628 * at least enough to feed every output port. */
1629 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1630 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1631 uint32_t nout = outputs.get (*t);
1632 if (nout == 0 || inx.get(*t) == 0) { continue; }
1633 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1636 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o generator: %1\n", name()));
1637 return Match (Replicate, f, _strict_io);
1648 if (m.method != Impossible) {
1652 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1654 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("resolving 'Impossible' match for %1\n", name()));
1656 if (info->reconfigurable_io()) {
1659 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1660 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1661 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1663 // houston, we have a problem.
1664 return Match (Impossible, 0);
1666 return Match (Delegate, 1, _strict_io);
1669 ChanCount midi_bypass;
1670 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1671 midi_bypass.set (DataType::MIDI, 1);
1674 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1676 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1677 uint32_t nin = ns_inputs.get (*t);
1678 uint32_t nout = outputs.get (*t);
1679 if (nin == 0 || inx.get(*t) == 0) { continue; }
1680 // prefer floor() so the count won't overly increase IFF (nin < nout)
1681 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1683 if (f > 0 && outputs * f >= _configured_out) {
1684 out = outputs * f + midi_bypass;
1685 return Match (Replicate, f, _strict_io);
1688 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1690 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1691 uint32_t nin = ns_inputs.get (*t);
1692 if (nin == 0 || inx.get(*t) == 0) { continue; }
1693 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1696 out = outputs * f + midi_bypass;
1697 return Match (Replicate, f, _strict_io);
1700 // add at least as many plugins needed to connect all inputs
1702 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1703 uint32_t nin = inputs.get (*t);
1704 if (nin == 0 || inx.get(*t) == 0) { continue; }
1705 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1707 out = outputs * f + midi_bypass;
1708 return Match (Replicate, f, _strict_io);
1711 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1713 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1715 if (_plugins.empty()) {
1719 PluginInfoPtr info = _plugins.front()->get_info();
1720 ChanCount in; in += inx;
1721 ChanCount midi_bypass;
1723 if (info->reconfigurable_io()) {
1724 /* Plugin has flexible I/O, so delegate to it
1725 * pre-seed outputs, plugin tries closest match
1728 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1729 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1730 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1732 return Match (Impossible, 0);
1734 return Match (Delegate, 1);
1737 ChanCount inputs = info->n_inputs;
1738 ChanCount outputs = info->n_outputs;
1739 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1741 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1742 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("bypassing midi-data around %1\n", name()));
1743 midi_bypass.set (DataType::MIDI, 1);
1745 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1746 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("hiding midi-port from plugin %1\n", name()));
1747 in.set(DataType::MIDI, 0);
1750 // add internally provided sidechain ports
1751 ChanCount insc = in + sidechain_input_ports ();
1753 bool no_inputs = true;
1754 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1755 if (inputs.get (*t) != 0) {
1762 /* no inputs so we can take any input configuration since we throw it away */
1763 out = outputs + midi_bypass;
1764 return Match (NoInputs, 1);
1767 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1768 if (inputs == insc) {
1769 out = outputs + midi_bypass;
1770 return Match (ExactMatch, 1);
1773 /* Plugin inputs matches without side-chain-pins */
1774 if (ns_inputs == in) {
1775 out = outputs + midi_bypass;
1776 return Match (ExactMatch, 1);
1779 /* We may be able to run more than one copy of the plugin within this insert
1780 to cope with the insert having more inputs than the plugin.
1781 We allow replication only for plugins with either zero or 1 inputs and outputs
1782 for every valid data type.
1786 bool can_replicate = true;
1787 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1789 // ignore side-chains
1790 uint32_t nin = ns_inputs.get (*t);
1792 // No inputs of this type
1793 if (nin == 0 && in.get(*t) == 0) {
1797 if (nin != 1 || outputs.get (*t) != 1) {
1798 can_replicate = false;
1802 // Potential factor not set yet
1804 f = in.get(*t) / nin;
1807 // Factor for this type does not match another type, can not replicate
1808 if (f != (in.get(*t) / nin)) {
1809 can_replicate = false;
1814 if (can_replicate && f > 0) {
1815 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1816 out.set (*t, outputs.get(*t) * f);
1819 return Match (Replicate, f);
1822 /* If the processor has exactly one input of a given type, and
1823 the plugin has more, we can feed the single processor input
1824 to some or all of the plugin inputs. This is rather
1825 special-case-y, but the 1-to-many case is by far the
1826 simplest. How do I split thy 2 processor inputs to 3
1827 plugin inputs? Let me count the ways ...
1830 bool can_split = true;
1831 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1833 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
1834 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1836 if (!can_split_type && !nothing_to_do_for_type) {
1842 out = outputs + midi_bypass;
1843 return Match (Split, 1);
1846 /* If the plugin has more inputs than we want, we can `hide' some of them
1847 by feeding them silence.
1850 bool could_hide = false;
1851 bool cannot_hide = false;
1852 ChanCount hide_channels;
1854 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1855 if (inputs.get(*t) > in.get(*t)) {
1856 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1857 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1859 } else if (inputs.get(*t) < in.get(*t)) {
1860 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1865 if (could_hide && !cannot_hide) {
1866 out = outputs + midi_bypass;
1867 return Match (Hide, 1, false, false, hide_channels);
1870 return Match (Impossible, 0);
1875 PluginInsert::get_state ()
1877 return state (true);
1881 PluginInsert::state (bool full)
1883 XMLNode& node = Processor::state (full);
1885 node.add_property("type", _plugins[0]->state_node_name());
1886 node.add_property("unique-id", _plugins[0]->unique_id());
1887 node.add_property("count", string_compose("%1", _plugins.size()));
1889 /* remember actual i/o configuration (for later placeholder
1890 * in case the plugin goes missing) */
1891 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1892 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1893 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
1895 /* save custom i/o config */
1896 node.add_property("custom", _custom_cfg ? "yes" : "no");
1897 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1899 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
1900 node.add_child_nocopy (* _in_map[pc].state (tmp));
1901 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
1902 node.add_child_nocopy (* _out_map[pc].state (tmp));
1904 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
1907 node.add_child_nocopy (_sidechain->state (full));
1910 _plugins[0]->set_insert_id(this->id());
1911 node.add_child_nocopy (_plugins[0]->get_state());
1913 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1914 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1916 node.add_child_nocopy (ac->get_state());
1924 PluginInsert::set_control_ids (const XMLNode& node, int version)
1926 const XMLNodeList& nlist = node.children();
1927 XMLNodeConstIterator iter;
1928 set<Evoral::Parameter>::const_iterator p;
1930 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1931 if ((*iter)->name() == Controllable::xml_node_name) {
1932 const XMLProperty* prop;
1934 uint32_t p = (uint32_t)-1;
1936 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1937 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1939 p = lv2plugin->port_index(prop->value().c_str());
1943 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1944 p = atoi (prop->value());
1947 if (p != (uint32_t)-1) {
1949 /* this may create the new controllable */
1951 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1953 #ifndef NO_PLUGIN_STATE
1957 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1959 ac->set_state (**iter, version);
1968 PluginInsert::set_state(const XMLNode& node, int version)
1970 XMLNodeList nlist = node.children();
1971 XMLNodeIterator niter;
1972 XMLPropertyList plist;
1973 const XMLProperty *prop;
1974 ARDOUR::PluginType type;
1976 if ((prop = node.property ("type")) == 0) {
1977 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1981 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1982 type = ARDOUR::LADSPA;
1983 } else if (prop->value() == X_("lv2")) {
1985 } else if (prop->value() == X_("windows-vst")) {
1986 type = ARDOUR::Windows_VST;
1987 } else if (prop->value() == X_("lxvst")) {
1988 type = ARDOUR::LXVST;
1989 } else if (prop->value() == X_("audiounit")) {
1990 type = ARDOUR::AudioUnit;
1991 } else if (prop->value() == X_("luaproc")) {
1994 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2000 prop = node.property ("unique-id");
2003 #ifdef WINDOWS_VST_SUPPORT
2004 /* older sessions contain VST plugins with only an "id" field.
2007 if (type == ARDOUR::Windows_VST) {
2008 prop = node.property ("id");
2012 #ifdef LXVST_SUPPORT
2013 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2015 if (type == ARDOUR::LXVST) {
2016 prop = node.property ("id");
2022 error << _("Plugin has no unique ID field") << endmsg;
2027 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2029 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2030 * allow to move sessions windows <> linux */
2031 #ifdef LXVST_SUPPORT
2032 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2033 type = ARDOUR::LXVST;
2034 plugin = find_plugin (_session, prop->value(), type);
2038 #ifdef WINDOWS_VST_SUPPORT
2039 if (plugin == 0 && type == ARDOUR::LXVST) {
2040 type = ARDOUR::Windows_VST;
2041 plugin = find_plugin (_session, prop->value(), type);
2046 error << string_compose(
2047 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2048 "Perhaps it was removed or moved since it was last used."),
2054 if (type == ARDOUR::Lua) {
2055 XMLNode *ls = node.child (plugin->state_node_name().c_str());
2056 // we need to load the script to set the name and parameters.
2057 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
2059 lp->set_script_from_state (*ls);
2063 // The name of the PluginInsert comes from the plugin, nothing else
2064 _name = plugin->get_info()->name;
2068 // Processor::set_state() will set this, but too late
2069 // for it to be available when setting up plugin
2070 // state. We can't call Processor::set_state() until
2071 // the plugins themselves are created and added.
2075 if (_plugins.empty()) {
2076 /* if we are adding the first plugin, we will need to set
2077 up automatable controls.
2079 add_plugin (plugin);
2080 create_automatable_parameters ();
2081 set_control_ids (node, version);
2084 if ((prop = node.property ("count")) != 0) {
2085 sscanf (prop->value().c_str(), "%u", &count);
2088 if (_plugins.size() != count) {
2089 for (uint32_t n = 1; n < count; ++n) {
2090 add_plugin (plugin_factory (plugin));
2094 Processor::set_state (node, version);
2096 PBD::ID new_id = this->id();
2097 PBD::ID old_id = this->id();
2099 if ((prop = node.property ("id")) != 0) {
2100 old_id = prop->value ();
2103 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2105 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2106 and set all plugins to the same state.
2109 if ((*niter)->name() == plugin->state_node_name()) {
2111 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2112 /* Plugin state can include external files which are named after the ID.
2114 * If regenerate_xml_or_string_ids() is set, the ID will already have
2115 * been changed, so we need to use the old ID from the XML to load the
2116 * state and then update the ID.
2118 * When copying a plugin-state, route_ui takes care of of updating the ID,
2119 * but we need to call set_insert_id() to clear the cached plugin-state
2120 * and force a change.
2122 if (!regenerate_xml_or_string_ids ()) {
2123 (*i)->set_insert_id (new_id);
2125 (*i)->set_insert_id (old_id);
2128 (*i)->set_state (**niter, version);
2130 if (regenerate_xml_or_string_ids ()) {
2131 (*i)->set_insert_id (new_id);
2139 if (version < 3000) {
2141 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2142 this is all handled by Automatable
2145 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2146 if ((*niter)->name() == "Redirect") {
2147 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2148 Processor::set_state (**niter, version);
2153 set_parameter_state_2X (node, version);
2156 if ((prop = node.property (X_("custom"))) != 0) {
2157 _custom_cfg = string_is_affirmative (prop->value());
2160 uint32_t in_maps = 0;
2161 uint32_t out_maps = 0;
2162 XMLNodeList kids = node.children ();
2163 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2164 if ((*i)->name() == X_("ConfiguredOutput")) {
2165 _custom_out = ChanCount(**i);
2167 if ((*i)->name() == X_("PresetOutput")) {
2168 _preset_out = ChanCount(**i);
2170 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2171 long pc = atol (&((*i)->name().c_str()[9]));
2172 if (pc >=0 && pc <= get_count()) {
2173 _in_map[pc] = ChanMapping (**i);
2177 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2178 long pc = atol (&((*i)->name().c_str()[10]));
2179 if (pc >=0 && pc <= get_count()) {
2180 _out_map[pc] = ChanMapping (**i);
2184 if ((*i)->name () == "ThruMap") {
2185 _thru_map = ChanMapping (**i);
2188 // sidechain is a Processor (IO)
2189 if ((*i)->name () == Processor::state_node_name) {
2193 _sidechain->set_state (**i, version);
2197 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2198 _maps_from_state = true;
2201 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2205 (*i)->deactivate ();
2209 PluginConfigChanged (); /* EMIT SIGNAL */
2214 PluginInsert::update_id (PBD::ID id)
2217 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2218 (*i)->set_insert_id (id);
2223 PluginInsert::set_state_dir (const std::string& d)
2225 // state() only saves the state of the first plugin
2226 _plugins[0]->set_state_dir (d);
2230 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2232 XMLNodeList nlist = node.children();
2233 XMLNodeIterator niter;
2235 /* look for port automation node */
2237 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2239 if ((*niter)->name() != port_automation_node_name) {
2245 XMLNodeConstIterator iter;
2250 cnodes = (*niter)->children ("port");
2252 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2256 if ((cprop = child->property("number")) != 0) {
2257 port = cprop->value().c_str();
2259 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2263 sscanf (port, "%" PRIu32, &port_id);
2265 if (port_id >= _plugins[0]->parameter_count()) {
2266 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2270 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2271 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2273 if (c && c->alist()) {
2274 if (!child->children().empty()) {
2275 c->alist()->set_state (*child->children().front(), version);
2277 /* In some cases 2.X saves lists with min_yval and max_yval
2278 being FLT_MIN and FLT_MAX respectively. This causes problems
2279 in A3 because these min/max values are used to compute
2280 where GUI control points should be drawn. If we see such
2281 values, `correct' them to the min/max of the appropriate
2285 float min_y = c->alist()->get_min_y ();
2286 float max_y = c->alist()->get_max_y ();
2288 ParameterDescriptor desc;
2289 _plugins.front()->get_parameter_descriptor (port_id, desc);
2291 if (min_y == FLT_MIN) {
2295 if (max_y == FLT_MAX) {
2299 c->alist()->set_yrange (min_y, max_y);
2302 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2314 PluginInsert::describe_parameter (Evoral::Parameter param)
2316 if (param.type() == PluginAutomation) {
2317 return _plugins[0]->describe_parameter (param);
2318 } else if (param.type() == PluginPropertyAutomation) {
2319 boost::shared_ptr<AutomationControl> c(automation_control(param));
2320 if (c && !c->desc().label.empty()) {
2321 return c->desc().label;
2324 return Automatable::describe_parameter(param);
2328 PluginInsert::signal_latency() const
2330 if (_user_latency) {
2331 return _user_latency;
2334 return _plugins[0]->signal_latency ();
2338 PluginInsert::type ()
2340 return plugin()->get_info()->type;
2343 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2344 const Evoral::Parameter& param,
2345 const ParameterDescriptor& desc,
2346 boost::shared_ptr<AutomationList> list)
2347 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2351 alist()->reset_default (desc.normal);
2353 list->set_interpolation(Evoral::ControlList::Discrete);
2358 set_flags(Controllable::Toggle);
2362 /** @param val `user' value */
2364 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2367 _set_value (user_val, group_override);
2371 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2373 /* used only by automation playback */
2374 _set_value (user_val, Controllable::NoGroup);
2378 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2380 /* FIXME: probably should be taking out some lock here.. */
2382 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2383 (*i)->set_parameter (_list->parameter().id(), user_val);
2386 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2388 iasp->set_parameter (_list->parameter().id(), user_val);
2391 AutomationControl::set_value (user_val, group_override);
2395 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2397 AutomationControl::set_value (user_val, Controllable::NoGroup);
2401 PluginInsert::PluginControl::get_state ()
2405 XMLNode& node (AutomationControl::get_state());
2406 ss << parameter().id();
2407 node.add_property (X_("parameter"), ss.str());
2409 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2411 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2418 /** @return `user' val */
2420 PluginInsert::PluginControl::get_value () const
2422 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2428 return plugin->get_parameter (_list->parameter().id());
2431 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2432 const Evoral::Parameter& param,
2433 const ParameterDescriptor& desc,
2434 boost::shared_ptr<AutomationList> list)
2435 : AutomationControl (p->session(), param, desc, list)
2439 alist()->set_yrange (desc.lower, desc.upper);
2440 alist()->reset_default (desc.normal);
2444 set_flags(Controllable::Toggle);
2449 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2452 set_value_unchecked (user_val);
2457 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2459 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2460 This is lossy, but better than nothing until Ardour's automation system
2461 can handle various datatypes all the way down. */
2462 const Variant value(_desc.datatype, user_val);
2463 if (value.type() == Variant::NOTHING) {
2464 error << "set_value(double) called for non-numeric property" << endmsg;
2468 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2469 (*i)->set_property(_list->parameter().id(), value);
2473 AutomationControl::set_value (user_val, Controllable::NoGroup);
2477 PluginInsert::PluginPropertyControl::get_state ()
2481 XMLNode& node (AutomationControl::get_state());
2482 ss << parameter().id();
2483 node.add_property (X_("property"), ss.str());
2484 node.remove_property (X_("value"));
2490 PluginInsert::PluginPropertyControl::get_value () const
2492 return _value.to_double();
2495 boost::shared_ptr<Plugin>
2496 PluginInsert::get_impulse_analysis_plugin()
2498 boost::shared_ptr<Plugin> ret;
2499 if (_impulseAnalysisPlugin.expired()) {
2500 ret = plugin_factory(_plugins[0]);
2501 ret->configure_io (internal_input_streams (), internal_output_streams ());
2502 _impulseAnalysisPlugin = ret;
2504 ret = _impulseAnalysisPlugin.lock();
2511 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2513 // called from outside the audio thread, so this should be safe
2514 // only do audio as analysis is (currently) only for audio plugins
2515 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2516 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2518 _signal_analysis_collected_nframes = 0;
2519 _signal_analysis_collect_nframes_max = nframes;
2522 /** Add a plugin to our list */
2524 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2526 plugin->set_insert_id (this->id());
2528 if (_plugins.empty()) {
2529 /* first (and probably only) plugin instance - connect to relevant signals */
2531 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2532 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2533 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2534 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2535 // cache sidechain port count
2536 _cached_sidechain_pins.reset ();
2537 const ChanCount& nis (plugin->get_info()->n_inputs);
2538 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2539 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2540 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2541 if (iod.is_sidechain) {
2542 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2547 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2548 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2550 vst->set_insert (this, _plugins.size ());
2553 _plugins.push_back (plugin);
2557 PluginInsert::realtime_handle_transport_stopped ()
2559 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2560 (*i)->realtime_handle_transport_stopped ();
2565 PluginInsert::realtime_locate ()
2567 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2568 (*i)->realtime_locate ();
2573 PluginInsert::monitoring_changed ()
2575 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2576 (*i)->monitoring_changed ();
2581 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2583 // this is called in RT context, LatencyChanged is emitted after run()
2584 _latency_changed = true;
2588 PluginInsert::start_touch (uint32_t param_id)
2590 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2592 ac->start_touch (session().audible_frame());
2597 PluginInsert::end_touch (uint32_t param_id)
2599 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2601 ac->stop_touch (true, session().audible_frame());
2605 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2608 case PluginInsert::Impossible: o << "Impossible"; break;
2609 case PluginInsert::Delegate: o << "Delegate"; break;
2610 case PluginInsert::NoInputs: o << "NoInputs"; break;
2611 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2612 case PluginInsert::Replicate: o << "Replicate"; break;
2613 case PluginInsert::Split: o << "Split"; break;
2614 case PluginInsert::Hide: o << "Hide"; break;
2616 o << " cnt: " << m.plugins
2617 << (m.strict_io ? " strict-io" : "")
2618 << (m.custom_cfg ? " custom-cfg" : "");
2619 if (m.method == PluginInsert::Hide) {
2620 o << " hide: " << m.hide;