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"
39 #include "ardour/port.h"
42 #include "ardour/lv2_plugin.h"
45 #ifdef WINDOWS_VST_SUPPORT
46 #include "ardour/windows_vst_plugin.h"
50 #include "ardour/lxvst_plugin.h"
53 #ifdef AUDIOUNIT_SUPPORT
54 #include "ardour/audio_unit.h"
57 #include "ardour/session.h"
58 #include "ardour/types.h"
63 using namespace ARDOUR;
66 const string PluginInsert::port_automation_node_name = "PortAutomation";
68 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
69 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
70 , _signal_analysis_collected_nframes(0)
71 , _signal_analysis_collect_nframes_max(0)
76 , _maps_from_state (false)
78 /* the first is the master */
82 create_automatable_parameters ();
83 const ChanCount& sc (sidechain_input_pins ());
84 if (sc.n_audio () > 0) {
85 add_sidechain (sc.n_audio ());
90 PluginInsert::~PluginInsert ()
95 PluginInsert::set_strict_io (bool b)
97 bool changed = _strict_io != b;
100 PluginConfigChanged (); /* EMIT SIGNAL */
105 PluginInsert::set_count (uint32_t num)
107 bool require_state = !_plugins.empty();
109 /* this is a bad idea.... we shouldn't do this while active.
110 only a route holding their redirect_lock should be calling this
115 } else if (num > _plugins.size()) {
116 uint32_t diff = num - _plugins.size();
118 for (uint32_t n = 0; n < diff; ++n) {
119 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
123 XMLNode& state = _plugins[0]->get_state ();
124 p->set_state (state, Stateful::loading_state_version);
131 PluginConfigChanged (); /* EMIT SIGNAL */
133 } else if (num < _plugins.size()) {
134 uint32_t diff = _plugins.size() - num;
135 for (uint32_t n= 0; n < diff; ++n) {
138 PluginConfigChanged (); /* EMIT SIGNAL */
146 PluginInsert::set_outputs (const ChanCount& c)
148 bool changed = (_custom_out != c) && _custom_cfg;
151 PluginConfigChanged (); /* EMIT SIGNAL */
156 PluginInsert::set_custom_cfg (bool b)
158 bool changed = _custom_cfg != b;
161 PluginConfigChanged (); /* EMIT SIGNAL */
166 PluginInsert::set_preset_out (const ChanCount& c)
168 bool changed = _preset_out != c;
170 if (changed && !_custom_cfg) {
171 PluginConfigChanged (); /* EMIT SIGNAL */
177 PluginInsert::add_sidechain (uint32_t n_audio)
179 // caller must hold process lock
183 std::ostringstream n;
185 n << "Sidechain " << Session::next_name_id ();
187 n << "TO BE RESET FROM XML";
189 SideChain *sc = new SideChain (_session, n.str ());
190 _sidechain = boost::shared_ptr<SideChain> (sc);
191 _sidechain->activate ();
192 for (uint32_t n = 0; n < n_audio; ++n) {
193 _sidechain->input()->add_port ("", owner()); // add a port, don't connect.
195 PluginConfigChanged (); /* EMIT SIGNAL */
200 PluginInsert::del_sidechain ()
206 PluginConfigChanged (); /* EMIT SIGNAL */
211 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
213 if (which.type() != PluginAutomation)
216 boost::shared_ptr<AutomationControl> c
217 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
220 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
225 PluginInsert::output_streams() const
227 assert (_configured);
228 return _configured_out;
232 PluginInsert::input_streams() const
234 assert (_configured);
235 return _configured_in;
239 PluginInsert::internal_streams() const
241 assert (_configured);
242 return _configured_internal;
246 PluginInsert::internal_output_streams() const
248 assert (!_plugins.empty());
250 PluginInfoPtr info = _plugins.front()->get_info();
252 if (info->reconfigurable_io()) {
253 ChanCount out = _plugins.front()->output_streams ();
254 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
257 ChanCount out = info->n_outputs;
258 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
259 out.set_audio (out.n_audio() * _plugins.size());
260 out.set_midi (out.n_midi() * _plugins.size());
266 PluginInsert::internal_input_streams() const
268 assert (!_plugins.empty());
272 PluginInfoPtr info = _plugins.front()->get_info();
274 if (info->reconfigurable_io()) {
275 in = _plugins.front()->input_streams();
280 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
282 if (_match.method == Split) {
284 /* we are splitting 1 processor input to multiple plugin inputs,
285 so we have a maximum of 1 stream of each type.
287 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
288 if (in.get (*t) > 1) {
294 } else if (_match.method == Hide) {
296 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
297 in.set (*t, in.get (*t) - _match.hide.get (*t));
303 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
304 in.set (*t, in.get (*t) * _plugins.size ());
312 PluginInsert::natural_output_streams() const
315 if (is_channelstrip ()) {
316 return _configured_out;
319 return _plugins[0]->get_info()->n_outputs;
323 PluginInsert::natural_input_streams() const
326 if (is_channelstrip ()) {
327 return _configured_in;
330 return _plugins[0]->get_info()->n_inputs;
334 PluginInsert::sidechain_input_pins() const
336 return _cached_sidechain_pins;
340 PluginInsert::has_no_inputs() const
342 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
346 PluginInsert::has_no_audio_inputs() const
348 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
352 PluginInsert::plugin_latency () const {
353 return _plugins.front()->signal_latency ();
357 PluginInsert::needs_midi_input() const
359 PluginInfoPtr pip = _plugins[0]->get_info();
360 if (pip->needs_midi_input ()) {
363 return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
367 PluginInsert::create_automatable_parameters ()
369 assert (!_plugins.empty());
371 set<Evoral::Parameter> a = _plugins.front()->automatable ();
373 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
374 if (i->type() == PluginAutomation) {
376 Evoral::Parameter param(*i);
378 ParameterDescriptor desc;
379 _plugins.front()->get_parameter_descriptor(i->id(), desc);
381 can_automate (param);
382 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
383 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
385 _plugins.front()->set_automation_control (i->id(), c);
386 } else if (i->type() == PluginPropertyAutomation) {
387 Evoral::Parameter param(*i);
388 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
389 if (desc.datatype != Variant::NOTHING) {
390 boost::shared_ptr<AutomationList> list;
391 if (Variant::type_is_numeric(desc.datatype)) {
392 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
394 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
399 /** Called when something outside of this host has modified a plugin
400 * parameter. Responsible for propagating the change to two places:
402 * 1) anything listening to the Control itself
403 * 2) any replicated plugins that make up this PluginInsert.
405 * The PluginInsert is connected to the ParameterChangedExternally signal for
406 * the first (primary) plugin, and here broadcasts that change to any others.
408 * XXX We should probably drop this whole replication idea (Paul, October 2015)
409 * since it isn't used by sensible plugin APIs (AU, LV2).
412 PluginInsert::parameter_changed_externally (uint32_t which, float val)
414 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
416 /* First propagation: alter the underlying value of the control,
417 * without telling the plugin(s) that own/use it to set it.
424 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
427 pc->catch_up_with_external_value (val);
430 /* Second propagation: tell all plugins except the first to
431 update the value of this parameter. For sane plugin APIs,
432 there are no other plugins, so this is a no-op in those
436 Plugins::iterator i = _plugins.begin();
438 /* don't set the first plugin, just all the slaves */
440 if (i != _plugins.end()) {
442 for (; i != _plugins.end(); ++i) {
443 (*i)->set_parameter (which, val);
449 PluginInsert::set_block_size (pframes_t nframes)
452 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
453 if ((*i)->set_block_size (nframes) != 0) {
461 PluginInsert::activate ()
463 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
467 Processor::activate ();
471 PluginInsert::deactivate ()
473 Processor::deactivate ();
475 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
481 PluginInsert::flush ()
483 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
489 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
491 // TODO: atomically copy maps & _no_inplace
492 PinMappings in_map (_in_map);
493 PinMappings out_map (_out_map);
494 ChanMapping thru_map (_thru_map);
495 if (_mapping_changed) { // ToDo use a counters, increment until match.
496 _no_inplace = check_inplace ();
497 _mapping_changed = false;
500 if (_latency_changed) {
501 /* delaylines are configured with the max possible latency (as reported by the plugin)
502 * so this won't allocate memory (unless the plugin lied about its max latency)
503 * It may still 'click' though, since the fixed delaylines are not de-clicked.
504 * Then again plugin-latency changes are not click-free to begin with.
506 * This is also worst case, there is currently no concept of per-stream latency.
508 * e.g. Two identical latent plugins:
509 * 1st plugin: process left (latent), bypass right.
510 * 2nd plugin: bypass left, process right (latent).
511 * -> currently this yields 2 times latency of the plugin,
513 _latency_changed = false;
514 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
517 if (_match.method == Split && !_no_inplace) {
518 // TODO: also use this optimization if one source-buffer
519 // feeds _all_ *connected* inputs.
520 // currently this is *first* buffer to all only --
521 // see PluginInsert::check_inplace
522 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
523 if (_configured_internal.get (*t) == 0) {
527 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
528 assert (valid && first_idx == 0); // check_inplace ensures this
529 /* copy the first stream's buffer contents to the others */
530 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
531 uint32_t idx = in_map[0].get (*t, i, &valid);
534 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
538 /* the copy operation produces a linear monotonic input map */
539 in_map[0] = ChanMapping (natural_input_streams ());
542 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
543 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
549 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
551 boost::shared_ptr<AutomationControl> c
552 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
554 if (c->list() && c->automation_playback()) {
557 const float val = c->list()->rt_safe_eval (now, valid);
560 /* This is the ONLY place where we are
562 * AutomationControl::set_value_unchecked(). We
563 * know that the control is in
564 * automation playback mode, so no
565 * check on writable() is required
566 * (which must be done in AutomationControl::set_value()
569 c->set_value_unchecked(val);
576 /* Calculate if, and how many frames we need to collect for analysis */
577 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
578 _signal_analysis_collected_nframes);
579 if (nframes < collect_signal_nframes) { // we might not get all frames now
580 collect_signal_nframes = nframes;
583 if (collect_signal_nframes > 0) {
585 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
586 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
587 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
589 _signal_analysis_inputs.set_count(internal_input_streams());
591 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
592 _signal_analysis_inputs.get_audio(i).read_from(
594 collect_signal_nframes,
595 _signal_analysis_collected_nframes); // offset is for target buffer
600 if (is_channelstrip ()) {
601 if (_configured_in.n_audio() > 0) {
602 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
603 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
605 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
607 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
608 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
614 // TODO optimize -- build maps once.
616 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
617 ARDOUR::ChanMapping used_outputs;
619 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
621 /* build used-output map */
622 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
623 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
624 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
626 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
628 used_outputs.set (*t, out_idx, 1); // mark as used
633 /* copy thru data to outputs before processing in-place */
634 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
635 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
637 uint32_t in_idx = thru_map.get (*t, out, &valid);
639 uint32_t m = out + natural_input_streams ().get (*t);
640 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
641 used_outputs.set (*t, out, 1); // mark as used
647 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
649 ARDOUR::ChanMapping i_in_map (natural_input_streams());
650 ARDOUR::ChanMapping i_out_map (out_map[pc]);
651 ARDOUR::ChanCount mapped;
653 /* map inputs sequentially */
654 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
655 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
657 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
658 uint32_t m = mapped.get (*t);
660 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
662 inplace_bufs.get (*t, m).silence (nframes, offset);
664 mapped.set (*t, m + 1);
668 /* outputs are mapped to inplace_bufs after the inputs */
669 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
670 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
673 if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
678 /* all instances have completed, now copy data that was written
679 * and zero unconnected buffers */
680 ARDOUR::ChanMapping nonzero_out (used_outputs);
681 if (has_midi_bypass ()) {
682 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
684 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
685 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
687 used_outputs.get (*t, out, &valid);
689 nonzero_out.get (*t, out, &valid);
691 bufs.get (*t, out).silence (nframes, offset);
694 uint32_t m = out + natural_input_streams ().get (*t);
695 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
700 /* in-place processing */
702 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
703 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
708 // TODO optimize: store "unconnected" in a fixed set.
709 // it only changes on reconfiguration.
710 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
711 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
713 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
714 mapped = true; // in-place Midi bypass
716 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
717 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
719 uint32_t idx = out_map[pc].get (*t, o, &valid);
720 if (valid && idx == out) {
727 bufs.get (*t, out).silence (nframes, offset);
733 if (collect_signal_nframes > 0) {
735 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
736 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
738 _signal_analysis_outputs.set_count(internal_output_streams());
740 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
741 _signal_analysis_outputs.get_audio(i).read_from(
743 collect_signal_nframes,
744 _signal_analysis_collected_nframes); // offset is for target buffer
747 _signal_analysis_collected_nframes += collect_signal_nframes;
748 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
750 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
751 _signal_analysis_collect_nframes_max = 0;
752 _signal_analysis_collected_nframes = 0;
754 AnalysisDataGathered(&_signal_analysis_inputs,
755 &_signal_analysis_outputs);
761 PluginInsert::silence (framecnt_t nframes)
767 _delaybuffers.flush ();
770 if (is_channelstrip ()) {
771 if (_configured_in.n_audio() > 0) {
772 ChanCount maxbuf = ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
773 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
774 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
775 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), mb_in_map, mb_out_map, nframes, 0);
780 ChanMapping in_map (natural_input_streams ());
781 ChanMapping out_map (natural_output_streams ());
782 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
783 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
784 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
790 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
792 if (_pending_active) {
793 /* run as normal if we are active or moving from inactive to active */
796 // collect sidechain input for complete cycle (!)
797 // TODO we need delaylines here for latency compensation
798 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
801 if (_session.transport_rolling() || _session.bounce_processing()) {
802 automation_run (bufs, start_frame, nframes);
804 connect_and_run (bufs, nframes, 0, false);
808 // TODO use mapping in bypassed mode ?!
809 // -> do we bypass the processor or the plugin
811 // TODO include sidechain??
813 uint32_t in = input_streams ().n_audio ();
814 uint32_t out = output_streams().n_audio ();
816 if (has_no_audio_inputs() || in == 0) {
818 /* silence all (audio) outputs. Should really declick
819 * at the transitions of "active"
822 for (uint32_t n = 0; n < out; ++n) {
823 bufs.get_audio (n).silence (nframes);
826 } else if (out > in) {
828 /* not active, but something has make up for any channel count increase
829 * for now , simply replicate last buffer
831 for (uint32_t n = in; n < out; ++n) {
832 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
836 bufs.count().set_audio (out);
839 _active = _pending_active;
841 /* we have no idea whether the plugin generated silence or not, so mark
842 * all buffers appropriately.
847 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
849 Evoral::ControlEvent next_event (0, 0.0f);
850 framepos_t now = start;
851 framepos_t end = now + nframes;
852 framecnt_t offset = 0;
854 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
857 connect_and_run (bufs, nframes, offset, false);
861 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
863 /* no events have a time within the relevant range */
865 connect_and_run (bufs, nframes, offset, true, now);
871 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
873 connect_and_run (bufs, cnt, offset, true, now);
879 if (!find_next_event (now, end, next_event)) {
884 /* cleanup anything that is left to do */
887 connect_and_run (bufs, nframes, offset, true, now);
892 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
894 if (param.type() != PluginAutomation)
897 if (_plugins.empty()) {
898 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
900 abort(); /*NOTREACHED*/
903 return _plugins[0]->default_value (param.id());
908 PluginInsert::can_reset_all_parameters ()
912 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
914 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
916 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
920 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
926 if (ac->automation_state() & Play) {
931 return all && (params > 0);
935 PluginInsert::reset_parameters_to_default ()
939 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
941 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
943 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
947 const float dflt = _plugins[0]->default_value (cid);
948 const float curr = _plugins[0]->get_parameter (cid);
954 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
959 if (ac->automation_state() & Play) {
964 ac->set_value (dflt, Controllable::NoGroup);
969 boost::shared_ptr<Plugin>
970 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
972 boost::shared_ptr<LadspaPlugin> lp;
973 boost::shared_ptr<LuaProc> lua;
975 boost::shared_ptr<LV2Plugin> lv2p;
977 #ifdef WINDOWS_VST_SUPPORT
978 boost::shared_ptr<WindowsVSTPlugin> vp;
981 boost::shared_ptr<LXVSTPlugin> lxvp;
983 #ifdef AUDIOUNIT_SUPPORT
984 boost::shared_ptr<AUPlugin> ap;
987 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
988 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
989 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
990 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
992 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
993 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
995 #ifdef WINDOWS_VST_SUPPORT
996 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
997 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1000 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1001 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1003 #ifdef AUDIOUNIT_SUPPORT
1004 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1005 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1009 fatal << string_compose (_("programming error: %1"),
1010 X_("unknown plugin type in PluginInsert::plugin_factory"))
1012 abort(); /*NOTREACHED*/
1013 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1017 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1018 if (num < _in_map.size()) {
1019 bool changed = _in_map[num] != m;
1021 changed |= sanitize_maps ();
1023 PluginMapChanged (); /* EMIT SIGNAL */
1024 _mapping_changed = true;
1025 _session.set_dirty();
1031 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1032 if (num < _out_map.size()) {
1033 bool changed = _out_map[num] != m;
1035 changed |= sanitize_maps ();
1037 PluginMapChanged (); /* EMIT SIGNAL */
1038 _mapping_changed = true;
1039 _session.set_dirty();
1045 PluginInsert::set_thru_map (ChanMapping m) {
1046 bool changed = _thru_map != m;
1048 changed |= sanitize_maps ();
1050 PluginMapChanged (); /* EMIT SIGNAL */
1051 _mapping_changed = true;
1052 _session.set_dirty();
1057 PluginInsert::input_map () const
1061 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1062 ChanMapping m (i->second);
1063 const ChanMapping::Mappings& mp ((*i).second.mappings());
1064 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1065 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1066 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1074 PluginInsert::output_map () const
1078 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1079 ChanMapping m (i->second);
1080 const ChanMapping::Mappings& mp ((*i).second.mappings());
1081 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1082 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1083 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1087 if (has_midi_bypass ()) {
1088 rv.set (DataType::MIDI, 0, 0);
1095 PluginInsert::has_midi_bypass () const
1097 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1098 && natural_output_streams ().n_midi () == 0) {
1105 PluginInsert::has_midi_thru () const
1107 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1108 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1116 PluginInsert::is_channelstrip () const {
1117 return _plugins.front()->is_channelstrip();
1122 PluginInsert::check_inplace ()
1124 bool inplace_ok = !_plugins.front()->inplace_broken ();
1126 if (_thru_map.n_total () > 0) {
1127 // TODO once midi-bypass is part of the mapping, ignore it
1131 if (_match.method == Split && inplace_ok) {
1132 assert (get_count() == 1);
1133 assert (_in_map.size () == 1);
1134 if (!_out_map[0].is_monotonic ()) {
1137 if (_configured_internal != _configured_in) {
1138 /* no sidechain -- TODO we could allow this with
1139 * some more logic in PluginInsert::connect_and_run().
1141 * PluginInsert::reset_map() already maps it.
1146 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1147 if (_configured_internal.get (*t) == 0) {
1151 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1152 if (!valid || first_idx != 0) {
1153 // so far only allow to copy the *first* stream's buffer to others
1156 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1157 uint32_t idx = _in_map[0].get (*t, i, &valid);
1158 if (valid && idx != first_idx) {
1167 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1172 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1173 if (!_in_map[pc].is_monotonic ()) {
1176 if (!_out_map[pc].is_monotonic ()) {
1180 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1181 return !inplace_ok; // no-inplace
1185 PluginInsert::sanitize_maps ()
1187 bool changed = false;
1188 /* strip dead wood */
1189 PinMappings new_ins;
1190 PinMappings new_outs;
1191 ChanMapping new_thru;
1193 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1195 ChanMapping new_out;
1196 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1197 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1199 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1200 if (valid && idx < _configured_internal.get (*t)) {
1201 new_in.set (*t, i, idx);
1204 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1206 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1207 if (valid && idx < _configured_out.get (*t)) {
1208 new_out.set (*t, o, idx);
1212 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1215 new_ins[pc] = new_in;
1216 new_outs[pc] = new_out;
1219 /* prevent dup output assignments */
1220 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1221 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1222 bool mapped = false;
1223 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1225 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1226 if (valid && mapped) {
1227 new_outs[pc].unset (*t, idx);
1235 /* remove excess thru */
1236 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1237 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1239 uint32_t idx = _thru_map.get (*t, o, &valid);
1240 if (valid && idx < _configured_internal.get (*t)) {
1241 new_thru.set (*t, o, idx);
1246 /* prevent out + thru, existing plugin outputs override thru */
1247 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1248 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1249 bool mapped = false;
1251 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1252 new_outs[pc].get_src (*t, o, &mapped);
1253 if (mapped) { break; }
1255 if (!mapped) { continue; }
1256 uint32_t idx = new_thru.get (*t, o, &valid);
1258 new_thru.unset (*t, idx);
1263 if (has_midi_bypass ()) {
1264 // TODO: include midi-bypass in the thru set,
1265 // remove dedicated handling.
1266 new_thru.unset (DataType::MIDI, 0);
1269 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1273 _out_map = new_outs;
1274 _thru_map = new_thru;
1280 PluginInsert::reset_map (bool emit)
1282 const PinMappings old_in (_in_map);
1283 const PinMappings old_out (_out_map);
1287 _thru_map = ChanMapping ();
1289 /* build input map */
1290 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1291 uint32_t sc = 0; // side-chain round-robin (all instances)
1293 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1294 const uint32_t nis = natural_input_streams ().get(*t);
1295 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1297 /* SC inputs are last in the plugin-insert.. */
1298 const uint32_t sc_start = _configured_in.get (*t);
1299 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1300 /* ...but may not be at the end of the plugin ports.
1301 * in case the side-chain is not the last port, shift connections back.
1302 * and connect to side-chain
1305 uint32_t ic = 0; // split inputs
1306 const uint32_t cend = _configured_in.get (*t);
1308 for (uint32_t in = 0; in < nis; ++in) {
1309 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1310 if (iod.is_sidechain) {
1311 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1312 if (sc_len > 0) {// side-chain may be hidden
1313 _in_map[pc].set (*t, in, sc_start + sc);
1314 sc = (sc + 1) % sc_len;
1318 if (_match.method == Split) {
1319 if (cend == 0) { continue; }
1320 if (_strict_io && ic + stride * pc >= cend) {
1323 /* connect *no* sidechain sinks in round-robin fashion */
1324 _in_map[pc].set (*t, in, ic + stride * pc);
1325 if (_strict_io && (ic + 1) == cend) {
1328 ic = (ic + 1) % cend;
1330 uint32_t s = in - shift;
1331 if (stride * pc + s < cend) {
1332 _in_map[pc].set (*t, in, s + stride * pc);
1340 /* build output map */
1342 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1343 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1344 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1345 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1350 if (old_in == _in_map && old_out == _out_map) {
1354 PluginMapChanged (); /* EMIT SIGNAL */
1355 _mapping_changed = true;
1356 _session.set_dirty();
1362 PluginInsert::configure_io (ChanCount in, ChanCount out)
1364 Match old_match = _match;
1366 ChanCount old_internal;
1370 old_in = _configured_in;
1371 old_internal = _configured_internal;
1372 old_out = _configured_out;
1375 _configured_in = in;
1376 _configured_internal = in;
1377 _configured_out = out;
1380 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1381 * (currently _sidechain->configure_io always succeeds
1382 * since Processor::configure_io() succeeds)
1384 if (!_sidechain->configure_io (in, out)) {
1385 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1388 _configured_internal += _sidechain->input()->n_ports();
1390 // include (static_cast<Route*>owner())->name() ??
1391 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1394 /* get plugin configuration */
1395 _match = private_can_support_io_configuration (in, out);
1397 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1399 DEBUG_STR_APPEND(a, string_compose ("Match '%1': ", name()));
1400 DEBUG_STR_APPEND(a, _match);
1401 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1405 /* set the matching method and number of plugins that we will use to meet this configuration */
1406 if (set_count (_match.plugins) == false) {
1407 PluginIoReConfigure (); /* EMIT SIGNAL */
1408 _configured = false;
1412 /* configure plugins */
1413 switch (_match.method) {
1416 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1417 PluginIoReConfigure (); /* EMIT SIGNAL */
1418 _configured = false;
1424 ChanCount dout (in); // hint
1427 } else if (_preset_out.n_audio () > 0) {
1428 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1429 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1430 dout.set (DataType::AUDIO, 2);
1432 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1434 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
1436 if (useins.n_audio() == 0) {
1439 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("Delegate configuration: %1 %2 %3\n", name(), useins, dout));
1441 if (_plugins.front()->configure_io (useins, dout) == false) {
1442 PluginIoReConfigure (); /* EMIT SIGNAL */
1443 _configured = false;
1449 if (_plugins.front()->configure_io (in, out) == false) {
1450 PluginIoReConfigure (); /* EMIT SIGNAL */
1451 _configured = false;
1457 bool mapping_changed = false;
1458 if (old_in == in && old_out == out
1460 && old_match.method == _match.method
1461 && _in_map.size() == _out_map.size()
1462 && _in_map.size() == get_count ()
1464 assert (_maps_from_state == false);
1465 /* If the configuration has not changed, keep the mapping */
1466 if (old_internal != _configured_internal) {
1467 mapping_changed = sanitize_maps ();
1469 } else if (_match.custom_cfg && _configured) {
1470 assert (_maps_from_state == false);
1471 mapping_changed = sanitize_maps ();
1474 if (is_channelstrip ()) { _maps_from_state = false; }
1476 if (_maps_from_state) {
1477 _maps_from_state = false;
1478 mapping_changed = true;
1481 /* generate a new mapping */
1482 mapping_changed = reset_map (false);
1486 if (mapping_changed) {
1487 PluginMapChanged (); /* EMIT SIGNAL */
1490 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1493 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1494 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1496 DEBUG_STR_APPEND(a, "----><----\n");
1498 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1499 DEBUG_STR_APPEND(a, " * Inputs:\n");
1500 DEBUG_STR_APPEND(a, _in_map[pc]);
1501 DEBUG_STR_APPEND(a, " * Outputs:\n");
1502 DEBUG_STR_APPEND(a, _out_map[pc]);
1504 DEBUG_STR_APPEND(a, " * Thru:\n");
1505 DEBUG_STR_APPEND(a, _thru_map);
1506 DEBUG_STR_APPEND(a, "-------->>--------\n");
1507 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1512 _no_inplace = check_inplace ();
1513 _mapping_changed = false;
1515 /* only the "noinplace_buffers" thread buffers need to be this large,
1516 * this can be optimized. other buffers are fine with
1517 * ChanCount::max (natural_input_streams (), natural_output_streams())
1518 * and route.cc's max (configured_in, configured_out)
1520 * no-inplace copies "thru" outputs (to emulate in-place) for
1521 * all outputs (to prevent overwrite) into a temporary space
1522 * which also holds input buffers (in case the plugin does process
1523 * in-place and overwrites those).
1525 * this buffers need to be at least as
1526 * natural_input_streams () + possible outputs.
1528 * sidechain inputs add a constraint on the input:
1529 * configured input + sidechain (=_configured_internal)
1531 _required_buffers =ChanCount::max (_configured_internal,
1532 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1534 if (old_in != in || old_out != out || old_internal != _configured_internal
1535 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1537 PluginIoReConfigure (); /* EMIT SIGNAL */
1540 _delaybuffers.configure (_configured_out, _plugins.front()->max_latency ());
1541 _latency_changed = true;
1543 // we don't know the analysis window size, so we must work with the
1544 // current buffer size here. each request for data fills in these
1545 // buffers and the analyser makes sure it gets enough data for the
1547 session().ensure_buffer_set (_signal_analysis_inputs, in);
1548 //_signal_analysis_inputs.set_count (in);
1550 session().ensure_buffer_set (_signal_analysis_outputs, out);
1551 //_signal_analysis_outputs.set_count (out);
1553 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1556 return Processor::configure_io (in, out);
1559 /** Decide whether this PluginInsert can support a given IO configuration.
1560 * To do this, we run through a set of possible solutions in rough order of
1563 * @param in Required input channel count.
1564 * @param out Filled in with the output channel count if we return true.
1565 * @return true if the given IO configuration can be supported.
1568 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1571 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1573 return private_can_support_io_configuration (in, out).method != Impossible;
1577 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1579 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1580 // preseed hint (for variable i/o)
1581 out.set (DataType::AUDIO, _preset_out.n_audio ());
1584 Match rv = internal_can_support_io_configuration (in, out);
1586 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1587 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("using output preset: %1 %2\n", name(), _preset_out));
1588 out.set (DataType::AUDIO, _preset_out.n_audio ());
1593 /** A private version of can_support_io_configuration which returns the method
1594 * by which the configuration can be matched, rather than just whether or not
1598 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1600 if (_plugins.empty()) {
1605 if (is_channelstrip ()) {
1607 return Match (ExactMatch, 1);
1611 /* if a user specified a custom cfg, so be it. */
1613 PluginInfoPtr info = _plugins.front()->get_info();
1615 if (info->reconfigurable_io()) {
1616 return Match (Delegate, get_count(), _strict_io, true);
1618 return Match (ExactMatch, get_count(), _strict_io, true);
1622 /* try automatic configuration */
1623 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1625 PluginInfoPtr info = _plugins.front()->get_info();
1626 ChanCount inputs = info->n_inputs;
1627 ChanCount outputs = info->n_outputs;
1629 /* handle case strict-i/o */
1630 if (_strict_io && m.method != Impossible) {
1633 /* special case MIDI instruments */
1634 if (needs_midi_input ()) {
1635 // output = midi-bypass + at most master-out channels.
1636 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1637 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1638 out = ChanCount::min (out, max_out);
1639 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o instrument: %1\n", name()));
1645 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1646 /* replicate processor to match output count (generators and such)
1647 * at least enough to feed every output port. */
1648 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1649 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1650 uint32_t nout = outputs.get (*t);
1651 if (nout == 0 || inx.get(*t) == 0) { continue; }
1652 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1655 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o generator: %1\n", name()));
1656 return Match (Replicate, f, _strict_io);
1667 if (m.method != Impossible) {
1671 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1673 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("resolving 'Impossible' match for %1\n", name()));
1675 if (info->reconfigurable_io()) {
1678 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1679 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1680 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1682 // houston, we have a problem.
1683 return Match (Impossible, 0);
1685 return Match (Delegate, 1, _strict_io);
1688 ChanCount midi_bypass;
1689 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1690 midi_bypass.set (DataType::MIDI, 1);
1693 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1695 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1696 uint32_t nin = ns_inputs.get (*t);
1697 uint32_t nout = outputs.get (*t);
1698 if (nin == 0 || inx.get(*t) == 0) { continue; }
1699 // prefer floor() so the count won't overly increase IFF (nin < nout)
1700 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1702 if (f > 0 && outputs * f >= _configured_out) {
1703 out = outputs * f + midi_bypass;
1704 return Match (Replicate, f, _strict_io);
1707 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1709 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1710 uint32_t nin = ns_inputs.get (*t);
1711 if (nin == 0 || inx.get(*t) == 0) { continue; }
1712 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1715 out = outputs * f + midi_bypass;
1716 return Match (Replicate, f, _strict_io);
1719 // add at least as many plugins needed to connect all inputs
1721 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1722 uint32_t nin = inputs.get (*t);
1723 if (nin == 0 || inx.get(*t) == 0) { continue; }
1724 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1726 out = outputs * f + midi_bypass;
1727 return Match (Replicate, f, _strict_io);
1730 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1732 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1734 if (_plugins.empty()) {
1738 PluginInfoPtr info = _plugins.front()->get_info();
1739 ChanCount in; in += inx;
1740 ChanCount midi_bypass;
1742 if (info->reconfigurable_io()) {
1743 /* Plugin has flexible I/O, so delegate to it
1744 * pre-seed outputs, plugin tries closest match
1747 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1748 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1749 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1751 return Match (Impossible, 0);
1753 return Match (Delegate, 1);
1756 ChanCount inputs = info->n_inputs;
1757 ChanCount outputs = info->n_outputs;
1758 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1760 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1761 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("bypassing midi-data around %1\n", name()));
1762 midi_bypass.set (DataType::MIDI, 1);
1764 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1765 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("hiding midi-port from plugin %1\n", name()));
1766 in.set(DataType::MIDI, 0);
1769 // add internally provided sidechain ports
1770 ChanCount insc = in + sidechain_input_ports ();
1772 bool no_inputs = true;
1773 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1774 if (inputs.get (*t) != 0) {
1781 /* no inputs so we can take any input configuration since we throw it away */
1782 out = outputs + midi_bypass;
1783 return Match (NoInputs, 1);
1786 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1787 if (inputs == insc) {
1788 out = outputs + midi_bypass;
1789 return Match (ExactMatch, 1);
1792 /* Plugin inputs matches without side-chain-pins */
1793 if (ns_inputs == in) {
1794 out = outputs + midi_bypass;
1795 return Match (ExactMatch, 1);
1798 /* We may be able to run more than one copy of the plugin within this insert
1799 to cope with the insert having more inputs than the plugin.
1800 We allow replication only for plugins with either zero or 1 inputs and outputs
1801 for every valid data type.
1805 bool can_replicate = true;
1806 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1808 // ignore side-chains
1809 uint32_t nin = ns_inputs.get (*t);
1811 // No inputs of this type
1812 if (nin == 0 && in.get(*t) == 0) {
1816 if (nin != 1 || outputs.get (*t) != 1) {
1817 can_replicate = false;
1821 // Potential factor not set yet
1823 f = in.get(*t) / nin;
1826 // Factor for this type does not match another type, can not replicate
1827 if (f != (in.get(*t) / nin)) {
1828 can_replicate = false;
1833 if (can_replicate && f > 0) {
1834 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1835 out.set (*t, outputs.get(*t) * f);
1838 return Match (Replicate, f);
1841 /* If the processor has exactly one input of a given type, and
1842 the plugin has more, we can feed the single processor input
1843 to some or all of the plugin inputs. This is rather
1844 special-case-y, but the 1-to-many case is by far the
1845 simplest. How do I split thy 2 processor inputs to 3
1846 plugin inputs? Let me count the ways ...
1849 bool can_split = true;
1850 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1852 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
1853 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1855 if (!can_split_type && !nothing_to_do_for_type) {
1861 out = outputs + midi_bypass;
1862 return Match (Split, 1);
1865 /* If the plugin has more inputs than we want, we can `hide' some of them
1866 by feeding them silence.
1869 bool could_hide = false;
1870 bool cannot_hide = false;
1871 ChanCount hide_channels;
1873 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1874 if (inputs.get(*t) > in.get(*t)) {
1875 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1876 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1878 } else if (inputs.get(*t) < in.get(*t)) {
1879 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1884 if (could_hide && !cannot_hide) {
1885 out = outputs + midi_bypass;
1886 return Match (Hide, 1, false, false, hide_channels);
1889 return Match (Impossible, 0);
1894 PluginInsert::get_state ()
1896 return state (true);
1900 PluginInsert::state (bool full)
1902 XMLNode& node = Processor::state (full);
1904 node.add_property("type", _plugins[0]->state_node_name());
1905 node.add_property("unique-id", _plugins[0]->unique_id());
1906 node.add_property("count", string_compose("%1", _plugins.size()));
1908 /* remember actual i/o configuration (for later placeholder
1909 * in case the plugin goes missing) */
1910 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1911 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1912 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
1914 /* save custom i/o config */
1915 node.add_property("custom", _custom_cfg ? "yes" : "no");
1916 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1918 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
1919 node.add_child_nocopy (* _in_map[pc].state (tmp));
1920 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
1921 node.add_child_nocopy (* _out_map[pc].state (tmp));
1923 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
1926 node.add_child_nocopy (_sidechain->state (full));
1929 _plugins[0]->set_insert_id(this->id());
1930 node.add_child_nocopy (_plugins[0]->get_state());
1932 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1933 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1935 node.add_child_nocopy (ac->get_state());
1943 PluginInsert::set_control_ids (const XMLNode& node, int version)
1945 const XMLNodeList& nlist = node.children();
1946 XMLNodeConstIterator iter;
1947 set<Evoral::Parameter>::const_iterator p;
1949 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1950 if ((*iter)->name() == Controllable::xml_node_name) {
1951 const XMLProperty* prop;
1953 uint32_t p = (uint32_t)-1;
1955 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1956 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1958 p = lv2plugin->port_index(prop->value().c_str());
1962 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1963 p = atoi (prop->value());
1966 if (p != (uint32_t)-1) {
1968 /* this may create the new controllable */
1970 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1972 #ifndef NO_PLUGIN_STATE
1976 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1978 ac->set_state (**iter, version);
1987 PluginInsert::set_state(const XMLNode& node, int version)
1989 XMLNodeList nlist = node.children();
1990 XMLNodeIterator niter;
1991 XMLPropertyList plist;
1992 const XMLProperty *prop;
1993 ARDOUR::PluginType type;
1995 if ((prop = node.property ("type")) == 0) {
1996 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2000 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
2001 type = ARDOUR::LADSPA;
2002 } else if (prop->value() == X_("lv2")) {
2004 } else if (prop->value() == X_("windows-vst")) {
2005 type = ARDOUR::Windows_VST;
2006 } else if (prop->value() == X_("lxvst")) {
2007 type = ARDOUR::LXVST;
2008 } else if (prop->value() == X_("audiounit")) {
2009 type = ARDOUR::AudioUnit;
2010 } else if (prop->value() == X_("luaproc")) {
2013 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2019 prop = node.property ("unique-id");
2022 #ifdef WINDOWS_VST_SUPPORT
2023 /* older sessions contain VST plugins with only an "id" field.
2026 if (type == ARDOUR::Windows_VST) {
2027 prop = node.property ("id");
2031 #ifdef LXVST_SUPPORT
2032 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2034 if (type == ARDOUR::LXVST) {
2035 prop = node.property ("id");
2041 error << _("Plugin has no unique ID field") << endmsg;
2046 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2048 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2049 * allow to move sessions windows <> linux */
2050 #ifdef LXVST_SUPPORT
2051 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2052 type = ARDOUR::LXVST;
2053 plugin = find_plugin (_session, prop->value(), type);
2057 #ifdef WINDOWS_VST_SUPPORT
2058 if (plugin == 0 && type == ARDOUR::LXVST) {
2059 type = ARDOUR::Windows_VST;
2060 plugin = find_plugin (_session, prop->value(), type);
2065 error << string_compose(
2066 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2067 "Perhaps it was removed or moved since it was last used."),
2073 if (type == ARDOUR::Lua) {
2074 XMLNode *ls = node.child (plugin->state_node_name().c_str());
2075 // we need to load the script to set the name and parameters.
2076 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
2078 lp->set_script_from_state (*ls);
2082 // The name of the PluginInsert comes from the plugin, nothing else
2083 _name = plugin->get_info()->name;
2087 // Processor::set_state() will set this, but too late
2088 // for it to be available when setting up plugin
2089 // state. We can't call Processor::set_state() until
2090 // the plugins themselves are created and added.
2094 if (_plugins.empty()) {
2095 /* if we are adding the first plugin, we will need to set
2096 up automatable controls.
2098 add_plugin (plugin);
2099 create_automatable_parameters ();
2100 set_control_ids (node, version);
2103 if ((prop = node.property ("count")) != 0) {
2104 sscanf (prop->value().c_str(), "%u", &count);
2107 if (_plugins.size() != count) {
2108 for (uint32_t n = 1; n < count; ++n) {
2109 add_plugin (plugin_factory (plugin));
2113 Processor::set_state (node, version);
2115 PBD::ID new_id = this->id();
2116 PBD::ID old_id = this->id();
2118 if ((prop = node.property ("id")) != 0) {
2119 old_id = prop->value ();
2122 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2124 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2125 and set all plugins to the same state.
2128 if ((*niter)->name() == plugin->state_node_name()) {
2130 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2131 /* Plugin state can include external files which are named after the ID.
2133 * If regenerate_xml_or_string_ids() is set, the ID will already have
2134 * been changed, so we need to use the old ID from the XML to load the
2135 * state and then update the ID.
2137 * When copying a plugin-state, route_ui takes care of of updating the ID,
2138 * but we need to call set_insert_id() to clear the cached plugin-state
2139 * and force a change.
2141 if (!regenerate_xml_or_string_ids ()) {
2142 (*i)->set_insert_id (new_id);
2144 (*i)->set_insert_id (old_id);
2147 (*i)->set_state (**niter, version);
2149 if (regenerate_xml_or_string_ids ()) {
2150 (*i)->set_insert_id (new_id);
2158 if (version < 3000) {
2160 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2161 this is all handled by Automatable
2164 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2165 if ((*niter)->name() == "Redirect") {
2166 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2167 Processor::set_state (**niter, version);
2172 set_parameter_state_2X (node, version);
2175 if ((prop = node.property (X_("custom"))) != 0) {
2176 _custom_cfg = string_is_affirmative (prop->value());
2179 uint32_t in_maps = 0;
2180 uint32_t out_maps = 0;
2181 XMLNodeList kids = node.children ();
2182 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2183 if ((*i)->name() == X_("ConfiguredOutput")) {
2184 _custom_out = ChanCount(**i);
2186 if ((*i)->name() == X_("PresetOutput")) {
2187 _preset_out = ChanCount(**i);
2189 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2190 long pc = atol (&((*i)->name().c_str()[9]));
2191 if (pc >=0 && pc <= get_count()) {
2192 _in_map[pc] = ChanMapping (**i);
2196 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2197 long pc = atol (&((*i)->name().c_str()[10]));
2198 if (pc >=0 && pc <= get_count()) {
2199 _out_map[pc] = ChanMapping (**i);
2203 if ((*i)->name () == "ThruMap") {
2204 _thru_map = ChanMapping (**i);
2207 // sidechain is a Processor (IO)
2208 if ((*i)->name () == Processor::state_node_name) {
2212 _sidechain->set_state (**i, version);
2216 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2217 _maps_from_state = true;
2220 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2224 (*i)->deactivate ();
2228 PluginConfigChanged (); /* EMIT SIGNAL */
2233 PluginInsert::update_id (PBD::ID id)
2236 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2237 (*i)->set_insert_id (id);
2242 PluginInsert::set_state_dir (const std::string& d)
2244 // state() only saves the state of the first plugin
2245 _plugins[0]->set_state_dir (d);
2249 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2251 XMLNodeList nlist = node.children();
2252 XMLNodeIterator niter;
2254 /* look for port automation node */
2256 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2258 if ((*niter)->name() != port_automation_node_name) {
2264 XMLNodeConstIterator iter;
2269 cnodes = (*niter)->children ("port");
2271 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2275 if ((cprop = child->property("number")) != 0) {
2276 port = cprop->value().c_str();
2278 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2282 sscanf (port, "%" PRIu32, &port_id);
2284 if (port_id >= _plugins[0]->parameter_count()) {
2285 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2289 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2290 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2292 if (c && c->alist()) {
2293 if (!child->children().empty()) {
2294 c->alist()->set_state (*child->children().front(), version);
2296 /* In some cases 2.X saves lists with min_yval and max_yval
2297 being FLT_MIN and FLT_MAX respectively. This causes problems
2298 in A3 because these min/max values are used to compute
2299 where GUI control points should be drawn. If we see such
2300 values, `correct' them to the min/max of the appropriate
2304 float min_y = c->alist()->get_min_y ();
2305 float max_y = c->alist()->get_max_y ();
2307 ParameterDescriptor desc;
2308 _plugins.front()->get_parameter_descriptor (port_id, desc);
2310 if (min_y == FLT_MIN) {
2314 if (max_y == FLT_MAX) {
2318 c->alist()->set_yrange (min_y, max_y);
2321 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2333 PluginInsert::describe_parameter (Evoral::Parameter param)
2335 if (param.type() == PluginAutomation) {
2336 return _plugins[0]->describe_parameter (param);
2337 } else if (param.type() == PluginPropertyAutomation) {
2338 boost::shared_ptr<AutomationControl> c(automation_control(param));
2339 if (c && !c->desc().label.empty()) {
2340 return c->desc().label;
2343 return Automatable::describe_parameter(param);
2347 PluginInsert::signal_latency() const
2349 if (_user_latency) {
2350 return _user_latency;
2353 return _plugins[0]->signal_latency ();
2357 PluginInsert::type ()
2359 return plugin()->get_info()->type;
2362 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2363 const Evoral::Parameter& param,
2364 const ParameterDescriptor& desc,
2365 boost::shared_ptr<AutomationList> list)
2366 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2370 alist()->reset_default (desc.normal);
2372 list->set_interpolation(Evoral::ControlList::Discrete);
2377 set_flags(Controllable::Toggle);
2381 /** @param val `user' value */
2383 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2386 _set_value (user_val, group_override);
2390 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2392 /* used only by automation playback */
2393 _set_value (user_val, Controllable::NoGroup);
2397 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2399 /* FIXME: probably should be taking out some lock here.. */
2401 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2402 (*i)->set_parameter (_list->parameter().id(), user_val);
2405 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2407 iasp->set_parameter (_list->parameter().id(), user_val);
2410 AutomationControl::set_value (user_val, group_override);
2414 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2416 AutomationControl::set_value (user_val, Controllable::NoGroup);
2420 PluginInsert::PluginControl::get_state ()
2424 XMLNode& node (AutomationControl::get_state());
2425 ss << parameter().id();
2426 node.add_property (X_("parameter"), ss.str());
2428 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2430 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2437 /** @return `user' val */
2439 PluginInsert::PluginControl::get_value () const
2441 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2447 return plugin->get_parameter (_list->parameter().id());
2450 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2451 const Evoral::Parameter& param,
2452 const ParameterDescriptor& desc,
2453 boost::shared_ptr<AutomationList> list)
2454 : AutomationControl (p->session(), param, desc, list)
2458 alist()->set_yrange (desc.lower, desc.upper);
2459 alist()->reset_default (desc.normal);
2463 set_flags(Controllable::Toggle);
2468 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2471 set_value_unchecked (user_val);
2476 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2478 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2479 This is lossy, but better than nothing until Ardour's automation system
2480 can handle various datatypes all the way down. */
2481 const Variant value(_desc.datatype, user_val);
2482 if (value.type() == Variant::NOTHING) {
2483 error << "set_value(double) called for non-numeric property" << endmsg;
2487 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2488 (*i)->set_property(_list->parameter().id(), value);
2492 AutomationControl::set_value (user_val, Controllable::NoGroup);
2496 PluginInsert::PluginPropertyControl::get_state ()
2500 XMLNode& node (AutomationControl::get_state());
2501 ss << parameter().id();
2502 node.add_property (X_("property"), ss.str());
2503 node.remove_property (X_("value"));
2509 PluginInsert::PluginPropertyControl::get_value () const
2511 return _value.to_double();
2514 boost::shared_ptr<Plugin>
2515 PluginInsert::get_impulse_analysis_plugin()
2517 boost::shared_ptr<Plugin> ret;
2518 if (_impulseAnalysisPlugin.expired()) {
2519 ret = plugin_factory(_plugins[0]);
2520 ret->configure_io (internal_input_streams (), internal_output_streams ());
2521 _impulseAnalysisPlugin = ret;
2523 ret = _impulseAnalysisPlugin.lock();
2530 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2532 // called from outside the audio thread, so this should be safe
2533 // only do audio as analysis is (currently) only for audio plugins
2534 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2535 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2537 _signal_analysis_collected_nframes = 0;
2538 _signal_analysis_collect_nframes_max = nframes;
2541 /** Add a plugin to our list */
2543 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2545 plugin->set_insert_id (this->id());
2547 if (_plugins.empty()) {
2548 /* first (and probably only) plugin instance - connect to relevant signals */
2550 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2551 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2552 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2553 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2554 // cache sidechain port count
2555 _cached_sidechain_pins.reset ();
2556 const ChanCount& nis (plugin->get_info()->n_inputs);
2557 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2558 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2559 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2560 if (iod.is_sidechain) {
2561 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2566 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2567 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2569 vst->set_insert (this, _plugins.size ());
2572 _plugins.push_back (plugin);
2576 PluginInsert::realtime_handle_transport_stopped ()
2578 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2579 (*i)->realtime_handle_transport_stopped ();
2584 PluginInsert::realtime_locate ()
2586 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2587 (*i)->realtime_locate ();
2592 PluginInsert::monitoring_changed ()
2594 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2595 (*i)->monitoring_changed ();
2600 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2602 // this is called in RT context, LatencyChanged is emitted after run()
2603 _latency_changed = true;
2607 PluginInsert::start_touch (uint32_t param_id)
2609 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2611 ac->start_touch (session().audible_frame());
2616 PluginInsert::end_touch (uint32_t param_id)
2618 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2620 ac->stop_touch (true, session().audible_frame());
2624 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2627 case PluginInsert::Impossible: o << "Impossible"; break;
2628 case PluginInsert::Delegate: o << "Delegate"; break;
2629 case PluginInsert::NoInputs: o << "NoInputs"; break;
2630 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2631 case PluginInsert::Replicate: o << "Replicate"; break;
2632 case PluginInsert::Split: o << "Split"; break;
2633 case PluginInsert::Hide: o << "Hide"; break;
2635 o << " cnt: " << m.plugins
2636 << (m.strict_io ? " strict-io" : "")
2637 << (m.custom_cfg ? " custom-cfg" : "");
2638 if (m.method == PluginInsert::Hide) {
2639 o << " hide: " << m.hide;