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 ChanMapping in_map (natural_input_streams ());
768 ChanMapping out_map (natural_output_streams ());
770 // TODO run sidechain (delaylines)
771 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
772 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
777 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
779 if (_pending_active) {
780 /* run as normal if we are active or moving from inactive to active */
783 // collect sidechain input for complete cycle (!)
784 // TODO we need delaylines here for latency compensation
785 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
788 if (_session.transport_rolling() || _session.bounce_processing()) {
789 automation_run (bufs, start_frame, nframes);
791 connect_and_run (bufs, nframes, 0, false);
795 // TODO use mapping in bypassed mode ?!
796 // -> do we bypass the processor or the plugin
798 // TODO include sidechain??
800 uint32_t in = input_streams ().n_audio ();
801 uint32_t out = output_streams().n_audio ();
803 if (has_no_audio_inputs() || in == 0) {
805 /* silence all (audio) outputs. Should really declick
806 * at the transitions of "active"
809 for (uint32_t n = 0; n < out; ++n) {
810 bufs.get_audio (n).silence (nframes);
813 } else if (out > in) {
815 /* not active, but something has make up for any channel count increase
816 * for now , simply replicate last buffer
818 for (uint32_t n = in; n < out; ++n) {
819 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
823 bufs.count().set_audio (out);
826 _active = _pending_active;
828 /* we have no idea whether the plugin generated silence or not, so mark
829 * all buffers appropriately.
834 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
836 Evoral::ControlEvent next_event (0, 0.0f);
837 framepos_t now = start;
838 framepos_t end = now + nframes;
839 framecnt_t offset = 0;
841 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
844 connect_and_run (bufs, nframes, offset, false);
848 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
850 /* no events have a time within the relevant range */
852 connect_and_run (bufs, nframes, offset, true, now);
858 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
860 connect_and_run (bufs, cnt, offset, true, now);
866 if (!find_next_event (now, end, next_event)) {
871 /* cleanup anything that is left to do */
874 connect_and_run (bufs, nframes, offset, true, now);
879 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
881 if (param.type() != PluginAutomation)
884 if (_plugins.empty()) {
885 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
887 abort(); /*NOTREACHED*/
890 return _plugins[0]->default_value (param.id());
895 PluginInsert::can_reset_all_parameters ()
899 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
901 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
903 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
907 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
913 if (ac->automation_state() & Play) {
918 return all && (params > 0);
922 PluginInsert::reset_parameters_to_default ()
926 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
928 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
930 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
934 const float dflt = _plugins[0]->default_value (cid);
935 const float curr = _plugins[0]->get_parameter (cid);
941 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
946 if (ac->automation_state() & Play) {
951 ac->set_value (dflt, Controllable::NoGroup);
956 boost::shared_ptr<Plugin>
957 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
959 boost::shared_ptr<LadspaPlugin> lp;
960 boost::shared_ptr<LuaProc> lua;
962 boost::shared_ptr<LV2Plugin> lv2p;
964 #ifdef WINDOWS_VST_SUPPORT
965 boost::shared_ptr<WindowsVSTPlugin> vp;
968 boost::shared_ptr<LXVSTPlugin> lxvp;
970 #ifdef AUDIOUNIT_SUPPORT
971 boost::shared_ptr<AUPlugin> ap;
974 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
975 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
976 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
977 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
979 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
980 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
982 #ifdef WINDOWS_VST_SUPPORT
983 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
984 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
987 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
988 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
990 #ifdef AUDIOUNIT_SUPPORT
991 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
992 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
996 fatal << string_compose (_("programming error: %1"),
997 X_("unknown plugin type in PluginInsert::plugin_factory"))
999 abort(); /*NOTREACHED*/
1000 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1004 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1005 if (num < _in_map.size()) {
1006 bool changed = _in_map[num] != m;
1008 changed |= sanitize_maps ();
1010 PluginMapChanged (); /* EMIT SIGNAL */
1011 _mapping_changed = true;
1012 _session.set_dirty();
1018 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1019 if (num < _out_map.size()) {
1020 bool changed = _out_map[num] != m;
1022 changed |= sanitize_maps ();
1024 PluginMapChanged (); /* EMIT SIGNAL */
1025 _mapping_changed = true;
1026 _session.set_dirty();
1032 PluginInsert::set_thru_map (ChanMapping m) {
1033 bool changed = _thru_map != m;
1035 changed |= sanitize_maps ();
1037 PluginMapChanged (); /* EMIT SIGNAL */
1038 _mapping_changed = true;
1039 _session.set_dirty();
1044 PluginInsert::input_map () const
1048 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1049 ChanMapping m (i->second);
1050 const ChanMapping::Mappings& mp ((*i).second.mappings());
1051 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1052 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1053 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1061 PluginInsert::output_map () const
1065 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1066 ChanMapping m (i->second);
1067 const ChanMapping::Mappings& mp ((*i).second.mappings());
1068 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1069 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1070 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1074 if (has_midi_bypass ()) {
1075 rv.set (DataType::MIDI, 0, 0);
1082 PluginInsert::has_midi_bypass () const
1084 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1085 && natural_output_streams ().n_midi () == 0) {
1092 PluginInsert::has_midi_thru () const
1094 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1095 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1103 PluginInsert::is_channelstrip () const {
1104 return _plugins.front()->is_channelstrip();
1109 PluginInsert::check_inplace ()
1111 bool inplace_ok = !_plugins.front()->inplace_broken ();
1113 if (_thru_map.n_total () > 0) {
1114 // TODO once midi-bypass is part of the mapping, ignore it
1118 if (_match.method == Split && inplace_ok) {
1119 assert (get_count() == 1);
1120 assert (_in_map.size () == 1);
1121 if (!_out_map[0].is_monotonic ()) {
1124 if (_configured_internal != _configured_in) {
1125 /* no sidechain -- TODO we could allow this with
1126 * some more logic in PluginInsert::connect_and_run().
1128 * PluginInsert::reset_map() already maps it.
1133 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1134 if (_configured_internal.get (*t) == 0) {
1138 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1139 if (!valid || first_idx != 0) {
1140 // so far only allow to copy the *first* stream's buffer to others
1143 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1144 uint32_t idx = _in_map[0].get (*t, i, &valid);
1145 if (valid && idx != first_idx) {
1154 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1159 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1160 if (!_in_map[pc].is_monotonic ()) {
1163 if (!_out_map[pc].is_monotonic ()) {
1167 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1168 return !inplace_ok; // no-inplace
1172 PluginInsert::sanitize_maps ()
1174 bool changed = false;
1175 /* strip dead wood */
1176 PinMappings new_ins;
1177 PinMappings new_outs;
1178 ChanMapping new_thru;
1180 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1182 ChanMapping new_out;
1183 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1184 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1186 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1187 if (valid && idx < _configured_internal.get (*t)) {
1188 new_in.set (*t, i, idx);
1191 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1193 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1194 if (valid && idx < _configured_out.get (*t)) {
1195 new_out.set (*t, o, idx);
1199 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1202 new_ins[pc] = new_in;
1203 new_outs[pc] = new_out;
1206 /* prevent dup output assignments */
1207 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1208 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1209 bool mapped = false;
1210 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1212 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1213 if (valid && mapped) {
1214 new_outs[pc].unset (*t, idx);
1222 /* remove excess thru */
1223 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1224 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1226 uint32_t idx = _thru_map.get (*t, o, &valid);
1227 if (valid && idx < _configured_internal.get (*t)) {
1228 new_thru.set (*t, o, idx);
1233 /* prevent out + thru, existing plugin outputs override thru */
1234 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1235 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1236 bool mapped = false;
1238 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1239 new_outs[pc].get_src (*t, o, &mapped);
1240 if (mapped) { break; }
1242 if (!mapped) { continue; }
1243 uint32_t idx = new_thru.get (*t, o, &valid);
1245 new_thru.unset (*t, idx);
1250 if (has_midi_bypass ()) {
1251 // TODO: include midi-bypass in the thru set,
1252 // remove dedicated handling.
1253 new_thru.unset (DataType::MIDI, 0);
1256 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1260 _out_map = new_outs;
1261 _thru_map = new_thru;
1267 PluginInsert::reset_map (bool emit)
1269 const PinMappings old_in (_in_map);
1270 const PinMappings old_out (_out_map);
1274 _thru_map = ChanMapping ();
1276 /* build input map */
1277 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1278 uint32_t sc = 0; // side-chain round-robin (all instances)
1280 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1281 const uint32_t nis = natural_input_streams ().get(*t);
1282 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1284 /* SC inputs are last in the plugin-insert.. */
1285 const uint32_t sc_start = _configured_in.get (*t);
1286 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1287 /* ...but may not be at the end of the plugin ports.
1288 * in case the side-chain is not the last port, shift connections back.
1289 * and connect to side-chain
1292 uint32_t ic = 0; // split inputs
1293 const uint32_t cend = _configured_in.get (*t);
1295 for (uint32_t in = 0; in < nis; ++in) {
1296 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1297 if (iod.is_sidechain) {
1298 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1299 if (sc_len > 0) {// side-chain may be hidden
1300 _in_map[pc].set (*t, in, sc_start + sc);
1301 sc = (sc + 1) % sc_len;
1305 if (_match.method == Split) {
1306 if (cend == 0) { continue; }
1307 if (_strict_io && ic + stride * pc >= cend) {
1310 /* connect *no* sidechain sinks in round-robin fashion */
1311 _in_map[pc].set (*t, in, ic + stride * pc);
1312 if (_strict_io && (ic + 1) == cend) {
1315 ic = (ic + 1) % cend;
1317 uint32_t s = in - shift;
1318 if (stride * pc + s < cend) {
1319 _in_map[pc].set (*t, in, s + stride * pc);
1327 /* build output map */
1329 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1330 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1331 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1332 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1337 if (old_in == _in_map && old_out == _out_map) {
1341 PluginMapChanged (); /* EMIT SIGNAL */
1342 _mapping_changed = true;
1343 _session.set_dirty();
1349 PluginInsert::configure_io (ChanCount in, ChanCount out)
1351 Match old_match = _match;
1353 ChanCount old_internal;
1357 old_in = _configured_in;
1358 old_internal = _configured_internal;
1359 old_out = _configured_out;
1362 _configured_in = in;
1363 _configured_internal = in;
1364 _configured_out = out;
1367 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1368 * (currently _sidechain->configure_io always succeeds
1369 * since Processor::configure_io() succeeds)
1371 if (!_sidechain->configure_io (in, out)) {
1372 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1375 _configured_internal += _sidechain->input()->n_ports();
1377 // include (static_cast<Route*>owner())->name() ??
1378 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1381 /* get plugin configuration */
1382 _match = private_can_support_io_configuration (in, out);
1384 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1386 DEBUG_STR_APPEND(a, string_compose ("Match '%1': ", name()));
1387 DEBUG_STR_APPEND(a, _match);
1388 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1392 /* set the matching method and number of plugins that we will use to meet this configuration */
1393 if (set_count (_match.plugins) == false) {
1394 PluginIoReConfigure (); /* EMIT SIGNAL */
1395 _configured = false;
1399 /* configure plugins */
1400 switch (_match.method) {
1403 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1404 PluginIoReConfigure (); /* EMIT SIGNAL */
1405 _configured = false;
1411 ChanCount dout (in); // hint
1414 } else if (_preset_out.n_audio () > 0) {
1415 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1416 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1417 dout.set (DataType::AUDIO, 2);
1419 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1421 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
1423 if (useins.n_audio() == 0) {
1426 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("Delegate configuration: %1 %2 %3\n", name(), useins, dout));
1428 if (_plugins.front()->configure_io (useins, dout) == false) {
1429 PluginIoReConfigure (); /* EMIT SIGNAL */
1430 _configured = false;
1436 if (_plugins.front()->configure_io (in, out) == false) {
1437 PluginIoReConfigure (); /* EMIT SIGNAL */
1438 _configured = false;
1444 bool mapping_changed = false;
1445 if (old_in == in && old_out == out
1447 && old_match.method == _match.method
1448 && _in_map.size() == _out_map.size()
1449 && _in_map.size() == get_count ()
1451 assert (_maps_from_state == false);
1452 /* If the configuration has not changed, keep the mapping */
1453 if (old_internal != _configured_internal) {
1454 mapping_changed = sanitize_maps ();
1456 } else if (_match.custom_cfg && _configured) {
1457 assert (_maps_from_state == false);
1458 mapping_changed = sanitize_maps ();
1461 if (is_channelstrip ()) { _maps_from_state = false; }
1463 if (_maps_from_state) {
1464 _maps_from_state = false;
1465 mapping_changed = true;
1468 /* generate a new mapping */
1469 mapping_changed = reset_map (false);
1473 if (mapping_changed) {
1474 PluginMapChanged (); /* EMIT SIGNAL */
1477 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1480 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1481 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1483 DEBUG_STR_APPEND(a, "----><----\n");
1485 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1486 DEBUG_STR_APPEND(a, " * Inputs:\n");
1487 DEBUG_STR_APPEND(a, _in_map[pc]);
1488 DEBUG_STR_APPEND(a, " * Outputs:\n");
1489 DEBUG_STR_APPEND(a, _out_map[pc]);
1491 DEBUG_STR_APPEND(a, " * Thru:\n");
1492 DEBUG_STR_APPEND(a, _thru_map);
1493 DEBUG_STR_APPEND(a, "-------->>--------\n");
1494 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1499 _no_inplace = check_inplace ();
1500 _mapping_changed = false;
1502 /* only the "noinplace_buffers" thread buffers need to be this large,
1503 * this can be optimized. other buffers are fine with
1504 * ChanCount::max (natural_input_streams (), natural_output_streams())
1505 * and route.cc's max (configured_in, configured_out)
1507 * no-inplace copies "thru" outputs (to emulate in-place) for
1508 * all outputs (to prevent overwrite) into a temporary space
1509 * which also holds input buffers (in case the plugin does process
1510 * in-place and overwrites those).
1512 * this buffers need to be at least as
1513 * natural_input_streams () + possible outputs.
1515 * sidechain inputs add a constraint on the input:
1516 * configured input + sidechain (=_configured_internal)
1518 _required_buffers =ChanCount::max (_configured_internal,
1519 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1521 if (old_in != in || old_out != out || old_internal != _configured_internal
1522 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1524 PluginIoReConfigure (); /* EMIT SIGNAL */
1527 _delaybuffers.configure (_configured_out, _plugins.front()->max_latency ());
1528 _latency_changed = true;
1530 // we don't know the analysis window size, so we must work with the
1531 // current buffer size here. each request for data fills in these
1532 // buffers and the analyser makes sure it gets enough data for the
1534 session().ensure_buffer_set (_signal_analysis_inputs, in);
1535 //_signal_analysis_inputs.set_count (in);
1537 session().ensure_buffer_set (_signal_analysis_outputs, out);
1538 //_signal_analysis_outputs.set_count (out);
1540 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1543 return Processor::configure_io (in, out);
1546 /** Decide whether this PluginInsert can support a given IO configuration.
1547 * To do this, we run through a set of possible solutions in rough order of
1550 * @param in Required input channel count.
1551 * @param out Filled in with the output channel count if we return true.
1552 * @return true if the given IO configuration can be supported.
1555 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1558 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1560 return private_can_support_io_configuration (in, out).method != Impossible;
1564 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1566 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1567 // preseed hint (for variable i/o)
1568 out.set (DataType::AUDIO, _preset_out.n_audio ());
1571 Match rv = internal_can_support_io_configuration (in, out);
1573 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1574 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("using output preset: %1 %2\n", name(), _preset_out));
1575 out.set (DataType::AUDIO, _preset_out.n_audio ());
1580 /** A private version of can_support_io_configuration which returns the method
1581 * by which the configuration can be matched, rather than just whether or not
1585 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1587 if (_plugins.empty()) {
1592 if (is_channelstrip ()) {
1594 return Match (ExactMatch, 1);
1598 /* if a user specified a custom cfg, so be it. */
1600 PluginInfoPtr info = _plugins.front()->get_info();
1602 if (info->reconfigurable_io()) {
1603 return Match (Delegate, get_count(), _strict_io, true);
1605 return Match (ExactMatch, get_count(), _strict_io, true);
1609 /* try automatic configuration */
1610 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1612 PluginInfoPtr info = _plugins.front()->get_info();
1613 ChanCount inputs = info->n_inputs;
1614 ChanCount outputs = info->n_outputs;
1616 /* handle case strict-i/o */
1617 if (_strict_io && m.method != Impossible) {
1620 /* special case MIDI instruments */
1621 if (needs_midi_input ()) {
1622 // output = midi-bypass + at most master-out channels.
1623 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1624 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1625 out = ChanCount::min (out, max_out);
1626 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o instrument: %1\n", name()));
1632 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1633 /* replicate processor to match output count (generators and such)
1634 * at least enough to feed every output port. */
1635 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1636 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1637 uint32_t nout = outputs.get (*t);
1638 if (nout == 0 || inx.get(*t) == 0) { continue; }
1639 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1642 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("special case strict-i/o generator: %1\n", name()));
1643 return Match (Replicate, f, _strict_io);
1654 if (m.method != Impossible) {
1658 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1660 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("resolving 'Impossible' match for %1\n", name()));
1662 if (info->reconfigurable_io()) {
1665 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1666 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1667 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1669 // houston, we have a problem.
1670 return Match (Impossible, 0);
1672 return Match (Delegate, 1, _strict_io);
1675 ChanCount midi_bypass;
1676 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1677 midi_bypass.set (DataType::MIDI, 1);
1680 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1682 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1683 uint32_t nin = ns_inputs.get (*t);
1684 uint32_t nout = outputs.get (*t);
1685 if (nin == 0 || inx.get(*t) == 0) { continue; }
1686 // prefer floor() so the count won't overly increase IFF (nin < nout)
1687 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1689 if (f > 0 && outputs * f >= _configured_out) {
1690 out = outputs * f + midi_bypass;
1691 return Match (Replicate, f, _strict_io);
1694 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1696 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1697 uint32_t nin = ns_inputs.get (*t);
1698 if (nin == 0 || inx.get(*t) == 0) { continue; }
1699 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1702 out = outputs * f + midi_bypass;
1703 return Match (Replicate, f, _strict_io);
1706 // add at least as many plugins needed to connect all inputs
1708 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1709 uint32_t nin = inputs.get (*t);
1710 if (nin == 0 || inx.get(*t) == 0) { continue; }
1711 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1713 out = outputs * f + midi_bypass;
1714 return Match (Replicate, f, _strict_io);
1717 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1719 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1721 if (_plugins.empty()) {
1725 PluginInfoPtr info = _plugins.front()->get_info();
1726 ChanCount in; in += inx;
1727 ChanCount midi_bypass;
1729 if (info->reconfigurable_io()) {
1730 /* Plugin has flexible I/O, so delegate to it
1731 * pre-seed outputs, plugin tries closest match
1734 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1735 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1736 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1738 return Match (Impossible, 0);
1740 return Match (Delegate, 1);
1743 ChanCount inputs = info->n_inputs;
1744 ChanCount outputs = info->n_outputs;
1745 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1747 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1748 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("bypassing midi-data around %1\n", name()));
1749 midi_bypass.set (DataType::MIDI, 1);
1751 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1752 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("hiding midi-port from plugin %1\n", name()));
1753 in.set(DataType::MIDI, 0);
1756 // add internally provided sidechain ports
1757 ChanCount insc = in + sidechain_input_ports ();
1759 bool no_inputs = true;
1760 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1761 if (inputs.get (*t) != 0) {
1768 /* no inputs so we can take any input configuration since we throw it away */
1769 out = outputs + midi_bypass;
1770 return Match (NoInputs, 1);
1773 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1774 if (inputs == insc) {
1775 out = outputs + midi_bypass;
1776 return Match (ExactMatch, 1);
1779 /* Plugin inputs matches without side-chain-pins */
1780 if (ns_inputs == in) {
1781 out = outputs + midi_bypass;
1782 return Match (ExactMatch, 1);
1785 /* We may be able to run more than one copy of the plugin within this insert
1786 to cope with the insert having more inputs than the plugin.
1787 We allow replication only for plugins with either zero or 1 inputs and outputs
1788 for every valid data type.
1792 bool can_replicate = true;
1793 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1795 // ignore side-chains
1796 uint32_t nin = ns_inputs.get (*t);
1798 // No inputs of this type
1799 if (nin == 0 && in.get(*t) == 0) {
1803 if (nin != 1 || outputs.get (*t) != 1) {
1804 can_replicate = false;
1808 // Potential factor not set yet
1810 f = in.get(*t) / nin;
1813 // Factor for this type does not match another type, can not replicate
1814 if (f != (in.get(*t) / nin)) {
1815 can_replicate = false;
1820 if (can_replicate && f > 0) {
1821 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1822 out.set (*t, outputs.get(*t) * f);
1825 return Match (Replicate, f);
1828 /* If the processor has exactly one input of a given type, and
1829 the plugin has more, we can feed the single processor input
1830 to some or all of the plugin inputs. This is rather
1831 special-case-y, but the 1-to-many case is by far the
1832 simplest. How do I split thy 2 processor inputs to 3
1833 plugin inputs? Let me count the ways ...
1836 bool can_split = true;
1837 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1839 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
1840 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1842 if (!can_split_type && !nothing_to_do_for_type) {
1848 out = outputs + midi_bypass;
1849 return Match (Split, 1);
1852 /* If the plugin has more inputs than we want, we can `hide' some of them
1853 by feeding them silence.
1856 bool could_hide = false;
1857 bool cannot_hide = false;
1858 ChanCount hide_channels;
1860 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1861 if (inputs.get(*t) > in.get(*t)) {
1862 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1863 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1865 } else if (inputs.get(*t) < in.get(*t)) {
1866 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1871 if (could_hide && !cannot_hide) {
1872 out = outputs + midi_bypass;
1873 return Match (Hide, 1, false, false, hide_channels);
1876 return Match (Impossible, 0);
1881 PluginInsert::get_state ()
1883 return state (true);
1887 PluginInsert::state (bool full)
1889 XMLNode& node = Processor::state (full);
1891 node.add_property("type", _plugins[0]->state_node_name());
1892 node.add_property("unique-id", _plugins[0]->unique_id());
1893 node.add_property("count", string_compose("%1", _plugins.size()));
1895 /* remember actual i/o configuration (for later placeholder
1896 * in case the plugin goes missing) */
1897 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1898 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1899 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
1901 /* save custom i/o config */
1902 node.add_property("custom", _custom_cfg ? "yes" : "no");
1903 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1905 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
1906 node.add_child_nocopy (* _in_map[pc].state (tmp));
1907 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
1908 node.add_child_nocopy (* _out_map[pc].state (tmp));
1910 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
1913 node.add_child_nocopy (_sidechain->state (full));
1916 _plugins[0]->set_insert_id(this->id());
1917 node.add_child_nocopy (_plugins[0]->get_state());
1919 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1920 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1922 node.add_child_nocopy (ac->get_state());
1930 PluginInsert::set_control_ids (const XMLNode& node, int version)
1932 const XMLNodeList& nlist = node.children();
1933 XMLNodeConstIterator iter;
1934 set<Evoral::Parameter>::const_iterator p;
1936 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1937 if ((*iter)->name() == Controllable::xml_node_name) {
1938 const XMLProperty* prop;
1940 uint32_t p = (uint32_t)-1;
1942 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1943 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1945 p = lv2plugin->port_index(prop->value().c_str());
1949 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1950 p = atoi (prop->value());
1953 if (p != (uint32_t)-1) {
1955 /* this may create the new controllable */
1957 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1959 #ifndef NO_PLUGIN_STATE
1963 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1965 ac->set_state (**iter, version);
1974 PluginInsert::set_state(const XMLNode& node, int version)
1976 XMLNodeList nlist = node.children();
1977 XMLNodeIterator niter;
1978 XMLPropertyList plist;
1979 const XMLProperty *prop;
1980 ARDOUR::PluginType type;
1982 if ((prop = node.property ("type")) == 0) {
1983 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1987 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1988 type = ARDOUR::LADSPA;
1989 } else if (prop->value() == X_("lv2")) {
1991 } else if (prop->value() == X_("windows-vst")) {
1992 type = ARDOUR::Windows_VST;
1993 } else if (prop->value() == X_("lxvst")) {
1994 type = ARDOUR::LXVST;
1995 } else if (prop->value() == X_("audiounit")) {
1996 type = ARDOUR::AudioUnit;
1997 } else if (prop->value() == X_("luaproc")) {
2000 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2006 prop = node.property ("unique-id");
2009 #ifdef WINDOWS_VST_SUPPORT
2010 /* older sessions contain VST plugins with only an "id" field.
2013 if (type == ARDOUR::Windows_VST) {
2014 prop = node.property ("id");
2018 #ifdef LXVST_SUPPORT
2019 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2021 if (type == ARDOUR::LXVST) {
2022 prop = node.property ("id");
2028 error << _("Plugin has no unique ID field") << endmsg;
2033 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2035 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2036 * allow to move sessions windows <> linux */
2037 #ifdef LXVST_SUPPORT
2038 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2039 type = ARDOUR::LXVST;
2040 plugin = find_plugin (_session, prop->value(), type);
2044 #ifdef WINDOWS_VST_SUPPORT
2045 if (plugin == 0 && type == ARDOUR::LXVST) {
2046 type = ARDOUR::Windows_VST;
2047 plugin = find_plugin (_session, prop->value(), type);
2052 error << string_compose(
2053 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2054 "Perhaps it was removed or moved since it was last used."),
2060 if (type == ARDOUR::Lua) {
2061 XMLNode *ls = node.child (plugin->state_node_name().c_str());
2062 // we need to load the script to set the name and parameters.
2063 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
2065 lp->set_script_from_state (*ls);
2069 // The name of the PluginInsert comes from the plugin, nothing else
2070 _name = plugin->get_info()->name;
2074 // Processor::set_state() will set this, but too late
2075 // for it to be available when setting up plugin
2076 // state. We can't call Processor::set_state() until
2077 // the plugins themselves are created and added.
2081 if (_plugins.empty()) {
2082 /* if we are adding the first plugin, we will need to set
2083 up automatable controls.
2085 add_plugin (plugin);
2086 create_automatable_parameters ();
2087 set_control_ids (node, version);
2090 if ((prop = node.property ("count")) != 0) {
2091 sscanf (prop->value().c_str(), "%u", &count);
2094 if (_plugins.size() != count) {
2095 for (uint32_t n = 1; n < count; ++n) {
2096 add_plugin (plugin_factory (plugin));
2100 Processor::set_state (node, version);
2102 PBD::ID new_id = this->id();
2103 PBD::ID old_id = this->id();
2105 if ((prop = node.property ("id")) != 0) {
2106 old_id = prop->value ();
2109 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2111 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2112 and set all plugins to the same state.
2115 if ((*niter)->name() == plugin->state_node_name()) {
2117 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2118 /* Plugin state can include external files which are named after the ID.
2120 * If regenerate_xml_or_string_ids() is set, the ID will already have
2121 * been changed, so we need to use the old ID from the XML to load the
2122 * state and then update the ID.
2124 * When copying a plugin-state, route_ui takes care of of updating the ID,
2125 * but we need to call set_insert_id() to clear the cached plugin-state
2126 * and force a change.
2128 if (!regenerate_xml_or_string_ids ()) {
2129 (*i)->set_insert_id (new_id);
2131 (*i)->set_insert_id (old_id);
2134 (*i)->set_state (**niter, version);
2136 if (regenerate_xml_or_string_ids ()) {
2137 (*i)->set_insert_id (new_id);
2145 if (version < 3000) {
2147 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2148 this is all handled by Automatable
2151 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2152 if ((*niter)->name() == "Redirect") {
2153 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2154 Processor::set_state (**niter, version);
2159 set_parameter_state_2X (node, version);
2162 if ((prop = node.property (X_("custom"))) != 0) {
2163 _custom_cfg = string_is_affirmative (prop->value());
2166 uint32_t in_maps = 0;
2167 uint32_t out_maps = 0;
2168 XMLNodeList kids = node.children ();
2169 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2170 if ((*i)->name() == X_("ConfiguredOutput")) {
2171 _custom_out = ChanCount(**i);
2173 if ((*i)->name() == X_("PresetOutput")) {
2174 _preset_out = ChanCount(**i);
2176 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2177 long pc = atol (&((*i)->name().c_str()[9]));
2178 if (pc >=0 && pc <= get_count()) {
2179 _in_map[pc] = ChanMapping (**i);
2183 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2184 long pc = atol (&((*i)->name().c_str()[10]));
2185 if (pc >=0 && pc <= get_count()) {
2186 _out_map[pc] = ChanMapping (**i);
2190 if ((*i)->name () == "ThruMap") {
2191 _thru_map = ChanMapping (**i);
2194 // sidechain is a Processor (IO)
2195 if ((*i)->name () == Processor::state_node_name) {
2199 _sidechain->set_state (**i, version);
2203 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2204 _maps_from_state = true;
2207 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2211 (*i)->deactivate ();
2215 PluginConfigChanged (); /* EMIT SIGNAL */
2220 PluginInsert::update_id (PBD::ID id)
2223 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2224 (*i)->set_insert_id (id);
2229 PluginInsert::set_state_dir (const std::string& d)
2231 // state() only saves the state of the first plugin
2232 _plugins[0]->set_state_dir (d);
2236 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2238 XMLNodeList nlist = node.children();
2239 XMLNodeIterator niter;
2241 /* look for port automation node */
2243 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2245 if ((*niter)->name() != port_automation_node_name) {
2251 XMLNodeConstIterator iter;
2256 cnodes = (*niter)->children ("port");
2258 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2262 if ((cprop = child->property("number")) != 0) {
2263 port = cprop->value().c_str();
2265 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2269 sscanf (port, "%" PRIu32, &port_id);
2271 if (port_id >= _plugins[0]->parameter_count()) {
2272 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2276 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2277 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2279 if (c && c->alist()) {
2280 if (!child->children().empty()) {
2281 c->alist()->set_state (*child->children().front(), version);
2283 /* In some cases 2.X saves lists with min_yval and max_yval
2284 being FLT_MIN and FLT_MAX respectively. This causes problems
2285 in A3 because these min/max values are used to compute
2286 where GUI control points should be drawn. If we see such
2287 values, `correct' them to the min/max of the appropriate
2291 float min_y = c->alist()->get_min_y ();
2292 float max_y = c->alist()->get_max_y ();
2294 ParameterDescriptor desc;
2295 _plugins.front()->get_parameter_descriptor (port_id, desc);
2297 if (min_y == FLT_MIN) {
2301 if (max_y == FLT_MAX) {
2305 c->alist()->set_yrange (min_y, max_y);
2308 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2320 PluginInsert::describe_parameter (Evoral::Parameter param)
2322 if (param.type() == PluginAutomation) {
2323 return _plugins[0]->describe_parameter (param);
2324 } else if (param.type() == PluginPropertyAutomation) {
2325 boost::shared_ptr<AutomationControl> c(automation_control(param));
2326 if (c && !c->desc().label.empty()) {
2327 return c->desc().label;
2330 return Automatable::describe_parameter(param);
2334 PluginInsert::signal_latency() const
2336 if (_user_latency) {
2337 return _user_latency;
2340 return _plugins[0]->signal_latency ();
2344 PluginInsert::type ()
2346 return plugin()->get_info()->type;
2349 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2350 const Evoral::Parameter& param,
2351 const ParameterDescriptor& desc,
2352 boost::shared_ptr<AutomationList> list)
2353 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2357 alist()->reset_default (desc.normal);
2359 list->set_interpolation(Evoral::ControlList::Discrete);
2364 set_flags(Controllable::Toggle);
2368 /** @param val `user' value */
2370 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2373 _set_value (user_val, group_override);
2377 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2379 /* used only by automation playback */
2380 _set_value (user_val, Controllable::NoGroup);
2384 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2386 /* FIXME: probably should be taking out some lock here.. */
2388 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2389 (*i)->set_parameter (_list->parameter().id(), user_val);
2392 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2394 iasp->set_parameter (_list->parameter().id(), user_val);
2397 AutomationControl::set_value (user_val, group_override);
2401 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2403 AutomationControl::set_value (user_val, Controllable::NoGroup);
2407 PluginInsert::PluginControl::get_state ()
2411 XMLNode& node (AutomationControl::get_state());
2412 ss << parameter().id();
2413 node.add_property (X_("parameter"), ss.str());
2415 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2417 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2424 /** @return `user' val */
2426 PluginInsert::PluginControl::get_value () const
2428 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2434 return plugin->get_parameter (_list->parameter().id());
2437 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2438 const Evoral::Parameter& param,
2439 const ParameterDescriptor& desc,
2440 boost::shared_ptr<AutomationList> list)
2441 : AutomationControl (p->session(), param, desc, list)
2445 alist()->set_yrange (desc.lower, desc.upper);
2446 alist()->reset_default (desc.normal);
2450 set_flags(Controllable::Toggle);
2455 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2458 set_value_unchecked (user_val);
2463 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2465 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2466 This is lossy, but better than nothing until Ardour's automation system
2467 can handle various datatypes all the way down. */
2468 const Variant value(_desc.datatype, user_val);
2469 if (value.type() == Variant::NOTHING) {
2470 error << "set_value(double) called for non-numeric property" << endmsg;
2474 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2475 (*i)->set_property(_list->parameter().id(), value);
2479 AutomationControl::set_value (user_val, Controllable::NoGroup);
2483 PluginInsert::PluginPropertyControl::get_state ()
2487 XMLNode& node (AutomationControl::get_state());
2488 ss << parameter().id();
2489 node.add_property (X_("property"), ss.str());
2490 node.remove_property (X_("value"));
2496 PluginInsert::PluginPropertyControl::get_value () const
2498 return _value.to_double();
2501 boost::shared_ptr<Plugin>
2502 PluginInsert::get_impulse_analysis_plugin()
2504 boost::shared_ptr<Plugin> ret;
2505 if (_impulseAnalysisPlugin.expired()) {
2506 ret = plugin_factory(_plugins[0]);
2507 ret->configure_io (internal_input_streams (), internal_output_streams ());
2508 _impulseAnalysisPlugin = ret;
2510 ret = _impulseAnalysisPlugin.lock();
2517 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2519 // called from outside the audio thread, so this should be safe
2520 // only do audio as analysis is (currently) only for audio plugins
2521 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2522 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2524 _signal_analysis_collected_nframes = 0;
2525 _signal_analysis_collect_nframes_max = nframes;
2528 /** Add a plugin to our list */
2530 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2532 plugin->set_insert_id (this->id());
2534 if (_plugins.empty()) {
2535 /* first (and probably only) plugin instance - connect to relevant signals */
2537 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2538 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2539 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2540 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2541 // cache sidechain port count
2542 _cached_sidechain_pins.reset ();
2543 const ChanCount& nis (plugin->get_info()->n_inputs);
2544 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2545 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2546 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2547 if (iod.is_sidechain) {
2548 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2553 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2554 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2556 vst->set_insert (this, _plugins.size ());
2559 _plugins.push_back (plugin);
2563 PluginInsert::realtime_handle_transport_stopped ()
2565 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2566 (*i)->realtime_handle_transport_stopped ();
2571 PluginInsert::realtime_locate ()
2573 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2574 (*i)->realtime_locate ();
2579 PluginInsert::monitoring_changed ()
2581 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2582 (*i)->monitoring_changed ();
2587 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2589 // this is called in RT context, LatencyChanged is emitted after run()
2590 _latency_changed = true;
2594 PluginInsert::start_touch (uint32_t param_id)
2596 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2598 ac->start_touch (session().audible_frame());
2603 PluginInsert::end_touch (uint32_t param_id)
2605 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2607 ac->stop_touch (true, session().audible_frame());
2611 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2614 case PluginInsert::Impossible: o << "Impossible"; break;
2615 case PluginInsert::Delegate: o << "Delegate"; break;
2616 case PluginInsert::NoInputs: o << "NoInputs"; break;
2617 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2618 case PluginInsert::Replicate: o << "Replicate"; break;
2619 case PluginInsert::Split: o << "Split"; break;
2620 case PluginInsert::Hide: o << "Hide"; break;
2622 o << " cnt: " << m.plugins
2623 << (m.strict_io ? " strict-io" : "")
2624 << (m.custom_cfg ? " custom-cfg" : "");
2625 if (m.method == PluginInsert::Hide) {
2626 o << " hide: " << m.hide;