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/types_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"
54 #include "ardour/mac_vst_plugin.h"
57 #ifdef AUDIOUNIT_SUPPORT
58 #include "ardour/audio_unit.h"
61 #include "ardour/session.h"
62 #include "ardour/types.h"
67 using namespace ARDOUR;
70 const string PluginInsert::port_automation_node_name = "PortAutomation";
72 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
73 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
74 , _sc_playback_latency (0)
75 , _sc_capture_latency (0)
76 , _plugin_signal_latency (0)
77 , _signal_analysis_collected_nframes(0)
78 , _signal_analysis_collect_nframes_max(0)
83 , _maps_from_state (false)
84 , _latency_changed (false)
85 , _bypass_port (UINT32_MAX)
88 /* the first is the master */
92 create_automatable_parameters ();
93 const ChanCount& sc (sidechain_input_pins ());
94 if (sc.n_audio () > 0 || sc.n_midi () > 0) {
95 add_sidechain (sc.n_audio (), sc.n_midi ());
100 PluginInsert::~PluginInsert ()
102 for (CtrlOutMap::const_iterator i = _control_outputs.begin(); i != _control_outputs.end(); ++i) {
103 boost::dynamic_pointer_cast<ReadOnlyControl>(i->second)->drop_references ();
108 PluginInsert::set_strict_io (bool b)
110 bool changed = _strict_io != b;
113 PluginConfigChanged (); /* EMIT SIGNAL */
118 PluginInsert::set_count (uint32_t num)
120 bool require_state = !_plugins.empty();
122 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
123 // we don't allow to replicate AUs
127 /* this is a bad idea.... we shouldn't do this while active.
128 * only a route holding their redirect_lock should be calling this
133 } else if (num > _plugins.size()) {
134 uint32_t diff = num - _plugins.size();
136 for (uint32_t n = 0; n < diff; ++n) {
137 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
141 XMLNode& state = _plugins[0]->get_state ();
142 p->set_state (state, Stateful::loading_state_version);
149 PluginConfigChanged (); /* EMIT SIGNAL */
151 } else if (num < _plugins.size()) {
152 uint32_t diff = _plugins.size() - num;
153 for (uint32_t n= 0; n < diff; ++n) {
156 PluginConfigChanged (); /* EMIT SIGNAL */
164 PluginInsert::set_sinks (const ChanCount& c)
167 /* no signal, change will only be visible after re-config */
171 PluginInsert::set_outputs (const ChanCount& c)
173 bool changed = (_custom_out != c) && _custom_cfg;
176 PluginConfigChanged (); /* EMIT SIGNAL */
181 PluginInsert::set_custom_cfg (bool b)
183 bool changed = _custom_cfg != b;
186 PluginConfigChanged (); /* EMIT SIGNAL */
191 PluginInsert::set_preset_out (const ChanCount& c)
193 bool changed = _preset_out != c;
195 if (changed && !_custom_cfg) {
196 PluginConfigChanged (); /* EMIT SIGNAL */
202 PluginInsert::add_sidechain (uint32_t n_audio, uint32_t n_midi)
204 // caller must hold process lock
208 std::ostringstream n;
209 if (n_audio == 0 && n_midi == 0) {
210 n << "TO BE RESET FROM XML";
211 } else if (owner()) {
212 n << "SC " << owner()->name() << "/" << name() << " " << Session::next_name_id ();
216 SideChain *sc = new SideChain (_session, n.str ());
217 _sidechain = boost::shared_ptr<SideChain> (sc);
218 _sidechain->activate ();
219 for (uint32_t n = 0; n < n_audio; ++n) {
220 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
222 for (uint32_t n = 0; n < n_midi; ++n) {
223 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
225 PluginConfigChanged (); /* EMIT SIGNAL */
230 PluginInsert::del_sidechain ()
236 _sc_playback_latency = 0;
237 _sc_capture_latency = 0;
238 PluginConfigChanged (); /* EMIT SIGNAL */
243 PluginInsert::update_sidechain_name ()
249 std::ostringstream n;
253 n << owner()->name() << "/";
256 n << name() << " " << Session::next_name_id ();
258 _sidechain->set_name (n.str());
262 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
264 if (which.type() != PluginAutomation)
267 boost::shared_ptr<AutomationControl> c
268 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
271 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()));
276 PluginInsert::output_streams() const
278 assert (_configured);
279 return _configured_out;
283 PluginInsert::input_streams() const
285 assert (_configured);
286 return _configured_in;
290 PluginInsert::internal_streams() const
292 assert (_configured);
293 return _configured_internal;
297 PluginInsert::internal_output_streams() const
299 assert (!_plugins.empty());
301 PluginInfoPtr info = _plugins.front()->get_info();
303 if (info->reconfigurable_io()) {
304 ChanCount out = _plugins.front()->output_streams ();
305 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
308 ChanCount out = info->n_outputs;
309 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
310 out.set_audio (out.n_audio() * _plugins.size());
311 out.set_midi (out.n_midi() * _plugins.size());
317 PluginInsert::internal_input_streams() const
319 assert (!_plugins.empty());
323 PluginInfoPtr info = _plugins.front()->get_info();
325 if (info->reconfigurable_io()) {
326 in = _plugins.front()->input_streams();
331 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
333 if (_match.method == Split) {
335 /* we are splitting 1 processor input to multiple plugin inputs,
336 so we have a maximum of 1 stream of each type.
338 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
339 if (in.get (*t) > 1) {
345 } else if (_match.method == Hide) {
347 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
348 in.set (*t, in.get (*t) - _match.hide.get (*t));
354 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
355 in.set (*t, in.get (*t) * _plugins.size ());
363 PluginInsert::natural_output_streams() const
366 if (is_channelstrip ()) {
367 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
370 return _plugins[0]->get_info()->n_outputs;
374 PluginInsert::natural_input_streams() const
377 if (is_channelstrip ()) {
378 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
381 return _plugins[0]->get_info()->n_inputs;
385 PluginInsert::sidechain_input_pins() const
387 return _cached_sidechain_pins;
391 PluginInsert::has_no_inputs() const
393 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
397 PluginInsert::has_no_audio_inputs() const
399 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
403 PluginInsert::plugin_latency () const {
404 return _plugins.front()->signal_latency ();
408 PluginInsert::is_instrument() const
410 PluginInfoPtr pip = _plugins[0]->get_info();
411 return (pip->is_instrument ());
415 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
417 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
418 // collect possible configurations, prefer given in/out
419 _plugins[0]->can_support_io_configuration (in, out);
422 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
424 if (ppc.size () == 0) {
427 if (!strict_io () && ppc.size () == 1) {
431 if (strict_io () && ppc.size () == 1) {
432 // "stereo" is currently preferred default for instruments
433 if (ppc.find (2) != ppc.end ()) {
438 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
439 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
440 // pretending to be an "Instrument"
444 if (!is_instrument ()) {
451 PluginInsert::create_automatable_parameters ()
453 assert (!_plugins.empty());
455 boost::shared_ptr<Plugin> plugin = _plugins.front();
456 set<Evoral::Parameter> a = _plugins.front()->automatable ();
458 const uint32_t limit_automatables = Config->get_limit_n_automatables ();
460 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
461 if (!plugin->parameter_is_control (i)) {
465 ParameterDescriptor desc;
466 plugin->get_parameter_descriptor(i, desc);
468 if (!plugin->parameter_is_input (i)) {
469 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
472 Evoral::Parameter param (PluginAutomation, 0, i);
474 const bool automatable = a.find(param) != a.end();
476 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
477 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
478 if (!automatable || (limit_automatables > 0 && i > limit_automatables)) {
479 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
482 plugin->set_automation_control (i, c);
486 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
487 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
488 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
489 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
490 if (desc.datatype != Variant::NOTHING) {
491 boost::shared_ptr<AutomationList> list;
492 if (Variant::type_is_numeric(desc.datatype)) {
493 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
495 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
496 if (!Variant::type_is_numeric(desc.datatype)) {
497 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
503 _bypass_port = plugin->designated_bypass_port ();
505 /* special case VST effSetBypass */
506 if (_bypass_port == UINT32_MAX -1) {
507 // emulate VST Bypass
508 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
509 ParameterDescriptor desc;
510 desc.label = _("Plugin Enable");
515 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
516 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
520 if (_bypass_port != UINT32_MAX) {
521 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
522 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
523 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
524 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
527 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
530 /** Called when something outside of this host has modified a plugin
531 * parameter. Responsible for propagating the change to two places:
533 * 1) anything listening to the Control itself
534 * 2) any replicated plugins that make up this PluginInsert.
536 * The PluginInsert is connected to the ParameterChangedExternally signal for
537 * the first (primary) plugin, and here broadcasts that change to any others.
539 * XXX We should probably drop this whole replication idea (Paul, October 2015)
540 * since it isn't used by sensible plugin APIs (AU, LV2).
543 PluginInsert::parameter_changed_externally (uint32_t which, float val)
545 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
547 /* First propagation: alter the underlying value of the control,
548 * without telling the plugin(s) that own/use it to set it.
555 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
558 pc->catch_up_with_external_value (val);
561 /* Second propagation: tell all plugins except the first to
562 update the value of this parameter. For sane plugin APIs,
563 there are no other plugins, so this is a no-op in those
567 Plugins::iterator i = _plugins.begin();
569 /* don't set the first plugin, just all the slaves */
571 if (i != _plugins.end()) {
573 for (; i != _plugins.end(); ++i) {
574 (*i)->set_parameter (which, val);
580 PluginInsert::set_block_size (pframes_t nframes)
583 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
584 if ((*i)->set_block_size (nframes) != 0) {
592 PluginInsert::automation_run (samplepos_t start, pframes_t nframes)
594 // XXX does not work when rolling backwards
595 if (_loop_location && nframes > 0) {
596 const samplepos_t loop_start = _loop_location->start ();
597 const samplepos_t loop_end = _loop_location->end ();
598 const samplecnt_t looplen = loop_end - loop_start;
600 samplecnt_t remain = nframes;
601 samplepos_t start_pos = start;
604 if (start_pos >= loop_end) {
605 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
606 start_pos = loop_start + start_off;
608 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
610 Automatable::automation_run (start_pos, move);
616 Automatable::automation_run (start, nframes);
620 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
622 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
624 if (_loop_location && now < end) {
626 end = ceil (next_event.when);
628 const samplepos_t loop_end = _loop_location->end ();
629 assert (now < loop_end); // due to map_loop_range ()
630 if (end > loop_end) {
631 next_event.when = loop_end;
639 PluginInsert::activate ()
641 _timing_stats.reset ();
642 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
646 Processor::activate ();
647 /* when setting state e.g ProcessorBox::paste_processor_state ()
648 * the plugin is not yet owned by a route.
649 * but no matter. Route::add_processors() will call activate () again
654 if (_plugin_signal_latency != signal_latency ()) {
655 _plugin_signal_latency = signal_latency ();
661 PluginInsert::deactivate ()
664 if (is_nonbypassable ()) {
668 _timing_stats.reset ();
669 Processor::deactivate ();
671 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
674 if (_plugin_signal_latency != signal_latency ()) {
675 _plugin_signal_latency = signal_latency ();
681 PluginInsert::flush ()
683 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
689 PluginInsert::enable (bool yn)
691 if (_bypass_port == UINT32_MAX) {
698 if (!_pending_active) {
701 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
702 const double val = yn ? 1.0 : 0.0;
703 ac->set_value (val, Controllable::NoGroup);
705 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
706 /* special case VST.. bypass may fail */
707 if (_bypass_port == UINT32_MAX - 1) {
708 /* check if bypass worked */
709 if (ac->get_value () != val) {
710 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
711 // set plugin to enabled (not-byassed)
712 ac->set_value (1.0, Controllable::NoGroup);
713 // ..and use host-provided hard-bypass
728 PluginInsert::enabled () const
730 if (_bypass_port == UINT32_MAX) {
731 return Processor::enabled ();
733 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
734 return (ac->get_value () > 0 && _pending_active);
739 PluginInsert::bypassable () const
741 if (_bypass_port == UINT32_MAX) {
744 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
746 return !ac->automation_playback ();
751 PluginInsert::enable_changed ()
757 PluginInsert::bypassable_changed ()
759 BypassableChanged ();
763 PluginInsert::write_immediate_event (size_t size, const uint8_t* buf)
766 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
767 if (!(*i)->write_immediate_event (size, buf)) {
775 PluginInsert::preset_load_set_value (uint32_t p, float v)
777 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
782 if (ac->automation_state() & Play) {
787 ac->set_value (v, Controllable::NoGroup);
792 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
794 // TODO optimize: store "unconnected" in a fixed set.
795 // it only changes on reconfiguration.
796 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
797 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
799 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
800 mapped = true; // in-place Midi bypass
802 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
803 PinMappings::const_iterator i = out_map.find (pc);
804 if (i == out_map.end ()) {
807 const ChanMapping& outmap (i->second);
808 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
810 uint32_t idx = outmap.get (*t, o, &valid);
811 if (valid && idx == out) {
818 bufs.get (*t, out).silence (nframes, offset);
825 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
827 if (_mapping_changed) { // ToDo use a counter, increment until match
828 _no_inplace = check_inplace ();
829 _mapping_changed = false;
831 // TODO: atomically copy maps & _no_inplace
832 PinMappings in_map (_in_map); // TODO Split case below overrides, use const& in_map
833 PinMappings const& out_map (_out_map);
834 ChanMapping const& thru_map (_thru_map);
836 if (_latency_changed) {
837 /* delaylines are configured with the max possible latency (as reported by the plugin)
838 * so this won't allocate memory (unless the plugin lied about its max latency)
839 * It may still 'click' though, since the fixed delaylines are not de-clicked.
840 * Then again plugin-latency changes are not click-free to begin with.
842 * This is also worst case, there is currently no concept of per-stream latency.
844 * e.g. Two identical latent plugins:
845 * 1st plugin: process left (latent), bypass right.
846 * 2nd plugin: bypass left, process right (latent).
847 * -> currently this yields 2 times latency of the plugin,
849 _latency_changed = false;
850 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
853 if (_match.method == Split && !_no_inplace) {
854 // TODO: also use this optimization if one source-buffer
855 // feeds _all_ *connected* inputs.
856 // currently this is *first* buffer to all only --
857 // see PluginInsert::check_inplace
858 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
859 if (_configured_internal.get (*t) == 0) {
863 uint32_t first_idx = in_map.p(0).get (*t, 0, &valid);
864 assert (valid && first_idx == 0); // check_inplace ensures this
865 /* copy the first stream's buffer contents to the others */
866 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
867 uint32_t idx = in_map.p(0).get (*t, i, &valid);
870 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
874 /* the copy operation produces a linear monotonic input map */
875 in_map[0] = ChanMapping (natural_input_streams ());
878 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
879 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
885 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
887 /* boost::dynamic_pointer_cast<> has significant overhead, since we know that
888 * all controls are AutomationControl and their lists - if any - are AutomationList,
889 * we can use static_cast<>. This yields a speedup of 2.8/4.6 over to the
890 * previous code (measuerd with VeeSeeVSTRack 10k parameters, optimized build) */
891 AutomationControl& c = static_cast<AutomationControl&> (*(li->second));
892 boost::shared_ptr<const Evoral::ControlList> clist (c.list());
893 if (clist && (static_cast<AutomationList const&> (*clist)).automation_playback ()) {
895 const float val = c.list()->rt_safe_eval (start, valid);
897 c.set_value_unchecked(val);
903 /* Calculate if, and how many samples we need to collect for analysis */
904 samplecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
905 _signal_analysis_collected_nframes);
906 if (nframes < collect_signal_nframes) { // we might not get all samples now
907 collect_signal_nframes = nframes;
910 if (collect_signal_nframes > 0) {
912 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
913 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
914 //std::cerr << "filling buffer with " << collect_signal_nframes << " samples at " << _signal_analysis_collected_nframes << std::endl;
916 _signal_analysis_inputs.set_count (ChanCount (DataType::AUDIO, input_streams().n_audio()));
918 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
919 _signal_analysis_inputs.get_audio(i).read_from (
921 collect_signal_nframes,
922 _signal_analysis_collected_nframes); // offset is for target buffer
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 (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 (*t, m), bufs.get (*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 (*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 (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
997 inplace_bufs.get (*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 (*t, out).silence (nframes, offset);
1029 uint32_t m = out + natural_input_streams ().get (*t);
1030 bufs.get (*t, out).read_from (inplace_bufs.get (*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 if (collect_signal_nframes > 0) {
1048 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
1049 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
1051 _signal_analysis_outputs.set_count (ChanCount (DataType::AUDIO, output_streams().n_audio()));
1053 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1054 _signal_analysis_outputs.get_audio(i).read_from(
1056 collect_signal_nframes,
1057 _signal_analysis_collected_nframes); // offset is for target buffer
1060 _signal_analysis_collected_nframes += collect_signal_nframes;
1061 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
1063 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
1064 _signal_analysis_collect_nframes_max = 0;
1065 _signal_analysis_collected_nframes = 0;
1067 AnalysisDataGathered(&_signal_analysis_inputs,
1068 &_signal_analysis_outputs);
1072 if (_plugin_signal_latency != signal_latency ()) {
1073 _plugin_signal_latency = signal_latency ();
1079 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1081 /* bypass the plugin(s) not the whole processor.
1082 * -> use mappings just like connect_and_run
1084 if (_mapping_changed) {
1085 _no_inplace = check_inplace ();
1086 _mapping_changed = false;
1088 // TODO: atomically copy maps & _no_inplace
1089 ChanMapping const& in_map (no_sc_input_map ());
1090 ChanMapping const& out_map (output_map ());
1092 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1093 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1096 ChanMapping thru_map (_thru_map);
1098 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1100 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1101 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1102 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
1105 ARDOUR::ChanMapping used_outputs;
1107 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1108 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1110 uint32_t in_idx = thru_map.get (*t, out, &valid);
1112 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1113 used_outputs.set (*t, out, 1); // mark as used
1117 // plugin no-op: assume every plugin has an internal identity map
1118 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1119 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1121 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1125 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1129 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1130 used_outputs.set (*t, out, 1); // mark as used
1133 // now silence all unused outputs
1134 if (has_midi_bypass ()) {
1135 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1137 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1138 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1140 used_outputs.get (*t, out, &valid);
1142 bufs.get (*t, out).silence (nframes, 0);
1147 if (_match.method == Split) {
1148 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1149 if (_configured_internal.get (*t) == 0) {
1152 // copy/feeds _all_ *connected* inputs, copy the first buffer
1154 uint32_t first_idx = in_map.get (*t, 0, &valid);
1155 assert (valid && first_idx == 0); // check_inplace ensures this
1156 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1157 uint32_t idx = in_map.get (*t, i, &valid);
1160 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
1166 // apply output map and/or monotonic but not identity i/o mappings
1167 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1168 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1170 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1172 bufs.get (*t, out).silence (nframes, 0);
1175 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1177 bufs.get (*t, out).silence (nframes, 0);
1180 if (in_idx != src_idx) {
1181 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
1189 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1191 automation_run (start_sample, nframes); // evaluate automation only
1194 // XXX delaybuffers need to be offset by nframes
1198 _delaybuffers.flush ();
1200 const ChanMapping in_map (natural_input_streams ());
1201 const ChanMapping out_map (natural_output_streams ());
1202 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1204 if (is_channelstrip ()) {
1205 if (_configured_in.n_audio() > 0) {
1206 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1210 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1211 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1216 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1219 // collect sidechain input for complete cycle (!)
1220 // TODO we need delaylines here for latency compensation
1221 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1224 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1225 _timing_stats.reset ();
1228 if (_pending_active) {
1229 #if defined MIXBUS && !defined NDEBUG
1230 if (!is_channelstrip ()) {
1231 _timing_stats.start ();
1234 _timing_stats.start ();
1236 /* run as normal if we are active or moving from inactive to active */
1238 if (_session.transport_rolling() || _session.bounce_processing()) {
1239 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1241 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1242 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1244 #if defined MIXBUS && !defined NDEBUG
1245 if (!is_channelstrip ()) {
1246 _timing_stats.update ();
1249 _timing_stats.update ();
1253 _timing_stats.reset ();
1254 // XXX should call ::silence() to run plugin(s) for consistent load.
1255 // We'll need to change this anyway when bypass can be automated
1256 bypass (bufs, nframes);
1257 automation_run (start_sample, nframes); // evaluate automation only
1258 _delaybuffers.flush ();
1261 _active = _pending_active;
1263 /* we have no idea whether the plugin generated silence or not, so mark
1264 * all buffers appropriately.
1269 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1271 Evoral::ControlEvent next_event (0, 0.0f);
1272 samplecnt_t offset = 0;
1274 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1277 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1281 /* map start back into loop-range, adjust end */
1282 map_loop_range (start, end);
1284 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1286 /* no events have a time within the relevant range */
1288 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1294 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1296 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1302 map_loop_range (start, end);
1304 if (!find_next_event (start, end, next_event)) {
1309 /* cleanup anything that is left to do */
1312 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1317 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1319 if (param.type() != PluginAutomation)
1322 if (_plugins.empty()) {
1323 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1325 abort(); /*NOTREACHED*/
1328 return _plugins[0]->default_value (param.id());
1333 PluginInsert::can_reset_all_parameters ()
1336 uint32_t params = 0;
1337 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1339 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1341 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1345 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1351 if (ac->automation_state() & Play) {
1356 return all && (params > 0);
1360 PluginInsert::reset_parameters_to_default ()
1364 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1366 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1368 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1372 const float dflt = _plugins[0]->default_value (cid);
1373 const float curr = _plugins[0]->get_parameter (cid);
1379 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1384 if (ac->automation_state() & Play) {
1389 ac->set_value (dflt, Controllable::NoGroup);
1394 boost::shared_ptr<Plugin>
1395 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1397 boost::shared_ptr<LadspaPlugin> lp;
1398 boost::shared_ptr<LuaProc> lua;
1400 boost::shared_ptr<LV2Plugin> lv2p;
1402 #ifdef WINDOWS_VST_SUPPORT
1403 boost::shared_ptr<WindowsVSTPlugin> vp;
1405 #ifdef LXVST_SUPPORT
1406 boost::shared_ptr<LXVSTPlugin> lxvp;
1408 #ifdef MACVST_SUPPORT
1409 boost::shared_ptr<MacVSTPlugin> mvp;
1411 #ifdef AUDIOUNIT_SUPPORT
1412 boost::shared_ptr<AUPlugin> ap;
1415 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1416 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1417 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1418 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1420 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1421 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1423 #ifdef WINDOWS_VST_SUPPORT
1424 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1425 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1427 #ifdef LXVST_SUPPORT
1428 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1429 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1431 #ifdef MACVST_SUPPORT
1432 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1433 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1435 #ifdef AUDIOUNIT_SUPPORT
1436 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1437 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1441 fatal << string_compose (_("programming error: %1"),
1442 X_("unknown plugin type in PluginInsert::plugin_factory"))
1444 abort(); /*NOTREACHED*/
1445 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1449 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1450 if (num < _in_map.size()) {
1451 bool changed = _in_map[num] != m;
1453 changed |= sanitize_maps ();
1455 PluginMapChanged (); /* EMIT SIGNAL */
1456 _mapping_changed = true;
1457 _session.set_dirty();
1463 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1464 if (num < _out_map.size()) {
1465 bool changed = _out_map[num] != m;
1467 changed |= sanitize_maps ();
1469 PluginMapChanged (); /* EMIT SIGNAL */
1470 _mapping_changed = true;
1471 _session.set_dirty();
1477 PluginInsert::set_thru_map (ChanMapping m) {
1478 bool changed = _thru_map != m;
1480 changed |= sanitize_maps ();
1482 PluginMapChanged (); /* EMIT SIGNAL */
1483 _mapping_changed = true;
1484 _session.set_dirty();
1489 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1490 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1492 if (_configured) { return false; }
1493 _configured_in = in;
1494 _configured_out = out;
1498 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1503 PluginInsert::input_map () const
1507 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1508 ChanMapping m (i->second);
1509 const ChanMapping::Mappings& mp ((*i).second.mappings());
1510 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1511 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1512 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1521 PluginInsert::no_sc_input_map () const
1525 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1526 ChanMapping m (i->second);
1527 const ChanMapping::Mappings& mp ((*i).second.mappings());
1528 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1529 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1530 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1531 if (i->first < ins) {
1532 rv.set (tm->first, i->first + pc * ins, i->second);
1541 PluginInsert::output_map () const
1545 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1546 ChanMapping m (i->second);
1547 const ChanMapping::Mappings& mp ((*i).second.mappings());
1548 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1549 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1550 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1554 if (has_midi_bypass ()) {
1555 rv.set (DataType::MIDI, 0, 0);
1562 PluginInsert::has_midi_bypass () const
1564 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1565 && natural_output_streams ().n_midi () == 0) {
1572 PluginInsert::has_midi_thru () const
1574 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1575 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1583 PluginInsert::is_channelstrip () const {
1584 return _plugins.front()->is_channelstrip();
1587 PluginInsert::is_nonbypassable () const {
1588 return _plugins.front()->is_nonbypassable ();
1593 PluginInsert::check_inplace ()
1595 bool inplace_ok = !_plugins.front()->inplace_broken ();
1597 if (_thru_map.n_total () > 0) {
1598 // TODO once midi-bypass is part of the mapping, ignore it
1602 if (_match.method == Split && inplace_ok) {
1603 assert (get_count() == 1);
1604 assert (_in_map.size () == 1);
1605 if (!_out_map[0].is_monotonic ()) {
1608 if (_configured_internal != _configured_in) {
1609 /* no sidechain -- TODO we could allow this with
1610 * some more logic in PluginInsert::connect_and_run().
1612 * PluginInsert::reset_map() already maps it.
1617 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1618 if (_configured_internal.get (*t) == 0) {
1622 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1623 if (!valid || first_idx != 0) {
1624 // so far only allow to copy the *first* stream's buffer to others
1627 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1628 uint32_t idx = _in_map[0].get (*t, i, &valid);
1629 if (valid && idx != first_idx) {
1638 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1643 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1644 if (!_in_map[pc].is_monotonic ()) {
1647 if (!_out_map[pc].is_monotonic ()) {
1653 /* check if every output is fed by the corresponding input
1655 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1656 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1658 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1660 ChanMapping const& in_map (input_map ());
1661 const ChanMapping::Mappings out_m (output_map ().mappings ());
1662 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1663 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1664 /* src-pin: c->first, out-port: c->second */
1666 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1667 if (valid && in_port != c->second) {
1675 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1676 return !inplace_ok; // no-inplace
1680 PluginInsert::sanitize_maps ()
1682 bool changed = false;
1683 /* strip dead wood */
1684 PinMappings new_ins;
1685 PinMappings new_outs;
1686 ChanMapping new_thru;
1688 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1690 ChanMapping new_out;
1691 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1692 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1694 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1695 if (valid && idx < _configured_internal.get (*t)) {
1696 new_in.set (*t, i, idx);
1699 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1701 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1702 if (valid && idx < _configured_out.get (*t)) {
1703 new_out.set (*t, o, idx);
1707 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1710 new_ins[pc] = new_in;
1711 new_outs[pc] = new_out;
1714 /* prevent dup output assignments */
1715 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1716 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1717 bool mapped = false;
1718 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1720 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1721 if (valid && mapped) {
1722 new_outs[pc].unset (*t, idx);
1730 /* remove excess thru */
1731 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1732 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1734 uint32_t idx = _thru_map.get (*t, o, &valid);
1735 if (valid && idx < _configured_internal.get (*t)) {
1736 new_thru.set (*t, o, idx);
1741 /* prevent out + thru, existing plugin outputs override thru */
1742 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1743 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1744 bool mapped = false;
1746 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1747 new_outs[pc].get_src (*t, o, &mapped);
1748 if (mapped) { break; }
1750 if (!mapped) { continue; }
1751 uint32_t idx = new_thru.get (*t, o, &valid);
1753 new_thru.unset (*t, idx);
1758 if (has_midi_bypass ()) {
1759 // TODO: include midi-bypass in the thru set,
1760 // remove dedicated handling.
1761 new_thru.unset (DataType::MIDI, 0);
1764 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1768 _out_map = new_outs;
1769 _thru_map = new_thru;
1775 PluginInsert::reset_map (bool emit)
1777 const PinMappings old_in (_in_map);
1778 const PinMappings old_out (_out_map);
1782 _thru_map = ChanMapping ();
1784 /* build input map */
1785 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1786 uint32_t sc = 0; // side-chain round-robin (all instances)
1788 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1789 const uint32_t nis = natural_input_streams ().get(*t);
1790 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1792 /* SC inputs are last in the plugin-insert.. */
1793 const uint32_t sc_start = _configured_in.get (*t);
1794 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1795 /* ...but may not be at the end of the plugin ports.
1796 * in case the side-chain is not the last port, shift connections back.
1797 * and connect to side-chain
1800 uint32_t ic = 0; // split inputs
1801 const uint32_t cend = _configured_in.get (*t);
1803 for (uint32_t in = 0; in < nis; ++in) {
1804 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1805 if (iod.is_sidechain) {
1806 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1807 if (sc_len > 0) {// side-chain may be hidden
1808 _in_map[pc].set (*t, in, sc_start + sc);
1809 sc = (sc + 1) % sc_len;
1813 if (_match.method == Split) {
1814 if (cend == 0) { continue; }
1815 if (_strict_io && ic + stride * pc >= cend) {
1818 /* connect *no* sidechain sinks in round-robin fashion */
1819 _in_map[pc].set (*t, in, ic + stride * pc);
1820 if (_strict_io && (ic + 1) == cend) {
1823 ic = (ic + 1) % cend;
1825 uint32_t s = in - shift;
1826 if (stride * pc + s < cend) {
1827 _in_map[pc].set (*t, in, s + stride * pc);
1835 /* build output map */
1837 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1838 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1839 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1840 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1845 if (old_in == _in_map && old_out == _out_map) {
1849 PluginMapChanged (); /* EMIT SIGNAL */
1850 _mapping_changed = true;
1851 _session.set_dirty();
1857 PluginInsert::configure_io (ChanCount in, ChanCount out)
1859 Match old_match = _match;
1861 ChanCount old_internal;
1865 old_pins = natural_input_streams();
1866 old_in = _configured_in;
1867 old_out = _configured_out;
1868 old_internal = _configured_internal;
1870 _configured_in = in;
1871 _configured_internal = in;
1872 _configured_out = out;
1875 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1876 * (currently _sidechain->configure_io always succeeds
1877 * since Processor::configure_io() succeeds)
1879 if (!_sidechain->configure_io (in, out)) {
1880 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1883 _configured_internal += _sidechain->input()->n_ports();
1885 // include (static_cast<Route*>owner())->name() ??
1886 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1889 /* get plugin configuration */
1890 _match = private_can_support_io_configuration (in, out);
1892 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1894 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1895 DEBUG_STR_APPEND(a, _match);
1896 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1900 /* set the matching method and number of plugins that we will use to meet this configuration */
1901 if (set_count (_match.plugins) == false) {
1902 PluginIoReConfigure (); /* EMIT SIGNAL */
1903 _configured = false;
1907 /* configure plugins */
1908 switch (_match.method) {
1911 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1912 PluginIoReConfigure (); /* EMIT SIGNAL */
1913 _configured = false;
1919 ChanCount din (_configured_internal);
1920 ChanCount dout (din); // hint
1922 if (_custom_sinks.n_total () > 0) {
1923 din = _custom_sinks;
1926 } else if (_preset_out.n_audio () > 0) {
1927 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1928 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1929 dout.set (DataType::AUDIO, 2);
1931 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1933 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1934 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1936 if (useins.n_audio() == 0) {
1939 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1941 if (_plugins.front()->configure_io (useins, dout) == false) {
1942 PluginIoReConfigure (); /* EMIT SIGNAL */
1943 _configured = false;
1947 _custom_sinks = din;
1952 if (_plugins.front()->configure_io (in, out) == false) {
1953 PluginIoReConfigure (); /* EMIT SIGNAL */
1954 _configured = false;
1960 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",
1962 _configured ? "Y" : "N",
1963 _maps_from_state ? "Y" : "N",
1964 old_in == in ? "==" : "!=",
1965 old_out == out ? "==" : "!=",
1966 old_pins == natural_input_streams () ? "==" : "!=",
1967 old_match.method == _match.method ? "==" : "!=",
1968 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1969 _in_map.size() == get_count () ? "==" : "!=",
1970 _out_map.size() == get_count () ? "==" : "!="
1973 bool mapping_changed = false;
1974 if (old_in == in && old_out == out
1976 && old_pins == natural_input_streams ()
1977 && old_match.method == _match.method
1978 && old_match.custom_cfg == _match.custom_cfg
1979 && _in_map.size() == _out_map.size()
1980 && _in_map.size() == get_count ()
1982 /* If the configuration has not changed, keep the mapping */
1983 mapping_changed = sanitize_maps ();
1984 } else if (_match.custom_cfg && _configured) {
1985 /* don't touch the map in manual mode */
1986 mapping_changed = sanitize_maps ();
1989 if (is_channelstrip ()) {
1990 /* fake channel map - for wire display */
1993 _thru_map = ChanMapping ();
1994 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1995 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1996 /* set "thru" map for in-place forward of audio */
1997 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1998 _thru_map.set (DataType::AUDIO, i, i);
2000 /* and midi (after implicit 1st channel bypass) */
2001 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
2002 _thru_map.set (DataType::MIDI, i, i);
2006 if (_maps_from_state && old_in == in && old_out == out) {
2007 mapping_changed = true;
2010 /* generate a new mapping */
2011 mapping_changed = reset_map (false);
2013 _maps_from_state = false;
2016 if (mapping_changed) {
2017 PluginMapChanged (); /* EMIT SIGNAL */
2020 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2023 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2024 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2026 DEBUG_STR_APPEND(a, "----><----\n");
2028 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2029 DEBUG_STR_APPEND(a, " * Inputs:\n");
2030 DEBUG_STR_APPEND(a, _in_map[pc]);
2031 DEBUG_STR_APPEND(a, " * Outputs:\n");
2032 DEBUG_STR_APPEND(a, _out_map[pc]);
2034 DEBUG_STR_APPEND(a, " * Thru:\n");
2035 DEBUG_STR_APPEND(a, _thru_map);
2036 DEBUG_STR_APPEND(a, "-------->>--------\n");
2037 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2042 _no_inplace = check_inplace ();
2043 _mapping_changed = false;
2045 /* only the "noinplace_buffers" thread buffers need to be this large,
2046 * this can be optimized. other buffers are fine with
2047 * ChanCount::max (natural_input_streams (), natural_output_streams())
2048 * and route.cc's max (configured_in, configured_out)
2050 * no-inplace copies "thru" outputs (to emulate in-place) for
2051 * all outputs (to prevent overwrite) into a temporary space
2052 * which also holds input buffers (in case the plugin does process
2053 * in-place and overwrites those).
2055 * this buffers need to be at least as
2056 * natural_input_streams () + possible outputs.
2058 * sidechain inputs add a constraint on the input:
2059 * configured input + sidechain (=_configured_internal)
2061 * NB. this also satisfies
2062 * max (natural_input_streams(), natural_output_streams())
2063 * which is needed for silence runs
2065 _required_buffers = ChanCount::max (_configured_internal,
2066 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2068 if (old_in != in || old_out != out || old_internal != _configured_internal
2069 || old_pins != natural_input_streams ()
2070 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2072 PluginIoReConfigure (); /* EMIT SIGNAL */
2075 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2076 _latency_changed = true;
2078 /* we don't know the analysis window size, so we must work with the
2079 * current buffer size here. each request for data fills in these
2080 * buffers and the analyser makes sure it gets enough data for the
2081 * analysis window. We also only analyze audio, so we can ignore
2084 ChanCount cc_analysis_in (DataType::AUDIO, in.n_audio());
2085 ChanCount cc_analysis_out (DataType::AUDIO, out.n_audio());
2087 session().ensure_buffer_set (_signal_analysis_inputs, cc_analysis_in);
2088 _signal_analysis_inputs.set_count (cc_analysis_in);
2090 session().ensure_buffer_set (_signal_analysis_outputs, cc_analysis_out);
2091 _signal_analysis_outputs.set_count (cc_analysis_out);
2093 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2096 return Processor::configure_io (in, out);
2099 /** Decide whether this PluginInsert can support a given IO configuration.
2100 * To do this, we run through a set of possible solutions in rough order of
2103 * @param in Required input channel count.
2104 * @param out Filled in with the output channel count if we return true.
2105 * @return true if the given IO configuration can be supported.
2108 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2111 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2113 return private_can_support_io_configuration (in, out).method != Impossible;
2117 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2119 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2120 // preseed hint (for variable i/o)
2121 out.set (DataType::AUDIO, _preset_out.n_audio ());
2124 Match rv = internal_can_support_io_configuration (in, out);
2126 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2127 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2128 out.set (DataType::AUDIO, _preset_out.n_audio ());
2133 /** A private version of can_support_io_configuration which returns the method
2134 * by which the configuration can be matched, rather than just whether or not
2138 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2140 if (_plugins.empty()) {
2145 if (is_channelstrip ()) {
2147 return Match (ExactMatch, 1);
2151 /* if a user specified a custom cfg, so be it. */
2153 PluginInfoPtr info = _plugins.front()->get_info();
2155 if (info->reconfigurable_io()) {
2156 return Match (Delegate, 1, _strict_io, true);
2158 return Match (ExactMatch, get_count(), _strict_io, true);
2162 /* try automatic configuration */
2163 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2165 PluginInfoPtr info = _plugins.front()->get_info();
2166 ChanCount inputs = info->n_inputs;
2167 ChanCount outputs = info->n_outputs;
2169 /* handle case strict-i/o */
2170 if (_strict_io && m.method != Impossible) {
2173 /* special case MIDI instruments */
2174 if (is_instrument ()) {
2175 // output = midi-bypass + at most master-out channels.
2176 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2177 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2178 out = ChanCount::min (out, max_out);
2179 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2185 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2186 /* replicate processor to match output count (generators and such)
2187 * at least enough to feed every output port. */
2188 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2189 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2190 uint32_t nout = outputs.get (*t);
2191 if (nout == 0 || inx.get(*t) == 0) { continue; }
2192 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2195 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2196 return Match (Replicate, f, _strict_io);
2207 if (m.method != Impossible) {
2211 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2213 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2215 if (info->reconfigurable_io()) {
2218 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2219 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2220 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2222 // houston, we have a problem.
2223 return Match (Impossible, 0);
2226 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2227 return Match (Delegate, 1, _strict_io);
2230 ChanCount midi_bypass;
2231 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2232 midi_bypass.set (DataType::MIDI, 1);
2235 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2237 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2238 uint32_t nin = ns_inputs.get (*t);
2239 uint32_t nout = outputs.get (*t);
2240 if (nin == 0 || inx.get(*t) == 0) { continue; }
2241 // prefer floor() so the count won't overly increase IFF (nin < nout)
2242 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2244 if (f > 0 && outputs * f >= _configured_out) {
2245 out = outputs * f + midi_bypass;
2246 return Match (Replicate, f, _strict_io);
2249 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2251 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2252 uint32_t nin = ns_inputs.get (*t);
2253 if (nin == 0 || inx.get(*t) == 0) { continue; }
2254 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2257 out = outputs * f + midi_bypass;
2258 return Match (Replicate, f, _strict_io);
2261 // add at least as many plugins needed to connect all inputs
2263 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2264 uint32_t nin = inputs.get (*t);
2265 if (nin == 0 || inx.get(*t) == 0) { continue; }
2266 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2268 out = outputs * f + midi_bypass;
2269 return Match (Replicate, f, _strict_io);
2272 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2274 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2276 if (_plugins.empty()) {
2280 PluginInfoPtr info = _plugins.front()->get_info();
2281 ChanCount in; in += inx;
2282 ChanCount midi_bypass;
2284 if (info->reconfigurable_io()) {
2285 /* Plugin has flexible I/O, so delegate to it
2286 * pre-seed outputs, plugin tries closest match
2289 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2290 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2291 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2293 return Match (Impossible, 0);
2296 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2297 return Match (Delegate, 1);
2300 ChanCount inputs = info->n_inputs;
2301 ChanCount outputs = info->n_outputs;
2302 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2304 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2305 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2306 midi_bypass.set (DataType::MIDI, 1);
2308 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2309 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2310 in.set(DataType::MIDI, 0);
2313 // add internally provided sidechain ports
2314 ChanCount insc = in + sidechain_input_ports ();
2316 bool no_inputs = true;
2317 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2318 if (inputs.get (*t) != 0) {
2325 /* no inputs so we can take any input configuration since we throw it away */
2326 out = outputs + midi_bypass;
2327 return Match (NoInputs, 1);
2330 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2331 if (inputs == insc) {
2332 out = outputs + midi_bypass;
2333 return Match (ExactMatch, 1);
2336 /* Plugin inputs matches without side-chain-pins */
2337 if (ns_inputs == in) {
2338 out = outputs + midi_bypass;
2339 return Match (ExactMatch, 1);
2342 /* We may be able to run more than one copy of the plugin within this insert
2343 to cope with the insert having more inputs than the plugin.
2344 We allow replication only for plugins with either zero or 1 inputs and outputs
2345 for every valid data type.
2349 bool can_replicate = true;
2350 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2352 // ignore side-chains
2353 uint32_t nin = ns_inputs.get (*t);
2355 // No inputs of this type
2356 if (nin == 0 && in.get(*t) == 0) {
2360 if (nin != 1 || outputs.get (*t) != 1) {
2361 can_replicate = false;
2365 // Potential factor not set yet
2367 f = in.get(*t) / nin;
2370 // Factor for this type does not match another type, can not replicate
2371 if (f != (in.get(*t) / nin)) {
2372 can_replicate = false;
2377 if (can_replicate && f > 0) {
2378 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2379 out.set (*t, outputs.get(*t) * f);
2382 return Match (Replicate, f);
2385 /* If the processor has exactly one input of a given type, and
2386 the plugin has more, we can feed the single processor input
2387 to some or all of the plugin inputs. This is rather
2388 special-case-y, but the 1-to-many case is by far the
2389 simplest. How do I split thy 2 processor inputs to 3
2390 plugin inputs? Let me count the ways ...
2393 bool can_split = true;
2394 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2396 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2397 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2399 if (!can_split_type && !nothing_to_do_for_type) {
2405 out = outputs + midi_bypass;
2406 return Match (Split, 1);
2409 /* If the plugin has more inputs than we want, we can `hide' some of them
2410 by feeding them silence.
2413 bool could_hide = false;
2414 bool cannot_hide = false;
2415 ChanCount hide_channels;
2417 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2418 if (inputs.get(*t) > in.get(*t)) {
2419 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2420 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2422 } else if (inputs.get(*t) < in.get(*t)) {
2423 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2428 if (could_hide && !cannot_hide) {
2429 out = outputs + midi_bypass;
2430 return Match (Hide, 1, false, false, hide_channels);
2433 return Match (Impossible, 0);
2438 PluginInsert::state ()
2440 XMLNode& node = Processor::state ();
2442 node.set_property("type", _plugins[0]->state_node_name());
2443 node.set_property("unique-id", _plugins[0]->unique_id());
2444 node.set_property("count", (uint32_t)_plugins.size());
2446 /* remember actual i/o configuration (for later placeholder
2447 * in case the plugin goes missing) */
2448 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2449 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2450 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2451 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2453 /* save custom i/o config */
2454 node.set_property("custom", _custom_cfg);
2455 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2457 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2458 node.add_child_nocopy (* _in_map[pc].state (tmp));
2459 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2460 node.add_child_nocopy (* _out_map[pc].state (tmp));
2462 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2465 node.add_child_nocopy (_sidechain->get_state ());
2468 _plugins[0]->set_insert_id(this->id());
2469 node.add_child_nocopy (_plugins[0]->get_state());
2471 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2472 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2474 node.add_child_nocopy (ac->get_state());
2482 PluginInsert::set_control_ids (const XMLNode& node, int version)
2484 const XMLNodeList& nlist = node.children();
2485 XMLNodeConstIterator iter;
2486 set<Evoral::Parameter>::const_iterator p;
2488 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2489 if ((*iter)->name() == Controllable::xml_node_name) {
2491 uint32_t p = (uint32_t)-1;
2494 if ((*iter)->get_property (X_("symbol"), str)) {
2495 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2497 p = lv2plugin->port_index(str.c_str());
2501 if (p == (uint32_t)-1) {
2502 (*iter)->get_property (X_("parameter"), p);
2505 if (p != (uint32_t)-1) {
2507 /* this may create the new controllable */
2509 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2511 #ifndef NO_PLUGIN_STATE
2515 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2517 ac->set_state (**iter, version);
2526 PluginInsert::set_state(const XMLNode& node, int version)
2528 XMLNodeList nlist = node.children();
2529 XMLNodeIterator niter;
2530 XMLPropertyList plist;
2531 ARDOUR::PluginType type;
2534 if (!node.get_property ("type", str)) {
2535 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2539 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2540 type = ARDOUR::LADSPA;
2541 } else if (str == X_("lv2")) {
2543 } else if (str == X_("windows-vst")) {
2544 type = ARDOUR::Windows_VST;
2545 } else if (str == X_("lxvst")) {
2546 type = ARDOUR::LXVST;
2547 } else if (str == X_("mac-vst")) {
2548 type = ARDOUR::MacVST;
2549 } else if (str == X_("audiounit")) {
2550 type = ARDOUR::AudioUnit;
2551 } else if (str == X_("luaproc")) {
2554 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2558 XMLProperty const * prop = node.property ("unique-id");
2561 #ifdef WINDOWS_VST_SUPPORT
2562 /* older sessions contain VST plugins with only an "id" field. */
2563 if (type == ARDOUR::Windows_VST) {
2564 prop = node.property ("id");
2568 #ifdef LXVST_SUPPORT
2569 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2570 if (type == ARDOUR::LXVST) {
2571 prop = node.property ("id");
2578 error << _("Plugin has no unique ID field") << endmsg;
2583 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2584 bool any_vst = false;
2586 /* treat VST plugins equivalent if they have the same uniqueID
2587 * allow to move sessions windows <> linux */
2588 #ifdef LXVST_SUPPORT
2589 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2590 type = ARDOUR::LXVST;
2591 plugin = find_plugin (_session, prop->value(), type);
2592 if (plugin) { any_vst = true; }
2596 #ifdef WINDOWS_VST_SUPPORT
2597 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2598 type = ARDOUR::Windows_VST;
2599 plugin = find_plugin (_session, prop->value(), type);
2600 if (plugin) { any_vst = true; }
2604 #ifdef MACVST_SUPPORT
2605 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2606 type = ARDOUR::MacVST;
2607 plugin = find_plugin (_session, prop->value(), type);
2608 if (plugin) { any_vst = true; }
2612 if (plugin == 0 && type == ARDOUR::Lua) {
2613 /* unique ID (sha1 of script) was not found,
2614 * load the plugin from the serialized version in the
2615 * session-file instead.
2617 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2618 XMLNode *ls = node.child (lp->state_node_name().c_str());
2620 lp->set_script_from_state (*ls);
2626 error << string_compose(
2627 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2628 "Perhaps it was removed or moved since it was last used."),
2634 // The name of the PluginInsert comes from the plugin, nothing else
2635 _name = plugin->get_info()->name;
2639 // Processor::set_state() will set this, but too late
2640 // for it to be available when setting up plugin
2641 // state. We can't call Processor::set_state() until
2642 // the plugins themselves are created and added.
2646 if (_plugins.empty()) {
2647 /* if we are adding the first plugin, we will need to set
2648 up automatable controls.
2650 add_plugin (plugin);
2651 create_automatable_parameters ();
2652 set_control_ids (node, version);
2655 node.get_property ("count", count);
2657 if (_plugins.size() != count) {
2658 for (uint32_t n = 1; n < count; ++n) {
2659 add_plugin (plugin_factory (plugin));
2663 Processor::set_state (node, version);
2665 PBD::ID new_id = this->id();
2666 PBD::ID old_id = this->id();
2668 node.get_property ("id", old_id);
2670 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2672 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2673 and set all plugins to the same state.
2676 if ( ((*niter)->name() == plugin->state_node_name())
2677 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2680 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2681 /* Plugin state can include external files which are named after the ID.
2683 * If regenerate_xml_or_string_ids() is set, the ID will already have
2684 * been changed, so we need to use the old ID from the XML to load the
2685 * state and then update the ID.
2687 * When copying a plugin-state, route_ui takes care of of updating the ID,
2688 * but we need to call set_insert_id() to clear the cached plugin-state
2689 * and force a change.
2691 if (!regenerate_xml_or_string_ids ()) {
2692 (*i)->set_insert_id (new_id);
2694 (*i)->set_insert_id (old_id);
2697 (*i)->set_state (**niter, version);
2699 if (regenerate_xml_or_string_ids ()) {
2700 (*i)->set_insert_id (new_id);
2704 /* when copying plugin state, notify UI */
2705 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2706 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2708 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2716 if (version < 3000) {
2718 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2719 this is all handled by Automatable
2722 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2723 if ((*niter)->name() == "Redirect") {
2724 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2725 Processor::set_state (**niter, version);
2730 set_parameter_state_2X (node, version);
2733 node.get_property (X_("custom"), _custom_cfg);
2735 uint32_t in_maps = 0;
2736 uint32_t out_maps = 0;
2737 XMLNodeList kids = node.children ();
2738 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2739 if ((*i)->name() == X_("ConfiguredInput")) {
2740 _configured_in = ChanCount(**i);
2742 if ((*i)->name() == X_("CustomSinks")) {
2743 _custom_sinks = ChanCount(**i);
2745 if ((*i)->name() == X_("ConfiguredOutput")) {
2746 _custom_out = ChanCount(**i);
2747 _configured_out = ChanCount(**i);
2749 if ((*i)->name() == X_("PresetOutput")) {
2750 _preset_out = ChanCount(**i);
2752 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2753 long pc = atol (&((*i)->name().c_str()[9]));
2754 if (pc >= 0 && pc <= (long) get_count()) {
2755 _in_map[pc] = ChanMapping (**i);
2759 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2760 long pc = atol (&((*i)->name().c_str()[10]));
2761 if (pc >= 0 && pc <= (long) get_count()) {
2762 _out_map[pc] = ChanMapping (**i);
2766 if ((*i)->name () == "ThruMap") {
2767 _thru_map = ChanMapping (**i);
2770 // sidechain is a Processor (IO)
2771 if ((*i)->name () == Processor::state_node_name) {
2773 if (regenerate_xml_or_string_ids ()) {
2774 add_sidechain_from_xml (**i, version);
2779 if (!regenerate_xml_or_string_ids ()) {
2780 _sidechain->set_state (**i, version);
2782 update_sidechain_name ();
2787 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2788 _maps_from_state = true;
2791 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2795 (*i)->deactivate ();
2799 PluginConfigChanged (); /* EMIT SIGNAL */
2804 PluginInsert::update_id (PBD::ID id)
2807 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2808 (*i)->set_insert_id (id);
2813 PluginInsert::set_owner (SessionObject* o)
2815 Processor::set_owner (o);
2816 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2817 (*i)->set_owner (o);
2822 PluginInsert::set_state_dir (const std::string& d)
2824 // state() only saves the state of the first plugin
2825 _plugins[0]->set_state_dir (d);
2829 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2831 XMLNodeList nlist = node.children();
2832 XMLNodeIterator niter;
2834 /* look for port automation node */
2836 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2838 if ((*niter)->name() != port_automation_node_name) {
2843 XMLNodeConstIterator iter;
2847 cnodes = (*niter)->children ("port");
2849 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2853 if (!child->get_property("number", port_id)) {
2854 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2858 if (port_id >= _plugins[0]->parameter_count()) {
2859 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2863 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2864 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2866 if (c && c->alist()) {
2867 if (!child->children().empty()) {
2868 c->alist()->set_state (*child->children().front(), version);
2871 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2881 boost::shared_ptr<ReadOnlyControl>
2882 PluginInsert::control_output (uint32_t num) const
2884 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2885 if (i == _control_outputs.end ()) {
2886 return boost::shared_ptr<ReadOnlyControl> ();
2893 PluginInsert::describe_parameter (Evoral::Parameter param)
2895 if (param.type() == PluginAutomation) {
2896 return _plugins[0]->describe_parameter (param);
2897 } else if (param.type() == PluginPropertyAutomation) {
2898 boost::shared_ptr<AutomationControl> c(automation_control(param));
2899 if (c && !c->desc().label.empty()) {
2900 return c->desc().label;
2903 return Automatable::describe_parameter(param);
2907 PluginInsert::signal_latency() const
2909 if (!_pending_active) {
2912 if (_user_latency) {
2913 return _user_latency;
2916 return _plugins[0]->signal_latency ();
2920 PluginInsert::type ()
2922 return plugin()->get_info()->type;
2925 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2926 const Evoral::Parameter& param,
2927 const ParameterDescriptor& desc,
2928 boost::shared_ptr<AutomationList> list)
2929 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2934 list->set_interpolation(Evoral::ControlList::Discrete);
2939 /** @param val `user' value */
2942 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2944 /* FIXME: probably should be taking out some lock here.. */
2946 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2947 (*i)->set_parameter (_list->parameter().id(), user_val);
2950 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2952 iasp->set_parameter (_list->parameter().id(), user_val);
2955 AutomationControl::actually_set_value (user_val, group_override);
2959 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2961 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2965 PluginInsert::PluginControl::get_state ()
2967 XMLNode& node (AutomationControl::get_state());
2968 node.set_property (X_("parameter"), parameter().id());
2970 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2972 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2979 /** @return `user' val */
2981 PluginInsert::PluginControl::get_value () const
2983 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2989 return plugin->get_parameter (_list->parameter().id());
2992 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2993 const Evoral::Parameter& param,
2994 const ParameterDescriptor& desc,
2995 boost::shared_ptr<AutomationList> list)
2996 : AutomationControl (p->session(), param, desc, list)
3002 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
3004 /* Old numeric set_value(), coerce to appropriate datatype if possible.
3005 This is lossy, but better than nothing until Ardour's automation system
3006 can handle various datatypes all the way down. */
3007 const Variant value(_desc.datatype, user_val);
3008 if (value.type() == Variant::NOTHING) {
3009 error << "set_value(double) called for non-numeric property" << endmsg;
3013 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3014 (*i)->set_property(_list->parameter().id(), value);
3019 AutomationControl::actually_set_value (user_val, gcd);
3023 PluginInsert::PluginPropertyControl::get_state ()
3025 XMLNode& node (AutomationControl::get_state());
3026 node.set_property (X_("property"), parameter().id());
3027 node.remove_property (X_("value"));
3033 PluginInsert::PluginPropertyControl::get_value () const
3035 return _value.to_double();
3038 boost::shared_ptr<Plugin>
3039 PluginInsert::get_impulse_analysis_plugin()
3041 boost::shared_ptr<Plugin> ret;
3042 if (_impulseAnalysisPlugin.expired()) {
3043 // LV2 in particular uses various _session params
3044 // during init() -- most notably block_size..
3046 ret = plugin_factory(_plugins[0]);
3047 ChanCount out (internal_output_streams ());
3048 if (ret->get_info ()->reconfigurable_io ()) {
3049 // populate get_info ()->n_inputs and ->n_outputs
3051 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3052 assert (out == internal_output_streams ());
3054 ret->configure_io (internal_input_streams (), out);
3055 ret->set_owner (_owner);
3056 _impulseAnalysisPlugin = ret;
3058 ret = _impulseAnalysisPlugin.lock();
3065 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3067 // called from outside the audio thread, so this should be safe
3068 // only do audio as analysis is (currently) only for audio plugins
3069 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3070 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3072 _signal_analysis_collected_nframes = 0;
3073 _signal_analysis_collect_nframes_max = nframes;
3076 /** Add a plugin to our list */
3078 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3080 plugin->set_insert_id (this->id());
3081 plugin->set_owner (_owner);
3083 if (_plugins.empty()) {
3084 /* first (and probably only) plugin instance - connect to relevant signals */
3086 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3087 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3088 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3089 _custom_sinks = plugin->get_info()->n_inputs;
3090 // cache sidechain port count
3091 _cached_sidechain_pins.reset ();
3092 const ChanCount& nis (plugin->get_info()->n_inputs);
3093 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3094 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3095 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3096 if (iod.is_sidechain) {
3097 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3102 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3103 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3105 vst->set_insert (this, _plugins.size ());
3109 _plugins.push_back (plugin);
3113 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3115 if (version < 3000) {
3119 XMLNodeList nlist = node.children();
3121 if (nlist.size() == 0) {
3128 XMLNodeConstIterator it = nlist.front()->children().begin();
3129 for ( ; it != nlist.front()->children().end(); ++ it) {
3130 if ((*it)->name() == "Port") {
3131 DataType type(DataType::NIL);
3132 (*it)->get_property ("type", type);
3133 if (type == DataType::AUDIO) {
3135 } else if (type == DataType::MIDI) {
3141 ChanCount in_cc = ChanCount();
3142 in_cc.set (DataType::AUDIO, audio);
3143 in_cc.set (DataType::MIDI, midi);
3145 add_sidechain (audio, midi);
3149 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3152 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3153 if (! (*i)->load_preset (pr)) {
3161 PluginInsert::realtime_handle_transport_stopped ()
3163 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3164 (*i)->realtime_handle_transport_stopped ();
3169 PluginInsert::realtime_locate ()
3171 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3172 (*i)->realtime_locate ();
3177 PluginInsert::monitoring_changed ()
3179 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3180 (*i)->monitoring_changed ();
3185 PluginInsert::latency_changed ()
3187 // this is called in RT context, LatencyChanged is emitted after run()
3188 _latency_changed = true;
3189 // XXX This also needs a proper API not an owner() hack.
3191 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3195 PluginInsert::start_touch (uint32_t param_id)
3197 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3199 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3200 ac->start_touch (session().audible_sample());
3205 PluginInsert::end_touch (uint32_t param_id)
3207 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3209 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3210 ac->stop_touch (session().audible_sample());
3215 PluginInsert::provides_stats () const
3217 #if defined MIXBUS && !defined NDEBUG
3218 if (is_channelstrip () || !display_to_user ()) {
3226 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3228 /* TODO: consider taking a try/lock: Don't run concurrently with
3229 * TimingStats::update, TimingStats::reset.
3231 return _timing_stats.get_stats (min, max, avg, dev);
3235 PluginInsert::clear_stats ()
3237 g_atomic_int_set (&_stat_reset, 1);
3240 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3243 case PluginInsert::Impossible: o << "Impossible"; break;
3244 case PluginInsert::Delegate: o << "Delegate"; break;
3245 case PluginInsert::NoInputs: o << "NoInputs"; break;
3246 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3247 case PluginInsert::Replicate: o << "Replicate"; break;
3248 case PluginInsert::Split: o << "Split"; break;
3249 case PluginInsert::Hide: o << "Hide"; break;
3251 o << " cnt: " << m.plugins
3252 << (m.strict_io ? " strict-io" : "")
3253 << (m.custom_cfg ? " custom-cfg" : "");
3254 if (m.method == PluginInsert::Hide) {
3255 o << " hide: " << m.hide;