2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "libardour-config.h"
26 #include "pbd/failed_constructor.h"
27 #include "pbd/xml++.h"
28 #include "pbd/types_convert.h"
30 #include "ardour/audio_buffer.h"
31 #include "ardour/automation_list.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/debug.h"
34 #include "ardour/event_type_map.h"
35 #include "ardour/ladspa_plugin.h"
36 #include "ardour/luaproc.h"
37 #include "ardour/plugin.h"
38 #include "ardour/plugin_insert.h"
39 #include "ardour/port.h"
42 #include "ardour/lv2_plugin.h"
45 #ifdef WINDOWS_VST_SUPPORT
46 #include "ardour/windows_vst_plugin.h"
50 #include "ardour/lxvst_plugin.h"
54 #include "ardour/mac_vst_plugin.h"
57 #ifdef AUDIOUNIT_SUPPORT
58 #include "ardour/audio_unit.h"
61 #include "ardour/session.h"
62 #include "ardour/types.h"
67 using namespace ARDOUR;
70 const string PluginInsert::port_automation_node_name = "PortAutomation";
72 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
73 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
74 , _sc_playback_latency (0)
75 , _sc_capture_latency (0)
76 , _plugin_signal_latency (0)
77 , _signal_analysis_collected_nframes(0)
78 , _signal_analysis_collect_nframes_max(0)
83 , _maps_from_state (false)
84 , _latency_changed (false)
85 , _bypass_port (UINT32_MAX)
88 /* the first is the master */
92 create_automatable_parameters ();
93 const ChanCount& sc (sidechain_input_pins ());
94 if (sc.n_audio () > 0 || sc.n_midi () > 0) {
95 add_sidechain (sc.n_audio (), sc.n_midi ());
100 PluginInsert::~PluginInsert ()
102 for (CtrlOutMap::const_iterator i = _control_outputs.begin(); i != _control_outputs.end(); ++i) {
103 boost::dynamic_pointer_cast<ReadOnlyControl>(i->second)->drop_references ();
108 PluginInsert::set_strict_io (bool b)
110 bool changed = _strict_io != b;
113 PluginConfigChanged (); /* EMIT SIGNAL */
118 PluginInsert::set_count (uint32_t num)
120 bool require_state = !_plugins.empty();
122 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
123 // we don't allow to replicate AUs
127 /* this is a bad idea.... we shouldn't do this while active.
128 * only a route holding their redirect_lock should be calling this
133 } else if (num > _plugins.size()) {
134 uint32_t diff = num - _plugins.size();
136 for (uint32_t n = 0; n < diff; ++n) {
137 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
141 XMLNode& state = _plugins[0]->get_state ();
142 p->set_state (state, Stateful::loading_state_version);
149 PluginConfigChanged (); /* EMIT SIGNAL */
151 } else if (num < _plugins.size()) {
152 uint32_t diff = _plugins.size() - num;
153 for (uint32_t n= 0; n < diff; ++n) {
156 PluginConfigChanged (); /* EMIT SIGNAL */
164 PluginInsert::set_sinks (const ChanCount& c)
167 /* no signal, change will only be visible after re-config */
171 PluginInsert::set_outputs (const ChanCount& c)
173 bool changed = (_custom_out != c) && _custom_cfg;
176 PluginConfigChanged (); /* EMIT SIGNAL */
181 PluginInsert::set_custom_cfg (bool b)
183 bool changed = _custom_cfg != b;
186 PluginConfigChanged (); /* EMIT SIGNAL */
191 PluginInsert::set_preset_out (const ChanCount& c)
193 bool changed = _preset_out != c;
195 if (changed && !_custom_cfg) {
196 PluginConfigChanged (); /* EMIT SIGNAL */
202 PluginInsert::add_sidechain (uint32_t n_audio, uint32_t n_midi)
204 // caller must hold process lock
208 std::ostringstream n;
209 if (n_audio == 0 && n_midi == 0) {
210 n << "TO BE RESET FROM XML";
211 } else if (owner()) {
212 n << "SC " << owner()->name() << "/" << name() << " " << Session::next_name_id ();
216 SideChain *sc = new SideChain (_session, n.str ());
217 _sidechain = boost::shared_ptr<SideChain> (sc);
218 _sidechain->activate ();
219 for (uint32_t n = 0; n < n_audio; ++n) {
220 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
222 for (uint32_t n = 0; n < n_midi; ++n) {
223 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
225 PluginConfigChanged (); /* EMIT SIGNAL */
230 PluginInsert::del_sidechain ()
236 _sc_playback_latency = 0;
237 _sc_capture_latency = 0;
238 PluginConfigChanged (); /* EMIT SIGNAL */
243 PluginInsert::update_sidechain_name ()
249 std::ostringstream n;
253 n << owner()->name() << "/";
256 n << name() << " " << Session::next_name_id ();
258 _sidechain->set_name (n.str());
262 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
264 if (which.type() != PluginAutomation)
267 boost::shared_ptr<AutomationControl> c
268 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
271 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()));
276 PluginInsert::output_streams() const
278 assert (_configured);
279 return _configured_out;
283 PluginInsert::input_streams() const
285 assert (_configured);
286 return _configured_in;
290 PluginInsert::internal_streams() const
292 assert (_configured);
293 return _configured_internal;
297 PluginInsert::internal_output_streams() const
299 assert (!_plugins.empty());
301 PluginInfoPtr info = _plugins.front()->get_info();
303 if (info->reconfigurable_io()) {
304 ChanCount out = _plugins.front()->output_streams ();
305 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
308 ChanCount out = info->n_outputs;
309 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
310 out.set_audio (out.n_audio() * _plugins.size());
311 out.set_midi (out.n_midi() * _plugins.size());
317 PluginInsert::internal_input_streams() const
319 assert (!_plugins.empty());
323 PluginInfoPtr info = _plugins.front()->get_info();
325 if (info->reconfigurable_io()) {
326 in = _plugins.front()->input_streams();
331 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
333 if (_match.method == Split) {
335 /* we are splitting 1 processor input to multiple plugin inputs,
336 so we have a maximum of 1 stream of each type.
338 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
339 if (in.get (*t) > 1) {
345 } else if (_match.method == Hide) {
347 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
348 in.set (*t, in.get (*t) - _match.hide.get (*t));
354 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
355 in.set (*t, in.get (*t) * _plugins.size ());
363 PluginInsert::natural_output_streams() const
366 if (is_channelstrip ()) {
367 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
370 return _plugins[0]->get_info()->n_outputs;
374 PluginInsert::natural_input_streams() const
377 if (is_channelstrip ()) {
378 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
381 return _plugins[0]->get_info()->n_inputs;
385 PluginInsert::sidechain_input_pins() const
387 return _cached_sidechain_pins;
391 PluginInsert::has_no_inputs() const
393 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
397 PluginInsert::has_no_audio_inputs() const
399 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
403 PluginInsert::plugin_latency () const {
404 return _plugins.front()->signal_latency ();
408 PluginInsert::is_instrument() const
410 PluginInfoPtr pip = _plugins[0]->get_info();
411 return (pip->is_instrument ());
415 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
417 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
418 // collect possible configurations, prefer given in/out
419 _plugins[0]->can_support_io_configuration (in, out);
422 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
424 if (ppc.size () == 0) {
427 if (!strict_io () && ppc.size () == 1) {
431 if (strict_io () && ppc.size () == 1) {
432 // "stereo" is currently preferred default for instruments
433 if (ppc.find (2) != ppc.end ()) {
438 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
439 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
440 // pretending to be an "Instrument"
444 if (!is_instrument ()) {
451 PluginInsert::create_automatable_parameters ()
453 assert (!_plugins.empty());
455 boost::shared_ptr<Plugin> plugin = _plugins.front();
456 set<Evoral::Parameter> a = _plugins.front()->automatable ();
458 const uint32_t limit_automatables = Config->get_limit_n_automatables ();
460 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
461 if (!plugin->parameter_is_control (i)) {
465 ParameterDescriptor desc;
466 plugin->get_parameter_descriptor(i, desc);
468 if (!plugin->parameter_is_input (i)) {
469 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
472 Evoral::Parameter param (PluginAutomation, 0, i);
474 const bool automatable = a.find(param) != a.end();
476 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
477 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
478 if (!automatable || (limit_automatables > 0 && i > limit_automatables)) {
479 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
482 plugin->set_automation_control (i, c);
486 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
487 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
488 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
489 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
490 if (desc.datatype != Variant::NOTHING) {
491 boost::shared_ptr<AutomationList> list;
492 if (Variant::type_is_numeric(desc.datatype)) {
493 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
495 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
496 if (!Variant::type_is_numeric(desc.datatype)) {
497 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
503 _bypass_port = plugin->designated_bypass_port ();
505 /* special case VST effSetBypass */
506 if (_bypass_port == UINT32_MAX -1) {
507 // emulate VST Bypass
508 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
509 ParameterDescriptor desc;
510 desc.label = _("Plugin Enable");
515 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
516 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
520 if (_bypass_port != UINT32_MAX) {
521 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
522 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
523 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
524 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
527 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
530 /** Called when something outside of this host has modified a plugin
531 * parameter. Responsible for propagating the change to two places:
533 * 1) anything listening to the Control itself
534 * 2) any replicated plugins that make up this PluginInsert.
536 * The PluginInsert is connected to the ParameterChangedExternally signal for
537 * the first (primary) plugin, and here broadcasts that change to any others.
539 * XXX We should probably drop this whole replication idea (Paul, October 2015)
540 * since it isn't used by sensible plugin APIs (AU, LV2).
543 PluginInsert::parameter_changed_externally (uint32_t which, float val)
545 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
547 /* First propagation: alter the underlying value of the control,
548 * without telling the plugin(s) that own/use it to set it.
555 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
558 pc->catch_up_with_external_value (val);
561 /* Second propagation: tell all plugins except the first to
562 update the value of this parameter. For sane plugin APIs,
563 there are no other plugins, so this is a no-op in those
567 Plugins::iterator i = _plugins.begin();
569 /* don't set the first plugin, just all the slaves */
571 if (i != _plugins.end()) {
573 for (; i != _plugins.end(); ++i) {
574 (*i)->set_parameter (which, val);
580 PluginInsert::set_block_size (pframes_t nframes)
583 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
584 if ((*i)->set_block_size (nframes) != 0) {
592 PluginInsert::automation_run (samplepos_t start, pframes_t nframes)
594 // XXX does not work when rolling backwards
595 if (_loop_location && nframes > 0) {
596 const samplepos_t loop_start = _loop_location->start ();
597 const samplepos_t loop_end = _loop_location->end ();
598 const samplecnt_t looplen = loop_end - loop_start;
600 samplecnt_t remain = nframes;
601 samplepos_t start_pos = start;
604 if (start_pos >= loop_end) {
605 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
606 start_pos = loop_start + start_off;
608 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
610 Automatable::automation_run (start_pos, move);
616 Automatable::automation_run (start, nframes);
620 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
622 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
624 if (_loop_location && now < end) {
626 end = ceil (next_event.when);
628 const samplepos_t loop_end = _loop_location->end ();
629 assert (now < loop_end); // due to map_loop_range ()
630 if (end > loop_end) {
631 next_event.when = loop_end;
639 PluginInsert::activate ()
641 _timing_stats.reset ();
642 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
646 Processor::activate ();
647 /* when setting state e.g ProcessorBox::paste_processor_state ()
648 * the plugin is not yet owned by a route.
649 * but no matter. Route::add_processors() will call activate () again
654 if (_plugin_signal_latency != signal_latency ()) {
655 _plugin_signal_latency = signal_latency ();
661 PluginInsert::deactivate ()
664 if (is_nonbypassable ()) {
668 _timing_stats.reset ();
669 Processor::deactivate ();
671 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
674 if (_plugin_signal_latency != signal_latency ()) {
675 _plugin_signal_latency = signal_latency ();
681 PluginInsert::flush ()
683 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
689 PluginInsert::enable (bool yn)
691 if (_bypass_port == UINT32_MAX) {
698 if (!_pending_active) {
701 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
702 const double val = yn ? 1.0 : 0.0;
703 ac->set_value (val, Controllable::NoGroup);
705 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
706 /* special case VST.. bypass may fail */
707 if (_bypass_port == UINT32_MAX - 1) {
708 /* check if bypass worked */
709 if (ac->get_value () != val) {
710 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
711 // set plugin to enabled (not-byassed)
712 ac->set_value (1.0, Controllable::NoGroup);
713 // ..and use host-provided hard-bypass
728 PluginInsert::enabled () const
730 if (_bypass_port == UINT32_MAX) {
731 return Processor::enabled ();
733 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
734 return (ac->get_value () > 0 && _pending_active);
739 PluginInsert::bypassable () const
741 if (_bypass_port == UINT32_MAX) {
744 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
746 return !ac->automation_playback ();
751 PluginInsert::enable_changed ()
757 PluginInsert::bypassable_changed ()
759 BypassableChanged ();
763 PluginInsert::write_immediate_event (size_t size, const uint8_t* buf)
766 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
767 if (!(*i)->write_immediate_event (size, buf)) {
775 PluginInsert::preset_load_set_value (uint32_t p, float v)
777 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
782 if (ac->automation_state() & Play) {
787 ac->set_value (v, Controllable::NoGroup);
792 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
794 // TODO optimize: store "unconnected" in a fixed set.
795 // it only changes on reconfiguration.
796 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
797 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
799 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
800 mapped = true; // in-place Midi bypass
802 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
803 PinMappings::const_iterator i = out_map.find (pc);
804 if (i == out_map.end ()) {
807 const ChanMapping& outmap (i->second);
808 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
810 uint32_t idx = outmap.get (*t, o, &valid);
811 if (valid && idx == out) {
818 bufs.get (*t, out).silence (nframes, offset);
825 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
827 // TODO: atomically copy maps & _no_inplace
828 PinMappings in_map (_in_map);
829 PinMappings out_map (_out_map);
830 ChanMapping thru_map (_thru_map);
831 if (_mapping_changed) { // ToDo use a counters, increment until match.
832 _no_inplace = check_inplace ();
833 _mapping_changed = false;
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.at(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.at(0).get (*t, i, &valid);
870 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
874 /* the copy operation produces a linear monotonic input map */
875 in_map[0] = ChanMapping (natural_input_streams ());
878 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
879 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
885 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
887 /* boost::dynamic_pointer_cast<> has significant overhead, since we know that
888 * all controls are AutomationControl and their lists - if any - are AutomationList,
889 * we can use static_cast<>. This yields a speedup of 2.8/4.6 over to the
890 * previous code (measuerd with VeeSeeVSTRack 10k parameters, optimized build) */
891 AutomationControl& c = static_cast<AutomationControl&> (*(li->second));
892 boost::shared_ptr<const Evoral::ControlList> clist (c.list());
893 if (clist && (static_cast<AutomationList const&> (*clist)).automation_playback ()) {
895 const float val = c.list()->rt_safe_eval (start, valid);
897 c.set_value_unchecked(val);
903 /* Calculate if, and how many samples we need to collect for analysis */
904 samplecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
905 _signal_analysis_collected_nframes);
906 if (nframes < collect_signal_nframes) { // we might not get all samples now
907 collect_signal_nframes = nframes;
910 if (collect_signal_nframes > 0) {
912 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
913 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
914 //std::cerr << "filling buffer with " << collect_signal_nframes << " samples at " << _signal_analysis_collected_nframes << std::endl;
916 _signal_analysis_inputs.set_count(input_streams());
918 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
919 _signal_analysis_inputs.get_audio(i).read_from (
921 collect_signal_nframes,
922 _signal_analysis_collected_nframes); // offset is for target buffer
927 if (is_channelstrip ()) {
928 if (_configured_in.n_audio() > 0) {
929 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
930 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
932 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
934 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
935 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
941 // TODO optimize -- build maps once.
943 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
944 ARDOUR::ChanMapping used_outputs;
946 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
948 /* build used-output map */
949 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
950 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
951 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
953 uint32_t out_idx = out_map.at(pc).get (*t, out, &valid);
955 used_outputs.set (*t, out_idx, 1); // mark as used
960 /* copy thru data to outputs before processing in-place */
961 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
962 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
964 uint32_t in_idx = thru_map.get (*t, out, &valid);
965 uint32_t m = out + natural_input_streams ().get (*t);
967 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
968 used_outputs.set (*t, out, 1); // mark as used
970 used_outputs.get (*t, out, &valid);
972 /* the plugin is expected to write here, but may not :(
973 * (e.g. drumgizmo w/o kit loaded)
975 inplace_bufs.get (*t, m).silence (nframes);
982 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
984 ARDOUR::ChanMapping i_in_map (natural_input_streams());
985 ARDOUR::ChanMapping i_out_map (out_map.at(pc));
986 ARDOUR::ChanCount mapped;
988 /* map inputs sequentially */
989 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
990 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
992 uint32_t in_idx = in_map.at(pc).get (*t, in, &valid);
993 uint32_t m = mapped.get (*t);
995 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
997 inplace_bufs.get (*t, m).silence (nframes, offset);
999 mapped.set (*t, m + 1);
1003 /* outputs are mapped to inplace_bufs after the inputs */
1004 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1005 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
1008 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1013 /* all instances have completed, now copy data that was written
1014 * and zero unconnected buffers */
1015 ARDOUR::ChanMapping nonzero_out (used_outputs);
1016 if (has_midi_bypass ()) {
1017 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1019 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1020 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1022 used_outputs.get (*t, out, &valid);
1024 nonzero_out.get (*t, out, &valid);
1026 bufs.get (*t, out).silence (nframes, offset);
1029 uint32_t m = out + natural_input_streams ().get (*t);
1030 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
1035 /* in-place processing */
1037 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1038 if ((*i)->connect_and_run(bufs, start, end, speed, in_map.at(pc), out_map.at(pc), nframes, offset)) {
1042 // now silence unconnected outputs
1043 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1046 if (collect_signal_nframes > 0) {
1048 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
1049 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
1051 _signal_analysis_outputs.set_count(output_streams());
1053 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1054 _signal_analysis_outputs.get_audio(i).read_from(
1056 collect_signal_nframes,
1057 _signal_analysis_collected_nframes); // offset is for target buffer
1060 _signal_analysis_collected_nframes += collect_signal_nframes;
1061 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
1063 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
1064 _signal_analysis_collect_nframes_max = 0;
1065 _signal_analysis_collected_nframes = 0;
1067 AnalysisDataGathered(&_signal_analysis_inputs,
1068 &_signal_analysis_outputs);
1072 if (_plugin_signal_latency != signal_latency ()) {
1073 _plugin_signal_latency = signal_latency ();
1079 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1081 /* bypass the plugin(s) not the whole processor.
1082 * -> use mappings just like connect_and_run
1085 // TODO: atomically copy maps & _no_inplace
1086 const ChanMapping in_map (no_sc_input_map ());
1087 const ChanMapping out_map (output_map ());
1088 if (_mapping_changed) {
1089 _no_inplace = check_inplace ();
1090 _mapping_changed = false;
1093 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1094 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1097 ChanMapping thru_map (_thru_map);
1099 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1101 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1102 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1103 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
1106 ARDOUR::ChanMapping used_outputs;
1108 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1109 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1111 uint32_t in_idx = thru_map.get (*t, out, &valid);
1113 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1114 used_outputs.set (*t, out, 1); // mark as used
1118 // plugin no-op: assume every plugin has an internal identity map
1119 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1120 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1122 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1126 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1130 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1131 used_outputs.set (*t, out, 1); // mark as used
1134 // now silence all unused outputs
1135 if (has_midi_bypass ()) {
1136 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1138 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1139 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1141 used_outputs.get (*t, out, &valid);
1143 bufs.get (*t, out).silence (nframes, 0);
1148 if (_match.method == Split) {
1149 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1150 if (_configured_internal.get (*t) == 0) {
1153 // copy/feeds _all_ *connected* inputs, copy the first buffer
1155 uint32_t first_idx = in_map.get (*t, 0, &valid);
1156 assert (valid && first_idx == 0); // check_inplace ensures this
1157 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1158 uint32_t idx = in_map.get (*t, i, &valid);
1161 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
1167 // apply output map and/or monotonic but not identity i/o mappings
1168 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1169 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1171 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1173 bufs.get (*t, out).silence (nframes, 0);
1176 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1178 bufs.get (*t, out).silence (nframes, 0);
1181 if (in_idx != src_idx) {
1182 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
1190 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1192 automation_run (start_sample, nframes); // evaluate automation only
1195 // XXX delaybuffers need to be offset by nframes
1199 _delaybuffers.flush ();
1201 ChanMapping in_map (natural_input_streams ());
1202 ChanMapping out_map (natural_output_streams ());
1203 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1205 if (is_channelstrip ()) {
1206 if (_configured_in.n_audio() > 0) {
1207 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1211 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1212 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1217 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1220 // collect sidechain input for complete cycle (!)
1221 // TODO we need delaylines here for latency compensation
1222 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1225 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1226 _timing_stats.reset ();
1229 if (_pending_active) {
1230 _timing_stats.start ();
1231 /* run as normal if we are active or moving from inactive to active */
1233 if (_session.transport_rolling() || _session.bounce_processing()) {
1234 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1236 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1237 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1239 _timing_stats.update ();
1242 _timing_stats.reset ();
1243 // XXX should call ::silence() to run plugin(s) for consistent load.
1244 // We'll need to change this anyway when bypass can be automated
1245 bypass (bufs, nframes);
1246 automation_run (start_sample, nframes); // evaluate automation only
1247 _delaybuffers.flush ();
1250 _active = _pending_active;
1252 /* we have no idea whether the plugin generated silence or not, so mark
1253 * all buffers appropriately.
1258 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1260 Evoral::ControlEvent next_event (0, 0.0f);
1261 samplecnt_t offset = 0;
1263 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1266 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1270 /* map start back into loop-range, adjust end */
1271 map_loop_range (start, end);
1273 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1275 /* no events have a time within the relevant range */
1277 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1283 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1285 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1291 map_loop_range (start, end);
1293 if (!find_next_event (start, end, next_event)) {
1298 /* cleanup anything that is left to do */
1301 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1306 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1308 if (param.type() != PluginAutomation)
1311 if (_plugins.empty()) {
1312 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1314 abort(); /*NOTREACHED*/
1317 return _plugins[0]->default_value (param.id());
1322 PluginInsert::can_reset_all_parameters ()
1325 uint32_t params = 0;
1326 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1328 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1330 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1334 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1340 if (ac->automation_state() & Play) {
1345 return all && (params > 0);
1349 PluginInsert::reset_parameters_to_default ()
1353 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1355 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1357 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1361 const float dflt = _plugins[0]->default_value (cid);
1362 const float curr = _plugins[0]->get_parameter (cid);
1368 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1373 if (ac->automation_state() & Play) {
1378 ac->set_value (dflt, Controllable::NoGroup);
1383 boost::shared_ptr<Plugin>
1384 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1386 boost::shared_ptr<LadspaPlugin> lp;
1387 boost::shared_ptr<LuaProc> lua;
1389 boost::shared_ptr<LV2Plugin> lv2p;
1391 #ifdef WINDOWS_VST_SUPPORT
1392 boost::shared_ptr<WindowsVSTPlugin> vp;
1394 #ifdef LXVST_SUPPORT
1395 boost::shared_ptr<LXVSTPlugin> lxvp;
1397 #ifdef MACVST_SUPPORT
1398 boost::shared_ptr<MacVSTPlugin> mvp;
1400 #ifdef AUDIOUNIT_SUPPORT
1401 boost::shared_ptr<AUPlugin> ap;
1404 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1405 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1406 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1407 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1409 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1410 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1412 #ifdef WINDOWS_VST_SUPPORT
1413 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1414 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1416 #ifdef LXVST_SUPPORT
1417 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1418 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1420 #ifdef MACVST_SUPPORT
1421 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1422 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1424 #ifdef AUDIOUNIT_SUPPORT
1425 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1426 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1430 fatal << string_compose (_("programming error: %1"),
1431 X_("unknown plugin type in PluginInsert::plugin_factory"))
1433 abort(); /*NOTREACHED*/
1434 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1438 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1439 if (num < _in_map.size()) {
1440 bool changed = _in_map[num] != m;
1442 changed |= sanitize_maps ();
1444 PluginMapChanged (); /* EMIT SIGNAL */
1445 _mapping_changed = true;
1446 _session.set_dirty();
1452 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1453 if (num < _out_map.size()) {
1454 bool changed = _out_map[num] != m;
1456 changed |= sanitize_maps ();
1458 PluginMapChanged (); /* EMIT SIGNAL */
1459 _mapping_changed = true;
1460 _session.set_dirty();
1466 PluginInsert::set_thru_map (ChanMapping m) {
1467 bool changed = _thru_map != m;
1469 changed |= sanitize_maps ();
1471 PluginMapChanged (); /* EMIT SIGNAL */
1472 _mapping_changed = true;
1473 _session.set_dirty();
1478 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1479 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1481 if (_configured) { return false; }
1482 _configured_in = in;
1483 _configured_out = out;
1487 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1492 PluginInsert::input_map () const
1496 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1497 ChanMapping m (i->second);
1498 const ChanMapping::Mappings& mp ((*i).second.mappings());
1499 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1500 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1501 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1510 PluginInsert::no_sc_input_map () const
1514 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1515 ChanMapping m (i->second);
1516 const ChanMapping::Mappings& mp ((*i).second.mappings());
1517 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1518 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1519 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1520 if (i->first < ins) {
1521 rv.set (tm->first, i->first + pc * ins, i->second);
1530 PluginInsert::output_map () const
1534 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1535 ChanMapping m (i->second);
1536 const ChanMapping::Mappings& mp ((*i).second.mappings());
1537 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1538 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1539 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1543 if (has_midi_bypass ()) {
1544 rv.set (DataType::MIDI, 0, 0);
1551 PluginInsert::has_midi_bypass () const
1553 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1554 && natural_output_streams ().n_midi () == 0) {
1561 PluginInsert::has_midi_thru () const
1563 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1564 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1572 PluginInsert::is_channelstrip () const {
1573 return _plugins.front()->is_channelstrip();
1576 PluginInsert::is_nonbypassable () const {
1577 return _plugins.front()->is_nonbypassable ();
1582 PluginInsert::check_inplace ()
1584 bool inplace_ok = !_plugins.front()->inplace_broken ();
1586 if (_thru_map.n_total () > 0) {
1587 // TODO once midi-bypass is part of the mapping, ignore it
1591 if (_match.method == Split && inplace_ok) {
1592 assert (get_count() == 1);
1593 assert (_in_map.size () == 1);
1594 if (!_out_map[0].is_monotonic ()) {
1597 if (_configured_internal != _configured_in) {
1598 /* no sidechain -- TODO we could allow this with
1599 * some more logic in PluginInsert::connect_and_run().
1601 * PluginInsert::reset_map() already maps it.
1606 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1607 if (_configured_internal.get (*t) == 0) {
1611 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1612 if (!valid || first_idx != 0) {
1613 // so far only allow to copy the *first* stream's buffer to others
1616 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1617 uint32_t idx = _in_map[0].get (*t, i, &valid);
1618 if (valid && idx != first_idx) {
1627 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1632 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1633 if (!_in_map[pc].is_monotonic ()) {
1636 if (!_out_map[pc].is_monotonic ()) {
1642 /* check if every output is fed by the corresponding input
1644 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1645 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1647 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1649 ChanMapping in_map (input_map ());
1650 const ChanMapping::Mappings out_m (output_map ().mappings ());
1651 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1652 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1653 /* src-pin: c->first, out-port: c->second */
1655 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1656 if (valid && in_port != c->second) {
1664 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1665 return !inplace_ok; // no-inplace
1669 PluginInsert::sanitize_maps ()
1671 bool changed = false;
1672 /* strip dead wood */
1673 PinMappings new_ins;
1674 PinMappings new_outs;
1675 ChanMapping new_thru;
1677 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1679 ChanMapping new_out;
1680 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1681 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1683 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1684 if (valid && idx < _configured_internal.get (*t)) {
1685 new_in.set (*t, i, idx);
1688 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1690 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1691 if (valid && idx < _configured_out.get (*t)) {
1692 new_out.set (*t, o, idx);
1696 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1699 new_ins[pc] = new_in;
1700 new_outs[pc] = new_out;
1703 /* prevent dup output assignments */
1704 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1705 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1706 bool mapped = false;
1707 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1709 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1710 if (valid && mapped) {
1711 new_outs[pc].unset (*t, idx);
1719 /* remove excess thru */
1720 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1721 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1723 uint32_t idx = _thru_map.get (*t, o, &valid);
1724 if (valid && idx < _configured_internal.get (*t)) {
1725 new_thru.set (*t, o, idx);
1730 /* prevent out + thru, existing plugin outputs override thru */
1731 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1732 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1733 bool mapped = false;
1735 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1736 new_outs[pc].get_src (*t, o, &mapped);
1737 if (mapped) { break; }
1739 if (!mapped) { continue; }
1740 uint32_t idx = new_thru.get (*t, o, &valid);
1742 new_thru.unset (*t, idx);
1747 if (has_midi_bypass ()) {
1748 // TODO: include midi-bypass in the thru set,
1749 // remove dedicated handling.
1750 new_thru.unset (DataType::MIDI, 0);
1753 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1757 _out_map = new_outs;
1758 _thru_map = new_thru;
1764 PluginInsert::reset_map (bool emit)
1766 const PinMappings old_in (_in_map);
1767 const PinMappings old_out (_out_map);
1771 _thru_map = ChanMapping ();
1773 /* build input map */
1774 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1775 uint32_t sc = 0; // side-chain round-robin (all instances)
1777 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1778 const uint32_t nis = natural_input_streams ().get(*t);
1779 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1781 /* SC inputs are last in the plugin-insert.. */
1782 const uint32_t sc_start = _configured_in.get (*t);
1783 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1784 /* ...but may not be at the end of the plugin ports.
1785 * in case the side-chain is not the last port, shift connections back.
1786 * and connect to side-chain
1789 uint32_t ic = 0; // split inputs
1790 const uint32_t cend = _configured_in.get (*t);
1792 for (uint32_t in = 0; in < nis; ++in) {
1793 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1794 if (iod.is_sidechain) {
1795 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1796 if (sc_len > 0) {// side-chain may be hidden
1797 _in_map[pc].set (*t, in, sc_start + sc);
1798 sc = (sc + 1) % sc_len;
1802 if (_match.method == Split) {
1803 if (cend == 0) { continue; }
1804 if (_strict_io && ic + stride * pc >= cend) {
1807 /* connect *no* sidechain sinks in round-robin fashion */
1808 _in_map[pc].set (*t, in, ic + stride * pc);
1809 if (_strict_io && (ic + 1) == cend) {
1812 ic = (ic + 1) % cend;
1814 uint32_t s = in - shift;
1815 if (stride * pc + s < cend) {
1816 _in_map[pc].set (*t, in, s + stride * pc);
1824 /* build output map */
1826 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1827 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1828 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1829 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1834 if (old_in == _in_map && old_out == _out_map) {
1838 PluginMapChanged (); /* EMIT SIGNAL */
1839 _mapping_changed = true;
1840 _session.set_dirty();
1846 PluginInsert::configure_io (ChanCount in, ChanCount out)
1848 Match old_match = _match;
1850 ChanCount old_internal;
1854 old_pins = natural_input_streams();
1855 old_in = _configured_in;
1856 old_out = _configured_out;
1857 old_internal = _configured_internal;
1859 _configured_in = in;
1860 _configured_internal = in;
1861 _configured_out = out;
1864 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1865 * (currently _sidechain->configure_io always succeeds
1866 * since Processor::configure_io() succeeds)
1868 if (!_sidechain->configure_io (in, out)) {
1869 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1872 _configured_internal += _sidechain->input()->n_ports();
1874 // include (static_cast<Route*>owner())->name() ??
1875 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1878 /* get plugin configuration */
1879 _match = private_can_support_io_configuration (in, out);
1881 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1883 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1884 DEBUG_STR_APPEND(a, _match);
1885 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1889 /* set the matching method and number of plugins that we will use to meet this configuration */
1890 if (set_count (_match.plugins) == false) {
1891 PluginIoReConfigure (); /* EMIT SIGNAL */
1892 _configured = false;
1896 /* configure plugins */
1897 switch (_match.method) {
1900 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1901 PluginIoReConfigure (); /* EMIT SIGNAL */
1902 _configured = false;
1908 ChanCount din (_configured_internal);
1909 ChanCount dout (din); // hint
1911 if (_custom_sinks.n_total () > 0) {
1912 din = _custom_sinks;
1915 } else if (_preset_out.n_audio () > 0) {
1916 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1917 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1918 dout.set (DataType::AUDIO, 2);
1920 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1922 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1923 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1925 if (useins.n_audio() == 0) {
1928 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1930 if (_plugins.front()->configure_io (useins, dout) == false) {
1931 PluginIoReConfigure (); /* EMIT SIGNAL */
1932 _configured = false;
1936 _custom_sinks = din;
1941 if (_plugins.front()->configure_io (in, out) == false) {
1942 PluginIoReConfigure (); /* EMIT SIGNAL */
1943 _configured = false;
1949 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",
1951 _configured ? "Y" : "N",
1952 _maps_from_state ? "Y" : "N",
1953 old_in == in ? "==" : "!=",
1954 old_out == out ? "==" : "!=",
1955 old_pins == natural_input_streams () ? "==" : "!=",
1956 old_match.method == _match.method ? "==" : "!=",
1957 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1958 _in_map.size() == get_count () ? "==" : "!=",
1959 _out_map.size() == get_count () ? "==" : "!="
1962 bool mapping_changed = false;
1963 if (old_in == in && old_out == out
1965 && old_pins == natural_input_streams ()
1966 && old_match.method == _match.method
1967 && old_match.custom_cfg == _match.custom_cfg
1968 && _in_map.size() == _out_map.size()
1969 && _in_map.size() == get_count ()
1971 /* If the configuration has not changed, keep the mapping */
1972 mapping_changed = sanitize_maps ();
1973 } else if (_match.custom_cfg && _configured) {
1974 /* don't touch the map in manual mode */
1975 mapping_changed = sanitize_maps ();
1978 if (is_channelstrip ()) {
1979 /* fake channel map - for wire display */
1982 _thru_map = ChanMapping ();
1983 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1984 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1985 /* set "thru" map for in-place forward of audio */
1986 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1987 _thru_map.set (DataType::AUDIO, i, i);
1989 /* and midi (after implicit 1st channel bypass) */
1990 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1991 _thru_map.set (DataType::MIDI, i, i);
1995 if (_maps_from_state && old_in == in && old_out == out) {
1996 mapping_changed = true;
1999 /* generate a new mapping */
2000 mapping_changed = reset_map (false);
2002 _maps_from_state = false;
2005 if (mapping_changed) {
2006 PluginMapChanged (); /* EMIT SIGNAL */
2009 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2012 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2013 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2015 DEBUG_STR_APPEND(a, "----><----\n");
2017 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2018 DEBUG_STR_APPEND(a, " * Inputs:\n");
2019 DEBUG_STR_APPEND(a, _in_map[pc]);
2020 DEBUG_STR_APPEND(a, " * Outputs:\n");
2021 DEBUG_STR_APPEND(a, _out_map[pc]);
2023 DEBUG_STR_APPEND(a, " * Thru:\n");
2024 DEBUG_STR_APPEND(a, _thru_map);
2025 DEBUG_STR_APPEND(a, "-------->>--------\n");
2026 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2031 _no_inplace = check_inplace ();
2032 _mapping_changed = false;
2034 /* only the "noinplace_buffers" thread buffers need to be this large,
2035 * this can be optimized. other buffers are fine with
2036 * ChanCount::max (natural_input_streams (), natural_output_streams())
2037 * and route.cc's max (configured_in, configured_out)
2039 * no-inplace copies "thru" outputs (to emulate in-place) for
2040 * all outputs (to prevent overwrite) into a temporary space
2041 * which also holds input buffers (in case the plugin does process
2042 * in-place and overwrites those).
2044 * this buffers need to be at least as
2045 * natural_input_streams () + possible outputs.
2047 * sidechain inputs add a constraint on the input:
2048 * configured input + sidechain (=_configured_internal)
2050 * NB. this also satisfies
2051 * max (natural_input_streams(), natural_output_streams())
2052 * which is needed for silence runs
2054 _required_buffers = ChanCount::max (_configured_internal,
2055 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2057 if (old_in != in || old_out != out || old_internal != _configured_internal
2058 || old_pins != natural_input_streams ()
2059 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2061 PluginIoReConfigure (); /* EMIT SIGNAL */
2064 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2065 _latency_changed = true;
2067 // we don't know the analysis window size, so we must work with the
2068 // current buffer size here. each request for data fills in these
2069 // buffers and the analyser makes sure it gets enough data for the
2071 session().ensure_buffer_set (_signal_analysis_inputs, in);
2072 _signal_analysis_inputs.set_count (in);
2074 session().ensure_buffer_set (_signal_analysis_outputs, out);
2075 _signal_analysis_outputs.set_count (out);
2077 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2080 return Processor::configure_io (in, out);
2083 /** Decide whether this PluginInsert can support a given IO configuration.
2084 * To do this, we run through a set of possible solutions in rough order of
2087 * @param in Required input channel count.
2088 * @param out Filled in with the output channel count if we return true.
2089 * @return true if the given IO configuration can be supported.
2092 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2095 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2097 return private_can_support_io_configuration (in, out).method != Impossible;
2101 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2103 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2104 // preseed hint (for variable i/o)
2105 out.set (DataType::AUDIO, _preset_out.n_audio ());
2108 Match rv = internal_can_support_io_configuration (in, out);
2110 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2111 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2112 out.set (DataType::AUDIO, _preset_out.n_audio ());
2117 /** A private version of can_support_io_configuration which returns the method
2118 * by which the configuration can be matched, rather than just whether or not
2122 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2124 if (_plugins.empty()) {
2129 if (is_channelstrip ()) {
2131 return Match (ExactMatch, 1);
2135 /* if a user specified a custom cfg, so be it. */
2137 PluginInfoPtr info = _plugins.front()->get_info();
2139 if (info->reconfigurable_io()) {
2140 return Match (Delegate, 1, _strict_io, true);
2142 return Match (ExactMatch, get_count(), _strict_io, true);
2146 /* try automatic configuration */
2147 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2149 PluginInfoPtr info = _plugins.front()->get_info();
2150 ChanCount inputs = info->n_inputs;
2151 ChanCount outputs = info->n_outputs;
2153 /* handle case strict-i/o */
2154 if (_strict_io && m.method != Impossible) {
2157 /* special case MIDI instruments */
2158 if (is_instrument ()) {
2159 // output = midi-bypass + at most master-out channels.
2160 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2161 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2162 out = ChanCount::min (out, max_out);
2163 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2169 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2170 /* replicate processor to match output count (generators and such)
2171 * at least enough to feed every output port. */
2172 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2173 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2174 uint32_t nout = outputs.get (*t);
2175 if (nout == 0 || inx.get(*t) == 0) { continue; }
2176 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2179 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2180 return Match (Replicate, f, _strict_io);
2191 if (m.method != Impossible) {
2195 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2197 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2199 if (info->reconfigurable_io()) {
2202 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2203 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2204 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2206 // houston, we have a problem.
2207 return Match (Impossible, 0);
2210 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2211 return Match (Delegate, 1, _strict_io);
2214 ChanCount midi_bypass;
2215 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2216 midi_bypass.set (DataType::MIDI, 1);
2219 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2221 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2222 uint32_t nin = ns_inputs.get (*t);
2223 uint32_t nout = outputs.get (*t);
2224 if (nin == 0 || inx.get(*t) == 0) { continue; }
2225 // prefer floor() so the count won't overly increase IFF (nin < nout)
2226 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2228 if (f > 0 && outputs * f >= _configured_out) {
2229 out = outputs * f + midi_bypass;
2230 return Match (Replicate, f, _strict_io);
2233 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2235 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2236 uint32_t nin = ns_inputs.get (*t);
2237 if (nin == 0 || inx.get(*t) == 0) { continue; }
2238 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2241 out = outputs * f + midi_bypass;
2242 return Match (Replicate, f, _strict_io);
2245 // add at least as many plugins needed to connect all inputs
2247 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2248 uint32_t nin = inputs.get (*t);
2249 if (nin == 0 || inx.get(*t) == 0) { continue; }
2250 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2252 out = outputs * f + midi_bypass;
2253 return Match (Replicate, f, _strict_io);
2256 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2258 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2260 if (_plugins.empty()) {
2264 PluginInfoPtr info = _plugins.front()->get_info();
2265 ChanCount in; in += inx;
2266 ChanCount midi_bypass;
2268 if (info->reconfigurable_io()) {
2269 /* Plugin has flexible I/O, so delegate to it
2270 * pre-seed outputs, plugin tries closest match
2273 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2274 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2275 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2277 return Match (Impossible, 0);
2280 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2281 return Match (Delegate, 1);
2284 ChanCount inputs = info->n_inputs;
2285 ChanCount outputs = info->n_outputs;
2286 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2288 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2289 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2290 midi_bypass.set (DataType::MIDI, 1);
2292 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2293 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2294 in.set(DataType::MIDI, 0);
2297 // add internally provided sidechain ports
2298 ChanCount insc = in + sidechain_input_ports ();
2300 bool no_inputs = true;
2301 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2302 if (inputs.get (*t) != 0) {
2309 /* no inputs so we can take any input configuration since we throw it away */
2310 out = outputs + midi_bypass;
2311 return Match (NoInputs, 1);
2314 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2315 if (inputs == insc) {
2316 out = outputs + midi_bypass;
2317 return Match (ExactMatch, 1);
2320 /* Plugin inputs matches without side-chain-pins */
2321 if (ns_inputs == in) {
2322 out = outputs + midi_bypass;
2323 return Match (ExactMatch, 1);
2326 /* We may be able to run more than one copy of the plugin within this insert
2327 to cope with the insert having more inputs than the plugin.
2328 We allow replication only for plugins with either zero or 1 inputs and outputs
2329 for every valid data type.
2333 bool can_replicate = true;
2334 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2336 // ignore side-chains
2337 uint32_t nin = ns_inputs.get (*t);
2339 // No inputs of this type
2340 if (nin == 0 && in.get(*t) == 0) {
2344 if (nin != 1 || outputs.get (*t) != 1) {
2345 can_replicate = false;
2349 // Potential factor not set yet
2351 f = in.get(*t) / nin;
2354 // Factor for this type does not match another type, can not replicate
2355 if (f != (in.get(*t) / nin)) {
2356 can_replicate = false;
2361 if (can_replicate && f > 0) {
2362 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2363 out.set (*t, outputs.get(*t) * f);
2366 return Match (Replicate, f);
2369 /* If the processor has exactly one input of a given type, and
2370 the plugin has more, we can feed the single processor input
2371 to some or all of the plugin inputs. This is rather
2372 special-case-y, but the 1-to-many case is by far the
2373 simplest. How do I split thy 2 processor inputs to 3
2374 plugin inputs? Let me count the ways ...
2377 bool can_split = true;
2378 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2380 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2381 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2383 if (!can_split_type && !nothing_to_do_for_type) {
2389 out = outputs + midi_bypass;
2390 return Match (Split, 1);
2393 /* If the plugin has more inputs than we want, we can `hide' some of them
2394 by feeding them silence.
2397 bool could_hide = false;
2398 bool cannot_hide = false;
2399 ChanCount hide_channels;
2401 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2402 if (inputs.get(*t) > in.get(*t)) {
2403 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2404 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2406 } else if (inputs.get(*t) < in.get(*t)) {
2407 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2412 if (could_hide && !cannot_hide) {
2413 out = outputs + midi_bypass;
2414 return Match (Hide, 1, false, false, hide_channels);
2417 return Match (Impossible, 0);
2422 PluginInsert::state ()
2424 XMLNode& node = Processor::state ();
2426 node.set_property("type", _plugins[0]->state_node_name());
2427 node.set_property("unique-id", _plugins[0]->unique_id());
2428 node.set_property("count", (uint32_t)_plugins.size());
2430 /* remember actual i/o configuration (for later placeholder
2431 * in case the plugin goes missing) */
2432 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2433 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2434 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2435 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2437 /* save custom i/o config */
2438 node.set_property("custom", _custom_cfg);
2439 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2441 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2442 node.add_child_nocopy (* _in_map[pc].state (tmp));
2443 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2444 node.add_child_nocopy (* _out_map[pc].state (tmp));
2446 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2449 node.add_child_nocopy (_sidechain->get_state ());
2452 _plugins[0]->set_insert_id(this->id());
2453 node.add_child_nocopy (_plugins[0]->get_state());
2455 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2456 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2458 node.add_child_nocopy (ac->get_state());
2466 PluginInsert::set_control_ids (const XMLNode& node, int version)
2468 const XMLNodeList& nlist = node.children();
2469 XMLNodeConstIterator iter;
2470 set<Evoral::Parameter>::const_iterator p;
2472 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2473 if ((*iter)->name() == Controllable::xml_node_name) {
2475 uint32_t p = (uint32_t)-1;
2478 if ((*iter)->get_property (X_("symbol"), str)) {
2479 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2481 p = lv2plugin->port_index(str.c_str());
2485 if (p == (uint32_t)-1) {
2486 (*iter)->get_property (X_("parameter"), p);
2489 if (p != (uint32_t)-1) {
2491 /* this may create the new controllable */
2493 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2495 #ifndef NO_PLUGIN_STATE
2499 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2501 ac->set_state (**iter, version);
2510 PluginInsert::set_state(const XMLNode& node, int version)
2512 XMLNodeList nlist = node.children();
2513 XMLNodeIterator niter;
2514 XMLPropertyList plist;
2515 ARDOUR::PluginType type;
2518 if (!node.get_property ("type", str)) {
2519 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2523 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2524 type = ARDOUR::LADSPA;
2525 } else if (str == X_("lv2")) {
2527 } else if (str == X_("windows-vst")) {
2528 type = ARDOUR::Windows_VST;
2529 } else if (str == X_("lxvst")) {
2530 type = ARDOUR::LXVST;
2531 } else if (str == X_("mac-vst")) {
2532 type = ARDOUR::MacVST;
2533 } else if (str == X_("audiounit")) {
2534 type = ARDOUR::AudioUnit;
2535 } else if (str == X_("luaproc")) {
2538 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2542 XMLProperty const * prop = node.property ("unique-id");
2545 #ifdef WINDOWS_VST_SUPPORT
2546 /* older sessions contain VST plugins with only an "id" field. */
2547 if (type == ARDOUR::Windows_VST) {
2548 prop = node.property ("id");
2552 #ifdef LXVST_SUPPORT
2553 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2554 if (type == ARDOUR::LXVST) {
2555 prop = node.property ("id");
2562 error << _("Plugin has no unique ID field") << endmsg;
2567 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2568 bool any_vst = false;
2570 /* treat VST plugins equivalent if they have the same uniqueID
2571 * allow to move sessions windows <> linux */
2572 #ifdef LXVST_SUPPORT
2573 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2574 type = ARDOUR::LXVST;
2575 plugin = find_plugin (_session, prop->value(), type);
2576 if (plugin) { any_vst = true; }
2580 #ifdef WINDOWS_VST_SUPPORT
2581 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2582 type = ARDOUR::Windows_VST;
2583 plugin = find_plugin (_session, prop->value(), type);
2584 if (plugin) { any_vst = true; }
2588 #ifdef MACVST_SUPPORT
2589 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2590 type = ARDOUR::MacVST;
2591 plugin = find_plugin (_session, prop->value(), type);
2592 if (plugin) { any_vst = true; }
2596 if (plugin == 0 && type == ARDOUR::Lua) {
2597 /* unique ID (sha1 of script) was not found,
2598 * load the plugin from the serialized version in the
2599 * session-file instead.
2601 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2602 XMLNode *ls = node.child (lp->state_node_name().c_str());
2604 lp->set_script_from_state (*ls);
2610 error << string_compose(
2611 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2612 "Perhaps it was removed or moved since it was last used."),
2618 // The name of the PluginInsert comes from the plugin, nothing else
2619 _name = plugin->get_info()->name;
2623 // Processor::set_state() will set this, but too late
2624 // for it to be available when setting up plugin
2625 // state. We can't call Processor::set_state() until
2626 // the plugins themselves are created and added.
2630 if (_plugins.empty()) {
2631 /* if we are adding the first plugin, we will need to set
2632 up automatable controls.
2634 add_plugin (plugin);
2635 create_automatable_parameters ();
2636 set_control_ids (node, version);
2639 node.get_property ("count", count);
2641 if (_plugins.size() != count) {
2642 for (uint32_t n = 1; n < count; ++n) {
2643 add_plugin (plugin_factory (plugin));
2647 Processor::set_state (node, version);
2649 PBD::ID new_id = this->id();
2650 PBD::ID old_id = this->id();
2652 node.get_property ("id", old_id);
2654 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2656 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2657 and set all plugins to the same state.
2660 if ( ((*niter)->name() == plugin->state_node_name())
2661 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2664 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2665 /* Plugin state can include external files which are named after the ID.
2667 * If regenerate_xml_or_string_ids() is set, the ID will already have
2668 * been changed, so we need to use the old ID from the XML to load the
2669 * state and then update the ID.
2671 * When copying a plugin-state, route_ui takes care of of updating the ID,
2672 * but we need to call set_insert_id() to clear the cached plugin-state
2673 * and force a change.
2675 if (!regenerate_xml_or_string_ids ()) {
2676 (*i)->set_insert_id (new_id);
2678 (*i)->set_insert_id (old_id);
2681 (*i)->set_state (**niter, version);
2683 if (regenerate_xml_or_string_ids ()) {
2684 (*i)->set_insert_id (new_id);
2688 /* when copying plugin state, notify UI */
2689 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2690 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2692 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2700 if (version < 3000) {
2702 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2703 this is all handled by Automatable
2706 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2707 if ((*niter)->name() == "Redirect") {
2708 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2709 Processor::set_state (**niter, version);
2714 set_parameter_state_2X (node, version);
2717 node.get_property (X_("custom"), _custom_cfg);
2719 uint32_t in_maps = 0;
2720 uint32_t out_maps = 0;
2721 XMLNodeList kids = node.children ();
2722 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2723 if ((*i)->name() == X_("ConfiguredInput")) {
2724 _configured_in = ChanCount(**i);
2726 if ((*i)->name() == X_("CustomSinks")) {
2727 _custom_sinks = ChanCount(**i);
2729 if ((*i)->name() == X_("ConfiguredOutput")) {
2730 _custom_out = ChanCount(**i);
2731 _configured_out = ChanCount(**i);
2733 if ((*i)->name() == X_("PresetOutput")) {
2734 _preset_out = ChanCount(**i);
2736 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2737 long pc = atol (&((*i)->name().c_str()[9]));
2738 if (pc >= 0 && pc <= (long) get_count()) {
2739 _in_map[pc] = ChanMapping (**i);
2743 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2744 long pc = atol (&((*i)->name().c_str()[10]));
2745 if (pc >= 0 && pc <= (long) get_count()) {
2746 _out_map[pc] = ChanMapping (**i);
2750 if ((*i)->name () == "ThruMap") {
2751 _thru_map = ChanMapping (**i);
2754 // sidechain is a Processor (IO)
2755 if ((*i)->name () == Processor::state_node_name) {
2757 if (regenerate_xml_or_string_ids ()) {
2758 add_sidechain_from_xml (**i, version);
2763 if (!regenerate_xml_or_string_ids ()) {
2764 _sidechain->set_state (**i, version);
2766 update_sidechain_name ();
2771 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2772 _maps_from_state = true;
2775 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2779 (*i)->deactivate ();
2783 PluginConfigChanged (); /* EMIT SIGNAL */
2788 PluginInsert::update_id (PBD::ID id)
2791 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2792 (*i)->set_insert_id (id);
2797 PluginInsert::set_owner (SessionObject* o)
2799 Processor::set_owner (o);
2800 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2801 (*i)->set_owner (o);
2806 PluginInsert::set_state_dir (const std::string& d)
2808 // state() only saves the state of the first plugin
2809 _plugins[0]->set_state_dir (d);
2813 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2815 XMLNodeList nlist = node.children();
2816 XMLNodeIterator niter;
2818 /* look for port automation node */
2820 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2822 if ((*niter)->name() != port_automation_node_name) {
2827 XMLNodeConstIterator iter;
2831 cnodes = (*niter)->children ("port");
2833 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2837 if (!child->get_property("number", port_id)) {
2838 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2842 if (port_id >= _plugins[0]->parameter_count()) {
2843 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2847 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2848 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2850 if (c && c->alist()) {
2851 if (!child->children().empty()) {
2852 c->alist()->set_state (*child->children().front(), version);
2855 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2865 boost::shared_ptr<ReadOnlyControl>
2866 PluginInsert::control_output (uint32_t num) const
2868 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2869 if (i == _control_outputs.end ()) {
2870 return boost::shared_ptr<ReadOnlyControl> ();
2877 PluginInsert::describe_parameter (Evoral::Parameter param)
2879 if (param.type() == PluginAutomation) {
2880 return _plugins[0]->describe_parameter (param);
2881 } else if (param.type() == PluginPropertyAutomation) {
2882 boost::shared_ptr<AutomationControl> c(automation_control(param));
2883 if (c && !c->desc().label.empty()) {
2884 return c->desc().label;
2887 return Automatable::describe_parameter(param);
2891 PluginInsert::signal_latency() const
2893 if (!_pending_active) {
2896 if (_user_latency) {
2897 return _user_latency;
2900 return _plugins[0]->signal_latency ();
2904 PluginInsert::type ()
2906 return plugin()->get_info()->type;
2909 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2910 const Evoral::Parameter& param,
2911 const ParameterDescriptor& desc,
2912 boost::shared_ptr<AutomationList> list)
2913 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2918 list->set_interpolation(Evoral::ControlList::Discrete);
2923 /** @param val `user' value */
2926 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2928 /* FIXME: probably should be taking out some lock here.. */
2930 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2931 (*i)->set_parameter (_list->parameter().id(), user_val);
2934 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2936 iasp->set_parameter (_list->parameter().id(), user_val);
2939 AutomationControl::actually_set_value (user_val, group_override);
2943 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2945 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2949 PluginInsert::PluginControl::get_state ()
2951 XMLNode& node (AutomationControl::get_state());
2952 node.set_property (X_("parameter"), parameter().id());
2954 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2956 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2963 /** @return `user' val */
2965 PluginInsert::PluginControl::get_value () const
2967 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2973 return plugin->get_parameter (_list->parameter().id());
2976 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2977 const Evoral::Parameter& param,
2978 const ParameterDescriptor& desc,
2979 boost::shared_ptr<AutomationList> list)
2980 : AutomationControl (p->session(), param, desc, list)
2986 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
2988 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2989 This is lossy, but better than nothing until Ardour's automation system
2990 can handle various datatypes all the way down. */
2991 const Variant value(_desc.datatype, user_val);
2992 if (value.type() == Variant::NOTHING) {
2993 error << "set_value(double) called for non-numeric property" << endmsg;
2997 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2998 (*i)->set_property(_list->parameter().id(), value);
3003 AutomationControl::actually_set_value (user_val, gcd);
3007 PluginInsert::PluginPropertyControl::get_state ()
3009 XMLNode& node (AutomationControl::get_state());
3010 node.set_property (X_("property"), parameter().id());
3011 node.remove_property (X_("value"));
3017 PluginInsert::PluginPropertyControl::get_value () const
3019 return _value.to_double();
3022 boost::shared_ptr<Plugin>
3023 PluginInsert::get_impulse_analysis_plugin()
3025 boost::shared_ptr<Plugin> ret;
3026 if (_impulseAnalysisPlugin.expired()) {
3027 // LV2 in particular uses various _session params
3028 // during init() -- most notably block_size..
3030 ret = plugin_factory(_plugins[0]);
3031 ChanCount out (internal_output_streams ());
3032 if (ret->get_info ()->reconfigurable_io ()) {
3033 // populate get_info ()->n_inputs and ->n_outputs
3035 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3036 assert (out == internal_output_streams ());
3038 ret->configure_io (internal_input_streams (), out);
3039 ret->set_owner (_owner);
3040 _impulseAnalysisPlugin = ret;
3042 ret = _impulseAnalysisPlugin.lock();
3049 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3051 // called from outside the audio thread, so this should be safe
3052 // only do audio as analysis is (currently) only for audio plugins
3053 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3054 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3056 _signal_analysis_collected_nframes = 0;
3057 _signal_analysis_collect_nframes_max = nframes;
3060 /** Add a plugin to our list */
3062 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3064 plugin->set_insert_id (this->id());
3065 plugin->set_owner (_owner);
3067 if (_plugins.empty()) {
3068 /* first (and probably only) plugin instance - connect to relevant signals */
3070 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3071 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3072 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3073 _custom_sinks = plugin->get_info()->n_inputs;
3074 // cache sidechain port count
3075 _cached_sidechain_pins.reset ();
3076 const ChanCount& nis (plugin->get_info()->n_inputs);
3077 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3078 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3079 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3080 if (iod.is_sidechain) {
3081 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3086 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3087 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3089 vst->set_insert (this, _plugins.size ());
3093 _plugins.push_back (plugin);
3097 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3099 if (version < 3000) {
3103 XMLNodeList nlist = node.children();
3105 if (nlist.size() == 0) {
3112 XMLNodeConstIterator it = nlist.front()->children().begin();
3113 for ( ; it != nlist.front()->children().end(); ++ it) {
3114 if ((*it)->name() == "Port") {
3115 DataType type(DataType::NIL);
3116 (*it)->get_property ("type", type);
3117 if (type == DataType::AUDIO) {
3119 } else if (type == DataType::MIDI) {
3125 ChanCount in_cc = ChanCount();
3126 in_cc.set (DataType::AUDIO, audio);
3127 in_cc.set (DataType::MIDI, midi);
3129 add_sidechain (audio, midi);
3133 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3136 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3137 if (! (*i)->load_preset (pr)) {
3145 PluginInsert::realtime_handle_transport_stopped ()
3147 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3148 (*i)->realtime_handle_transport_stopped ();
3153 PluginInsert::realtime_locate ()
3155 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3156 (*i)->realtime_locate ();
3161 PluginInsert::monitoring_changed ()
3163 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3164 (*i)->monitoring_changed ();
3169 PluginInsert::latency_changed ()
3171 // this is called in RT context, LatencyChanged is emitted after run()
3172 _latency_changed = true;
3173 // XXX This also needs a proper API not an owner() hack.
3175 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3179 PluginInsert::start_touch (uint32_t param_id)
3181 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3183 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3184 ac->start_touch (session().audible_sample());
3189 PluginInsert::end_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->stop_touch (session().audible_sample());
3199 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3201 /* TODO: consider taking a try/lock: Don't run concurrently with
3202 * TimingStats::update, TimingStats::reset.
3204 return _timing_stats.get_stats (min, max, avg, dev);
3208 PluginInsert::clear_stats ()
3210 g_atomic_int_set (&_stat_reset, 1);
3213 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3216 case PluginInsert::Impossible: o << "Impossible"; break;
3217 case PluginInsert::Delegate: o << "Delegate"; break;
3218 case PluginInsert::NoInputs: o << "NoInputs"; break;
3219 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3220 case PluginInsert::Replicate: o << "Replicate"; break;
3221 case PluginInsert::Split: o << "Split"; break;
3222 case PluginInsert::Hide: o << "Hide"; break;
3224 o << " cnt: " << m.plugins
3225 << (m.strict_io ? " strict-io" : "")
3226 << (m.custom_cfg ? " custom-cfg" : "");
3227 if (m.method == PluginInsert::Hide) {
3228 o << " hide: " << m.hide;