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, bool only_active)
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, only_active);
616 Automatable::automation_run (start, nframes, only_active);
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));
882 boost::shared_ptr<ControlList> cl = _automated_controls.reader ();
883 for (ControlList::const_iterator ci = cl->begin(); ci != cl->end(); ++ci) {
884 AutomationControl& c = *(ci->get());
885 boost::shared_ptr<const Evoral::ControlList> clist (c.list());
886 /* we still need to check for Touch and Latch */
887 if (clist && (static_cast<AutomationList const&> (*clist)).automation_playback ()) {
889 const float val = c.list()->rt_safe_eval (start, valid);
891 c.set_value_unchecked(val);
897 /* Calculate if, and how many samples we need to collect for analysis */
898 samplecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
899 _signal_analysis_collected_nframes);
900 if (nframes < collect_signal_nframes) { // we might not get all samples now
901 collect_signal_nframes = nframes;
904 if (collect_signal_nframes > 0) {
906 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
907 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
908 //std::cerr << "filling buffer with " << collect_signal_nframes << " samples at " << _signal_analysis_collected_nframes << std::endl;
910 _signal_analysis_inputs.set_count (ChanCount (DataType::AUDIO, input_streams().n_audio()));
912 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
913 _signal_analysis_inputs.get_audio(i).read_from (
915 collect_signal_nframes,
916 _signal_analysis_collected_nframes); // offset is for target buffer
921 if (is_channelstrip ()) {
922 if (_configured_in.n_audio() > 0) {
923 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
924 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
926 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
928 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
929 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
935 // TODO optimize -- build maps once.
937 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
938 ARDOUR::ChanMapping used_outputs;
940 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
942 /* build used-output map */
943 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
944 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
945 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
947 uint32_t out_idx = out_map.p(pc).get (*t, out, &valid);
949 used_outputs.set (*t, out_idx, 1); // mark as used
954 /* copy thru data to outputs before processing in-place */
955 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
956 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
958 uint32_t in_idx = thru_map.get (*t, out, &valid);
959 uint32_t m = out + natural_input_streams ().get (*t);
961 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
962 used_outputs.set (*t, out, 1); // mark as used
964 used_outputs.get (*t, out, &valid);
966 /* the plugin is expected to write here, but may not :(
967 * (e.g. drumgizmo w/o kit loaded)
969 inplace_bufs.get (*t, m).silence (nframes);
976 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
978 ARDOUR::ChanMapping i_in_map (natural_input_streams());
979 ARDOUR::ChanMapping i_out_map (out_map.p(pc));
980 ARDOUR::ChanCount mapped;
982 /* map inputs sequentially */
983 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
984 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
986 uint32_t in_idx = in_map.p(pc).get (*t, in, &valid);
987 uint32_t m = mapped.get (*t);
989 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
991 inplace_bufs.get (*t, m).silence (nframes, offset);
993 mapped.set (*t, m + 1);
997 /* outputs are mapped to inplace_bufs after the inputs */
998 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
999 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
1002 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1007 /* all instances have completed, now copy data that was written
1008 * and zero unconnected buffers */
1009 ARDOUR::ChanMapping nonzero_out (used_outputs);
1010 if (has_midi_bypass ()) {
1011 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1013 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1014 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1016 used_outputs.get (*t, out, &valid);
1018 nonzero_out.get (*t, out, &valid);
1020 bufs.get (*t, out).silence (nframes, offset);
1023 uint32_t m = out + natural_input_streams ().get (*t);
1024 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
1029 /* in-place processing */
1031 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1032 if ((*i)->connect_and_run(bufs, start, end, speed, in_map.p(pc), out_map.p(pc), nframes, offset)) {
1036 // now silence unconnected outputs
1037 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1040 if (collect_signal_nframes > 0) {
1042 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
1043 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
1045 _signal_analysis_outputs.set_count (ChanCount (DataType::AUDIO, output_streams().n_audio()));
1047 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1048 _signal_analysis_outputs.get_audio(i).read_from(
1050 collect_signal_nframes,
1051 _signal_analysis_collected_nframes); // offset is for target buffer
1054 _signal_analysis_collected_nframes += collect_signal_nframes;
1055 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
1057 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
1058 _signal_analysis_collect_nframes_max = 0;
1059 _signal_analysis_collected_nframes = 0;
1061 AnalysisDataGathered(&_signal_analysis_inputs,
1062 &_signal_analysis_outputs);
1066 if (_plugin_signal_latency != signal_latency ()) {
1067 _plugin_signal_latency = signal_latency ();
1073 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1075 /* bypass the plugin(s) not the whole processor.
1076 * -> use mappings just like connect_and_run
1078 if (_mapping_changed) {
1079 _no_inplace = check_inplace ();
1080 _mapping_changed = false;
1082 // TODO: atomically copy maps & _no_inplace
1083 ChanMapping const& in_map (no_sc_input_map ());
1084 ChanMapping const& out_map (output_map ());
1086 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1087 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1090 ChanMapping thru_map (_thru_map);
1092 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1094 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1095 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1096 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
1099 ARDOUR::ChanMapping used_outputs;
1101 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1102 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1104 uint32_t in_idx = thru_map.get (*t, out, &valid);
1106 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1107 used_outputs.set (*t, out, 1); // mark as used
1111 // plugin no-op: assume every plugin has an internal identity map
1112 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1113 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1115 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1119 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1123 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1124 used_outputs.set (*t, out, 1); // mark as used
1127 // now silence all unused outputs
1128 if (has_midi_bypass ()) {
1129 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1131 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1132 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1134 used_outputs.get (*t, out, &valid);
1136 bufs.get (*t, out).silence (nframes, 0);
1141 if (_match.method == Split) {
1142 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1143 if (_configured_internal.get (*t) == 0) {
1146 // copy/feeds _all_ *connected* inputs, copy the first buffer
1148 uint32_t first_idx = in_map.get (*t, 0, &valid);
1149 assert (valid && first_idx == 0); // check_inplace ensures this
1150 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1151 uint32_t idx = in_map.get (*t, i, &valid);
1154 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
1160 // apply output map and/or monotonic but not identity i/o mappings
1161 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1162 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1164 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1166 bufs.get (*t, out).silence (nframes, 0);
1169 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1171 bufs.get (*t, out).silence (nframes, 0);
1174 if (in_idx != src_idx) {
1175 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
1183 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1185 automation_run (start_sample, nframes, true); // evaluate automation only
1188 // XXX delaybuffers need to be offset by nframes
1192 _delaybuffers.flush ();
1194 const ChanMapping in_map (natural_input_streams ());
1195 const ChanMapping out_map (natural_output_streams ());
1196 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1198 if (is_channelstrip ()) {
1199 if (_configured_in.n_audio() > 0) {
1200 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1204 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1205 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1210 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1213 // collect sidechain input for complete cycle (!)
1214 // TODO we need delaylines here for latency compensation
1215 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1218 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1219 _timing_stats.reset ();
1222 if (_pending_active) {
1223 #if defined MIXBUS && defined NDEBUG
1224 if (!is_channelstrip ()) {
1225 _timing_stats.start ();
1228 _timing_stats.start ();
1230 /* run as normal if we are active or moving from inactive to active */
1232 if (_session.transport_rolling() || _session.bounce_processing()) {
1233 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1235 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1236 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1238 #if defined MIXBUS && defined NDEBUG
1239 if (!is_channelstrip ()) {
1240 _timing_stats.update ();
1243 _timing_stats.update ();
1247 _timing_stats.reset ();
1248 // XXX should call ::silence() to run plugin(s) for consistent load.
1249 // We'll need to change this anyway when bypass can be automated
1250 bypass (bufs, nframes);
1251 automation_run (start_sample, nframes, true); // evaluate automation only
1252 _delaybuffers.flush ();
1255 _active = _pending_active;
1257 /* we have no idea whether the plugin generated silence or not, so mark
1258 * all buffers appropriately.
1263 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1265 Evoral::ControlEvent next_event (0, 0.0f);
1266 samplecnt_t offset = 0;
1268 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1271 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1275 /* map start back into loop-range, adjust end */
1276 map_loop_range (start, end);
1278 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1280 /* no events have a time within the relevant range */
1282 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1288 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1290 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1296 map_loop_range (start, end);
1298 if (!find_next_event (start, end, next_event)) {
1303 /* cleanup anything that is left to do */
1306 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1311 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1313 if (param.type() != PluginAutomation)
1316 if (_plugins.empty()) {
1317 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1319 abort(); /*NOTREACHED*/
1322 return _plugins[0]->default_value (param.id());
1327 PluginInsert::can_reset_all_parameters ()
1330 uint32_t params = 0;
1331 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1333 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1335 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1339 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1345 if (ac->automation_state() & Play) {
1350 return all && (params > 0);
1354 PluginInsert::reset_parameters_to_default ()
1358 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1360 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1362 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1366 const float dflt = _plugins[0]->default_value (cid);
1367 const float curr = _plugins[0]->get_parameter (cid);
1373 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1378 if (ac->automation_state() & Play) {
1383 ac->set_value (dflt, Controllable::NoGroup);
1388 boost::shared_ptr<Plugin>
1389 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1391 boost::shared_ptr<LadspaPlugin> lp;
1392 boost::shared_ptr<LuaProc> lua;
1394 boost::shared_ptr<LV2Plugin> lv2p;
1396 #ifdef WINDOWS_VST_SUPPORT
1397 boost::shared_ptr<WindowsVSTPlugin> vp;
1399 #ifdef LXVST_SUPPORT
1400 boost::shared_ptr<LXVSTPlugin> lxvp;
1402 #ifdef MACVST_SUPPORT
1403 boost::shared_ptr<MacVSTPlugin> mvp;
1405 #ifdef AUDIOUNIT_SUPPORT
1406 boost::shared_ptr<AUPlugin> ap;
1409 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1410 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1411 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1412 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1414 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1415 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1417 #ifdef WINDOWS_VST_SUPPORT
1418 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1419 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1421 #ifdef LXVST_SUPPORT
1422 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1423 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1425 #ifdef MACVST_SUPPORT
1426 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1427 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1429 #ifdef AUDIOUNIT_SUPPORT
1430 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1431 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1435 fatal << string_compose (_("programming error: %1"),
1436 X_("unknown plugin type in PluginInsert::plugin_factory"))
1438 abort(); /*NOTREACHED*/
1439 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1443 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1444 if (num < _in_map.size()) {
1445 bool changed = _in_map[num] != m;
1447 changed |= sanitize_maps ();
1449 PluginMapChanged (); /* EMIT SIGNAL */
1450 _mapping_changed = true;
1451 _session.set_dirty();
1457 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1458 if (num < _out_map.size()) {
1459 bool changed = _out_map[num] != m;
1461 changed |= sanitize_maps ();
1463 PluginMapChanged (); /* EMIT SIGNAL */
1464 _mapping_changed = true;
1465 _session.set_dirty();
1471 PluginInsert::set_thru_map (ChanMapping m) {
1472 bool changed = _thru_map != m;
1474 changed |= sanitize_maps ();
1476 PluginMapChanged (); /* EMIT SIGNAL */
1477 _mapping_changed = true;
1478 _session.set_dirty();
1483 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1484 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1486 if (_configured) { return false; }
1487 _configured_in = in;
1488 _configured_out = out;
1492 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1497 PluginInsert::input_map () const
1501 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1502 ChanMapping m (i->second);
1503 const ChanMapping::Mappings& mp ((*i).second.mappings());
1504 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1505 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1506 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1515 PluginInsert::no_sc_input_map () const
1519 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1520 ChanMapping m (i->second);
1521 const ChanMapping::Mappings& mp ((*i).second.mappings());
1522 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1523 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1524 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1525 if (i->first < ins) {
1526 rv.set (tm->first, i->first + pc * ins, i->second);
1531 if (has_midi_thru ()) {
1532 rv.set (DataType::MIDI, 0, 0);
1538 PluginInsert::output_map () const
1542 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1543 ChanMapping m (i->second);
1544 const ChanMapping::Mappings& mp ((*i).second.mappings());
1545 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1546 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1547 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1551 if (has_midi_bypass ()) {
1552 rv.set (DataType::MIDI, 0, 0);
1559 PluginInsert::has_midi_bypass () const
1561 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1562 && natural_output_streams ().n_midi () == 0) {
1569 PluginInsert::has_midi_thru () const
1571 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1572 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1580 PluginInsert::is_channelstrip () const {
1581 return _plugins.front()->is_channelstrip();
1584 PluginInsert::is_nonbypassable () const {
1585 return _plugins.front()->is_nonbypassable ();
1590 PluginInsert::check_inplace ()
1592 bool inplace_ok = !_plugins.front()->inplace_broken ();
1594 if (_thru_map.n_total () > 0) {
1595 // TODO once midi-bypass is part of the mapping, ignore it
1599 if (_match.method == Split && inplace_ok) {
1600 assert (get_count() == 1);
1601 assert (_in_map.size () == 1);
1602 if (!_out_map[0].is_monotonic ()) {
1605 if (_configured_internal != _configured_in) {
1606 /* no sidechain -- TODO we could allow this with
1607 * some more logic in PluginInsert::connect_and_run().
1609 * PluginInsert::reset_map() already maps it.
1614 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1615 if (_configured_internal.get (*t) == 0) {
1619 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1620 if (!valid || first_idx != 0) {
1621 // so far only allow to copy the *first* stream's buffer to others
1624 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1625 uint32_t idx = _in_map[0].get (*t, i, &valid);
1626 if (valid && idx != first_idx) {
1635 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1640 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1641 if (!_in_map[pc].is_monotonic ()) {
1644 if (!_out_map[pc].is_monotonic ()) {
1650 /* check if every output is fed by the corresponding input
1652 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1653 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1655 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1657 ChanMapping const& in_map (input_map ());
1658 const ChanMapping::Mappings out_m (output_map ().mappings ());
1659 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1660 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1661 /* src-pin: c->first, out-port: c->second */
1663 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1664 if (valid && in_port != c->second) {
1672 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1673 return !inplace_ok; // no-inplace
1677 PluginInsert::sanitize_maps ()
1679 bool changed = false;
1680 /* strip dead wood */
1681 PinMappings new_ins;
1682 PinMappings new_outs;
1683 ChanMapping new_thru;
1685 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1687 ChanMapping new_out;
1688 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1689 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1691 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1692 if (valid && idx < _configured_internal.get (*t)) {
1693 new_in.set (*t, i, idx);
1696 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1698 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1699 if (valid && idx < _configured_out.get (*t)) {
1700 new_out.set (*t, o, idx);
1704 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1707 new_ins[pc] = new_in;
1708 new_outs[pc] = new_out;
1711 /* prevent dup output assignments */
1712 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1713 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1714 bool mapped = false;
1715 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1717 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1718 if (valid && mapped) {
1719 new_outs[pc].unset (*t, idx);
1727 /* remove excess thru */
1728 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1729 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1731 uint32_t idx = _thru_map.get (*t, o, &valid);
1732 if (valid && idx < _configured_internal.get (*t)) {
1733 new_thru.set (*t, o, idx);
1738 /* prevent out + thru, existing plugin outputs override thru */
1739 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1740 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1741 bool mapped = false;
1743 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1744 new_outs[pc].get_src (*t, o, &mapped);
1745 if (mapped) { break; }
1747 if (!mapped) { continue; }
1748 uint32_t idx = new_thru.get (*t, o, &valid);
1750 new_thru.unset (*t, idx);
1755 if (has_midi_bypass ()) {
1756 // TODO: include midi-bypass in the thru set,
1757 // remove dedicated handling.
1758 new_thru.unset (DataType::MIDI, 0);
1761 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1765 _out_map = new_outs;
1766 _thru_map = new_thru;
1772 PluginInsert::reset_map (bool emit)
1774 const PinMappings old_in (_in_map);
1775 const PinMappings old_out (_out_map);
1779 _thru_map = ChanMapping ();
1781 /* build input map */
1782 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1783 uint32_t sc = 0; // side-chain round-robin (all instances)
1785 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1786 const uint32_t nis = natural_input_streams ().get(*t);
1787 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1789 /* SC inputs are last in the plugin-insert.. */
1790 const uint32_t sc_start = _configured_in.get (*t);
1791 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1792 /* ...but may not be at the end of the plugin ports.
1793 * in case the side-chain is not the last port, shift connections back.
1794 * and connect to side-chain
1797 uint32_t ic = 0; // split inputs
1798 const uint32_t cend = _configured_in.get (*t);
1800 for (uint32_t in = 0; in < nis; ++in) {
1801 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1802 if (iod.is_sidechain) {
1803 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1804 if (sc_len > 0) {// side-chain may be hidden
1805 _in_map[pc].set (*t, in, sc_start + sc);
1806 sc = (sc + 1) % sc_len;
1810 if (_match.method == Split) {
1811 if (cend == 0) { continue; }
1812 if (_strict_io && ic + stride * pc >= cend) {
1815 /* connect *no* sidechain sinks in round-robin fashion */
1816 _in_map[pc].set (*t, in, ic + stride * pc);
1817 if (_strict_io && (ic + 1) == cend) {
1820 ic = (ic + 1) % cend;
1822 uint32_t s = in - shift;
1823 if (stride * pc + s < cend) {
1824 _in_map[pc].set (*t, in, s + stride * pc);
1832 /* build output map */
1834 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1835 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1836 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1837 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1842 if (old_in == _in_map && old_out == _out_map) {
1846 PluginMapChanged (); /* EMIT SIGNAL */
1847 _mapping_changed = true;
1848 _session.set_dirty();
1854 PluginInsert::configure_io (ChanCount in, ChanCount out)
1856 Match old_match = _match;
1858 ChanCount old_internal;
1862 old_pins = natural_input_streams();
1863 old_in = _configured_in;
1864 old_out = _configured_out;
1865 old_internal = _configured_internal;
1867 _configured_in = in;
1868 _configured_internal = in;
1869 _configured_out = out;
1872 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1873 * (currently _sidechain->configure_io always succeeds
1874 * since Processor::configure_io() succeeds)
1876 if (!_sidechain->configure_io (in, out)) {
1877 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1880 _configured_internal += _sidechain->input()->n_ports();
1882 // include (static_cast<Route*>owner())->name() ??
1883 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1886 /* get plugin configuration */
1887 _match = private_can_support_io_configuration (in, out);
1889 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1891 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1892 DEBUG_STR_APPEND(a, _match);
1893 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1897 /* set the matching method and number of plugins that we will use to meet this configuration */
1898 if (set_count (_match.plugins) == false) {
1899 PluginIoReConfigure (); /* EMIT SIGNAL */
1900 _configured = false;
1904 /* configure plugins */
1905 switch (_match.method) {
1908 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1909 PluginIoReConfigure (); /* EMIT SIGNAL */
1910 _configured = false;
1916 ChanCount din (_configured_internal);
1917 ChanCount dout (din); // hint
1919 if (_custom_sinks.n_total () > 0) {
1920 din = _custom_sinks;
1923 } else if (_preset_out.n_audio () > 0) {
1924 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1925 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1926 dout.set (DataType::AUDIO, 2);
1928 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1930 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1931 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1933 if (useins.n_audio() == 0) {
1936 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1938 if (_plugins.front()->configure_io (useins, dout) == false) {
1939 PluginIoReConfigure (); /* EMIT SIGNAL */
1940 _configured = false;
1944 _custom_sinks = din;
1949 if (_plugins.front()->configure_io (in, out) == false) {
1950 PluginIoReConfigure (); /* EMIT SIGNAL */
1951 _configured = false;
1957 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",
1959 _configured ? "Y" : "N",
1960 _maps_from_state ? "Y" : "N",
1961 old_in == in ? "==" : "!=",
1962 old_out == out ? "==" : "!=",
1963 old_pins == natural_input_streams () ? "==" : "!=",
1964 old_match.method == _match.method ? "==" : "!=",
1965 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1966 _in_map.size() == get_count () ? "==" : "!=",
1967 _out_map.size() == get_count () ? "==" : "!="
1970 bool mapping_changed = false;
1971 if (old_in == in && old_out == out
1973 && old_pins == natural_input_streams ()
1974 && old_match.method == _match.method
1975 && old_match.custom_cfg == _match.custom_cfg
1976 && _in_map.size() == _out_map.size()
1977 && _in_map.size() == get_count ()
1979 /* If the configuration has not changed, keep the mapping */
1980 mapping_changed = sanitize_maps ();
1981 } else if (_match.custom_cfg && _configured) {
1982 /* don't touch the map in manual mode */
1983 mapping_changed = sanitize_maps ();
1986 if (is_channelstrip ()) {
1987 /* fake channel map - for wire display */
1990 _thru_map = ChanMapping ();
1991 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1992 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1993 /* set "thru" map for in-place forward of audio */
1994 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1995 _thru_map.set (DataType::AUDIO, i, i);
1997 /* and midi (after implicit 1st channel bypass) */
1998 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1999 _thru_map.set (DataType::MIDI, i, i);
2003 if (_maps_from_state && old_in == in && old_out == out) {
2004 mapping_changed = true;
2007 /* generate a new mapping */
2008 mapping_changed = reset_map (false);
2010 _maps_from_state = false;
2013 if (mapping_changed) {
2014 PluginMapChanged (); /* EMIT SIGNAL */
2017 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2020 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2021 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2023 DEBUG_STR_APPEND(a, "----><----\n");
2025 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2026 DEBUG_STR_APPEND(a, " * Inputs:\n");
2027 DEBUG_STR_APPEND(a, _in_map[pc]);
2028 DEBUG_STR_APPEND(a, " * Outputs:\n");
2029 DEBUG_STR_APPEND(a, _out_map[pc]);
2031 DEBUG_STR_APPEND(a, " * Thru:\n");
2032 DEBUG_STR_APPEND(a, _thru_map);
2033 DEBUG_STR_APPEND(a, "-------->>--------\n");
2034 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2039 _no_inplace = check_inplace ();
2040 _mapping_changed = false;
2042 /* only the "noinplace_buffers" thread buffers need to be this large,
2043 * this can be optimized. other buffers are fine with
2044 * ChanCount::max (natural_input_streams (), natural_output_streams())
2045 * and route.cc's max (configured_in, configured_out)
2047 * no-inplace copies "thru" outputs (to emulate in-place) for
2048 * all outputs (to prevent overwrite) into a temporary space
2049 * which also holds input buffers (in case the plugin does process
2050 * in-place and overwrites those).
2052 * this buffers need to be at least as
2053 * natural_input_streams () + possible outputs.
2055 * sidechain inputs add a constraint on the input:
2056 * configured input + sidechain (=_configured_internal)
2058 * NB. this also satisfies
2059 * max (natural_input_streams(), natural_output_streams())
2060 * which is needed for silence runs
2062 _required_buffers = ChanCount::max (_configured_internal,
2063 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2065 if (old_in != in || old_out != out || old_internal != _configured_internal
2066 || old_pins != natural_input_streams ()
2067 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2069 PluginIoReConfigure (); /* EMIT SIGNAL */
2072 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2073 _latency_changed = true;
2075 /* we don't know the analysis window size, so we must work with the
2076 * current buffer size here. each request for data fills in these
2077 * buffers and the analyser makes sure it gets enough data for the
2078 * analysis window. We also only analyze audio, so we can ignore
2081 ChanCount cc_analysis_in (DataType::AUDIO, in.n_audio());
2082 ChanCount cc_analysis_out (DataType::AUDIO, out.n_audio());
2084 session().ensure_buffer_set (_signal_analysis_inputs, cc_analysis_in);
2085 _signal_analysis_inputs.set_count (cc_analysis_in);
2087 session().ensure_buffer_set (_signal_analysis_outputs, cc_analysis_out);
2088 _signal_analysis_outputs.set_count (cc_analysis_out);
2090 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2093 return Processor::configure_io (in, out);
2096 /** Decide whether this PluginInsert can support a given IO configuration.
2097 * To do this, we run through a set of possible solutions in rough order of
2100 * @param in Required input channel count.
2101 * @param out Filled in with the output channel count if we return true.
2102 * @return true if the given IO configuration can be supported.
2105 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2108 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2110 return private_can_support_io_configuration (in, out).method != Impossible;
2114 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2116 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2117 // preseed hint (for variable i/o)
2118 out.set (DataType::AUDIO, _preset_out.n_audio ());
2121 Match rv = internal_can_support_io_configuration (in, out);
2123 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2124 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2125 out.set (DataType::AUDIO, _preset_out.n_audio ());
2130 /** A private version of can_support_io_configuration which returns the method
2131 * by which the configuration can be matched, rather than just whether or not
2135 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2137 if (_plugins.empty()) {
2142 if (is_channelstrip ()) {
2144 return Match (ExactMatch, 1);
2148 /* if a user specified a custom cfg, so be it. */
2150 PluginInfoPtr info = _plugins.front()->get_info();
2152 if (info->reconfigurable_io()) {
2153 return Match (Delegate, 1, _strict_io, true);
2155 return Match (ExactMatch, get_count(), _strict_io, true);
2159 /* try automatic configuration */
2160 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2162 PluginInfoPtr info = _plugins.front()->get_info();
2163 ChanCount inputs = info->n_inputs;
2164 ChanCount outputs = info->n_outputs;
2166 /* handle case strict-i/o */
2167 if (_strict_io && m.method != Impossible) {
2170 /* special case MIDI instruments */
2171 if (is_instrument ()) {
2172 // output = midi-bypass + at most master-out channels.
2173 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2174 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2175 out = ChanCount::min (out, max_out);
2176 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2182 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2183 /* replicate processor to match output count (generators and such)
2184 * at least enough to feed every output port. */
2185 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2186 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2187 uint32_t nout = outputs.get (*t);
2188 if (nout == 0 || inx.get(*t) == 0) { continue; }
2189 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2192 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2193 return Match (Replicate, f, _strict_io);
2204 if (m.method != Impossible) {
2208 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2210 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2212 if (info->reconfigurable_io()) {
2215 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2216 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2217 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2219 // houston, we have a problem.
2220 return Match (Impossible, 0);
2223 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2224 return Match (Delegate, 1, _strict_io);
2227 ChanCount midi_bypass;
2228 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2229 midi_bypass.set (DataType::MIDI, 1);
2232 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2234 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2235 uint32_t nin = ns_inputs.get (*t);
2236 uint32_t nout = outputs.get (*t);
2237 if (nin == 0 || inx.get(*t) == 0) { continue; }
2238 // prefer floor() so the count won't overly increase IFF (nin < nout)
2239 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2241 if (f > 0 && outputs * f >= _configured_out) {
2242 out = outputs * f + midi_bypass;
2243 return Match (Replicate, f, _strict_io);
2246 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2248 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2249 uint32_t nin = ns_inputs.get (*t);
2250 if (nin == 0 || inx.get(*t) == 0) { continue; }
2251 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2254 out = outputs * f + midi_bypass;
2255 return Match (Replicate, f, _strict_io);
2258 // add at least as many plugins needed to connect all inputs
2260 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2261 uint32_t nin = inputs.get (*t);
2262 if (nin == 0 || inx.get(*t) == 0) { continue; }
2263 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2265 out = outputs * f + midi_bypass;
2266 return Match (Replicate, f, _strict_io);
2269 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2271 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2273 if (_plugins.empty()) {
2277 PluginInfoPtr info = _plugins.front()->get_info();
2278 ChanCount in; in += inx;
2279 ChanCount midi_bypass;
2281 if (info->reconfigurable_io()) {
2282 /* Plugin has flexible I/O, so delegate to it
2283 * pre-seed outputs, plugin tries closest match
2286 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2287 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2288 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2290 return Match (Impossible, 0);
2293 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2294 return Match (Delegate, 1);
2297 ChanCount inputs = info->n_inputs;
2298 ChanCount outputs = info->n_outputs;
2299 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2301 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2302 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2303 midi_bypass.set (DataType::MIDI, 1);
2305 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2306 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2307 in.set(DataType::MIDI, 0);
2310 // add internally provided sidechain ports
2311 ChanCount insc = in + sidechain_input_ports ();
2313 bool no_inputs = true;
2314 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2315 if (inputs.get (*t) != 0) {
2322 /* no inputs so we can take any input configuration since we throw it away */
2323 out = outputs + midi_bypass;
2324 return Match (NoInputs, 1);
2327 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2328 if (inputs == insc) {
2329 out = outputs + midi_bypass;
2330 return Match (ExactMatch, 1);
2333 /* Plugin inputs matches without side-chain-pins */
2334 if (ns_inputs == in) {
2335 out = outputs + midi_bypass;
2336 return Match (ExactMatch, 1);
2339 /* We may be able to run more than one copy of the plugin within this insert
2340 to cope with the insert having more inputs than the plugin.
2341 We allow replication only for plugins with either zero or 1 inputs and outputs
2342 for every valid data type.
2346 bool can_replicate = true;
2347 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2349 // ignore side-chains
2350 uint32_t nin = ns_inputs.get (*t);
2352 // No inputs of this type
2353 if (nin == 0 && in.get(*t) == 0) {
2357 if (nin != 1 || outputs.get (*t) != 1) {
2358 can_replicate = false;
2362 // Potential factor not set yet
2364 f = in.get(*t) / nin;
2367 // Factor for this type does not match another type, can not replicate
2368 if (f != (in.get(*t) / nin)) {
2369 can_replicate = false;
2374 if (can_replicate && f > 0) {
2375 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2376 out.set (*t, outputs.get(*t) * f);
2379 return Match (Replicate, f);
2382 /* If the processor has exactly one input of a given type, and
2383 the plugin has more, we can feed the single processor input
2384 to some or all of the plugin inputs. This is rather
2385 special-case-y, but the 1-to-many case is by far the
2386 simplest. How do I split thy 2 processor inputs to 3
2387 plugin inputs? Let me count the ways ...
2390 bool can_split = true;
2391 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2393 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2394 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2396 if (!can_split_type && !nothing_to_do_for_type) {
2402 out = outputs + midi_bypass;
2403 return Match (Split, 1);
2406 /* If the plugin has more inputs than we want, we can `hide' some of them
2407 by feeding them silence.
2410 bool could_hide = false;
2411 bool cannot_hide = false;
2412 ChanCount hide_channels;
2414 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2415 if (inputs.get(*t) > in.get(*t)) {
2416 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2417 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2419 } else if (inputs.get(*t) < in.get(*t)) {
2420 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2425 if (could_hide && !cannot_hide) {
2426 out = outputs + midi_bypass;
2427 return Match (Hide, 1, false, false, hide_channels);
2430 return Match (Impossible, 0);
2435 PluginInsert::state ()
2437 XMLNode& node = Processor::state ();
2439 node.set_property("type", _plugins[0]->state_node_name());
2440 node.set_property("unique-id", _plugins[0]->unique_id());
2441 node.set_property("count", (uint32_t)_plugins.size());
2443 /* remember actual i/o configuration (for later placeholder
2444 * in case the plugin goes missing) */
2445 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2446 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2447 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2448 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2450 /* save custom i/o config */
2451 node.set_property("custom", _custom_cfg);
2452 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2454 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2455 node.add_child_nocopy (* _in_map[pc].state (tmp));
2456 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2457 node.add_child_nocopy (* _out_map[pc].state (tmp));
2459 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2462 node.add_child_nocopy (_sidechain->get_state ());
2465 _plugins[0]->set_insert_id(this->id());
2466 node.add_child_nocopy (_plugins[0]->get_state());
2468 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2469 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2471 node.add_child_nocopy (ac->get_state());
2479 PluginInsert::set_control_ids (const XMLNode& node, int version)
2481 const XMLNodeList& nlist = node.children();
2482 XMLNodeConstIterator iter;
2483 set<Evoral::Parameter>::const_iterator p;
2485 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2486 if ((*iter)->name() == Controllable::xml_node_name) {
2488 uint32_t p = (uint32_t)-1;
2491 if ((*iter)->get_property (X_("symbol"), str)) {
2492 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2494 p = lv2plugin->port_index(str.c_str());
2498 if (p == (uint32_t)-1) {
2499 (*iter)->get_property (X_("parameter"), p);
2502 if (p != (uint32_t)-1) {
2504 /* this may create the new controllable */
2506 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2508 #ifndef NO_PLUGIN_STATE
2512 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2514 ac->set_state (**iter, version);
2523 PluginInsert::set_state(const XMLNode& node, int version)
2525 XMLNodeList nlist = node.children();
2526 XMLNodeIterator niter;
2527 XMLPropertyList plist;
2528 ARDOUR::PluginType type;
2531 if (!node.get_property ("type", str)) {
2532 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2536 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2537 type = ARDOUR::LADSPA;
2538 } else if (str == X_("lv2")) {
2540 } else if (str == X_("windows-vst")) {
2541 type = ARDOUR::Windows_VST;
2542 } else if (str == X_("lxvst")) {
2543 type = ARDOUR::LXVST;
2544 } else if (str == X_("mac-vst")) {
2545 type = ARDOUR::MacVST;
2546 } else if (str == X_("audiounit")) {
2547 type = ARDOUR::AudioUnit;
2548 } else if (str == X_("luaproc")) {
2551 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2555 XMLProperty const * prop = node.property ("unique-id");
2558 #ifdef WINDOWS_VST_SUPPORT
2559 /* older sessions contain VST plugins with only an "id" field. */
2560 if (type == ARDOUR::Windows_VST) {
2561 prop = node.property ("id");
2565 #ifdef LXVST_SUPPORT
2566 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2567 if (type == ARDOUR::LXVST) {
2568 prop = node.property ("id");
2575 error << _("Plugin has no unique ID field") << endmsg;
2580 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2581 bool any_vst = false;
2583 /* treat VST plugins equivalent if they have the same uniqueID
2584 * allow to move sessions windows <> linux */
2585 #ifdef LXVST_SUPPORT
2586 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2587 type = ARDOUR::LXVST;
2588 plugin = find_plugin (_session, prop->value(), type);
2589 if (plugin) { any_vst = true; }
2593 #ifdef WINDOWS_VST_SUPPORT
2594 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2595 type = ARDOUR::Windows_VST;
2596 plugin = find_plugin (_session, prop->value(), type);
2597 if (plugin) { any_vst = true; }
2601 #ifdef MACVST_SUPPORT
2602 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2603 type = ARDOUR::MacVST;
2604 plugin = find_plugin (_session, prop->value(), type);
2605 if (plugin) { any_vst = true; }
2609 if (plugin == 0 && type == ARDOUR::Lua) {
2610 /* unique ID (sha1 of script) was not found,
2611 * load the plugin from the serialized version in the
2612 * session-file instead.
2614 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2615 XMLNode *ls = node.child (lp->state_node_name().c_str());
2617 lp->set_script_from_state (*ls);
2623 error << string_compose(
2624 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2625 "Perhaps it was removed or moved since it was last used."),
2631 // The name of the PluginInsert comes from the plugin, nothing else
2632 _name = plugin->get_info()->name;
2636 // Processor::set_state() will set this, but too late
2637 // for it to be available when setting up plugin
2638 // state. We can't call Processor::set_state() until
2639 // the plugins themselves are created and added.
2643 if (_plugins.empty()) {
2644 /* if we are adding the first plugin, we will need to set
2645 up automatable controls.
2647 add_plugin (plugin);
2648 create_automatable_parameters ();
2649 set_control_ids (node, version);
2652 node.get_property ("count", count);
2654 if (_plugins.size() != count) {
2655 for (uint32_t n = 1; n < count; ++n) {
2656 add_plugin (plugin_factory (plugin));
2660 Processor::set_state (node, version);
2662 PBD::ID new_id = this->id();
2663 PBD::ID old_id = this->id();
2665 node.get_property ("id", old_id);
2667 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2669 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2670 and set all plugins to the same state.
2673 if ( ((*niter)->name() == plugin->state_node_name())
2674 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2677 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2678 /* Plugin state can include external files which are named after the ID.
2680 * If regenerate_xml_or_string_ids() is set, the ID will already have
2681 * been changed, so we need to use the old ID from the XML to load the
2682 * state and then update the ID.
2684 * When copying a plugin-state, route_ui takes care of of updating the ID,
2685 * but we need to call set_insert_id() to clear the cached plugin-state
2686 * and force a change.
2688 if (!regenerate_xml_or_string_ids ()) {
2689 (*i)->set_insert_id (new_id);
2691 (*i)->set_insert_id (old_id);
2694 (*i)->set_state (**niter, version);
2696 if (regenerate_xml_or_string_ids ()) {
2697 (*i)->set_insert_id (new_id);
2701 /* when copying plugin state, notify UI */
2702 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2703 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2705 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2713 if (version < 3000) {
2715 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2716 this is all handled by Automatable
2719 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2720 if ((*niter)->name() == "Redirect") {
2721 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2722 Processor::set_state (**niter, version);
2727 set_parameter_state_2X (node, version);
2730 node.get_property (X_("custom"), _custom_cfg);
2732 uint32_t in_maps = 0;
2733 uint32_t out_maps = 0;
2734 XMLNodeList kids = node.children ();
2735 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2736 if ((*i)->name() == X_("ConfiguredInput")) {
2737 _configured_in = ChanCount(**i);
2739 if ((*i)->name() == X_("CustomSinks")) {
2740 _custom_sinks = ChanCount(**i);
2742 if ((*i)->name() == X_("ConfiguredOutput")) {
2743 _custom_out = ChanCount(**i);
2744 _configured_out = ChanCount(**i);
2746 if ((*i)->name() == X_("PresetOutput")) {
2747 _preset_out = ChanCount(**i);
2749 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2750 long pc = atol (&((*i)->name().c_str()[9]));
2751 if (pc >= 0 && pc <= (long) get_count()) {
2752 _in_map[pc] = ChanMapping (**i);
2756 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2757 long pc = atol (&((*i)->name().c_str()[10]));
2758 if (pc >= 0 && pc <= (long) get_count()) {
2759 _out_map[pc] = ChanMapping (**i);
2763 if ((*i)->name () == "ThruMap") {
2764 _thru_map = ChanMapping (**i);
2767 // sidechain is a Processor (IO)
2768 if ((*i)->name () == Processor::state_node_name) {
2770 if (regenerate_xml_or_string_ids ()) {
2771 add_sidechain_from_xml (**i, version);
2776 if (!regenerate_xml_or_string_ids ()) {
2777 _sidechain->set_state (**i, version);
2779 update_sidechain_name ();
2784 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2785 _maps_from_state = true;
2788 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2792 (*i)->deactivate ();
2796 PluginConfigChanged (); /* EMIT SIGNAL */
2801 PluginInsert::update_id (PBD::ID id)
2804 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2805 (*i)->set_insert_id (id);
2810 PluginInsert::set_owner (SessionObject* o)
2812 Processor::set_owner (o);
2813 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2814 (*i)->set_owner (o);
2819 PluginInsert::set_state_dir (const std::string& d)
2821 // state() only saves the state of the first plugin
2822 _plugins[0]->set_state_dir (d);
2826 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2828 XMLNodeList nlist = node.children();
2829 XMLNodeIterator niter;
2831 /* look for port automation node */
2833 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2835 if ((*niter)->name() != port_automation_node_name) {
2840 XMLNodeConstIterator iter;
2844 cnodes = (*niter)->children ("port");
2846 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2850 if (!child->get_property("number", port_id)) {
2851 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2855 if (port_id >= _plugins[0]->parameter_count()) {
2856 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2860 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2861 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2863 if (c && c->alist()) {
2864 if (!child->children().empty()) {
2865 c->alist()->set_state (*child->children().front(), version);
2868 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2878 boost::shared_ptr<ReadOnlyControl>
2879 PluginInsert::control_output (uint32_t num) const
2881 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2882 if (i == _control_outputs.end ()) {
2883 return boost::shared_ptr<ReadOnlyControl> ();
2890 PluginInsert::describe_parameter (Evoral::Parameter param)
2892 if (param.type() == PluginAutomation) {
2893 return _plugins[0]->describe_parameter (param);
2894 } else if (param.type() == PluginPropertyAutomation) {
2895 boost::shared_ptr<AutomationControl> c(automation_control(param));
2896 if (c && !c->desc().label.empty()) {
2897 return c->desc().label;
2900 return Automatable::describe_parameter(param);
2904 PluginInsert::signal_latency() const
2906 if (!_pending_active) {
2909 if (_user_latency) {
2910 return _user_latency;
2913 return _plugins[0]->signal_latency ();
2917 PluginInsert::type ()
2919 return plugin()->get_info()->type;
2922 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2923 const Evoral::Parameter& param,
2924 const ParameterDescriptor& desc,
2925 boost::shared_ptr<AutomationList> list)
2926 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2931 list->set_interpolation(Evoral::ControlList::Discrete);
2936 /** @param val `user' value */
2939 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2941 /* FIXME: probably should be taking out some lock here.. */
2943 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2944 (*i)->set_parameter (_list->parameter().id(), user_val);
2947 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2949 iasp->set_parameter (_list->parameter().id(), user_val);
2952 AutomationControl::actually_set_value (user_val, group_override);
2956 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2958 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2962 PluginInsert::PluginControl::get_state ()
2964 XMLNode& node (AutomationControl::get_state());
2965 node.set_property (X_("parameter"), parameter().id());
2967 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2969 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2976 /** @return `user' val */
2978 PluginInsert::PluginControl::get_value () const
2980 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2986 return plugin->get_parameter (_list->parameter().id());
2989 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2990 const Evoral::Parameter& param,
2991 const ParameterDescriptor& desc,
2992 boost::shared_ptr<AutomationList> list)
2993 : AutomationControl (p->session(), param, desc, list)
2999 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
3001 /* Old numeric set_value(), coerce to appropriate datatype if possible.
3002 This is lossy, but better than nothing until Ardour's automation system
3003 can handle various datatypes all the way down. */
3004 const Variant value(_desc.datatype, user_val);
3005 if (value.type() == Variant::NOTHING) {
3006 error << "set_value(double) called for non-numeric property" << endmsg;
3010 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3011 (*i)->set_property(_list->parameter().id(), value);
3016 AutomationControl::actually_set_value (user_val, gcd);
3020 PluginInsert::PluginPropertyControl::get_state ()
3022 XMLNode& node (AutomationControl::get_state());
3023 node.set_property (X_("property"), parameter().id());
3024 node.remove_property (X_("value"));
3030 PluginInsert::PluginPropertyControl::get_value () const
3032 return _value.to_double();
3035 boost::shared_ptr<Plugin>
3036 PluginInsert::get_impulse_analysis_plugin()
3038 boost::shared_ptr<Plugin> ret;
3039 if (_impulseAnalysisPlugin.expired()) {
3040 // LV2 in particular uses various _session params
3041 // during init() -- most notably block_size..
3043 ret = plugin_factory(_plugins[0]);
3044 ChanCount out (internal_output_streams ());
3045 if (ret->get_info ()->reconfigurable_io ()) {
3046 // populate get_info ()->n_inputs and ->n_outputs
3048 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3049 assert (out == internal_output_streams ());
3051 ret->configure_io (internal_input_streams (), out);
3052 ret->set_owner (_owner);
3053 _impulseAnalysisPlugin = ret;
3055 ret = _impulseAnalysisPlugin.lock();
3062 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3064 // called from outside the audio thread, so this should be safe
3065 // only do audio as analysis is (currently) only for audio plugins
3066 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3067 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3069 _signal_analysis_collected_nframes = 0;
3070 _signal_analysis_collect_nframes_max = nframes;
3073 /** Add a plugin to our list */
3075 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3077 plugin->set_insert_id (this->id());
3078 plugin->set_owner (_owner);
3080 if (_plugins.empty()) {
3081 /* first (and probably only) plugin instance - connect to relevant signals */
3083 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3084 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3085 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3086 _custom_sinks = plugin->get_info()->n_inputs;
3087 // cache sidechain port count
3088 _cached_sidechain_pins.reset ();
3089 const ChanCount& nis (plugin->get_info()->n_inputs);
3090 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3091 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3092 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3093 if (iod.is_sidechain) {
3094 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3099 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3100 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3102 vst->set_insert (this, _plugins.size ());
3106 _plugins.push_back (plugin);
3110 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3112 if (version < 3000) {
3116 XMLNodeList nlist = node.children();
3118 if (nlist.size() == 0) {
3125 XMLNodeConstIterator it = nlist.front()->children().begin();
3126 for ( ; it != nlist.front()->children().end(); ++ it) {
3127 if ((*it)->name() == "Port") {
3128 DataType type(DataType::NIL);
3129 (*it)->get_property ("type", type);
3130 if (type == DataType::AUDIO) {
3132 } else if (type == DataType::MIDI) {
3138 ChanCount in_cc = ChanCount();
3139 in_cc.set (DataType::AUDIO, audio);
3140 in_cc.set (DataType::MIDI, midi);
3142 add_sidechain (audio, midi);
3146 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3149 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3150 if (! (*i)->load_preset (pr)) {
3158 PluginInsert::realtime_handle_transport_stopped ()
3160 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3161 (*i)->realtime_handle_transport_stopped ();
3166 PluginInsert::realtime_locate ()
3168 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3169 (*i)->realtime_locate ();
3174 PluginInsert::monitoring_changed ()
3176 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3177 (*i)->monitoring_changed ();
3182 PluginInsert::latency_changed ()
3184 // this is called in RT context, LatencyChanged is emitted after run()
3185 _latency_changed = true;
3186 // XXX This also needs a proper API not an owner() hack.
3188 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3192 PluginInsert::start_touch (uint32_t param_id)
3194 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3196 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3197 ac->start_touch (session().audible_sample());
3202 PluginInsert::end_touch (uint32_t param_id)
3204 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3206 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3207 ac->stop_touch (session().audible_sample());
3212 PluginInsert::provides_stats () const
3214 #if defined MIXBUS && defined NDEBUG
3215 if (is_channelstrip () || !display_to_user ()) {
3223 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3225 /* TODO: consider taking a try/lock: Don't run concurrently with
3226 * TimingStats::update, TimingStats::reset.
3228 return _timing_stats.get_stats (min, max, avg, dev);
3232 PluginInsert::clear_stats ()
3234 g_atomic_int_set (&_stat_reset, 1);
3237 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3240 case PluginInsert::Impossible: o << "Impossible"; break;
3241 case PluginInsert::Delegate: o << "Delegate"; break;
3242 case PluginInsert::NoInputs: o << "NoInputs"; break;
3243 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3244 case PluginInsert::Replicate: o << "Replicate"; break;
3245 case PluginInsert::Split: o << "Split"; break;
3246 case PluginInsert::Hide: o << "Hide"; break;
3248 o << " cnt: " << m.plugins
3249 << (m.strict_io ? " strict-io" : "")
3250 << (m.custom_cfg ? " custom-cfg" : "");
3251 if (m.method == PluginInsert::Hide) {
3252 o << " hide: " << m.hide;