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);
1535 PluginInsert::output_map () const
1539 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1540 ChanMapping m (i->second);
1541 const ChanMapping::Mappings& mp ((*i).second.mappings());
1542 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1543 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1544 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1548 if (has_midi_bypass ()) {
1549 rv.set (DataType::MIDI, 0, 0);
1556 PluginInsert::has_midi_bypass () const
1558 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1559 && natural_output_streams ().n_midi () == 0) {
1566 PluginInsert::has_midi_thru () const
1568 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1569 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1577 PluginInsert::is_channelstrip () const {
1578 return _plugins.front()->is_channelstrip();
1581 PluginInsert::is_nonbypassable () const {
1582 return _plugins.front()->is_nonbypassable ();
1587 PluginInsert::check_inplace ()
1589 bool inplace_ok = !_plugins.front()->inplace_broken ();
1591 if (_thru_map.n_total () > 0) {
1592 // TODO once midi-bypass is part of the mapping, ignore it
1596 if (_match.method == Split && inplace_ok) {
1597 assert (get_count() == 1);
1598 assert (_in_map.size () == 1);
1599 if (!_out_map[0].is_monotonic ()) {
1602 if (_configured_internal != _configured_in) {
1603 /* no sidechain -- TODO we could allow this with
1604 * some more logic in PluginInsert::connect_and_run().
1606 * PluginInsert::reset_map() already maps it.
1611 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1612 if (_configured_internal.get (*t) == 0) {
1616 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1617 if (!valid || first_idx != 0) {
1618 // so far only allow to copy the *first* stream's buffer to others
1621 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1622 uint32_t idx = _in_map[0].get (*t, i, &valid);
1623 if (valid && idx != first_idx) {
1632 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1637 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1638 if (!_in_map[pc].is_monotonic ()) {
1641 if (!_out_map[pc].is_monotonic ()) {
1647 /* check if every output is fed by the corresponding input
1649 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1650 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1652 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1654 ChanMapping const& in_map (input_map ());
1655 const ChanMapping::Mappings out_m (output_map ().mappings ());
1656 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1657 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1658 /* src-pin: c->first, out-port: c->second */
1660 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1661 if (valid && in_port != c->second) {
1669 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1670 return !inplace_ok; // no-inplace
1674 PluginInsert::sanitize_maps ()
1676 bool changed = false;
1677 /* strip dead wood */
1678 PinMappings new_ins;
1679 PinMappings new_outs;
1680 ChanMapping new_thru;
1682 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1684 ChanMapping new_out;
1685 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1686 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1688 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1689 if (valid && idx < _configured_internal.get (*t)) {
1690 new_in.set (*t, i, idx);
1693 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1695 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1696 if (valid && idx < _configured_out.get (*t)) {
1697 new_out.set (*t, o, idx);
1701 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1704 new_ins[pc] = new_in;
1705 new_outs[pc] = new_out;
1708 /* prevent dup output assignments */
1709 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1710 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1711 bool mapped = false;
1712 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1714 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1715 if (valid && mapped) {
1716 new_outs[pc].unset (*t, idx);
1724 /* remove excess thru */
1725 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1726 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1728 uint32_t idx = _thru_map.get (*t, o, &valid);
1729 if (valid && idx < _configured_internal.get (*t)) {
1730 new_thru.set (*t, o, idx);
1735 /* prevent out + thru, existing plugin outputs override thru */
1736 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1737 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1738 bool mapped = false;
1740 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1741 new_outs[pc].get_src (*t, o, &mapped);
1742 if (mapped) { break; }
1744 if (!mapped) { continue; }
1745 uint32_t idx = new_thru.get (*t, o, &valid);
1747 new_thru.unset (*t, idx);
1752 if (has_midi_bypass ()) {
1753 // TODO: include midi-bypass in the thru set,
1754 // remove dedicated handling.
1755 new_thru.unset (DataType::MIDI, 0);
1758 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1762 _out_map = new_outs;
1763 _thru_map = new_thru;
1769 PluginInsert::reset_map (bool emit)
1771 const PinMappings old_in (_in_map);
1772 const PinMappings old_out (_out_map);
1776 _thru_map = ChanMapping ();
1778 /* build input map */
1779 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1780 uint32_t sc = 0; // side-chain round-robin (all instances)
1782 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1783 const uint32_t nis = natural_input_streams ().get(*t);
1784 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1786 /* SC inputs are last in the plugin-insert.. */
1787 const uint32_t sc_start = _configured_in.get (*t);
1788 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1789 /* ...but may not be at the end of the plugin ports.
1790 * in case the side-chain is not the last port, shift connections back.
1791 * and connect to side-chain
1794 uint32_t ic = 0; // split inputs
1795 const uint32_t cend = _configured_in.get (*t);
1797 for (uint32_t in = 0; in < nis; ++in) {
1798 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1799 if (iod.is_sidechain) {
1800 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1801 if (sc_len > 0) {// side-chain may be hidden
1802 _in_map[pc].set (*t, in, sc_start + sc);
1803 sc = (sc + 1) % sc_len;
1807 if (_match.method == Split) {
1808 if (cend == 0) { continue; }
1809 if (_strict_io && ic + stride * pc >= cend) {
1812 /* connect *no* sidechain sinks in round-robin fashion */
1813 _in_map[pc].set (*t, in, ic + stride * pc);
1814 if (_strict_io && (ic + 1) == cend) {
1817 ic = (ic + 1) % cend;
1819 uint32_t s = in - shift;
1820 if (stride * pc + s < cend) {
1821 _in_map[pc].set (*t, in, s + stride * pc);
1829 /* build output map */
1831 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1832 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1833 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1834 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1839 if (old_in == _in_map && old_out == _out_map) {
1843 PluginMapChanged (); /* EMIT SIGNAL */
1844 _mapping_changed = true;
1845 _session.set_dirty();
1851 PluginInsert::configure_io (ChanCount in, ChanCount out)
1853 Match old_match = _match;
1855 ChanCount old_internal;
1859 old_pins = natural_input_streams();
1860 old_in = _configured_in;
1861 old_out = _configured_out;
1862 old_internal = _configured_internal;
1864 _configured_in = in;
1865 _configured_internal = in;
1866 _configured_out = out;
1869 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1870 * (currently _sidechain->configure_io always succeeds
1871 * since Processor::configure_io() succeeds)
1873 if (!_sidechain->configure_io (in, out)) {
1874 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1877 _configured_internal += _sidechain->input()->n_ports();
1879 // include (static_cast<Route*>owner())->name() ??
1880 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1883 /* get plugin configuration */
1884 _match = private_can_support_io_configuration (in, out);
1886 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1888 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1889 DEBUG_STR_APPEND(a, _match);
1890 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1894 /* set the matching method and number of plugins that we will use to meet this configuration */
1895 if (set_count (_match.plugins) == false) {
1896 PluginIoReConfigure (); /* EMIT SIGNAL */
1897 _configured = false;
1901 /* configure plugins */
1902 switch (_match.method) {
1905 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1906 PluginIoReConfigure (); /* EMIT SIGNAL */
1907 _configured = false;
1913 ChanCount din (_configured_internal);
1914 ChanCount dout (din); // hint
1916 if (_custom_sinks.n_total () > 0) {
1917 din = _custom_sinks;
1920 } else if (_preset_out.n_audio () > 0) {
1921 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1922 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1923 dout.set (DataType::AUDIO, 2);
1925 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1927 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1928 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1930 if (useins.n_audio() == 0) {
1933 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1935 if (_plugins.front()->configure_io (useins, dout) == false) {
1936 PluginIoReConfigure (); /* EMIT SIGNAL */
1937 _configured = false;
1941 _custom_sinks = din;
1946 if (_plugins.front()->configure_io (in, out) == false) {
1947 PluginIoReConfigure (); /* EMIT SIGNAL */
1948 _configured = false;
1954 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",
1956 _configured ? "Y" : "N",
1957 _maps_from_state ? "Y" : "N",
1958 old_in == in ? "==" : "!=",
1959 old_out == out ? "==" : "!=",
1960 old_pins == natural_input_streams () ? "==" : "!=",
1961 old_match.method == _match.method ? "==" : "!=",
1962 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1963 _in_map.size() == get_count () ? "==" : "!=",
1964 _out_map.size() == get_count () ? "==" : "!="
1967 bool mapping_changed = false;
1968 if (old_in == in && old_out == out
1970 && old_pins == natural_input_streams ()
1971 && old_match.method == _match.method
1972 && old_match.custom_cfg == _match.custom_cfg
1973 && _in_map.size() == _out_map.size()
1974 && _in_map.size() == get_count ()
1976 /* If the configuration has not changed, keep the mapping */
1977 mapping_changed = sanitize_maps ();
1978 } else if (_match.custom_cfg && _configured) {
1979 /* don't touch the map in manual mode */
1980 mapping_changed = sanitize_maps ();
1983 if (is_channelstrip ()) {
1984 /* fake channel map - for wire display */
1987 _thru_map = ChanMapping ();
1988 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1989 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1990 /* set "thru" map for in-place forward of audio */
1991 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1992 _thru_map.set (DataType::AUDIO, i, i);
1994 /* and midi (after implicit 1st channel bypass) */
1995 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1996 _thru_map.set (DataType::MIDI, i, i);
2000 if (_maps_from_state && old_in == in && old_out == out) {
2001 mapping_changed = true;
2004 /* generate a new mapping */
2005 mapping_changed = reset_map (false);
2007 _maps_from_state = false;
2010 if (mapping_changed) {
2011 PluginMapChanged (); /* EMIT SIGNAL */
2014 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2017 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2018 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2020 DEBUG_STR_APPEND(a, "----><----\n");
2022 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2023 DEBUG_STR_APPEND(a, " * Inputs:\n");
2024 DEBUG_STR_APPEND(a, _in_map[pc]);
2025 DEBUG_STR_APPEND(a, " * Outputs:\n");
2026 DEBUG_STR_APPEND(a, _out_map[pc]);
2028 DEBUG_STR_APPEND(a, " * Thru:\n");
2029 DEBUG_STR_APPEND(a, _thru_map);
2030 DEBUG_STR_APPEND(a, "-------->>--------\n");
2031 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2036 _no_inplace = check_inplace ();
2037 _mapping_changed = false;
2039 /* only the "noinplace_buffers" thread buffers need to be this large,
2040 * this can be optimized. other buffers are fine with
2041 * ChanCount::max (natural_input_streams (), natural_output_streams())
2042 * and route.cc's max (configured_in, configured_out)
2044 * no-inplace copies "thru" outputs (to emulate in-place) for
2045 * all outputs (to prevent overwrite) into a temporary space
2046 * which also holds input buffers (in case the plugin does process
2047 * in-place and overwrites those).
2049 * this buffers need to be at least as
2050 * natural_input_streams () + possible outputs.
2052 * sidechain inputs add a constraint on the input:
2053 * configured input + sidechain (=_configured_internal)
2055 * NB. this also satisfies
2056 * max (natural_input_streams(), natural_output_streams())
2057 * which is needed for silence runs
2059 _required_buffers = ChanCount::max (_configured_internal,
2060 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2062 if (old_in != in || old_out != out || old_internal != _configured_internal
2063 || old_pins != natural_input_streams ()
2064 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2066 PluginIoReConfigure (); /* EMIT SIGNAL */
2069 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2070 _latency_changed = true;
2072 /* we don't know the analysis window size, so we must work with the
2073 * current buffer size here. each request for data fills in these
2074 * buffers and the analyser makes sure it gets enough data for the
2075 * analysis window. We also only analyze audio, so we can ignore
2078 ChanCount cc_analysis_in (DataType::AUDIO, in.n_audio());
2079 ChanCount cc_analysis_out (DataType::AUDIO, out.n_audio());
2081 session().ensure_buffer_set (_signal_analysis_inputs, cc_analysis_in);
2082 _signal_analysis_inputs.set_count (cc_analysis_in);
2084 session().ensure_buffer_set (_signal_analysis_outputs, cc_analysis_out);
2085 _signal_analysis_outputs.set_count (cc_analysis_out);
2087 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2090 return Processor::configure_io (in, out);
2093 /** Decide whether this PluginInsert can support a given IO configuration.
2094 * To do this, we run through a set of possible solutions in rough order of
2097 * @param in Required input channel count.
2098 * @param out Filled in with the output channel count if we return true.
2099 * @return true if the given IO configuration can be supported.
2102 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2105 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2107 return private_can_support_io_configuration (in, out).method != Impossible;
2111 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2113 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2114 // preseed hint (for variable i/o)
2115 out.set (DataType::AUDIO, _preset_out.n_audio ());
2118 Match rv = internal_can_support_io_configuration (in, out);
2120 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2121 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2122 out.set (DataType::AUDIO, _preset_out.n_audio ());
2127 /** A private version of can_support_io_configuration which returns the method
2128 * by which the configuration can be matched, rather than just whether or not
2132 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2134 if (_plugins.empty()) {
2139 if (is_channelstrip ()) {
2141 return Match (ExactMatch, 1);
2145 /* if a user specified a custom cfg, so be it. */
2147 PluginInfoPtr info = _plugins.front()->get_info();
2149 if (info->reconfigurable_io()) {
2150 return Match (Delegate, 1, _strict_io, true);
2152 return Match (ExactMatch, get_count(), _strict_io, true);
2156 /* try automatic configuration */
2157 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2159 PluginInfoPtr info = _plugins.front()->get_info();
2160 ChanCount inputs = info->n_inputs;
2161 ChanCount outputs = info->n_outputs;
2163 /* handle case strict-i/o */
2164 if (_strict_io && m.method != Impossible) {
2167 /* special case MIDI instruments */
2168 if (is_instrument ()) {
2169 // output = midi-bypass + at most master-out channels.
2170 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2171 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2172 out = ChanCount::min (out, max_out);
2173 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2179 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2180 /* replicate processor to match output count (generators and such)
2181 * at least enough to feed every output port. */
2182 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2183 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2184 uint32_t nout = outputs.get (*t);
2185 if (nout == 0 || inx.get(*t) == 0) { continue; }
2186 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2189 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2190 return Match (Replicate, f, _strict_io);
2201 if (m.method != Impossible) {
2205 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2207 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2209 if (info->reconfigurable_io()) {
2212 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2213 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2214 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2216 // houston, we have a problem.
2217 return Match (Impossible, 0);
2220 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2221 return Match (Delegate, 1, _strict_io);
2224 ChanCount midi_bypass;
2225 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2226 midi_bypass.set (DataType::MIDI, 1);
2229 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2231 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2232 uint32_t nin = ns_inputs.get (*t);
2233 uint32_t nout = outputs.get (*t);
2234 if (nin == 0 || inx.get(*t) == 0) { continue; }
2235 // prefer floor() so the count won't overly increase IFF (nin < nout)
2236 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2238 if (f > 0 && outputs * f >= _configured_out) {
2239 out = outputs * f + midi_bypass;
2240 return Match (Replicate, f, _strict_io);
2243 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2245 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2246 uint32_t nin = ns_inputs.get (*t);
2247 if (nin == 0 || inx.get(*t) == 0) { continue; }
2248 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2251 out = outputs * f + midi_bypass;
2252 return Match (Replicate, f, _strict_io);
2255 // add at least as many plugins needed to connect all inputs
2257 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2258 uint32_t nin = inputs.get (*t);
2259 if (nin == 0 || inx.get(*t) == 0) { continue; }
2260 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2262 out = outputs * f + midi_bypass;
2263 return Match (Replicate, f, _strict_io);
2266 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2268 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2270 if (_plugins.empty()) {
2274 PluginInfoPtr info = _plugins.front()->get_info();
2275 ChanCount in; in += inx;
2276 ChanCount midi_bypass;
2278 if (info->reconfigurable_io()) {
2279 /* Plugin has flexible I/O, so delegate to it
2280 * pre-seed outputs, plugin tries closest match
2283 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2284 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2285 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2287 return Match (Impossible, 0);
2290 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2291 return Match (Delegate, 1);
2294 ChanCount inputs = info->n_inputs;
2295 ChanCount outputs = info->n_outputs;
2296 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2298 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2299 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2300 midi_bypass.set (DataType::MIDI, 1);
2302 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2303 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2304 in.set(DataType::MIDI, 0);
2307 // add internally provided sidechain ports
2308 ChanCount insc = in + sidechain_input_ports ();
2310 bool no_inputs = true;
2311 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2312 if (inputs.get (*t) != 0) {
2319 /* no inputs so we can take any input configuration since we throw it away */
2320 out = outputs + midi_bypass;
2321 return Match (NoInputs, 1);
2324 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2325 if (inputs == insc) {
2326 out = outputs + midi_bypass;
2327 return Match (ExactMatch, 1);
2330 /* Plugin inputs matches without side-chain-pins */
2331 if (ns_inputs == in) {
2332 out = outputs + midi_bypass;
2333 return Match (ExactMatch, 1);
2336 /* We may be able to run more than one copy of the plugin within this insert
2337 to cope with the insert having more inputs than the plugin.
2338 We allow replication only for plugins with either zero or 1 inputs and outputs
2339 for every valid data type.
2343 bool can_replicate = true;
2344 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2346 // ignore side-chains
2347 uint32_t nin = ns_inputs.get (*t);
2349 // No inputs of this type
2350 if (nin == 0 && in.get(*t) == 0) {
2354 if (nin != 1 || outputs.get (*t) != 1) {
2355 can_replicate = false;
2359 // Potential factor not set yet
2361 f = in.get(*t) / nin;
2364 // Factor for this type does not match another type, can not replicate
2365 if (f != (in.get(*t) / nin)) {
2366 can_replicate = false;
2371 if (can_replicate && f > 0) {
2372 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2373 out.set (*t, outputs.get(*t) * f);
2376 return Match (Replicate, f);
2379 /* If the processor has exactly one input of a given type, and
2380 the plugin has more, we can feed the single processor input
2381 to some or all of the plugin inputs. This is rather
2382 special-case-y, but the 1-to-many case is by far the
2383 simplest. How do I split thy 2 processor inputs to 3
2384 plugin inputs? Let me count the ways ...
2387 bool can_split = true;
2388 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2390 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2391 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2393 if (!can_split_type && !nothing_to_do_for_type) {
2399 out = outputs + midi_bypass;
2400 return Match (Split, 1);
2403 /* If the plugin has more inputs than we want, we can `hide' some of them
2404 by feeding them silence.
2407 bool could_hide = false;
2408 bool cannot_hide = false;
2409 ChanCount hide_channels;
2411 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2412 if (inputs.get(*t) > in.get(*t)) {
2413 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2414 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2416 } else if (inputs.get(*t) < in.get(*t)) {
2417 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2422 if (could_hide && !cannot_hide) {
2423 out = outputs + midi_bypass;
2424 return Match (Hide, 1, false, false, hide_channels);
2427 return Match (Impossible, 0);
2432 PluginInsert::state ()
2434 XMLNode& node = Processor::state ();
2436 node.set_property("type", _plugins[0]->state_node_name());
2437 node.set_property("unique-id", _plugins[0]->unique_id());
2438 node.set_property("count", (uint32_t)_plugins.size());
2440 /* remember actual i/o configuration (for later placeholder
2441 * in case the plugin goes missing) */
2442 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2443 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2444 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2445 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2447 /* save custom i/o config */
2448 node.set_property("custom", _custom_cfg);
2449 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2451 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2452 node.add_child_nocopy (* _in_map[pc].state (tmp));
2453 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2454 node.add_child_nocopy (* _out_map[pc].state (tmp));
2456 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2459 node.add_child_nocopy (_sidechain->get_state ());
2462 _plugins[0]->set_insert_id(this->id());
2463 node.add_child_nocopy (_plugins[0]->get_state());
2465 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2466 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2468 node.add_child_nocopy (ac->get_state());
2476 PluginInsert::set_control_ids (const XMLNode& node, int version)
2478 const XMLNodeList& nlist = node.children();
2479 XMLNodeConstIterator iter;
2480 set<Evoral::Parameter>::const_iterator p;
2482 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2483 if ((*iter)->name() == Controllable::xml_node_name) {
2485 uint32_t p = (uint32_t)-1;
2488 if ((*iter)->get_property (X_("symbol"), str)) {
2489 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2491 p = lv2plugin->port_index(str.c_str());
2495 if (p == (uint32_t)-1) {
2496 (*iter)->get_property (X_("parameter"), p);
2499 if (p != (uint32_t)-1) {
2501 /* this may create the new controllable */
2503 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2505 #ifndef NO_PLUGIN_STATE
2509 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2511 ac->set_state (**iter, version);
2520 PluginInsert::set_state(const XMLNode& node, int version)
2522 XMLNodeList nlist = node.children();
2523 XMLNodeIterator niter;
2524 XMLPropertyList plist;
2525 ARDOUR::PluginType type;
2528 if (!node.get_property ("type", str)) {
2529 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2533 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2534 type = ARDOUR::LADSPA;
2535 } else if (str == X_("lv2")) {
2537 } else if (str == X_("windows-vst")) {
2538 type = ARDOUR::Windows_VST;
2539 } else if (str == X_("lxvst")) {
2540 type = ARDOUR::LXVST;
2541 } else if (str == X_("mac-vst")) {
2542 type = ARDOUR::MacVST;
2543 } else if (str == X_("audiounit")) {
2544 type = ARDOUR::AudioUnit;
2545 } else if (str == X_("luaproc")) {
2548 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2552 XMLProperty const * prop = node.property ("unique-id");
2555 #ifdef WINDOWS_VST_SUPPORT
2556 /* older sessions contain VST plugins with only an "id" field. */
2557 if (type == ARDOUR::Windows_VST) {
2558 prop = node.property ("id");
2562 #ifdef LXVST_SUPPORT
2563 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2564 if (type == ARDOUR::LXVST) {
2565 prop = node.property ("id");
2572 error << _("Plugin has no unique ID field") << endmsg;
2577 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2578 bool any_vst = false;
2580 /* treat VST plugins equivalent if they have the same uniqueID
2581 * allow to move sessions windows <> linux */
2582 #ifdef LXVST_SUPPORT
2583 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2584 type = ARDOUR::LXVST;
2585 plugin = find_plugin (_session, prop->value(), type);
2586 if (plugin) { any_vst = true; }
2590 #ifdef WINDOWS_VST_SUPPORT
2591 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2592 type = ARDOUR::Windows_VST;
2593 plugin = find_plugin (_session, prop->value(), type);
2594 if (plugin) { any_vst = true; }
2598 #ifdef MACVST_SUPPORT
2599 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2600 type = ARDOUR::MacVST;
2601 plugin = find_plugin (_session, prop->value(), type);
2602 if (plugin) { any_vst = true; }
2606 if (plugin == 0 && type == ARDOUR::Lua) {
2607 /* unique ID (sha1 of script) was not found,
2608 * load the plugin from the serialized version in the
2609 * session-file instead.
2611 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2612 XMLNode *ls = node.child (lp->state_node_name().c_str());
2614 lp->set_script_from_state (*ls);
2620 error << string_compose(
2621 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2622 "Perhaps it was removed or moved since it was last used."),
2628 // The name of the PluginInsert comes from the plugin, nothing else
2629 _name = plugin->get_info()->name;
2633 // Processor::set_state() will set this, but too late
2634 // for it to be available when setting up plugin
2635 // state. We can't call Processor::set_state() until
2636 // the plugins themselves are created and added.
2640 if (_plugins.empty()) {
2641 /* if we are adding the first plugin, we will need to set
2642 up automatable controls.
2644 add_plugin (plugin);
2645 create_automatable_parameters ();
2646 set_control_ids (node, version);
2649 node.get_property ("count", count);
2651 if (_plugins.size() != count) {
2652 for (uint32_t n = 1; n < count; ++n) {
2653 add_plugin (plugin_factory (plugin));
2657 Processor::set_state (node, version);
2659 PBD::ID new_id = this->id();
2660 PBD::ID old_id = this->id();
2662 node.get_property ("id", old_id);
2664 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2666 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2667 and set all plugins to the same state.
2670 if ( ((*niter)->name() == plugin->state_node_name())
2671 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2674 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2675 /* Plugin state can include external files which are named after the ID.
2677 * If regenerate_xml_or_string_ids() is set, the ID will already have
2678 * been changed, so we need to use the old ID from the XML to load the
2679 * state and then update the ID.
2681 * When copying a plugin-state, route_ui takes care of of updating the ID,
2682 * but we need to call set_insert_id() to clear the cached plugin-state
2683 * and force a change.
2685 if (!regenerate_xml_or_string_ids ()) {
2686 (*i)->set_insert_id (new_id);
2688 (*i)->set_insert_id (old_id);
2691 (*i)->set_state (**niter, version);
2693 if (regenerate_xml_or_string_ids ()) {
2694 (*i)->set_insert_id (new_id);
2698 /* when copying plugin state, notify UI */
2699 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2700 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2702 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2710 if (version < 3000) {
2712 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2713 this is all handled by Automatable
2716 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2717 if ((*niter)->name() == "Redirect") {
2718 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2719 Processor::set_state (**niter, version);
2724 set_parameter_state_2X (node, version);
2727 node.get_property (X_("custom"), _custom_cfg);
2729 uint32_t in_maps = 0;
2730 uint32_t out_maps = 0;
2731 XMLNodeList kids = node.children ();
2732 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2733 if ((*i)->name() == X_("ConfiguredInput")) {
2734 _configured_in = ChanCount(**i);
2736 if ((*i)->name() == X_("CustomSinks")) {
2737 _custom_sinks = ChanCount(**i);
2739 if ((*i)->name() == X_("ConfiguredOutput")) {
2740 _custom_out = ChanCount(**i);
2741 _configured_out = ChanCount(**i);
2743 if ((*i)->name() == X_("PresetOutput")) {
2744 _preset_out = ChanCount(**i);
2746 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2747 long pc = atol (&((*i)->name().c_str()[9]));
2748 if (pc >= 0 && pc <= (long) get_count()) {
2749 _in_map[pc] = ChanMapping (**i);
2753 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2754 long pc = atol (&((*i)->name().c_str()[10]));
2755 if (pc >= 0 && pc <= (long) get_count()) {
2756 _out_map[pc] = ChanMapping (**i);
2760 if ((*i)->name () == "ThruMap") {
2761 _thru_map = ChanMapping (**i);
2764 // sidechain is a Processor (IO)
2765 if ((*i)->name () == Processor::state_node_name) {
2767 if (regenerate_xml_or_string_ids ()) {
2768 add_sidechain_from_xml (**i, version);
2773 if (!regenerate_xml_or_string_ids ()) {
2774 _sidechain->set_state (**i, version);
2776 update_sidechain_name ();
2781 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2782 _maps_from_state = true;
2785 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2789 (*i)->deactivate ();
2793 PluginConfigChanged (); /* EMIT SIGNAL */
2798 PluginInsert::update_id (PBD::ID id)
2801 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2802 (*i)->set_insert_id (id);
2807 PluginInsert::set_owner (SessionObject* o)
2809 Processor::set_owner (o);
2810 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2811 (*i)->set_owner (o);
2816 PluginInsert::set_state_dir (const std::string& d)
2818 // state() only saves the state of the first plugin
2819 _plugins[0]->set_state_dir (d);
2823 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2825 XMLNodeList nlist = node.children();
2826 XMLNodeIterator niter;
2828 /* look for port automation node */
2830 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2832 if ((*niter)->name() != port_automation_node_name) {
2837 XMLNodeConstIterator iter;
2841 cnodes = (*niter)->children ("port");
2843 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2847 if (!child->get_property("number", port_id)) {
2848 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2852 if (port_id >= _plugins[0]->parameter_count()) {
2853 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2857 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2858 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2860 if (c && c->alist()) {
2861 if (!child->children().empty()) {
2862 c->alist()->set_state (*child->children().front(), version);
2865 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2875 boost::shared_ptr<ReadOnlyControl>
2876 PluginInsert::control_output (uint32_t num) const
2878 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2879 if (i == _control_outputs.end ()) {
2880 return boost::shared_ptr<ReadOnlyControl> ();
2887 PluginInsert::describe_parameter (Evoral::Parameter param)
2889 if (param.type() == PluginAutomation) {
2890 return _plugins[0]->describe_parameter (param);
2891 } else if (param.type() == PluginPropertyAutomation) {
2892 boost::shared_ptr<AutomationControl> c(automation_control(param));
2893 if (c && !c->desc().label.empty()) {
2894 return c->desc().label;
2897 return Automatable::describe_parameter(param);
2901 PluginInsert::signal_latency() const
2903 if (!_pending_active) {
2906 if (_user_latency) {
2907 return _user_latency;
2910 return _plugins[0]->signal_latency ();
2914 PluginInsert::type ()
2916 return plugin()->get_info()->type;
2919 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2920 const Evoral::Parameter& param,
2921 const ParameterDescriptor& desc,
2922 boost::shared_ptr<AutomationList> list)
2923 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2928 list->set_interpolation(Evoral::ControlList::Discrete);
2933 /** @param val `user' value */
2936 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2938 /* FIXME: probably should be taking out some lock here.. */
2940 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2941 (*i)->set_parameter (_list->parameter().id(), user_val);
2944 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2946 iasp->set_parameter (_list->parameter().id(), user_val);
2949 AutomationControl::actually_set_value (user_val, group_override);
2953 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2955 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2959 PluginInsert::PluginControl::get_state ()
2961 XMLNode& node (AutomationControl::get_state());
2962 node.set_property (X_("parameter"), parameter().id());
2964 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2966 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2973 /** @return `user' val */
2975 PluginInsert::PluginControl::get_value () const
2977 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2983 return plugin->get_parameter (_list->parameter().id());
2986 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2987 const Evoral::Parameter& param,
2988 const ParameterDescriptor& desc,
2989 boost::shared_ptr<AutomationList> list)
2990 : AutomationControl (p->session(), param, desc, list)
2996 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
2998 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2999 This is lossy, but better than nothing until Ardour's automation system
3000 can handle various datatypes all the way down. */
3001 const Variant value(_desc.datatype, user_val);
3002 if (value.type() == Variant::NOTHING) {
3003 error << "set_value(double) called for non-numeric property" << endmsg;
3007 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3008 (*i)->set_property(_list->parameter().id(), value);
3013 AutomationControl::actually_set_value (user_val, gcd);
3017 PluginInsert::PluginPropertyControl::get_state ()
3019 XMLNode& node (AutomationControl::get_state());
3020 node.set_property (X_("property"), parameter().id());
3021 node.remove_property (X_("value"));
3027 PluginInsert::PluginPropertyControl::get_value () const
3029 return _value.to_double();
3032 boost::shared_ptr<Plugin>
3033 PluginInsert::get_impulse_analysis_plugin()
3035 boost::shared_ptr<Plugin> ret;
3036 if (_impulseAnalysisPlugin.expired()) {
3037 // LV2 in particular uses various _session params
3038 // during init() -- most notably block_size..
3040 ret = plugin_factory(_plugins[0]);
3041 ChanCount out (internal_output_streams ());
3042 if (ret->get_info ()->reconfigurable_io ()) {
3043 // populate get_info ()->n_inputs and ->n_outputs
3045 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3046 assert (out == internal_output_streams ());
3048 ret->configure_io (internal_input_streams (), out);
3049 ret->set_owner (_owner);
3050 _impulseAnalysisPlugin = ret;
3052 ret = _impulseAnalysisPlugin.lock();
3059 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3061 // called from outside the audio thread, so this should be safe
3062 // only do audio as analysis is (currently) only for audio plugins
3063 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3064 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3066 _signal_analysis_collected_nframes = 0;
3067 _signal_analysis_collect_nframes_max = nframes;
3070 /** Add a plugin to our list */
3072 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3074 plugin->set_insert_id (this->id());
3075 plugin->set_owner (_owner);
3077 if (_plugins.empty()) {
3078 /* first (and probably only) plugin instance - connect to relevant signals */
3080 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3081 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3082 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3083 _custom_sinks = plugin->get_info()->n_inputs;
3084 // cache sidechain port count
3085 _cached_sidechain_pins.reset ();
3086 const ChanCount& nis (plugin->get_info()->n_inputs);
3087 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3088 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3089 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3090 if (iod.is_sidechain) {
3091 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3096 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3097 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3099 vst->set_insert (this, _plugins.size ());
3103 _plugins.push_back (plugin);
3107 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3109 if (version < 3000) {
3113 XMLNodeList nlist = node.children();
3115 if (nlist.size() == 0) {
3122 XMLNodeConstIterator it = nlist.front()->children().begin();
3123 for ( ; it != nlist.front()->children().end(); ++ it) {
3124 if ((*it)->name() == "Port") {
3125 DataType type(DataType::NIL);
3126 (*it)->get_property ("type", type);
3127 if (type == DataType::AUDIO) {
3129 } else if (type == DataType::MIDI) {
3135 ChanCount in_cc = ChanCount();
3136 in_cc.set (DataType::AUDIO, audio);
3137 in_cc.set (DataType::MIDI, midi);
3139 add_sidechain (audio, midi);
3143 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3146 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3147 if (! (*i)->load_preset (pr)) {
3155 PluginInsert::realtime_handle_transport_stopped ()
3157 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3158 (*i)->realtime_handle_transport_stopped ();
3163 PluginInsert::realtime_locate ()
3165 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3166 (*i)->realtime_locate ();
3171 PluginInsert::monitoring_changed ()
3173 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3174 (*i)->monitoring_changed ();
3179 PluginInsert::latency_changed ()
3181 // this is called in RT context, LatencyChanged is emitted after run()
3182 _latency_changed = true;
3183 // XXX This also needs a proper API not an owner() hack.
3185 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3189 PluginInsert::start_touch (uint32_t param_id)
3191 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3193 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3194 ac->start_touch (session().audible_sample());
3199 PluginInsert::end_touch (uint32_t param_id)
3201 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3203 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3204 ac->stop_touch (session().audible_sample());
3209 PluginInsert::provides_stats () const
3211 #if defined MIXBUS && defined NDEBUG
3212 if (is_channelstrip () || !display_to_user ()) {
3220 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3222 /* TODO: consider taking a try/lock: Don't run concurrently with
3223 * TimingStats::update, TimingStats::reset.
3225 return _timing_stats.get_stats (min, max, avg, dev);
3229 PluginInsert::clear_stats ()
3231 g_atomic_int_set (&_stat_reset, 1);
3234 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3237 case PluginInsert::Impossible: o << "Impossible"; break;
3238 case PluginInsert::Delegate: o << "Delegate"; break;
3239 case PluginInsert::NoInputs: o << "NoInputs"; break;
3240 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3241 case PluginInsert::Replicate: o << "Replicate"; break;
3242 case PluginInsert::Split: o << "Split"; break;
3243 case PluginInsert::Hide: o << "Hide"; break;
3245 o << " cnt: " << m.plugins
3246 << (m.strict_io ? " strict-io" : "")
3247 << (m.custom_cfg ? " custom-cfg" : "");
3248 if (m.method == PluginInsert::Hide) {
3249 o << " hide: " << m.hide;