2 * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2007-2014 David Robillard <d@drobilla.net>
5 * Copyright (C) 2008-2009 Sampo Savolainen <v2@iki.fi>
6 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
7 * Copyright (C) 2016-2017 Tim Mayberry <mojofunk@gmail.com>
8 * Copyright (C) 2018 Johannes Mueller <github@johannes-mueller.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "libardour-config.h"
31 #include "pbd/failed_constructor.h"
32 #include "pbd/xml++.h"
33 #include "pbd/types_convert.h"
35 #include "ardour/audio_buffer.h"
36 #include "ardour/automation_list.h"
37 #include "ardour/buffer_set.h"
38 #include "ardour/debug.h"
39 #include "ardour/event_type_map.h"
40 #include "ardour/ladspa_plugin.h"
41 #include "ardour/luaproc.h"
42 #include "ardour/plugin.h"
43 #include "ardour/plugin_insert.h"
44 #include "ardour/port.h"
47 #include "ardour/lv2_plugin.h"
50 #ifdef WINDOWS_VST_SUPPORT
51 #include "ardour/windows_vst_plugin.h"
55 #include "ardour/lxvst_plugin.h"
59 #include "ardour/mac_vst_plugin.h"
62 #ifdef AUDIOUNIT_SUPPORT
63 #include "ardour/audio_unit.h"
66 #include "ardour/session.h"
67 #include "ardour/types.h"
72 using namespace ARDOUR;
75 const string PluginInsert::port_automation_node_name = "PortAutomation";
77 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
78 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
79 , _sc_playback_latency (0)
80 , _sc_capture_latency (0)
81 , _plugin_signal_latency (0)
82 , _signal_analysis_collect_nsamples (0)
83 , _signal_analysis_collect_nsamples_max (0)
88 , _maps_from_state (false)
89 , _latency_changed (false)
90 , _bypass_port (UINT32_MAX)
93 /* the first is the master */
97 create_automatable_parameters ();
98 const ChanCount& sc (sidechain_input_pins ());
99 if (sc.n_audio () > 0 || sc.n_midi () > 0) {
100 add_sidechain (sc.n_audio (), sc.n_midi ());
105 PluginInsert::~PluginInsert ()
107 for (CtrlOutMap::const_iterator i = _control_outputs.begin(); i != _control_outputs.end(); ++i) {
108 boost::dynamic_pointer_cast<ReadOnlyControl>(i->second)->drop_references ();
113 PluginInsert::set_strict_io (bool b)
115 if (!_plugins.empty() && _plugins.front()->connect_all_audio_outputs ()) {
116 /* Ignore route setting, allow plugin to add/remove ports */
120 bool changed = _strict_io != b;
124 PluginConfigChanged (); /* EMIT SIGNAL */
129 PluginInsert::set_count (uint32_t num)
131 bool require_state = !_plugins.empty();
133 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
134 // we don't allow to replicate AUs
138 /* this is a bad idea.... we shouldn't do this while active.
139 * only a route holding their redirect_lock should be calling this
144 } else if (num > _plugins.size()) {
145 uint32_t diff = num - _plugins.size();
147 for (uint32_t n = 0; n < diff; ++n) {
148 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
152 XMLNode& state = _plugins[0]->get_state ();
153 p->set_state (state, Stateful::loading_state_version);
160 PluginConfigChanged (); /* EMIT SIGNAL */
162 } else if (num < _plugins.size()) {
163 uint32_t diff = _plugins.size() - num;
164 for (uint32_t n= 0; n < diff; ++n) {
167 PluginConfigChanged (); /* EMIT SIGNAL */
175 PluginInsert::set_sinks (const ChanCount& c)
178 /* no signal, change will only be visible after re-config */
182 PluginInsert::set_outputs (const ChanCount& c)
184 bool changed = (_custom_out != c) && _custom_cfg;
187 PluginConfigChanged (); /* EMIT SIGNAL */
192 PluginInsert::set_custom_cfg (bool b)
194 bool changed = _custom_cfg != b;
197 PluginConfigChanged (); /* EMIT SIGNAL */
202 PluginInsert::set_preset_out (const ChanCount& c)
204 bool changed = _preset_out != c;
206 if (changed && !_custom_cfg) {
207 PluginConfigChanged (); /* EMIT SIGNAL */
213 PluginInsert::add_sidechain (uint32_t n_audio, uint32_t n_midi)
215 // caller must hold process lock
219 std::ostringstream n;
220 if (n_audio == 0 && n_midi == 0) {
221 n << "TO BE RESET FROM XML";
222 } else if (owner()) {
223 n << "SC " << owner()->name() << "/" << name() << " " << Session::next_name_id ();
227 SideChain *sc = new SideChain (_session, n.str ());
228 _sidechain = boost::shared_ptr<SideChain> (sc);
229 _sidechain->activate ();
230 for (uint32_t n = 0; n < n_audio; ++n) {
231 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
233 for (uint32_t n = 0; n < n_midi; ++n) {
234 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
236 PluginConfigChanged (); /* EMIT SIGNAL */
241 PluginInsert::del_sidechain ()
247 _sc_playback_latency = 0;
248 _sc_capture_latency = 0;
249 PluginConfigChanged (); /* EMIT SIGNAL */
254 PluginInsert::update_sidechain_name ()
260 std::ostringstream n;
264 n << owner()->name() << "/";
267 n << name() << " " << Session::next_name_id ();
269 _sidechain->set_name (n.str());
273 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
275 if (which.type() != PluginAutomation)
278 boost::shared_ptr<AutomationControl> c
279 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
282 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()));
287 PluginInsert::output_streams() const
289 assert (_configured);
290 return _configured_out;
294 PluginInsert::input_streams() const
296 assert (_configured);
297 return _configured_in;
301 PluginInsert::internal_streams() const
303 assert (_configured);
304 return _configured_internal;
308 PluginInsert::internal_output_streams() const
310 assert (!_plugins.empty());
312 PluginInfoPtr info = _plugins.front()->get_info();
314 if (info->reconfigurable_io()) {
315 ChanCount out = _plugins.front()->output_streams ();
316 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
319 ChanCount out = info->n_outputs;
320 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
321 out.set_audio (out.n_audio() * _plugins.size());
322 out.set_midi (out.n_midi() * _plugins.size());
328 PluginInsert::internal_input_streams() const
330 assert (!_plugins.empty());
334 PluginInfoPtr info = _plugins.front()->get_info();
336 if (info->reconfigurable_io()) {
337 in = _plugins.front()->input_streams();
342 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
344 if (_match.method == Split) {
346 /* we are splitting 1 processor input to multiple plugin inputs,
347 so we have a maximum of 1 stream of each type.
349 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
350 if (in.get (*t) > 1) {
356 } else if (_match.method == Hide) {
358 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
359 in.set (*t, in.get (*t) - _match.hide.get (*t));
365 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
366 in.set (*t, in.get (*t) * _plugins.size ());
374 PluginInsert::natural_output_streams() const
377 if (is_channelstrip ()) {
378 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
381 return _plugins[0]->get_info()->n_outputs;
385 PluginInsert::natural_input_streams() const
388 if (is_channelstrip ()) {
389 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
392 return _plugins[0]->get_info()->n_inputs;
396 PluginInsert::sidechain_input_pins() const
398 return _cached_sidechain_pins;
402 PluginInsert::has_no_inputs() const
404 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
408 PluginInsert::has_no_audio_inputs() const
410 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
414 PluginInsert::plugin_latency () const {
415 return _plugins.front()->signal_latency ();
419 PluginInsert::is_instrument() const
421 PluginInfoPtr pip = _plugins[0]->get_info();
422 return (pip->is_instrument ());
426 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
428 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
429 // collect possible configurations, prefer given in/out
430 _plugins[0]->can_support_io_configuration (in, out);
433 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
435 if (ppc.size () == 0) {
438 if (!strict_io () && ppc.size () == 1) {
442 if (strict_io () && ppc.size () == 1) {
443 // "stereo" is currently preferred default for instruments
444 if (ppc.find (2) != ppc.end ()) {
449 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
450 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
451 // pretending to be an "Instrument"
455 if (!is_instrument ()) {
462 PluginInsert::create_automatable_parameters ()
464 assert (!_plugins.empty());
466 boost::shared_ptr<Plugin> plugin = _plugins.front();
467 set<Evoral::Parameter> a = _plugins.front()->automatable ();
469 const uint32_t limit_automatables = Config->get_limit_n_automatables ();
471 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
472 if (!plugin->parameter_is_control (i)) {
476 ParameterDescriptor desc;
477 plugin->get_parameter_descriptor(i, desc);
479 if (!plugin->parameter_is_input (i)) {
480 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
483 Evoral::Parameter param (PluginAutomation, 0, i);
485 const bool automatable = a.find(param) != a.end();
487 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
488 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
489 if (!automatable || (limit_automatables > 0 && i > limit_automatables)) {
490 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
493 plugin->set_automation_control (i, c);
497 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
498 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
499 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
500 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
501 if (desc.datatype != Variant::NOTHING) {
502 boost::shared_ptr<AutomationList> list;
503 if (Variant::type_is_numeric(desc.datatype)) {
504 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
506 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
507 if (!Variant::type_is_numeric(desc.datatype)) {
508 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
514 _bypass_port = plugin->designated_bypass_port ();
516 /* special case VST effSetBypass */
517 if (_bypass_port == UINT32_MAX -1) {
518 // emulate VST Bypass
519 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
520 ParameterDescriptor desc;
521 desc.label = _("Plugin Enable");
526 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
527 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
531 if (_bypass_port != UINT32_MAX) {
532 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
533 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
534 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
535 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
538 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
541 /** Called when something outside of this host has modified a plugin
542 * parameter. Responsible for propagating the change to two places:
544 * 1) anything listening to the Control itself
545 * 2) any replicated plugins that make up this PluginInsert.
547 * The PluginInsert is connected to the ParameterChangedExternally signal for
548 * the first (primary) plugin, and here broadcasts that change to any others.
550 * XXX We should probably drop this whole replication idea (Paul, October 2015)
551 * since it isn't used by sensible plugin APIs (AU, LV2).
554 PluginInsert::parameter_changed_externally (uint32_t which, float val)
556 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
558 /* First propagation: alter the underlying value of the control,
559 * without telling the plugin(s) that own/use it to set it.
566 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
569 pc->catch_up_with_external_value (val);
572 /* Second propagation: tell all plugins except the first to
573 update the value of this parameter. For sane plugin APIs,
574 there are no other plugins, so this is a no-op in those
578 Plugins::iterator i = _plugins.begin();
580 /* don't set the first plugin, just all the slaves */
582 if (i != _plugins.end()) {
584 for (; i != _plugins.end(); ++i) {
585 (*i)->set_parameter (which, val);
588 boost::shared_ptr<Plugin> iasp = _impulseAnalysisPlugin.lock();
590 iasp->set_parameter (which, val);
595 PluginInsert::set_block_size (pframes_t nframes)
598 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
599 if ((*i)->set_block_size (nframes) != 0) {
607 PluginInsert::automation_run (samplepos_t start, pframes_t nframes, bool only_active)
609 // XXX does not work when rolling backwards
610 if (_loop_location && nframes > 0) {
611 const samplepos_t loop_start = _loop_location->start ();
612 const samplepos_t loop_end = _loop_location->end ();
613 const samplecnt_t looplen = loop_end - loop_start;
615 samplecnt_t remain = nframes;
616 samplepos_t start_pos = start;
619 if (start_pos >= loop_end) {
620 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
621 start_pos = loop_start + start_off;
623 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
625 Automatable::automation_run (start_pos, move, only_active);
631 Automatable::automation_run (start, nframes, only_active);
635 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
637 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
639 if (_loop_location && now < end) {
641 end = ceil (next_event.when);
643 const samplepos_t loop_end = _loop_location->end ();
644 assert (now < loop_end); // due to map_loop_range ()
645 if (end > loop_end) {
646 next_event.when = loop_end;
654 PluginInsert::activate ()
656 _timing_stats.reset ();
657 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
661 Processor::activate ();
662 /* when setting state e.g ProcessorBox::paste_processor_state ()
663 * the plugin is not yet owned by a route.
664 * but no matter. Route::add_processors() will call activate () again
670 const samplecnt_t l = effective_latency ();
671 if (_plugin_signal_latency != l) {
672 _plugin_signal_latency = l;
678 PluginInsert::deactivate ()
680 _timing_stats.reset ();
681 Processor::deactivate ();
683 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
687 const samplecnt_t l = effective_latency ();
688 if (_plugin_signal_latency != l) {
689 _plugin_signal_latency = l;
695 PluginInsert::flush ()
697 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
703 PluginInsert::enable (bool yn)
705 if (_bypass_port == UINT32_MAX) {
712 if (!_pending_active) {
715 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
716 const double val = yn ? 1.0 : 0.0;
717 ac->set_value (val, Controllable::NoGroup);
719 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
720 /* special case VST.. bypass may fail */
721 if (_bypass_port == UINT32_MAX - 1) {
722 /* check if bypass worked */
723 if (ac->get_value () != val) {
724 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
725 // set plugin to enabled (not-byassed)
726 ac->set_value (1.0, Controllable::NoGroup);
727 // ..and use host-provided hard-bypass
742 PluginInsert::enabled () const
744 if (_bypass_port == UINT32_MAX) {
745 return Processor::enabled ();
747 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
748 return (ac->get_value () > 0 && _pending_active);
753 PluginInsert::bypassable () const
755 if (_bypass_port == UINT32_MAX) {
758 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
760 return !ac->automation_playback ();
765 PluginInsert::enable_changed ()
771 PluginInsert::bypassable_changed ()
773 BypassableChanged ();
777 PluginInsert::write_immediate_event (size_t size, const uint8_t* buf)
780 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
781 if (!(*i)->write_immediate_event (size, buf)) {
789 PluginInsert::preset_load_set_value (uint32_t p, float v)
791 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
796 if (ac->automation_state() & Play) {
801 ac->set_value (v, Controllable::NoGroup);
806 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
808 // TODO optimize: store "unconnected" in a fixed set.
809 // it only changes on reconfiguration.
810 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
811 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
813 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
814 mapped = true; // in-place Midi bypass
816 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
817 PinMappings::const_iterator i = out_map.find (pc);
818 if (i == out_map.end ()) {
821 const ChanMapping& outmap (i->second);
822 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
824 uint32_t idx = outmap.get (*t, o, &valid);
825 if (valid && idx == out) {
832 bufs.get_available (*t, out).silence (nframes, offset);
839 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
841 if (_mapping_changed) { // ToDo use a counter, increment until match
842 _no_inplace = check_inplace ();
843 _mapping_changed = false;
845 // TODO: atomically copy maps & _no_inplace
846 PinMappings in_map (_in_map); // TODO Split case below overrides, use const& in_map
847 PinMappings const& out_map (_out_map);
848 ChanMapping const& thru_map (_thru_map);
850 if (_latency_changed) {
851 /* delaylines are configured with the max possible latency (as reported by the plugin)
852 * so this won't allocate memory (unless the plugin lied about its max latency)
853 * It may still 'click' though, since the fixed delaylines are not de-clicked.
854 * Then again plugin-latency changes are not click-free to begin with.
856 * This is also worst case, there is currently no concept of per-stream latency.
858 * e.g. Two identical latent plugins:
859 * 1st plugin: process left (latent), bypass right.
860 * 2nd plugin: bypass left, process right (latent).
861 * -> currently this yields 2 times latency of the plugin,
863 _latency_changed = false;
864 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
867 if (_match.method == Split && !_no_inplace) {
868 // TODO: also use this optimization if one source-buffer
869 // feeds _all_ *connected* inputs.
870 // currently this is *first* buffer to all only --
871 // see PluginInsert::check_inplace
872 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
873 if (_configured_internal.get (*t) == 0) {
877 uint32_t first_idx = in_map.p(0).get (*t, 0, &valid);
878 assert (valid && first_idx == 0); // check_inplace ensures this
879 /* copy the first stream's buffer contents to the others */
880 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
881 uint32_t idx = in_map.p(0).get (*t, i, &valid);
884 bufs.get_available (*t, i).read_from (bufs.get_available (*t, first_idx), nframes, offset, offset);
888 /* the copy operation produces a linear monotonic input map */
889 in_map[0] = ChanMapping (natural_input_streams ());
892 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
893 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
896 boost::shared_ptr<ControlList> cl = _automated_controls.reader ();
897 for (ControlList::const_iterator ci = cl->begin(); ci != cl->end(); ++ci) {
898 AutomationControl& c = *(ci->get());
899 boost::shared_ptr<const Evoral::ControlList> clist (c.list());
900 /* we still need to check for Touch and Latch */
901 if (clist && (static_cast<AutomationList const&> (*clist)).automation_playback ()) {
903 const float val = c.list()->rt_safe_eval (start, valid);
905 c.set_value_unchecked(val);
911 if (_signal_analysis_collect_nsamples_max > 0) {
912 if (_signal_analysis_collect_nsamples < _signal_analysis_collect_nsamples_max) {
913 samplecnt_t ns = std::min ((samplecnt_t) nframes, _signal_analysis_collect_nsamples_max - _signal_analysis_collect_nsamples);
914 _signal_analysis_inputs.set_count (ChanCount (DataType::AUDIO, input_streams().n_audio()));
916 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
917 _signal_analysis_inputs.get_audio(i).read_from (
920 _signal_analysis_collect_nsamples);
923 _signal_analysis_collect_nsamples += nframes;
927 if (is_channelstrip ()) {
928 if (_configured_in.n_audio() > 0) {
929 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
930 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
932 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
934 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
935 bufs.get_available (DataType::AUDIO, out).silence (nframes, offset);
941 // TODO optimize -- build maps once.
943 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
944 ARDOUR::ChanMapping used_outputs;
946 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
948 /* build used-output map */
949 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
950 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
951 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
953 uint32_t out_idx = out_map.p(pc).get (*t, out, &valid);
955 used_outputs.set (*t, out_idx, 1); // mark as used
960 /* copy thru data to outputs before processing in-place */
961 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
962 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
964 uint32_t in_idx = thru_map.get (*t, out, &valid);
965 uint32_t m = out + natural_input_streams ().get (*t);
967 _delaybuffers.delay (*t, out, inplace_bufs.get_available (*t, m), bufs.get_available (*t, in_idx), nframes, offset, offset);
968 used_outputs.set (*t, out, 1); // mark as used
970 used_outputs.get (*t, out, &valid);
972 /* the plugin is expected to write here, but may not :(
973 * (e.g. drumgizmo w/o kit loaded)
975 inplace_bufs.get_available (*t, m).silence (nframes);
982 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
984 ARDOUR::ChanMapping i_in_map (natural_input_streams());
985 ARDOUR::ChanMapping i_out_map (out_map.p(pc));
986 ARDOUR::ChanCount mapped;
988 /* map inputs sequentially */
989 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
990 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
992 uint32_t in_idx = in_map.p(pc).get (*t, in, &valid);
993 uint32_t m = mapped.get (*t);
995 inplace_bufs.get_available (*t, m).read_from (bufs.get_available (*t, in_idx), nframes, offset, offset);
997 inplace_bufs.get_available (*t, m).silence (nframes, offset);
999 mapped.set (*t, m + 1);
1003 /* outputs are mapped to inplace_bufs after the inputs */
1004 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1005 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
1008 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1013 /* all instances have completed, now copy data that was written
1014 * and zero unconnected buffers */
1015 ARDOUR::ChanMapping nonzero_out (used_outputs);
1016 if (has_midi_bypass ()) {
1017 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1019 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1020 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1022 used_outputs.get (*t, out, &valid);
1024 nonzero_out.get (*t, out, &valid);
1026 bufs.get_available (*t, out).silence (nframes, offset);
1029 uint32_t m = out + natural_input_streams ().get (*t);
1030 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, m), nframes, offset, offset);
1035 /* in-place processing */
1037 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1038 if ((*i)->connect_and_run(bufs, start, end, speed, in_map.p(pc), out_map.p(pc), nframes, offset)) {
1042 // now silence unconnected outputs
1043 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1046 const samplecnt_t l = effective_latency ();
1047 if (_plugin_signal_latency != l) {
1048 _plugin_signal_latency = l;
1049 _signal_analysis_collect_nsamples = 0;
1053 if (_signal_analysis_collect_nsamples > l) {
1054 assert (_signal_analysis_collect_nsamples_max > 0);
1055 assert (_signal_analysis_collect_nsamples >= nframes);
1056 samplecnt_t sample_pos = _signal_analysis_collect_nsamples - nframes;
1058 samplecnt_t dst_off = sample_pos >= l ? sample_pos - l : 0;
1059 samplecnt_t src_off = sample_pos >= l ? 0 : l - sample_pos;
1060 samplecnt_t n_copy = std::min ((samplecnt_t)nframes, _signal_analysis_collect_nsamples - l);
1061 n_copy = std::min (n_copy, _signal_analysis_collect_nsamples_max - dst_off);
1063 _signal_analysis_outputs.set_count (ChanCount (DataType::AUDIO, output_streams().n_audio()));
1065 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1066 _signal_analysis_outputs.get_audio(i).read_from(
1067 bufs.get_audio(i), n_copy, dst_off, src_off);
1070 if (dst_off + n_copy == _signal_analysis_collect_nsamples_max) {
1071 _signal_analysis_collect_nsamples_max = 0;
1072 _signal_analysis_collect_nsamples = 0;
1074 AnalysisDataGathered (&_signal_analysis_inputs, &_signal_analysis_outputs); /* EMIT SIGNAL */
1080 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1082 /* bypass the plugin(s) not the whole processor.
1083 * -> use mappings just like connect_and_run
1085 if (_mapping_changed) {
1086 _no_inplace = check_inplace ();
1087 _mapping_changed = false;
1089 // TODO: atomically copy maps & _no_inplace
1090 ChanMapping const& in_map (no_sc_input_map ());
1091 ChanMapping const& out_map (output_map ());
1093 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1094 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1097 ChanMapping thru_map (_thru_map);
1099 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1101 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1102 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1103 inplace_bufs.get_available (*t, in).read_from (bufs.get_available (*t, in), nframes, 0, 0);
1106 ARDOUR::ChanMapping used_outputs;
1108 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1109 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1111 uint32_t in_idx = thru_map.get (*t, out, &valid);
1113 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, in_idx), nframes, 0, 0);
1114 used_outputs.set (*t, out, 1); // mark as used
1118 // plugin no-op: assume every plugin has an internal identity map
1119 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1120 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1122 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1126 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1130 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, in_idx), nframes, 0, 0);
1131 used_outputs.set (*t, out, 1); // mark as used
1134 // now silence all unused outputs
1135 if (has_midi_bypass ()) {
1136 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1138 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1139 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1141 used_outputs.get (*t, out, &valid);
1143 bufs.get_available (*t, out).silence (nframes, 0);
1148 if (_match.method == Split) {
1149 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1150 if (_configured_internal.get (*t) == 0) {
1153 // copy/feeds _all_ *connected* inputs, copy the first buffer
1155 uint32_t first_idx = in_map.get (*t, 0, &valid);
1156 assert (valid && first_idx == 0); // check_inplace ensures this
1157 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1158 uint32_t idx = in_map.get (*t, i, &valid);
1161 bufs.get_available (*t, i).read_from (bufs.get_available (*t, first_idx), nframes, 0, 0);
1167 // apply output map and/or monotonic but not identity i/o mappings
1168 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1169 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1171 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1173 bufs.get_available (*t, out).silence (nframes, 0);
1176 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1178 bufs.get_available (*t, out).silence (nframes, 0);
1181 if (in_idx != src_idx) {
1182 bufs.get_available (*t, out).read_from (bufs.get_available (*t, in_idx), nframes, 0, 0);
1190 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1192 automation_run (start_sample, nframes, true); // evaluate automation only
1195 // XXX delaybuffers need to be offset by nframes
1199 _delaybuffers.flush ();
1201 const ChanMapping in_map (natural_input_streams ());
1202 const ChanMapping out_map (natural_output_streams ());
1203 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1205 if (is_channelstrip ()) {
1206 if (_configured_in.n_audio() > 0) {
1207 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1211 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1212 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1217 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1220 // collect sidechain input for complete cycle (!)
1221 // TODO we need delaylines here for latency compensation
1222 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1225 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1226 _timing_stats.reset ();
1229 if (_pending_active) {
1230 #if defined MIXBUS && defined NDEBUG
1231 if (!is_channelstrip ()) {
1232 _timing_stats.start ();
1235 _timing_stats.start ();
1237 /* run as normal if we are active or moving from inactive to active */
1239 if (_session.transport_rolling() || _session.bounce_processing()) {
1240 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1242 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1243 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1245 #if defined MIXBUS && defined NDEBUG
1246 if (!is_channelstrip ()) {
1247 _timing_stats.update ();
1250 _timing_stats.update ();
1254 _timing_stats.reset ();
1255 // XXX should call ::silence() to run plugin(s) for consistent load.
1256 // We'll need to change this anyway when bypass can be automated
1257 bypass (bufs, nframes);
1258 automation_run (start_sample, nframes, true); // evaluate automation only
1259 _delaybuffers.flush ();
1262 _active = _pending_active;
1264 /* we have no idea whether the plugin generated silence or not, so mark
1265 * all buffers appropriately.
1270 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1272 Evoral::ControlEvent next_event (0, 0.0f);
1273 samplecnt_t offset = 0;
1275 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1278 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1282 /* map start back into loop-range, adjust end */
1283 map_loop_range (start, end);
1285 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1287 /* no events have a time within the relevant range */
1289 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1295 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1297 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1303 map_loop_range (start, end);
1305 if (!find_next_event (start, end, next_event)) {
1310 /* cleanup anything that is left to do */
1313 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1318 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1320 if (param.type() != PluginAutomation)
1323 if (_plugins.empty()) {
1324 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1326 abort(); /*NOTREACHED*/
1329 return _plugins[0]->default_value (param.id());
1334 PluginInsert::can_reset_all_parameters ()
1337 uint32_t params = 0;
1338 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1340 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1342 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1346 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1352 if (ac->automation_state() & Play) {
1357 return all && (params > 0);
1361 PluginInsert::reset_parameters_to_default ()
1365 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1367 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1369 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1373 const float dflt = _plugins[0]->default_value (cid);
1374 const float curr = _plugins[0]->get_parameter (cid);
1380 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1385 if (ac->automation_state() & Play) {
1390 ac->set_value (dflt, Controllable::NoGroup);
1395 boost::shared_ptr<Plugin>
1396 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1398 boost::shared_ptr<LadspaPlugin> lp;
1399 boost::shared_ptr<LuaProc> lua;
1401 boost::shared_ptr<LV2Plugin> lv2p;
1403 #ifdef WINDOWS_VST_SUPPORT
1404 boost::shared_ptr<WindowsVSTPlugin> vp;
1406 #ifdef LXVST_SUPPORT
1407 boost::shared_ptr<LXVSTPlugin> lxvp;
1409 #ifdef MACVST_SUPPORT
1410 boost::shared_ptr<MacVSTPlugin> mvp;
1412 #ifdef AUDIOUNIT_SUPPORT
1413 boost::shared_ptr<AUPlugin> ap;
1416 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1417 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1418 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1419 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1421 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1422 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1424 #ifdef WINDOWS_VST_SUPPORT
1425 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1426 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1428 #ifdef LXVST_SUPPORT
1429 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1430 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1432 #ifdef MACVST_SUPPORT
1433 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1434 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1436 #ifdef AUDIOUNIT_SUPPORT
1437 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1438 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1442 fatal << string_compose (_("programming error: %1"),
1443 X_("unknown plugin type in PluginInsert::plugin_factory"))
1445 abort(); /*NOTREACHED*/
1446 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1450 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1451 if (num < _in_map.size()) {
1452 bool changed = _in_map[num] != m;
1454 changed |= sanitize_maps ();
1456 PluginMapChanged (); /* EMIT SIGNAL */
1457 _mapping_changed = true;
1458 _session.set_dirty();
1464 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1465 if (num < _out_map.size()) {
1466 bool changed = _out_map[num] != m;
1468 changed |= sanitize_maps ();
1470 PluginMapChanged (); /* EMIT SIGNAL */
1471 _mapping_changed = true;
1472 _session.set_dirty();
1478 PluginInsert::set_thru_map (ChanMapping m) {
1479 bool changed = _thru_map != m;
1481 changed |= sanitize_maps ();
1483 PluginMapChanged (); /* EMIT SIGNAL */
1484 _mapping_changed = true;
1485 _session.set_dirty();
1490 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1491 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1493 if (_configured) { return false; }
1494 _configured_in = in;
1495 _configured_out = out;
1499 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1504 PluginInsert::input_map () const
1508 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1509 ChanMapping m (i->second);
1510 const ChanMapping::Mappings& mp ((*i).second.mappings());
1511 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1512 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1513 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1522 PluginInsert::no_sc_input_map () const
1526 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1527 ChanMapping m (i->second);
1528 const ChanMapping::Mappings& mp ((*i).second.mappings());
1529 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1530 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1531 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1532 if (i->first < ins) {
1533 rv.set (tm->first, i->first + pc * ins, i->second);
1538 if (has_midi_thru ()) {
1539 rv.set (DataType::MIDI, 0, 0);
1545 PluginInsert::output_map () const
1549 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1550 ChanMapping m (i->second);
1551 const ChanMapping::Mappings& mp ((*i).second.mappings());
1552 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1553 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1554 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1558 if (has_midi_bypass ()) {
1559 rv.set (DataType::MIDI, 0, 0);
1566 PluginInsert::has_midi_bypass () const
1568 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1569 && natural_output_streams ().n_midi () == 0) {
1576 PluginInsert::has_midi_thru () const
1578 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1579 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1586 PluginInsert::is_channelstrip () const
1592 PluginInsert::check_inplace ()
1594 bool inplace_ok = !_plugins.front()->inplace_broken ();
1596 if (_thru_map.n_total () > 0) {
1597 // TODO once midi-bypass is part of the mapping, ignore it
1601 if (_match.method == Split && inplace_ok) {
1602 assert (get_count() == 1);
1603 assert (_in_map.size () == 1);
1604 if (!_out_map[0].is_monotonic ()) {
1607 if (_configured_internal != _configured_in) {
1608 /* no sidechain -- TODO we could allow this with
1609 * some more logic in PluginInsert::connect_and_run().
1611 * PluginInsert::reset_map() already maps it.
1616 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1617 if (_configured_internal.get (*t) == 0) {
1621 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1622 if (!valid || first_idx != 0) {
1623 // so far only allow to copy the *first* stream's buffer to others
1626 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1627 uint32_t idx = _in_map[0].get (*t, i, &valid);
1628 if (valid && idx != first_idx) {
1637 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1642 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1643 if (!_in_map[pc].is_monotonic ()) {
1646 if (!_out_map[pc].is_monotonic ()) {
1652 /* check if every output is fed by the corresponding input
1654 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1655 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1657 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1659 ChanMapping const& in_map (input_map ());
1660 const ChanMapping::Mappings out_m (output_map ().mappings ());
1661 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1662 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1663 /* src-pin: c->first, out-port: c->second */
1665 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1666 if (valid && in_port != c->second) {
1674 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1675 return !inplace_ok; // no-inplace
1679 PluginInsert::sanitize_maps ()
1681 bool changed = false;
1682 /* strip dead wood */
1683 PinMappings new_ins;
1684 PinMappings new_outs;
1685 ChanMapping new_thru;
1687 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1689 ChanMapping new_out;
1690 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1691 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1693 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1694 if (valid && idx < _configured_internal.get (*t)) {
1695 new_in.set (*t, i, idx);
1698 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1700 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1701 if (valid && idx < _configured_out.get (*t)) {
1702 new_out.set (*t, o, idx);
1706 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1709 new_ins[pc] = new_in;
1710 new_outs[pc] = new_out;
1713 /* prevent dup output assignments */
1714 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1715 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1716 bool mapped = false;
1717 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1719 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1720 if (valid && mapped) {
1721 new_outs[pc].unset (*t, idx);
1729 /* remove excess thru */
1730 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1731 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1733 uint32_t idx = _thru_map.get (*t, o, &valid);
1734 if (valid && idx < _configured_internal.get (*t)) {
1735 new_thru.set (*t, o, idx);
1740 /* prevent out + thru, existing plugin outputs override thru */
1741 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1742 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1743 bool mapped = false;
1745 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1746 new_outs[pc].get_src (*t, o, &mapped);
1747 if (mapped) { break; }
1749 if (!mapped) { continue; }
1750 uint32_t idx = new_thru.get (*t, o, &valid);
1752 new_thru.unset (*t, idx);
1757 if (has_midi_bypass ()) {
1758 // TODO: include midi-bypass in the thru set,
1759 // remove dedicated handling.
1760 new_thru.unset (DataType::MIDI, 0);
1763 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1767 _out_map = new_outs;
1768 _thru_map = new_thru;
1774 PluginInsert::reset_map (bool emit)
1776 const PinMappings old_in (_in_map);
1777 const PinMappings old_out (_out_map);
1781 _thru_map = ChanMapping ();
1783 /* build input map */
1784 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1785 uint32_t sc = 0; // side-chain round-robin (all instances)
1787 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1788 const uint32_t nis = natural_input_streams ().get(*t);
1789 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1791 /* SC inputs are last in the plugin-insert.. */
1792 const uint32_t sc_start = _configured_in.get (*t);
1793 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1794 /* ...but may not be at the end of the plugin ports.
1795 * in case the side-chain is not the last port, shift connections back.
1796 * and connect to side-chain
1799 uint32_t ic = 0; // split inputs
1800 const uint32_t cend = _configured_in.get (*t);
1802 for (uint32_t in = 0; in < nis; ++in) {
1803 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1804 if (iod.is_sidechain) {
1805 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1806 if (sc_len > 0) {// side-chain may be hidden
1807 _in_map[pc].set (*t, in, sc_start + sc);
1808 sc = (sc + 1) % sc_len;
1812 if (_match.method == Split) {
1813 if (cend == 0) { continue; }
1814 if (_strict_io && ic + stride * pc >= cend) {
1817 /* connect *no* sidechain sinks in round-robin fashion */
1818 _in_map[pc].set (*t, in, ic + stride * pc);
1819 if (_strict_io && (ic + 1) == cend) {
1822 ic = (ic + 1) % cend;
1824 uint32_t s = in - shift;
1825 if (stride * pc + s < cend) {
1826 _in_map[pc].set (*t, in, s + stride * pc);
1834 /* build output map */
1836 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1837 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1838 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1839 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1844 if (old_in == _in_map && old_out == _out_map) {
1848 PluginMapChanged (); /* EMIT SIGNAL */
1849 _mapping_changed = true;
1850 _session.set_dirty();
1856 PluginInsert::configure_io (ChanCount in, ChanCount out)
1858 Match old_match = _match;
1860 ChanCount old_internal;
1864 old_pins = natural_input_streams();
1865 old_in = _configured_in;
1866 old_out = _configured_out;
1867 old_internal = _configured_internal;
1869 _configured_in = in;
1870 _configured_internal = in;
1871 _configured_out = out;
1874 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1875 * (currently _sidechain->configure_io always succeeds
1876 * since Processor::configure_io() succeeds)
1878 if (!_sidechain->configure_io (in, out)) {
1879 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1882 _configured_internal += _sidechain->input()->n_ports();
1884 // include (static_cast<Route*>owner())->name() ??
1885 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1888 /* get plugin configuration */
1889 _match = private_can_support_io_configuration (in, out);
1891 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1893 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1894 DEBUG_STR_APPEND(a, _match);
1895 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1899 /* set the matching method and number of plugins that we will use to meet this configuration */
1900 if (set_count (_match.plugins) == false) {
1901 PluginIoReConfigure (); /* EMIT SIGNAL */
1902 _configured = false;
1906 /* configure plugins */
1907 switch (_match.method) {
1910 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1911 PluginIoReConfigure (); /* EMIT SIGNAL */
1912 _configured = false;
1918 ChanCount din (_configured_internal);
1919 ChanCount dout (din); // hint
1921 if (_custom_sinks.n_total () > 0) {
1922 din = _custom_sinks;
1925 } else if (_preset_out.n_audio () > 0) {
1926 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1927 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1928 dout.set (DataType::AUDIO, 2);
1930 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1932 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1933 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1935 if (useins.n_audio() == 0) {
1938 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1940 if (_plugins.front()->configure_io (useins, dout) == false) {
1941 PluginIoReConfigure (); /* EMIT SIGNAL */
1942 _configured = false;
1946 _custom_sinks = din;
1951 if (_plugins.front()->configure_io (in, out) == false) {
1952 PluginIoReConfigure (); /* EMIT SIGNAL */
1953 _configured = false;
1959 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: cfg:%2 state:%3 chn-in:%4 chn-out:%5 inpin:%6 match:%7 cust:%8 size-in:%9 size-out:%10\n",
1961 _configured ? "Y" : "N",
1962 _maps_from_state ? "Y" : "N",
1963 old_in == in ? "==" : "!=",
1964 old_out == out ? "==" : "!=",
1965 old_pins == natural_input_streams () ? "==" : "!=",
1966 old_match.method == _match.method ? "==" : "!=",
1967 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1968 _in_map.size() == get_count () ? "==" : "!=",
1969 _out_map.size() == get_count () ? "==" : "!="
1972 bool mapping_changed = false;
1973 if (old_in == in && old_out == out
1975 && old_pins == natural_input_streams ()
1976 && old_match.method == _match.method
1977 && old_match.custom_cfg == _match.custom_cfg
1978 && _in_map.size() == _out_map.size()
1979 && _in_map.size() == get_count ()
1981 /* If the configuration has not changed, keep the mapping */
1982 mapping_changed = sanitize_maps ();
1983 } else if (_match.custom_cfg && _configured) {
1984 /* don't touch the map in manual mode */
1985 mapping_changed = sanitize_maps ();
1988 if (is_channelstrip ()) {
1989 /* fake channel map - for wire display */
1992 _thru_map = ChanMapping ();
1993 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1994 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1995 /* set "thru" map for in-place forward of audio */
1996 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1997 _thru_map.set (DataType::AUDIO, i, i);
1999 /* and midi (after implicit 1st channel bypass) */
2000 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
2001 _thru_map.set (DataType::MIDI, i, i);
2005 if (_maps_from_state && old_in == in && old_out == out) {
2006 mapping_changed = true;
2009 /* generate a new mapping */
2010 mapping_changed = reset_map (false);
2012 _maps_from_state = false;
2015 if (mapping_changed) {
2016 PluginMapChanged (); /* EMIT SIGNAL */
2019 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2022 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2023 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2025 DEBUG_STR_APPEND(a, "----><----\n");
2027 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2028 DEBUG_STR_APPEND(a, " * Inputs:\n");
2029 DEBUG_STR_APPEND(a, _in_map[pc]);
2030 DEBUG_STR_APPEND(a, " * Outputs:\n");
2031 DEBUG_STR_APPEND(a, _out_map[pc]);
2033 DEBUG_STR_APPEND(a, " * Thru:\n");
2034 DEBUG_STR_APPEND(a, _thru_map);
2035 DEBUG_STR_APPEND(a, "-------->>--------\n");
2036 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2041 _no_inplace = check_inplace ();
2042 _mapping_changed = false;
2044 /* only the "noinplace_buffers" thread buffers need to be this large,
2045 * this can be optimized. other buffers are fine with
2046 * ChanCount::max (natural_input_streams (), natural_output_streams())
2047 * and route.cc's max (configured_in, configured_out)
2049 * no-inplace copies "thru" outputs (to emulate in-place) for
2050 * all outputs (to prevent overwrite) into a temporary space
2051 * which also holds input buffers (in case the plugin does process
2052 * in-place and overwrites those).
2054 * this buffers need to be at least as
2055 * natural_input_streams () + possible outputs.
2057 * sidechain inputs add a constraint on the input:
2058 * configured input + sidechain (=_configured_internal)
2060 * NB. this also satisfies
2061 * max (natural_input_streams(), natural_output_streams())
2062 * which is needed for silence runs
2064 _required_buffers = ChanCount::max (_configured_internal,
2065 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2067 if (old_in != in || old_out != out || old_internal != _configured_internal
2068 || old_pins != natural_input_streams ()
2069 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2071 PluginIoReConfigure (); /* EMIT SIGNAL */
2074 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2075 _latency_changed = true;
2077 /* we don't know the analysis window size, so we must work with the
2078 * current buffer size here. each request for data fills in these
2079 * buffers and the analyser makes sure it gets enough data for the
2080 * analysis window. We also only analyze audio, so we can ignore
2083 ChanCount cc_analysis_in (DataType::AUDIO, in.n_audio());
2084 ChanCount cc_analysis_out (DataType::AUDIO, out.n_audio());
2086 session().ensure_buffer_set (_signal_analysis_inputs, cc_analysis_in);
2087 _signal_analysis_inputs.set_count (cc_analysis_in);
2089 session().ensure_buffer_set (_signal_analysis_outputs, cc_analysis_out);
2090 _signal_analysis_outputs.set_count (cc_analysis_out);
2092 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2095 return Processor::configure_io (in, out);
2098 /** Decide whether this PluginInsert can support a given IO configuration.
2099 * To do this, we run through a set of possible solutions in rough order of
2102 * @param in Required input channel count.
2103 * @param out Filled in with the output channel count if we return true.
2104 * @return true if the given IO configuration can be supported.
2107 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2110 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2112 return private_can_support_io_configuration (in, out).method != Impossible;
2116 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2118 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2119 // preseed hint (for variable i/o)
2120 out.set (DataType::AUDIO, _preset_out.n_audio ());
2123 Match rv = internal_can_support_io_configuration (in, out);
2125 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2126 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2127 out.set (DataType::AUDIO, _preset_out.n_audio ());
2132 /** A private version of can_support_io_configuration which returns the method
2133 * by which the configuration can be matched, rather than just whether or not
2137 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2139 if (_plugins.empty()) {
2144 if (is_channelstrip ()) {
2146 return Match (ExactMatch, 1);
2150 /* if a user specified a custom cfg, so be it. */
2152 PluginInfoPtr info = _plugins.front()->get_info();
2154 if (info->reconfigurable_io()) {
2155 return Match (Delegate, 1, _strict_io, true);
2157 return Match (ExactMatch, get_count(), _strict_io, true);
2161 /* try automatic configuration */
2162 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2164 PluginInfoPtr info = _plugins.front()->get_info();
2165 ChanCount inputs = info->n_inputs;
2166 ChanCount outputs = info->n_outputs;
2168 /* handle case strict-i/o */
2169 if (_strict_io && m.method != Impossible) {
2172 /* special case MIDI instruments */
2173 if (is_instrument ()) {
2174 // output = midi-bypass + at most master-out channels.
2175 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2176 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2177 out = ChanCount::min (out, max_out);
2178 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2184 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2185 /* replicate processor to match output count (generators and such)
2186 * at least enough to feed every output port. */
2187 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2188 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2189 uint32_t nout = outputs.get (*t);
2190 if (nout == 0 || inx.get(*t) == 0) { continue; }
2191 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2194 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2195 return Match (Replicate, f, _strict_io);
2206 if (m.method != Impossible) {
2210 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2212 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2214 if (info->reconfigurable_io()) {
2217 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2218 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2219 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2221 // houston, we have a problem.
2222 return Match (Impossible, 0);
2225 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2226 return Match (Delegate, 1, _strict_io);
2229 ChanCount midi_bypass;
2230 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2231 midi_bypass.set (DataType::MIDI, 1);
2234 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2236 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2237 uint32_t nin = ns_inputs.get (*t);
2238 uint32_t nout = outputs.get (*t);
2239 if (nin == 0 || inx.get(*t) == 0) { continue; }
2240 // prefer floor() so the count won't overly increase IFF (nin < nout)
2241 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2243 if (f > 0 && outputs * f >= _configured_out) {
2244 out = outputs * f + midi_bypass;
2245 return Match (Replicate, f, _strict_io);
2248 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2250 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2251 uint32_t nin = ns_inputs.get (*t);
2252 if (nin == 0 || inx.get(*t) == 0) { continue; }
2253 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2256 out = outputs * f + midi_bypass;
2257 return Match (Replicate, f, _strict_io);
2260 // add at least as many plugins needed to connect all inputs
2262 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2263 uint32_t nin = inputs.get (*t);
2264 if (nin == 0 || inx.get(*t) == 0) { continue; }
2265 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2267 out = outputs * f + midi_bypass;
2268 return Match (Replicate, f, _strict_io);
2271 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2273 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2275 if (_plugins.empty()) {
2279 PluginInfoPtr info = _plugins.front()->get_info();
2280 ChanCount in; in += inx;
2281 ChanCount midi_bypass;
2283 if (info->reconfigurable_io()) {
2284 /* Plugin has flexible I/O, so delegate to it
2285 * pre-seed outputs, plugin tries closest match
2288 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2289 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2290 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2292 return Match (Impossible, 0);
2295 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2296 return Match (Delegate, 1);
2299 ChanCount inputs = info->n_inputs;
2300 ChanCount outputs = info->n_outputs;
2301 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2303 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2304 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2305 midi_bypass.set (DataType::MIDI, 1);
2307 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2308 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2309 in.set(DataType::MIDI, 0);
2312 // add internally provided sidechain ports
2313 ChanCount insc = in + sidechain_input_ports ();
2315 bool no_inputs = true;
2316 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2317 if (inputs.get (*t) != 0) {
2324 /* no inputs so we can take any input configuration since we throw it away */
2325 out = outputs + midi_bypass;
2326 return Match (NoInputs, 1);
2329 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2330 if (inputs == insc) {
2331 out = outputs + midi_bypass;
2332 return Match (ExactMatch, 1);
2335 /* Plugin inputs matches without side-chain-pins */
2336 if (ns_inputs == in) {
2337 out = outputs + midi_bypass;
2338 return Match (ExactMatch, 1);
2341 /* We may be able to run more than one copy of the plugin within this insert
2342 to cope with the insert having more inputs than the plugin.
2343 We allow replication only for plugins with either zero or 1 inputs and outputs
2344 for every valid data type.
2348 bool can_replicate = true;
2349 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2351 // ignore side-chains
2352 uint32_t nin = ns_inputs.get (*t);
2354 // No inputs of this type
2355 if (nin == 0 && in.get(*t) == 0) {
2359 if (nin != 1 || outputs.get (*t) != 1) {
2360 can_replicate = false;
2364 // Potential factor not set yet
2366 f = in.get(*t) / nin;
2369 // Factor for this type does not match another type, can not replicate
2370 if (f != (in.get(*t) / nin)) {
2371 can_replicate = false;
2376 if (can_replicate && f > 0) {
2377 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2378 out.set (*t, outputs.get(*t) * f);
2381 return Match (Replicate, f);
2384 /* If the processor has exactly one input of a given type, and
2385 the plugin has more, we can feed the single processor input
2386 to some or all of the plugin inputs. This is rather
2387 special-case-y, but the 1-to-many case is by far the
2388 simplest. How do I split thy 2 processor inputs to 3
2389 plugin inputs? Let me count the ways ...
2392 bool can_split = true;
2393 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2395 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2396 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2398 if (!can_split_type && !nothing_to_do_for_type) {
2404 out = outputs + midi_bypass;
2405 return Match (Split, 1);
2408 /* If the plugin has more inputs than we want, we can `hide' some of them
2409 by feeding them silence.
2412 bool could_hide = false;
2413 bool cannot_hide = false;
2414 ChanCount hide_channels;
2416 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2417 if (inputs.get(*t) > in.get(*t)) {
2418 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2419 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2421 } else if (inputs.get(*t) < in.get(*t)) {
2422 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2427 if (could_hide && !cannot_hide) {
2428 out = outputs + midi_bypass;
2429 return Match (Hide, 1, false, false, hide_channels);
2432 return Match (Impossible, 0);
2437 PluginInsert::state ()
2439 XMLNode& node = Processor::state ();
2441 node.set_property("type", _plugins[0]->state_node_name());
2442 node.set_property("unique-id", _plugins[0]->unique_id());
2443 node.set_property("count", (uint32_t)_plugins.size());
2445 /* remember actual i/o configuration (for later placeholder
2446 * in case the plugin goes missing) */
2447 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2448 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2449 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2450 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2452 /* save custom i/o config */
2453 node.set_property("custom", _custom_cfg);
2454 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2456 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2457 node.add_child_nocopy (* _in_map[pc].state (tmp));
2458 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2459 node.add_child_nocopy (* _out_map[pc].state (tmp));
2461 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2464 node.add_child_nocopy (_sidechain->get_state ());
2467 _plugins[0]->set_insert_id(this->id());
2468 node.add_child_nocopy (_plugins[0]->get_state());
2470 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2471 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2473 node.add_child_nocopy (ac->get_state());
2481 PluginInsert::set_control_ids (const XMLNode& node, int version)
2483 const XMLNodeList& nlist = node.children();
2484 for (XMLNodeConstIterator iter = nlist.begin(); iter != nlist.end(); ++iter) {
2485 if ((*iter)->name() != Controllable::xml_node_name) {
2489 uint32_t p = (uint32_t)-1;
2492 if ((*iter)->get_property (X_("symbol"), str)) {
2493 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2495 p = lv2plugin->port_index(str.c_str());
2499 if (p == (uint32_t)-1) {
2500 (*iter)->get_property (X_("parameter"), p);
2503 if (p == (uint32_t)-1) {
2507 /* this may create the new controllable */
2508 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2513 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2515 ac->set_state (**iter, version);
2521 PluginInsert::update_control_values (const XMLNode& node, int version)
2523 const XMLNodeList& nlist = node.children();
2524 for (XMLNodeConstIterator iter = nlist.begin(); iter != nlist.end(); ++iter) {
2525 if ((*iter)->name() != Controllable::xml_node_name) {
2530 if (!(*iter)->get_property (X_("value"), val)) {
2534 uint32_t p = (uint32_t)-1;
2537 if ((*iter)->get_property (X_("symbol"), str)) {
2538 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2540 p = lv2plugin->port_index(str.c_str());
2544 if (p == (uint32_t)-1) {
2545 (*iter)->get_property (X_("parameter"), p);
2548 if (p == (uint32_t)-1) {
2552 /* lookup controllable */
2553 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p), false);
2557 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2559 ac->set_value (val, Controllable::NoGroup);
2565 PluginInsert::set_state(const XMLNode& node, int version)
2567 XMLNodeList nlist = node.children();
2568 XMLNodeIterator niter;
2569 XMLPropertyList plist;
2570 ARDOUR::PluginType type;
2573 if (!node.get_property ("type", str)) {
2574 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2578 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2579 type = ARDOUR::LADSPA;
2580 } else if (str == X_("lv2")) {
2582 } else if (str == X_("windows-vst")) {
2583 type = ARDOUR::Windows_VST;
2584 } else if (str == X_("lxvst")) {
2585 type = ARDOUR::LXVST;
2586 } else if (str == X_("mac-vst")) {
2587 type = ARDOUR::MacVST;
2588 } else if (str == X_("audiounit")) {
2589 type = ARDOUR::AudioUnit;
2590 } else if (str == X_("luaproc")) {
2593 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2597 XMLProperty const * prop = node.property ("unique-id");
2600 #ifdef WINDOWS_VST_SUPPORT
2601 /* older sessions contain VST plugins with only an "id" field. */
2602 if (type == ARDOUR::Windows_VST) {
2603 prop = node.property ("id");
2607 #ifdef LXVST_SUPPORT
2608 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2609 if (type == ARDOUR::LXVST) {
2610 prop = node.property ("id");
2617 error << _("Plugin has no unique ID field") << endmsg;
2622 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2623 bool any_vst = false;
2625 /* treat VST plugins equivalent if they have the same uniqueID
2626 * allow to move sessions windows <> linux */
2627 #ifdef LXVST_SUPPORT
2628 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2629 type = ARDOUR::LXVST;
2630 plugin = find_plugin (_session, prop->value(), type);
2631 if (plugin) { any_vst = true; }
2635 #ifdef WINDOWS_VST_SUPPORT
2636 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2637 type = ARDOUR::Windows_VST;
2638 plugin = find_plugin (_session, prop->value(), type);
2639 if (plugin) { any_vst = true; }
2643 #ifdef MACVST_SUPPORT
2644 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2645 type = ARDOUR::MacVST;
2646 plugin = find_plugin (_session, prop->value(), type);
2647 if (plugin) { any_vst = true; }
2651 if (plugin == 0 && type == ARDOUR::Lua) {
2652 /* unique ID (sha1 of script) was not found,
2653 * load the plugin from the serialized version in the
2654 * session-file instead.
2656 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2657 XMLNode *ls = node.child (lp->state_node_name().c_str());
2659 if (0 == lp->set_script_from_state (*ls)) {
2666 error << string_compose(
2667 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2668 "Perhaps it was removed or moved since it was last used."),
2674 // The name of the PluginInsert comes from the plugin, nothing else
2675 _name = plugin->get_info()->name;
2679 // Processor::set_state() will set this, but too late
2680 // for it to be available when setting up plugin
2681 // state. We can't call Processor::set_state() until
2682 // the plugins themselves are created and added.
2686 if (_plugins.empty()) {
2687 /* if we are adding the first plugin, we will need to set
2688 * up automatable controls.
2690 add_plugin (plugin);
2691 create_automatable_parameters ();
2692 set_control_ids (node, version);
2694 /* update controllable value only (copy plugin state) */
2695 update_control_values (node, version);
2698 node.get_property ("count", count);
2700 if (_plugins.size() != count) {
2701 for (uint32_t n = 1; n < count; ++n) {
2702 add_plugin (plugin_factory (plugin));
2706 Processor::set_state (node, version);
2708 PBD::ID new_id = this->id();
2709 PBD::ID old_id = this->id();
2711 node.get_property ("id", old_id);
2713 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2715 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2716 and set all plugins to the same state.
2719 if ( ((*niter)->name() == plugin->state_node_name())
2720 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2723 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2724 /* Plugin state can include external files which are named after the ID.
2726 * If regenerate_xml_or_string_ids() is set, the ID will already have
2727 * been changed, so we need to use the old ID from the XML to load the
2728 * state and then update the ID.
2730 * When copying a plugin-state, route_ui takes care of of updating the ID,
2731 * but we need to call set_insert_id() to clear the cached plugin-state
2732 * and force a change.
2734 if (!regenerate_xml_or_string_ids ()) {
2735 (*i)->set_insert_id (new_id);
2737 (*i)->set_insert_id (old_id);
2740 (*i)->set_state (**niter, version);
2742 if (regenerate_xml_or_string_ids ()) {
2743 (*i)->set_insert_id (new_id);
2747 /* when copying plugin state, notify UI */
2748 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2749 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2751 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2759 if (version < 3000) {
2761 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2762 this is all handled by Automatable
2765 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2766 if ((*niter)->name() == "Redirect") {
2767 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2768 Processor::set_state (**niter, version);
2773 set_parameter_state_2X (node, version);
2776 node.get_property (X_("custom"), _custom_cfg);
2778 uint32_t in_maps = 0;
2779 uint32_t out_maps = 0;
2780 XMLNodeList kids = node.children ();
2781 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2782 if ((*i)->name() == X_("ConfiguredInput")) {
2783 _configured_in = ChanCount(**i);
2785 if ((*i)->name() == X_("CustomSinks")) {
2786 _custom_sinks = ChanCount(**i);
2788 if ((*i)->name() == X_("ConfiguredOutput")) {
2789 _custom_out = ChanCount(**i);
2790 _configured_out = ChanCount(**i);
2792 if ((*i)->name() == X_("PresetOutput")) {
2793 _preset_out = ChanCount(**i);
2795 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2796 long pc = atol (&((*i)->name().c_str()[9]));
2797 if (pc >= 0 && pc <= (long) get_count()) {
2798 _in_map[pc] = ChanMapping (**i);
2802 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2803 long pc = atol (&((*i)->name().c_str()[10]));
2804 if (pc >= 0 && pc <= (long) get_count()) {
2805 _out_map[pc] = ChanMapping (**i);
2809 if ((*i)->name () == "ThruMap") {
2810 _thru_map = ChanMapping (**i);
2813 // sidechain is a Processor (IO)
2814 if ((*i)->name () == Processor::state_node_name) {
2816 if (regenerate_xml_or_string_ids ()) {
2817 add_sidechain_from_xml (**i, version);
2822 if (!regenerate_xml_or_string_ids ()) {
2823 _sidechain->set_state (**i, version);
2825 update_sidechain_name ();
2830 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2831 _maps_from_state = true;
2834 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2838 (*i)->deactivate ();
2842 PluginConfigChanged (); /* EMIT SIGNAL */
2847 PluginInsert::update_id (PBD::ID id)
2850 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2851 (*i)->set_insert_id (id);
2856 PluginInsert::set_owner (SessionObject* o)
2858 Processor::set_owner (o);
2859 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2860 (*i)->set_owner (o);
2865 PluginInsert::set_state_dir (const std::string& d)
2867 // state() only saves the state of the first plugin
2868 _plugins[0]->set_state_dir (d);
2872 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2874 XMLNodeList nlist = node.children();
2875 XMLNodeIterator niter;
2877 /* look for port automation node */
2879 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2881 if ((*niter)->name() != port_automation_node_name) {
2886 XMLNodeConstIterator iter;
2890 cnodes = (*niter)->children ("port");
2892 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2896 if (!child->get_property("number", port_id)) {
2897 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2901 if (port_id >= _plugins[0]->parameter_count()) {
2902 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2906 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2907 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2909 if (c && c->alist()) {
2910 if (!child->children().empty()) {
2911 c->alist()->set_state (*child->children().front(), version);
2914 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2924 boost::shared_ptr<ReadOnlyControl>
2925 PluginInsert::control_output (uint32_t num) const
2927 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2928 if (i == _control_outputs.end ()) {
2929 return boost::shared_ptr<ReadOnlyControl> ();
2936 PluginInsert::describe_parameter (Evoral::Parameter param)
2938 if (param.type() == PluginAutomation) {
2939 return _plugins[0]->describe_parameter (param);
2940 } else if (param.type() == PluginPropertyAutomation) {
2941 boost::shared_ptr<AutomationControl> c(automation_control(param));
2942 if (c && !c->desc().label.empty()) {
2943 return c->desc().label;
2946 return Automatable::describe_parameter(param);
2950 PluginInsert::signal_latency() const
2952 if (!_pending_active) {
2955 return plugin_latency ();
2959 PluginInsert::type () const
2961 return plugin()->get_info()->type;
2964 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2965 const Evoral::Parameter& param,
2966 const ParameterDescriptor& desc,
2967 boost::shared_ptr<AutomationList> list)
2968 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2973 list->set_interpolation(Evoral::ControlList::Discrete);
2978 /** @param val `user' value */
2981 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2983 /* FIXME: probably should be taking out some lock here.. */
2985 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2986 (*i)->set_parameter (_list->parameter().id(), user_val);
2989 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2991 iasp->set_parameter (_list->parameter().id(), user_val);
2994 AutomationControl::actually_set_value (user_val, group_override);
2998 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
3000 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
3004 PluginInsert::PluginControl::get_state ()
3006 XMLNode& node (AutomationControl::get_state());
3007 node.set_property (X_("parameter"), parameter().id());
3009 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
3011 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
3018 /** @return `user' val */
3020 PluginInsert::PluginControl::get_value () const
3022 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
3028 return plugin->get_parameter (_list->parameter().id());
3032 PluginInsert::PluginControl::get_user_string () const
3034 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
3037 if (plugin->print_parameter (parameter().id(), buf, sizeof(buf))) {
3038 assert (strlen (buf) > 0);
3039 return std::string (buf) + " (" + AutomationControl::get_user_string () + ")";
3042 return AutomationControl::get_user_string ();
3045 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
3046 const Evoral::Parameter& param,
3047 const ParameterDescriptor& desc,
3048 boost::shared_ptr<AutomationList> list)
3049 : AutomationControl (p->session(), param, desc, list)
3055 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
3057 /* Old numeric set_value(), coerce to appropriate datatype if possible.
3058 This is lossy, but better than nothing until Ardour's automation system
3059 can handle various datatypes all the way down. */
3060 const Variant value(_desc.datatype, user_val);
3061 if (value.type() == Variant::NOTHING) {
3062 error << "set_value(double) called for non-numeric property" << endmsg;
3066 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3067 (*i)->set_property(_list->parameter().id(), value);
3072 AutomationControl::actually_set_value (user_val, gcd);
3076 PluginInsert::PluginPropertyControl::get_state ()
3078 XMLNode& node (AutomationControl::get_state());
3079 node.set_property (X_("property"), parameter().id());
3080 node.remove_property (X_("value"));
3086 PluginInsert::PluginPropertyControl::get_value () const
3088 return _value.to_double();
3091 boost::shared_ptr<Plugin>
3092 PluginInsert::get_impulse_analysis_plugin()
3094 boost::shared_ptr<Plugin> ret;
3095 if (_impulseAnalysisPlugin.expired()) {
3096 // LV2 in particular uses various _session params
3097 // during init() -- most notably block_size..
3099 ret = plugin_factory(_plugins[0]);
3100 ret->use_for_impulse_analysis ();
3101 ChanCount out (internal_output_streams ());
3102 if (ret->get_info ()->reconfigurable_io ()) {
3103 // populate get_info ()->n_inputs and ->n_outputs
3105 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3106 assert (out == internal_output_streams ());
3108 ret->configure_io (internal_input_streams (), out);
3109 ret->set_owner (_owner);
3110 _impulseAnalysisPlugin = ret;
3112 ret = _impulseAnalysisPlugin.lock();
3119 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3121 if (_signal_analysis_collect_nsamples_max != 0
3122 || _signal_analysis_collect_nsamples != 0) {
3126 // called from outside the audio thread, so this should be safe
3127 // only do audio as analysis is (currently) only for audio plugins
3128 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3129 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3131 /* these however should not be set while processing,
3132 * however in the given order, this should be fine.
3134 _signal_analysis_collect_nsamples = 0;
3135 _signal_analysis_collect_nsamples_max = nframes;
3138 /** Add a plugin to our list */
3140 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3142 plugin->set_insert_id (this->id());
3143 plugin->set_owner (_owner);
3145 if (_plugins.empty()) {
3146 /* first (and probably only) plugin instance - connect to relevant signals */
3148 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3149 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3150 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3151 _custom_sinks = plugin->get_info()->n_inputs;
3152 // cache sidechain port count
3153 _cached_sidechain_pins.reset ();
3154 const ChanCount& nis (plugin->get_info()->n_inputs);
3155 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3156 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3157 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3158 if (iod.is_sidechain) {
3159 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3164 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3165 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3167 vst->set_insert (this, _plugins.size ());
3171 _plugins.push_back (plugin);
3175 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3177 if (version < 3000) {
3181 XMLNodeList nlist = node.children();
3183 if (nlist.size() == 0) {
3190 XMLNodeConstIterator it = nlist.front()->children().begin();
3191 for ( ; it != nlist.front()->children().end(); ++ it) {
3192 if ((*it)->name() == "Port") {
3193 DataType type(DataType::NIL);
3194 (*it)->get_property ("type", type);
3195 if (type == DataType::AUDIO) {
3197 } else if (type == DataType::MIDI) {
3203 ChanCount in_cc = ChanCount();
3204 in_cc.set (DataType::AUDIO, audio);
3205 in_cc.set (DataType::MIDI, midi);
3207 add_sidechain (audio, midi);
3211 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3214 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3215 if (! (*i)->load_preset (pr)) {
3220 boost::shared_ptr<Plugin> iasp = _impulseAnalysisPlugin.lock();
3222 iasp->load_preset (pr);
3229 PluginInsert::realtime_handle_transport_stopped ()
3231 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3232 (*i)->realtime_handle_transport_stopped ();
3237 PluginInsert::realtime_locate ()
3239 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3240 (*i)->realtime_locate ();
3245 PluginInsert::monitoring_changed ()
3247 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3248 (*i)->monitoring_changed ();
3253 PluginInsert::latency_changed ()
3255 // this is called in RT context, LatencyChanged is emitted after run()
3256 _latency_changed = true;
3257 LatencyChanged (); /* EMIT SIGNAL */
3258 // XXX This needs a proper API not an owner() hack:
3259 // TODO Route should subscribe to LatencyChanged() and forward it
3260 // to the session as processor_latency_changed.
3262 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3266 PluginInsert::start_touch (uint32_t param_id)
3268 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3270 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3271 ac->start_touch (session().audible_sample());
3276 PluginInsert::end_touch (uint32_t param_id)
3278 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3280 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3281 ac->stop_touch (session().audible_sample());
3286 PluginInsert::provides_stats () const
3288 #if defined MIXBUS && defined NDEBUG
3289 if (is_channelstrip () || !display_to_user ()) {
3297 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3299 /* TODO: consider taking a try/lock: Don't run concurrently with
3300 * TimingStats::update, TimingStats::reset.
3302 return _timing_stats.get_stats (min, max, avg, dev);
3306 PluginInsert::clear_stats ()
3308 g_atomic_int_set (&_stat_reset, 1);
3311 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3314 case PluginInsert::Impossible: o << "Impossible"; break;
3315 case PluginInsert::Delegate: o << "Delegate"; break;
3316 case PluginInsert::NoInputs: o << "NoInputs"; break;
3317 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3318 case PluginInsert::Replicate: o << "Replicate"; break;
3319 case PluginInsert::Split: o << "Split"; break;
3320 case PluginInsert::Hide: o << "Hide"; break;
3322 o << " cnt: " << m.plugins
3323 << (m.strict_io ? " strict-io" : "")
3324 << (m.custom_cfg ? " custom-cfg" : "");
3325 if (m.method == PluginInsert::Hide) {
3326 o << " hide: " << m.hide;