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)
87 /* the first is the master */
91 create_automatable_parameters ();
92 const ChanCount& sc (sidechain_input_pins ());
93 if (sc.n_audio () > 0 || sc.n_midi () > 0) {
94 add_sidechain (sc.n_audio (), sc.n_midi ());
99 PluginInsert::~PluginInsert ()
101 for (CtrlOutMap::const_iterator i = _control_outputs.begin(); i != _control_outputs.end(); ++i) {
102 boost::dynamic_pointer_cast<ReadOnlyControl>(i->second)->drop_references ();
107 PluginInsert::set_strict_io (bool b)
109 bool changed = _strict_io != b;
112 PluginConfigChanged (); /* EMIT SIGNAL */
117 PluginInsert::set_count (uint32_t num)
119 bool require_state = !_plugins.empty();
121 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
122 // we don't allow to replicate AUs
126 /* this is a bad idea.... we shouldn't do this while active.
127 * only a route holding their redirect_lock should be calling this
132 } else if (num > _plugins.size()) {
133 uint32_t diff = num - _plugins.size();
135 for (uint32_t n = 0; n < diff; ++n) {
136 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
140 XMLNode& state = _plugins[0]->get_state ();
141 p->set_state (state, Stateful::loading_state_version);
148 PluginConfigChanged (); /* EMIT SIGNAL */
150 } else if (num < _plugins.size()) {
151 uint32_t diff = _plugins.size() - num;
152 for (uint32_t n= 0; n < diff; ++n) {
155 PluginConfigChanged (); /* EMIT SIGNAL */
163 PluginInsert::set_sinks (const ChanCount& c)
166 /* no signal, change will only be visible after re-config */
170 PluginInsert::set_outputs (const ChanCount& c)
172 bool changed = (_custom_out != c) && _custom_cfg;
175 PluginConfigChanged (); /* EMIT SIGNAL */
180 PluginInsert::set_custom_cfg (bool b)
182 bool changed = _custom_cfg != b;
185 PluginConfigChanged (); /* EMIT SIGNAL */
190 PluginInsert::set_preset_out (const ChanCount& c)
192 bool changed = _preset_out != c;
194 if (changed && !_custom_cfg) {
195 PluginConfigChanged (); /* EMIT SIGNAL */
201 PluginInsert::add_sidechain (uint32_t n_audio, uint32_t n_midi)
203 // caller must hold process lock
207 std::ostringstream n;
208 if (n_audio > 0 || n_midi > 0) {
209 n << "Sidechain " << Session::next_name_id ();
211 n << "TO BE RESET FROM XML";
213 SideChain *sc = new SideChain (_session, n.str ());
214 _sidechain = boost::shared_ptr<SideChain> (sc);
215 _sidechain->activate ();
216 for (uint32_t n = 0; n < n_audio; ++n) {
217 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
219 for (uint32_t n = 0; n < n_midi; ++n) {
220 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
222 PluginConfigChanged (); /* EMIT SIGNAL */
227 PluginInsert::del_sidechain ()
233 _sc_playback_latency = 0;
234 _sc_capture_latency = 0;
235 PluginConfigChanged (); /* EMIT SIGNAL */
240 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
242 if (which.type() != PluginAutomation)
245 boost::shared_ptr<AutomationControl> c
246 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
249 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()));
254 PluginInsert::output_streams() const
256 assert (_configured);
257 return _configured_out;
261 PluginInsert::input_streams() const
263 assert (_configured);
264 return _configured_in;
268 PluginInsert::internal_streams() const
270 assert (_configured);
271 return _configured_internal;
275 PluginInsert::internal_output_streams() const
277 assert (!_plugins.empty());
279 PluginInfoPtr info = _plugins.front()->get_info();
281 if (info->reconfigurable_io()) {
282 ChanCount out = _plugins.front()->output_streams ();
283 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
286 ChanCount out = info->n_outputs;
287 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
288 out.set_audio (out.n_audio() * _plugins.size());
289 out.set_midi (out.n_midi() * _plugins.size());
295 PluginInsert::internal_input_streams() const
297 assert (!_plugins.empty());
301 PluginInfoPtr info = _plugins.front()->get_info();
303 if (info->reconfigurable_io()) {
304 in = _plugins.front()->input_streams();
309 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
311 if (_match.method == Split) {
313 /* we are splitting 1 processor input to multiple plugin inputs,
314 so we have a maximum of 1 stream of each type.
316 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
317 if (in.get (*t) > 1) {
323 } else if (_match.method == Hide) {
325 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
326 in.set (*t, in.get (*t) - _match.hide.get (*t));
332 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
333 in.set (*t, in.get (*t) * _plugins.size ());
341 PluginInsert::natural_output_streams() const
344 if (is_channelstrip ()) {
345 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
348 return _plugins[0]->get_info()->n_outputs;
352 PluginInsert::natural_input_streams() const
355 if (is_channelstrip ()) {
356 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
359 return _plugins[0]->get_info()->n_inputs;
363 PluginInsert::sidechain_input_pins() const
365 return _cached_sidechain_pins;
369 PluginInsert::has_no_inputs() const
371 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
375 PluginInsert::has_no_audio_inputs() const
377 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
381 PluginInsert::plugin_latency () const {
382 return _plugins.front()->signal_latency ();
386 PluginInsert::is_instrument() const
388 PluginInfoPtr pip = _plugins[0]->get_info();
389 return (pip->is_instrument ());
393 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
395 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
396 // collect possible configurations, prefer given in/out
397 _plugins[0]->can_support_io_configuration (in, out);
400 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
402 if (ppc.size () == 0) {
405 if (!strict_io () && ppc.size () == 1) {
409 if (strict_io () && ppc.size () == 1) {
410 // "stereo" is currently preferred default for instruments
411 if (ppc.find (2) != ppc.end ()) {
416 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
417 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
418 // pretending to be an "Instrument"
422 if (!is_instrument ()) {
429 PluginInsert::create_automatable_parameters ()
431 assert (!_plugins.empty());
433 boost::shared_ptr<Plugin> plugin = _plugins.front();
434 set<Evoral::Parameter> a = _plugins.front()->automatable ();
436 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
437 if (!plugin->parameter_is_control (i)) {
441 ParameterDescriptor desc;
442 plugin->get_parameter_descriptor(i, desc);
444 if (!plugin->parameter_is_input (i)) {
445 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
448 Evoral::Parameter param (PluginAutomation, 0, i);
450 const bool automatable = a.find(param) != a.end();
453 can_automate (param);
455 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
456 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
458 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
461 plugin->set_automation_control (i, c);
465 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
466 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
467 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
468 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
469 if (desc.datatype != Variant::NOTHING) {
470 boost::shared_ptr<AutomationList> list;
471 if (Variant::type_is_numeric(desc.datatype)) {
472 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
474 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
475 if (!Variant::type_is_numeric(desc.datatype)) {
476 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
482 _bypass_port = plugin->designated_bypass_port ();
484 /* special case VST effSetBypass */
485 if (_bypass_port == UINT32_MAX -1) {
486 // emulate VST Bypass
487 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
488 ParameterDescriptor desc;
489 desc.label = _("Plugin Enable");
494 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
495 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
499 if (_bypass_port != UINT32_MAX) {
500 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
501 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
502 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
503 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
506 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
509 /** Called when something outside of this host has modified a plugin
510 * parameter. Responsible for propagating the change to two places:
512 * 1) anything listening to the Control itself
513 * 2) any replicated plugins that make up this PluginInsert.
515 * The PluginInsert is connected to the ParameterChangedExternally signal for
516 * the first (primary) plugin, and here broadcasts that change to any others.
518 * XXX We should probably drop this whole replication idea (Paul, October 2015)
519 * since it isn't used by sensible plugin APIs (AU, LV2).
522 PluginInsert::parameter_changed_externally (uint32_t which, float val)
524 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
526 /* First propagation: alter the underlying value of the control,
527 * without telling the plugin(s) that own/use it to set it.
534 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
537 pc->catch_up_with_external_value (val);
540 /* Second propagation: tell all plugins except the first to
541 update the value of this parameter. For sane plugin APIs,
542 there are no other plugins, so this is a no-op in those
546 Plugins::iterator i = _plugins.begin();
548 /* don't set the first plugin, just all the slaves */
550 if (i != _plugins.end()) {
552 for (; i != _plugins.end(); ++i) {
553 (*i)->set_parameter (which, val);
559 PluginInsert::set_block_size (pframes_t nframes)
562 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
563 if ((*i)->set_block_size (nframes) != 0) {
571 PluginInsert::automation_run (samplepos_t start, pframes_t nframes)
573 // XXX does not work when rolling backwards
574 if (_loop_location && nframes > 0) {
575 const samplepos_t loop_start = _loop_location->start ();
576 const samplepos_t loop_end = _loop_location->end ();
577 const samplecnt_t looplen = loop_end - loop_start;
579 samplecnt_t remain = nframes;
580 samplepos_t start_pos = start;
583 if (start_pos >= loop_end) {
584 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
585 start_pos = loop_start + start_off;
587 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
589 Automatable::automation_run (start_pos, move);
595 Automatable::automation_run (start, nframes);
599 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
601 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
603 if (_loop_location && now < end) {
605 end = ceil (next_event.when);
607 const samplepos_t loop_end = _loop_location->end ();
608 assert (now < loop_end); // due to map_loop_range ()
609 if (end > loop_end) {
610 next_event.when = loop_end;
618 PluginInsert::activate ()
620 _timing_stats.reset ();
621 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
625 Processor::activate ();
626 /* when setting state e.g ProcessorBox::paste_processor_state ()
627 * the plugin is not yet owned by a route.
628 * but no matter. Route::add_processors() will call activate () again
633 if (_plugin_signal_latency != signal_latency ()) {
634 _plugin_signal_latency = signal_latency ();
640 PluginInsert::deactivate ()
643 if (is_nonbypassable ()) {
647 _timing_stats.reset ();
648 Processor::deactivate ();
650 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
653 if (_plugin_signal_latency != signal_latency ()) {
654 _plugin_signal_latency = signal_latency ();
660 PluginInsert::flush ()
662 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
668 PluginInsert::enable (bool yn)
670 if (_bypass_port == UINT32_MAX) {
677 if (!_pending_active) {
680 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
681 const double val = yn ? 1.0 : 0.0;
682 ac->set_value (val, Controllable::NoGroup);
684 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
685 /* special case VST.. bypass may fail */
686 if (_bypass_port == UINT32_MAX - 1) {
687 /* check if bypass worked */
688 if (ac->get_value () != val) {
689 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
690 // set plugin to enabled (not-byassed)
691 ac->set_value (1.0, Controllable::NoGroup);
692 // ..and use host-provided hard-bypass
707 PluginInsert::enabled () const
709 if (_bypass_port == UINT32_MAX) {
710 return Processor::enabled ();
712 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
713 return (ac->get_value () > 0 && _pending_active);
718 PluginInsert::bypassable () const
720 if (_bypass_port == UINT32_MAX) {
723 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
725 return !ac->automation_playback ();
730 PluginInsert::enable_changed ()
736 PluginInsert::bypassable_changed ()
738 BypassableChanged ();
742 PluginInsert::write_immediate_event (size_t size, const uint8_t* buf)
745 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
746 if (!(*i)->write_immediate_event (size, buf)) {
754 PluginInsert::preset_load_set_value (uint32_t p, float v)
756 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
761 if (ac->automation_state() & Play) {
766 ac->set_value (v, Controllable::NoGroup);
771 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
773 // TODO optimize: store "unconnected" in a fixed set.
774 // it only changes on reconfiguration.
775 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
776 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
778 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
779 mapped = true; // in-place Midi bypass
781 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
782 PinMappings::const_iterator i = out_map.find (pc);
783 if (i == out_map.end ()) {
786 const ChanMapping& outmap (i->second);
787 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
789 uint32_t idx = outmap.get (*t, o, &valid);
790 if (valid && idx == out) {
797 bufs.get (*t, out).silence (nframes, offset);
804 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
806 // TODO: atomically copy maps & _no_inplace
807 PinMappings in_map (_in_map);
808 PinMappings out_map (_out_map);
809 ChanMapping thru_map (_thru_map);
810 if (_mapping_changed) { // ToDo use a counters, increment until match.
811 _no_inplace = check_inplace ();
812 _mapping_changed = false;
815 if (_latency_changed) {
816 /* delaylines are configured with the max possible latency (as reported by the plugin)
817 * so this won't allocate memory (unless the plugin lied about its max latency)
818 * It may still 'click' though, since the fixed delaylines are not de-clicked.
819 * Then again plugin-latency changes are not click-free to begin with.
821 * This is also worst case, there is currently no concept of per-stream latency.
823 * e.g. Two identical latent plugins:
824 * 1st plugin: process left (latent), bypass right.
825 * 2nd plugin: bypass left, process right (latent).
826 * -> currently this yields 2 times latency of the plugin,
828 _latency_changed = false;
829 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
832 if (_match.method == Split && !_no_inplace) {
833 // TODO: also use this optimization if one source-buffer
834 // feeds _all_ *connected* inputs.
835 // currently this is *first* buffer to all only --
836 // see PluginInsert::check_inplace
837 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
838 if (_configured_internal.get (*t) == 0) {
842 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
843 assert (valid && first_idx == 0); // check_inplace ensures this
844 /* copy the first stream's buffer contents to the others */
845 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
846 uint32_t idx = in_map[0].get (*t, i, &valid);
849 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
853 /* the copy operation produces a linear monotonic input map */
854 in_map[0] = ChanMapping (natural_input_streams ());
857 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
858 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
864 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
866 boost::shared_ptr<AutomationControl> c
867 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
869 if (c->list() && c->automation_playback()) {
872 const float val = c->list()->rt_safe_eval (start, valid);
875 /* This is the ONLY place where we are
877 * AutomationControl::set_value_unchecked(). We
878 * know that the control is in
879 * automation playback mode, so no
880 * check on writable() is required
881 * (which must be done in AutomationControl::set_value()
884 c->set_value_unchecked(val);
891 /* Calculate if, and how many samples we need to collect for analysis */
892 samplecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
893 _signal_analysis_collected_nframes);
894 if (nframes < collect_signal_nframes) { // we might not get all samples now
895 collect_signal_nframes = nframes;
898 if (collect_signal_nframes > 0) {
900 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
901 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
902 //std::cerr << "filling buffer with " << collect_signal_nframes << " samples at " << _signal_analysis_collected_nframes << std::endl;
904 _signal_analysis_inputs.set_count(input_streams());
906 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
907 _signal_analysis_inputs.get_audio(i).read_from (
909 collect_signal_nframes,
910 _signal_analysis_collected_nframes); // offset is for target buffer
915 if (is_channelstrip ()) {
916 if (_configured_in.n_audio() > 0) {
917 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
918 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
920 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
922 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
923 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
929 // TODO optimize -- build maps once.
931 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
932 ARDOUR::ChanMapping used_outputs;
934 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
936 /* build used-output map */
937 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
938 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
939 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
941 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
943 used_outputs.set (*t, out_idx, 1); // mark as used
948 /* copy thru data to outputs before processing in-place */
949 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
950 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
952 uint32_t in_idx = thru_map.get (*t, out, &valid);
953 uint32_t m = out + natural_input_streams ().get (*t);
955 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
956 used_outputs.set (*t, out, 1); // mark as used
958 used_outputs.get (*t, out, &valid);
960 /* the plugin is expected to write here, but may not :(
961 * (e.g. drumgizmo w/o kit loaded)
963 inplace_bufs.get (*t, m).silence (nframes);
970 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
972 ARDOUR::ChanMapping i_in_map (natural_input_streams());
973 ARDOUR::ChanMapping i_out_map (out_map[pc]);
974 ARDOUR::ChanCount mapped;
976 /* map inputs sequentially */
977 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
978 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
980 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
981 uint32_t m = mapped.get (*t);
983 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
985 inplace_bufs.get (*t, m).silence (nframes, offset);
987 mapped.set (*t, m + 1);
991 /* outputs are mapped to inplace_bufs after the inputs */
992 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
993 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
996 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1001 /* all instances have completed, now copy data that was written
1002 * and zero unconnected buffers */
1003 ARDOUR::ChanMapping nonzero_out (used_outputs);
1004 if (has_midi_bypass ()) {
1005 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1007 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1008 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1010 used_outputs.get (*t, out, &valid);
1012 nonzero_out.get (*t, out, &valid);
1014 bufs.get (*t, out).silence (nframes, offset);
1017 uint32_t m = out + natural_input_streams ().get (*t);
1018 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
1023 /* in-place processing */
1025 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1026 if ((*i)->connect_and_run(bufs, start, end, speed, in_map[pc], out_map[pc], nframes, offset)) {
1030 // now silence unconnected outputs
1031 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1034 if (collect_signal_nframes > 0) {
1036 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
1037 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
1039 _signal_analysis_outputs.set_count(output_streams());
1041 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1042 _signal_analysis_outputs.get_audio(i).read_from(
1044 collect_signal_nframes,
1045 _signal_analysis_collected_nframes); // offset is for target buffer
1048 _signal_analysis_collected_nframes += collect_signal_nframes;
1049 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
1051 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
1052 _signal_analysis_collect_nframes_max = 0;
1053 _signal_analysis_collected_nframes = 0;
1055 AnalysisDataGathered(&_signal_analysis_inputs,
1056 &_signal_analysis_outputs);
1060 if (_plugin_signal_latency != signal_latency ()) {
1061 _plugin_signal_latency = signal_latency ();
1067 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1069 /* bypass the plugin(s) not the whole processor.
1070 * -> use mappings just like connect_and_run
1073 // TODO: atomically copy maps & _no_inplace
1074 const ChanMapping in_map (no_sc_input_map ());
1075 const ChanMapping out_map (output_map ());
1076 if (_mapping_changed) {
1077 _no_inplace = check_inplace ();
1078 _mapping_changed = false;
1081 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1082 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1085 ChanMapping thru_map (_thru_map);
1087 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1089 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1090 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1091 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
1094 ARDOUR::ChanMapping used_outputs;
1096 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1097 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1099 uint32_t in_idx = thru_map.get (*t, out, &valid);
1101 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1102 used_outputs.set (*t, out, 1); // mark as used
1106 // plugin no-op: assume every plugin has an internal identity map
1107 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1108 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1110 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1114 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1118 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1119 used_outputs.set (*t, out, 1); // mark as used
1122 // now silence all unused outputs
1123 if (has_midi_bypass ()) {
1124 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1126 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1127 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1129 used_outputs.get (*t, out, &valid);
1131 bufs.get (*t, out).silence (nframes, 0);
1136 if (_match.method == Split) {
1137 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1138 if (_configured_internal.get (*t) == 0) {
1141 // copy/feeds _all_ *connected* inputs, copy the first buffer
1143 uint32_t first_idx = in_map.get (*t, 0, &valid);
1144 assert (valid && first_idx == 0); // check_inplace ensures this
1145 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1146 uint32_t idx = in_map.get (*t, i, &valid);
1149 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
1155 // apply output map and/or monotonic but not identity i/o mappings
1156 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1157 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1159 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1161 bufs.get (*t, out).silence (nframes, 0);
1164 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1166 bufs.get (*t, out).silence (nframes, 0);
1169 if (in_idx != src_idx) {
1170 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
1178 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1180 automation_run (start_sample, nframes); // evaluate automation only
1183 // XXX delaybuffers need to be offset by nframes
1187 _delaybuffers.flush ();
1189 ChanMapping in_map (natural_input_streams ());
1190 ChanMapping out_map (natural_output_streams ());
1191 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1193 if (is_channelstrip ()) {
1194 if (_configured_in.n_audio() > 0) {
1195 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1199 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1200 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1205 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1208 // collect sidechain input for complete cycle (!)
1209 // TODO we need delaylines here for latency compensation
1210 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1213 if (_pending_active) {
1214 _timing_stats.start ();
1215 /* run as normal if we are active or moving from inactive to active */
1217 if (_session.transport_rolling() || _session.bounce_processing()) {
1218 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1220 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1221 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1223 _timing_stats.update ();
1226 _timing_stats.reset ();
1227 // XXX should call ::silence() to run plugin(s) for consistent load.
1228 // We'll need to change this anyway when bypass can be automated
1229 bypass (bufs, nframes);
1230 automation_run (start_sample, nframes); // evaluate automation only
1231 _delaybuffers.flush ();
1234 _active = _pending_active;
1236 /* we have no idea whether the plugin generated silence or not, so mark
1237 * all buffers appropriately.
1242 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1244 Evoral::ControlEvent next_event (0, 0.0f);
1245 samplecnt_t offset = 0;
1247 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1250 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1254 /* map start back into loop-range, adjust end */
1255 map_loop_range (start, end);
1257 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1259 /* no events have a time within the relevant range */
1261 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1267 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1269 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1275 map_loop_range (start, end);
1277 if (!find_next_event (start, end, next_event)) {
1282 /* cleanup anything that is left to do */
1285 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1290 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1292 if (param.type() != PluginAutomation)
1295 if (_plugins.empty()) {
1296 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1298 abort(); /*NOTREACHED*/
1301 return _plugins[0]->default_value (param.id());
1306 PluginInsert::can_reset_all_parameters ()
1309 uint32_t params = 0;
1310 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1312 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1314 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1318 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1324 if (ac->automation_state() & Play) {
1329 return all && (params > 0);
1333 PluginInsert::reset_parameters_to_default ()
1337 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1339 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1341 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1345 const float dflt = _plugins[0]->default_value (cid);
1346 const float curr = _plugins[0]->get_parameter (cid);
1352 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1357 if (ac->automation_state() & Play) {
1362 ac->set_value (dflt, Controllable::NoGroup);
1367 boost::shared_ptr<Plugin>
1368 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1370 boost::shared_ptr<LadspaPlugin> lp;
1371 boost::shared_ptr<LuaProc> lua;
1373 boost::shared_ptr<LV2Plugin> lv2p;
1375 #ifdef WINDOWS_VST_SUPPORT
1376 boost::shared_ptr<WindowsVSTPlugin> vp;
1378 #ifdef LXVST_SUPPORT
1379 boost::shared_ptr<LXVSTPlugin> lxvp;
1381 #ifdef MACVST_SUPPORT
1382 boost::shared_ptr<MacVSTPlugin> mvp;
1384 #ifdef AUDIOUNIT_SUPPORT
1385 boost::shared_ptr<AUPlugin> ap;
1388 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1389 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1390 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1391 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1393 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1394 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1396 #ifdef WINDOWS_VST_SUPPORT
1397 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1398 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1400 #ifdef LXVST_SUPPORT
1401 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1402 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1404 #ifdef MACVST_SUPPORT
1405 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1406 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1408 #ifdef AUDIOUNIT_SUPPORT
1409 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1410 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1414 fatal << string_compose (_("programming error: %1"),
1415 X_("unknown plugin type in PluginInsert::plugin_factory"))
1417 abort(); /*NOTREACHED*/
1418 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1422 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1423 if (num < _in_map.size()) {
1424 bool changed = _in_map[num] != m;
1426 changed |= sanitize_maps ();
1428 PluginMapChanged (); /* EMIT SIGNAL */
1429 _mapping_changed = true;
1430 _session.set_dirty();
1436 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1437 if (num < _out_map.size()) {
1438 bool changed = _out_map[num] != m;
1440 changed |= sanitize_maps ();
1442 PluginMapChanged (); /* EMIT SIGNAL */
1443 _mapping_changed = true;
1444 _session.set_dirty();
1450 PluginInsert::set_thru_map (ChanMapping m) {
1451 bool changed = _thru_map != m;
1453 changed |= sanitize_maps ();
1455 PluginMapChanged (); /* EMIT SIGNAL */
1456 _mapping_changed = true;
1457 _session.set_dirty();
1462 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1463 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1465 if (_configured) { return false; }
1466 _configured_in = in;
1467 _configured_out = out;
1471 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1476 PluginInsert::input_map () const
1480 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1481 ChanMapping m (i->second);
1482 const ChanMapping::Mappings& mp ((*i).second.mappings());
1483 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1484 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1485 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1494 PluginInsert::no_sc_input_map () const
1498 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1499 ChanMapping m (i->second);
1500 const ChanMapping::Mappings& mp ((*i).second.mappings());
1501 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1502 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1503 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1504 if (i->first < ins) {
1505 rv.set (tm->first, i->first + pc * ins, i->second);
1514 PluginInsert::output_map () const
1518 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1519 ChanMapping m (i->second);
1520 const ChanMapping::Mappings& mp ((*i).second.mappings());
1521 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1522 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1523 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1527 if (has_midi_bypass ()) {
1528 rv.set (DataType::MIDI, 0, 0);
1535 PluginInsert::has_midi_bypass () const
1537 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1538 && natural_output_streams ().n_midi () == 0) {
1545 PluginInsert::has_midi_thru () const
1547 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1548 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1556 PluginInsert::is_channelstrip () const {
1557 return _plugins.front()->is_channelstrip();
1560 PluginInsert::is_nonbypassable () const {
1561 return _plugins.front()->is_nonbypassable ();
1566 PluginInsert::check_inplace ()
1568 bool inplace_ok = !_plugins.front()->inplace_broken ();
1570 if (_thru_map.n_total () > 0) {
1571 // TODO once midi-bypass is part of the mapping, ignore it
1575 if (_match.method == Split && inplace_ok) {
1576 assert (get_count() == 1);
1577 assert (_in_map.size () == 1);
1578 if (!_out_map[0].is_monotonic ()) {
1581 if (_configured_internal != _configured_in) {
1582 /* no sidechain -- TODO we could allow this with
1583 * some more logic in PluginInsert::connect_and_run().
1585 * PluginInsert::reset_map() already maps it.
1590 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1591 if (_configured_internal.get (*t) == 0) {
1595 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1596 if (!valid || first_idx != 0) {
1597 // so far only allow to copy the *first* stream's buffer to others
1600 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1601 uint32_t idx = _in_map[0].get (*t, i, &valid);
1602 if (valid && idx != first_idx) {
1611 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1616 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1617 if (!_in_map[pc].is_monotonic ()) {
1620 if (!_out_map[pc].is_monotonic ()) {
1626 /* check if every output is fed by the corresponding input
1628 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1629 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1631 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1633 ChanMapping in_map (input_map ());
1634 const ChanMapping::Mappings out_m (output_map ().mappings ());
1635 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1636 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1637 /* src-pin: c->first, out-port: c->second */
1639 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1640 if (valid && in_port != c->second) {
1648 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1649 return !inplace_ok; // no-inplace
1653 PluginInsert::sanitize_maps ()
1655 bool changed = false;
1656 /* strip dead wood */
1657 PinMappings new_ins;
1658 PinMappings new_outs;
1659 ChanMapping new_thru;
1661 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1663 ChanMapping new_out;
1664 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1665 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1667 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1668 if (valid && idx < _configured_internal.get (*t)) {
1669 new_in.set (*t, i, idx);
1672 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1674 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1675 if (valid && idx < _configured_out.get (*t)) {
1676 new_out.set (*t, o, idx);
1680 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1683 new_ins[pc] = new_in;
1684 new_outs[pc] = new_out;
1687 /* prevent dup output assignments */
1688 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1689 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1690 bool mapped = false;
1691 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1693 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1694 if (valid && mapped) {
1695 new_outs[pc].unset (*t, idx);
1703 /* remove excess thru */
1704 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1705 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1707 uint32_t idx = _thru_map.get (*t, o, &valid);
1708 if (valid && idx < _configured_internal.get (*t)) {
1709 new_thru.set (*t, o, idx);
1714 /* prevent out + thru, existing plugin outputs override thru */
1715 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1716 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1717 bool mapped = false;
1719 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1720 new_outs[pc].get_src (*t, o, &mapped);
1721 if (mapped) { break; }
1723 if (!mapped) { continue; }
1724 uint32_t idx = new_thru.get (*t, o, &valid);
1726 new_thru.unset (*t, idx);
1731 if (has_midi_bypass ()) {
1732 // TODO: include midi-bypass in the thru set,
1733 // remove dedicated handling.
1734 new_thru.unset (DataType::MIDI, 0);
1737 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1741 _out_map = new_outs;
1742 _thru_map = new_thru;
1748 PluginInsert::reset_map (bool emit)
1750 const PinMappings old_in (_in_map);
1751 const PinMappings old_out (_out_map);
1755 _thru_map = ChanMapping ();
1757 /* build input map */
1758 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1759 uint32_t sc = 0; // side-chain round-robin (all instances)
1761 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1762 const uint32_t nis = natural_input_streams ().get(*t);
1763 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1765 /* SC inputs are last in the plugin-insert.. */
1766 const uint32_t sc_start = _configured_in.get (*t);
1767 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1768 /* ...but may not be at the end of the plugin ports.
1769 * in case the side-chain is not the last port, shift connections back.
1770 * and connect to side-chain
1773 uint32_t ic = 0; // split inputs
1774 const uint32_t cend = _configured_in.get (*t);
1776 for (uint32_t in = 0; in < nis; ++in) {
1777 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1778 if (iod.is_sidechain) {
1779 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1780 if (sc_len > 0) {// side-chain may be hidden
1781 _in_map[pc].set (*t, in, sc_start + sc);
1782 sc = (sc + 1) % sc_len;
1786 if (_match.method == Split) {
1787 if (cend == 0) { continue; }
1788 if (_strict_io && ic + stride * pc >= cend) {
1791 /* connect *no* sidechain sinks in round-robin fashion */
1792 _in_map[pc].set (*t, in, ic + stride * pc);
1793 if (_strict_io && (ic + 1) == cend) {
1796 ic = (ic + 1) % cend;
1798 uint32_t s = in - shift;
1799 if (stride * pc + s < cend) {
1800 _in_map[pc].set (*t, in, s + stride * pc);
1808 /* build output map */
1810 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1811 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1812 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1813 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1818 if (old_in == _in_map && old_out == _out_map) {
1822 PluginMapChanged (); /* EMIT SIGNAL */
1823 _mapping_changed = true;
1824 _session.set_dirty();
1830 PluginInsert::configure_io (ChanCount in, ChanCount out)
1832 Match old_match = _match;
1834 ChanCount old_internal;
1838 old_pins = natural_input_streams();
1839 old_in = _configured_in;
1840 old_out = _configured_out;
1841 old_internal = _configured_internal;
1843 _configured_in = in;
1844 _configured_internal = in;
1845 _configured_out = out;
1848 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1849 * (currently _sidechain->configure_io always succeeds
1850 * since Processor::configure_io() succeeds)
1852 if (!_sidechain->configure_io (in, out)) {
1853 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1856 _configured_internal += _sidechain->input()->n_ports();
1858 // include (static_cast<Route*>owner())->name() ??
1859 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1862 /* get plugin configuration */
1863 _match = private_can_support_io_configuration (in, out);
1865 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1867 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1868 DEBUG_STR_APPEND(a, _match);
1869 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1873 /* set the matching method and number of plugins that we will use to meet this configuration */
1874 if (set_count (_match.plugins) == false) {
1875 PluginIoReConfigure (); /* EMIT SIGNAL */
1876 _configured = false;
1880 /* configure plugins */
1881 switch (_match.method) {
1884 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1885 PluginIoReConfigure (); /* EMIT SIGNAL */
1886 _configured = false;
1892 ChanCount din (_configured_internal);
1893 ChanCount dout (din); // hint
1895 if (_custom_sinks.n_total () > 0) {
1896 din = _custom_sinks;
1899 } else if (_preset_out.n_audio () > 0) {
1900 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1901 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1902 dout.set (DataType::AUDIO, 2);
1904 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1906 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1907 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1909 if (useins.n_audio() == 0) {
1912 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1914 if (_plugins.front()->configure_io (useins, dout) == false) {
1915 PluginIoReConfigure (); /* EMIT SIGNAL */
1916 _configured = false;
1920 _custom_sinks = din;
1925 if (_plugins.front()->configure_io (in, out) == false) {
1926 PluginIoReConfigure (); /* EMIT SIGNAL */
1927 _configured = false;
1933 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",
1935 _configured ? "Y" : "N",
1936 _maps_from_state ? "Y" : "N",
1937 old_in == in ? "==" : "!=",
1938 old_out == out ? "==" : "!=",
1939 old_pins == natural_input_streams () ? "==" : "!=",
1940 old_match.method == _match.method ? "==" : "!=",
1941 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1942 _in_map.size() == get_count () ? "==" : "!=",
1943 _out_map.size() == get_count () ? "==" : "!="
1946 bool mapping_changed = false;
1947 if (old_in == in && old_out == out
1949 && old_pins == natural_input_streams ()
1950 && old_match.method == _match.method
1951 && old_match.custom_cfg == _match.custom_cfg
1952 && _in_map.size() == _out_map.size()
1953 && _in_map.size() == get_count ()
1955 /* If the configuration has not changed, keep the mapping */
1956 mapping_changed = sanitize_maps ();
1957 } else if (_match.custom_cfg && _configured) {
1958 /* don't touch the map in manual mode */
1959 mapping_changed = sanitize_maps ();
1962 if (is_channelstrip ()) {
1963 /* fake channel map - for wire display */
1966 _thru_map = ChanMapping ();
1967 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1968 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1969 /* set "thru" map for in-place forward of audio */
1970 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1971 _thru_map.set (DataType::AUDIO, i, i);
1973 /* and midi (after implicit 1st channel bypass) */
1974 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1975 _thru_map.set (DataType::MIDI, i, i);
1979 if (_maps_from_state && old_in == in && old_out == out) {
1980 mapping_changed = true;
1983 /* generate a new mapping */
1984 mapping_changed = reset_map (false);
1986 _maps_from_state = false;
1989 if (mapping_changed) {
1990 PluginMapChanged (); /* EMIT SIGNAL */
1993 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1996 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1997 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1999 DEBUG_STR_APPEND(a, "----><----\n");
2001 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2002 DEBUG_STR_APPEND(a, " * Inputs:\n");
2003 DEBUG_STR_APPEND(a, _in_map[pc]);
2004 DEBUG_STR_APPEND(a, " * Outputs:\n");
2005 DEBUG_STR_APPEND(a, _out_map[pc]);
2007 DEBUG_STR_APPEND(a, " * Thru:\n");
2008 DEBUG_STR_APPEND(a, _thru_map);
2009 DEBUG_STR_APPEND(a, "-------->>--------\n");
2010 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2015 _no_inplace = check_inplace ();
2016 _mapping_changed = false;
2018 /* only the "noinplace_buffers" thread buffers need to be this large,
2019 * this can be optimized. other buffers are fine with
2020 * ChanCount::max (natural_input_streams (), natural_output_streams())
2021 * and route.cc's max (configured_in, configured_out)
2023 * no-inplace copies "thru" outputs (to emulate in-place) for
2024 * all outputs (to prevent overwrite) into a temporary space
2025 * which also holds input buffers (in case the plugin does process
2026 * in-place and overwrites those).
2028 * this buffers need to be at least as
2029 * natural_input_streams () + possible outputs.
2031 * sidechain inputs add a constraint on the input:
2032 * configured input + sidechain (=_configured_internal)
2034 * NB. this also satisfies
2035 * max (natural_input_streams(), natural_output_streams())
2036 * which is needed for silence runs
2038 _required_buffers = ChanCount::max (_configured_internal,
2039 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2041 if (old_in != in || old_out != out || old_internal != _configured_internal
2042 || old_pins != natural_input_streams ()
2043 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2045 PluginIoReConfigure (); /* EMIT SIGNAL */
2048 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2049 _latency_changed = true;
2051 // we don't know the analysis window size, so we must work with the
2052 // current buffer size here. each request for data fills in these
2053 // buffers and the analyser makes sure it gets enough data for the
2055 session().ensure_buffer_set (_signal_analysis_inputs, in);
2056 _signal_analysis_inputs.set_count (in);
2058 session().ensure_buffer_set (_signal_analysis_outputs, out);
2059 _signal_analysis_outputs.set_count (out);
2061 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2064 return Processor::configure_io (in, out);
2067 /** Decide whether this PluginInsert can support a given IO configuration.
2068 * To do this, we run through a set of possible solutions in rough order of
2071 * @param in Required input channel count.
2072 * @param out Filled in with the output channel count if we return true.
2073 * @return true if the given IO configuration can be supported.
2076 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2079 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2081 return private_can_support_io_configuration (in, out).method != Impossible;
2085 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2087 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2088 // preseed hint (for variable i/o)
2089 out.set (DataType::AUDIO, _preset_out.n_audio ());
2092 Match rv = internal_can_support_io_configuration (in, out);
2094 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2095 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2096 out.set (DataType::AUDIO, _preset_out.n_audio ());
2101 /** A private version of can_support_io_configuration which returns the method
2102 * by which the configuration can be matched, rather than just whether or not
2106 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2108 if (_plugins.empty()) {
2113 if (is_channelstrip ()) {
2115 return Match (ExactMatch, 1);
2119 /* if a user specified a custom cfg, so be it. */
2121 PluginInfoPtr info = _plugins.front()->get_info();
2123 if (info->reconfigurable_io()) {
2124 return Match (Delegate, 1, _strict_io, true);
2126 return Match (ExactMatch, get_count(), _strict_io, true);
2130 /* try automatic configuration */
2131 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2133 PluginInfoPtr info = _plugins.front()->get_info();
2134 ChanCount inputs = info->n_inputs;
2135 ChanCount outputs = info->n_outputs;
2137 /* handle case strict-i/o */
2138 if (_strict_io && m.method != Impossible) {
2141 /* special case MIDI instruments */
2142 if (is_instrument ()) {
2143 // output = midi-bypass + at most master-out channels.
2144 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2145 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2146 out = ChanCount::min (out, max_out);
2147 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2153 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2154 /* replicate processor to match output count (generators and such)
2155 * at least enough to feed every output port. */
2156 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2157 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2158 uint32_t nout = outputs.get (*t);
2159 if (nout == 0 || inx.get(*t) == 0) { continue; }
2160 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2163 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2164 return Match (Replicate, f, _strict_io);
2175 if (m.method != Impossible) {
2179 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2181 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2183 if (info->reconfigurable_io()) {
2186 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2187 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2188 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2190 // houston, we have a problem.
2191 return Match (Impossible, 0);
2194 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2195 return Match (Delegate, 1, _strict_io);
2198 ChanCount midi_bypass;
2199 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2200 midi_bypass.set (DataType::MIDI, 1);
2203 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2205 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2206 uint32_t nin = ns_inputs.get (*t);
2207 uint32_t nout = outputs.get (*t);
2208 if (nin == 0 || inx.get(*t) == 0) { continue; }
2209 // prefer floor() so the count won't overly increase IFF (nin < nout)
2210 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2212 if (f > 0 && outputs * f >= _configured_out) {
2213 out = outputs * f + midi_bypass;
2214 return Match (Replicate, f, _strict_io);
2217 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2219 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2220 uint32_t nin = ns_inputs.get (*t);
2221 if (nin == 0 || inx.get(*t) == 0) { continue; }
2222 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2225 out = outputs * f + midi_bypass;
2226 return Match (Replicate, f, _strict_io);
2229 // add at least as many plugins needed to connect all inputs
2231 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2232 uint32_t nin = inputs.get (*t);
2233 if (nin == 0 || inx.get(*t) == 0) { continue; }
2234 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2236 out = outputs * f + midi_bypass;
2237 return Match (Replicate, f, _strict_io);
2240 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2242 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2244 if (_plugins.empty()) {
2248 PluginInfoPtr info = _plugins.front()->get_info();
2249 ChanCount in; in += inx;
2250 ChanCount midi_bypass;
2252 if (info->reconfigurable_io()) {
2253 /* Plugin has flexible I/O, so delegate to it
2254 * pre-seed outputs, plugin tries closest match
2257 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2258 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2259 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2261 return Match (Impossible, 0);
2264 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2265 return Match (Delegate, 1);
2268 ChanCount inputs = info->n_inputs;
2269 ChanCount outputs = info->n_outputs;
2270 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2272 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2273 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2274 midi_bypass.set (DataType::MIDI, 1);
2276 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2277 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2278 in.set(DataType::MIDI, 0);
2281 // add internally provided sidechain ports
2282 ChanCount insc = in + sidechain_input_ports ();
2284 bool no_inputs = true;
2285 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2286 if (inputs.get (*t) != 0) {
2293 /* no inputs so we can take any input configuration since we throw it away */
2294 out = outputs + midi_bypass;
2295 return Match (NoInputs, 1);
2298 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2299 if (inputs == insc) {
2300 out = outputs + midi_bypass;
2301 return Match (ExactMatch, 1);
2304 /* Plugin inputs matches without side-chain-pins */
2305 if (ns_inputs == in) {
2306 out = outputs + midi_bypass;
2307 return Match (ExactMatch, 1);
2310 /* We may be able to run more than one copy of the plugin within this insert
2311 to cope with the insert having more inputs than the plugin.
2312 We allow replication only for plugins with either zero or 1 inputs and outputs
2313 for every valid data type.
2317 bool can_replicate = true;
2318 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2320 // ignore side-chains
2321 uint32_t nin = ns_inputs.get (*t);
2323 // No inputs of this type
2324 if (nin == 0 && in.get(*t) == 0) {
2328 if (nin != 1 || outputs.get (*t) != 1) {
2329 can_replicate = false;
2333 // Potential factor not set yet
2335 f = in.get(*t) / nin;
2338 // Factor for this type does not match another type, can not replicate
2339 if (f != (in.get(*t) / nin)) {
2340 can_replicate = false;
2345 if (can_replicate && f > 0) {
2346 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2347 out.set (*t, outputs.get(*t) * f);
2350 return Match (Replicate, f);
2353 /* If the processor has exactly one input of a given type, and
2354 the plugin has more, we can feed the single processor input
2355 to some or all of the plugin inputs. This is rather
2356 special-case-y, but the 1-to-many case is by far the
2357 simplest. How do I split thy 2 processor inputs to 3
2358 plugin inputs? Let me count the ways ...
2361 bool can_split = true;
2362 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2364 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2365 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2367 if (!can_split_type && !nothing_to_do_for_type) {
2373 out = outputs + midi_bypass;
2374 return Match (Split, 1);
2377 /* If the plugin has more inputs than we want, we can `hide' some of them
2378 by feeding them silence.
2381 bool could_hide = false;
2382 bool cannot_hide = false;
2383 ChanCount hide_channels;
2385 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2386 if (inputs.get(*t) > in.get(*t)) {
2387 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2388 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2390 } else if (inputs.get(*t) < in.get(*t)) {
2391 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2396 if (could_hide && !cannot_hide) {
2397 out = outputs + midi_bypass;
2398 return Match (Hide, 1, false, false, hide_channels);
2401 return Match (Impossible, 0);
2406 PluginInsert::state ()
2408 XMLNode& node = Processor::state ();
2410 node.set_property("type", _plugins[0]->state_node_name());
2411 node.set_property("unique-id", _plugins[0]->unique_id());
2412 node.set_property("count", (uint32_t)_plugins.size());
2414 /* remember actual i/o configuration (for later placeholder
2415 * in case the plugin goes missing) */
2416 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2417 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2418 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2419 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2421 /* save custom i/o config */
2422 node.set_property("custom", _custom_cfg);
2423 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2425 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2426 node.add_child_nocopy (* _in_map[pc].state (tmp));
2427 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2428 node.add_child_nocopy (* _out_map[pc].state (tmp));
2430 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2433 node.add_child_nocopy (_sidechain->get_state ());
2436 _plugins[0]->set_insert_id(this->id());
2437 node.add_child_nocopy (_plugins[0]->get_state());
2439 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2440 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2442 node.add_child_nocopy (ac->get_state());
2450 PluginInsert::set_control_ids (const XMLNode& node, int version)
2452 const XMLNodeList& nlist = node.children();
2453 XMLNodeConstIterator iter;
2454 set<Evoral::Parameter>::const_iterator p;
2456 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2457 if ((*iter)->name() == Controllable::xml_node_name) {
2459 uint32_t p = (uint32_t)-1;
2462 if ((*iter)->get_property (X_("symbol"), str)) {
2463 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2465 p = lv2plugin->port_index(str.c_str());
2469 if (p == (uint32_t)-1) {
2470 (*iter)->get_property (X_("parameter"), p);
2473 if (p != (uint32_t)-1) {
2475 /* this may create the new controllable */
2477 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2479 #ifndef NO_PLUGIN_STATE
2483 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2485 ac->set_state (**iter, version);
2494 PluginInsert::set_state(const XMLNode& node, int version)
2496 XMLNodeList nlist = node.children();
2497 XMLNodeIterator niter;
2498 XMLPropertyList plist;
2499 ARDOUR::PluginType type;
2502 if (!node.get_property ("type", str)) {
2503 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2507 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2508 type = ARDOUR::LADSPA;
2509 } else if (str == X_("lv2")) {
2511 } else if (str == X_("windows-vst")) {
2512 type = ARDOUR::Windows_VST;
2513 } else if (str == X_("lxvst")) {
2514 type = ARDOUR::LXVST;
2515 } else if (str == X_("mac-vst")) {
2516 type = ARDOUR::MacVST;
2517 } else if (str == X_("audiounit")) {
2518 type = ARDOUR::AudioUnit;
2519 } else if (str == X_("luaproc")) {
2522 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2526 XMLProperty const * prop = node.property ("unique-id");
2529 #ifdef WINDOWS_VST_SUPPORT
2530 /* older sessions contain VST plugins with only an "id" field. */
2531 if (type == ARDOUR::Windows_VST) {
2532 prop = node.property ("id");
2536 #ifdef LXVST_SUPPORT
2537 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2538 if (type == ARDOUR::LXVST) {
2539 prop = node.property ("id");
2546 error << _("Plugin has no unique ID field") << endmsg;
2551 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2552 bool any_vst = false;
2554 /* treat VST plugins equivalent if they have the same uniqueID
2555 * allow to move sessions windows <> linux */
2556 #ifdef LXVST_SUPPORT
2557 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2558 type = ARDOUR::LXVST;
2559 plugin = find_plugin (_session, prop->value(), type);
2560 if (plugin) { any_vst = true; }
2564 #ifdef WINDOWS_VST_SUPPORT
2565 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2566 type = ARDOUR::Windows_VST;
2567 plugin = find_plugin (_session, prop->value(), type);
2568 if (plugin) { any_vst = true; }
2572 #ifdef MACVST_SUPPORT
2573 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2574 type = ARDOUR::MacVST;
2575 plugin = find_plugin (_session, prop->value(), type);
2576 if (plugin) { any_vst = true; }
2580 if (plugin == 0 && type == ARDOUR::Lua) {
2581 /* unique ID (sha1 of script) was not found,
2582 * load the plugin from the serialized version in the
2583 * session-file instead.
2585 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2586 XMLNode *ls = node.child (lp->state_node_name().c_str());
2588 lp->set_script_from_state (*ls);
2594 error << string_compose(
2595 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2596 "Perhaps it was removed or moved since it was last used."),
2602 // The name of the PluginInsert comes from the plugin, nothing else
2603 _name = plugin->get_info()->name;
2607 // Processor::set_state() will set this, but too late
2608 // for it to be available when setting up plugin
2609 // state. We can't call Processor::set_state() until
2610 // the plugins themselves are created and added.
2614 if (_plugins.empty()) {
2615 /* if we are adding the first plugin, we will need to set
2616 up automatable controls.
2618 add_plugin (plugin);
2619 create_automatable_parameters ();
2620 set_control_ids (node, version);
2623 node.get_property ("count", count);
2625 if (_plugins.size() != count) {
2626 for (uint32_t n = 1; n < count; ++n) {
2627 add_plugin (plugin_factory (plugin));
2631 Processor::set_state (node, version);
2633 PBD::ID new_id = this->id();
2634 PBD::ID old_id = this->id();
2636 node.get_property ("id", old_id);
2638 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2640 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2641 and set all plugins to the same state.
2644 if ( ((*niter)->name() == plugin->state_node_name())
2645 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2648 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2649 /* Plugin state can include external files which are named after the ID.
2651 * If regenerate_xml_or_string_ids() is set, the ID will already have
2652 * been changed, so we need to use the old ID from the XML to load the
2653 * state and then update the ID.
2655 * When copying a plugin-state, route_ui takes care of of updating the ID,
2656 * but we need to call set_insert_id() to clear the cached plugin-state
2657 * and force a change.
2659 if (!regenerate_xml_or_string_ids ()) {
2660 (*i)->set_insert_id (new_id);
2662 (*i)->set_insert_id (old_id);
2665 (*i)->set_state (**niter, version);
2667 if (regenerate_xml_or_string_ids ()) {
2668 (*i)->set_insert_id (new_id);
2672 /* when copying plugin state, notify UI */
2673 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2674 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2676 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2684 if (version < 3000) {
2686 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2687 this is all handled by Automatable
2690 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2691 if ((*niter)->name() == "Redirect") {
2692 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2693 Processor::set_state (**niter, version);
2698 set_parameter_state_2X (node, version);
2701 node.get_property (X_("custom"), _custom_cfg);
2703 uint32_t in_maps = 0;
2704 uint32_t out_maps = 0;
2705 XMLNodeList kids = node.children ();
2706 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2707 if ((*i)->name() == X_("ConfiguredInput")) {
2708 _configured_in = ChanCount(**i);
2710 if ((*i)->name() == X_("CustomSinks")) {
2711 _custom_sinks = ChanCount(**i);
2713 if ((*i)->name() == X_("ConfiguredOutput")) {
2714 _custom_out = ChanCount(**i);
2715 _configured_out = ChanCount(**i);
2717 if ((*i)->name() == X_("PresetOutput")) {
2718 _preset_out = ChanCount(**i);
2720 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2721 long pc = atol (&((*i)->name().c_str()[9]));
2722 if (pc >= 0 && pc <= (long) get_count()) {
2723 _in_map[pc] = ChanMapping (**i);
2727 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2728 long pc = atol (&((*i)->name().c_str()[10]));
2729 if (pc >= 0 && pc <= (long) get_count()) {
2730 _out_map[pc] = ChanMapping (**i);
2734 if ((*i)->name () == "ThruMap") {
2735 _thru_map = ChanMapping (**i);
2738 // sidechain is a Processor (IO)
2739 if ((*i)->name () == Processor::state_node_name) {
2743 if (!regenerate_xml_or_string_ids ()) {
2744 _sidechain->set_state (**i, version);
2749 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2750 _maps_from_state = true;
2753 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2757 (*i)->deactivate ();
2761 PluginConfigChanged (); /* EMIT SIGNAL */
2766 PluginInsert::update_id (PBD::ID id)
2769 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2770 (*i)->set_insert_id (id);
2775 PluginInsert::set_owner (SessionObject* o)
2777 Processor::set_owner (o);
2778 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2779 (*i)->set_owner (o);
2784 PluginInsert::set_state_dir (const std::string& d)
2786 // state() only saves the state of the first plugin
2787 _plugins[0]->set_state_dir (d);
2791 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2793 XMLNodeList nlist = node.children();
2794 XMLNodeIterator niter;
2796 /* look for port automation node */
2798 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2800 if ((*niter)->name() != port_automation_node_name) {
2805 XMLNodeConstIterator iter;
2809 cnodes = (*niter)->children ("port");
2811 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2815 if (!child->get_property("number", port_id)) {
2816 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2820 if (port_id >= _plugins[0]->parameter_count()) {
2821 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2825 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2826 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2828 if (c && c->alist()) {
2829 if (!child->children().empty()) {
2830 c->alist()->set_state (*child->children().front(), version);
2833 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2843 boost::shared_ptr<ReadOnlyControl>
2844 PluginInsert::control_output (uint32_t num) const
2846 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2847 if (i == _control_outputs.end ()) {
2848 return boost::shared_ptr<ReadOnlyControl> ();
2855 PluginInsert::describe_parameter (Evoral::Parameter param)
2857 if (param.type() == PluginAutomation) {
2858 return _plugins[0]->describe_parameter (param);
2859 } else if (param.type() == PluginPropertyAutomation) {
2860 boost::shared_ptr<AutomationControl> c(automation_control(param));
2861 if (c && !c->desc().label.empty()) {
2862 return c->desc().label;
2865 return Automatable::describe_parameter(param);
2869 PluginInsert::signal_latency() const
2871 if (!_pending_active) {
2874 if (_user_latency) {
2875 return _user_latency;
2878 return _plugins[0]->signal_latency ();
2882 PluginInsert::type ()
2884 return plugin()->get_info()->type;
2887 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2888 const Evoral::Parameter& param,
2889 const ParameterDescriptor& desc,
2890 boost::shared_ptr<AutomationList> list)
2891 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2896 list->set_interpolation(Evoral::ControlList::Discrete);
2901 /** @param val `user' value */
2904 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2906 /* FIXME: probably should be taking out some lock here.. */
2908 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2909 (*i)->set_parameter (_list->parameter().id(), user_val);
2912 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2914 iasp->set_parameter (_list->parameter().id(), user_val);
2917 AutomationControl::actually_set_value (user_val, group_override);
2921 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2923 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2927 PluginInsert::PluginControl::get_state ()
2929 XMLNode& node (AutomationControl::get_state());
2930 node.set_property (X_("parameter"), parameter().id());
2932 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2934 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2941 /** @return `user' val */
2943 PluginInsert::PluginControl::get_value () const
2945 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2951 return plugin->get_parameter (_list->parameter().id());
2954 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2955 const Evoral::Parameter& param,
2956 const ParameterDescriptor& desc,
2957 boost::shared_ptr<AutomationList> list)
2958 : AutomationControl (p->session(), param, desc, list)
2964 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
2966 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2967 This is lossy, but better than nothing until Ardour's automation system
2968 can handle various datatypes all the way down. */
2969 const Variant value(_desc.datatype, user_val);
2970 if (value.type() == Variant::NOTHING) {
2971 error << "set_value(double) called for non-numeric property" << endmsg;
2975 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2976 (*i)->set_property(_list->parameter().id(), value);
2981 AutomationControl::actually_set_value (user_val, gcd);
2985 PluginInsert::PluginPropertyControl::get_state ()
2987 XMLNode& node (AutomationControl::get_state());
2988 node.set_property (X_("property"), parameter().id());
2989 node.remove_property (X_("value"));
2995 PluginInsert::PluginPropertyControl::get_value () const
2997 return _value.to_double();
3000 boost::shared_ptr<Plugin>
3001 PluginInsert::get_impulse_analysis_plugin()
3003 boost::shared_ptr<Plugin> ret;
3004 if (_impulseAnalysisPlugin.expired()) {
3005 // LV2 in particular uses various _session params
3006 // during init() -- most notably block_size..
3008 ret = plugin_factory(_plugins[0]);
3009 ChanCount out (internal_output_streams ());
3010 if (ret->get_info ()->reconfigurable_io ()) {
3011 // populate get_info ()->n_inputs and ->n_outputs
3013 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3014 assert (out == internal_output_streams ());
3016 ret->configure_io (internal_input_streams (), out);
3017 ret->set_owner (_owner);
3018 _impulseAnalysisPlugin = ret;
3020 ret = _impulseAnalysisPlugin.lock();
3027 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3029 // called from outside the audio thread, so this should be safe
3030 // only do audio as analysis is (currently) only for audio plugins
3031 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3032 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3034 _signal_analysis_collected_nframes = 0;
3035 _signal_analysis_collect_nframes_max = nframes;
3038 /** Add a plugin to our list */
3040 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3042 plugin->set_insert_id (this->id());
3043 plugin->set_owner (_owner);
3045 if (_plugins.empty()) {
3046 /* first (and probably only) plugin instance - connect to relevant signals */
3048 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3049 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3050 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3051 _custom_sinks = plugin->get_info()->n_inputs;
3052 // cache sidechain port count
3053 _cached_sidechain_pins.reset ();
3054 const ChanCount& nis (plugin->get_info()->n_inputs);
3055 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3056 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3057 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3058 if (iod.is_sidechain) {
3059 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3064 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3065 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3067 vst->set_insert (this, _plugins.size ());
3071 _plugins.push_back (plugin);
3075 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3078 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3079 if (! (*i)->load_preset (pr)) {
3087 PluginInsert::realtime_handle_transport_stopped ()
3089 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3090 (*i)->realtime_handle_transport_stopped ();
3095 PluginInsert::realtime_locate ()
3097 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3098 (*i)->realtime_locate ();
3103 PluginInsert::monitoring_changed ()
3105 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3106 (*i)->monitoring_changed ();
3111 PluginInsert::latency_changed ()
3113 // this is called in RT context, LatencyChanged is emitted after run()
3114 _latency_changed = true;
3115 // XXX This also needs a proper API not an owner() hack.
3117 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3121 PluginInsert::start_touch (uint32_t param_id)
3123 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3125 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3126 ac->start_touch (session().audible_sample());
3131 PluginInsert::end_touch (uint32_t param_id)
3133 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3135 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3136 ac->stop_touch (session().audible_sample());
3141 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3143 /* TODO: consider taking a try/lock: Don't run concurrently with
3144 * TimingStats::update, TimingStats::reset.
3146 return _timing_stats.get_stats (min, max, avg, dev);
3149 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3152 case PluginInsert::Impossible: o << "Impossible"; break;
3153 case PluginInsert::Delegate: o << "Delegate"; break;
3154 case PluginInsert::NoInputs: o << "NoInputs"; break;
3155 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3156 case PluginInsert::Replicate: o << "Replicate"; break;
3157 case PluginInsert::Split: o << "Split"; break;
3158 case PluginInsert::Hide: o << "Hide"; break;
3160 o << " cnt: " << m.plugins
3161 << (m.strict_io ? " strict-io" : "")
3162 << (m.custom_cfg ? " custom-cfg" : "");
3163 if (m.method == PluginInsert::Hide) {
3164 o << " hide: " << m.hide;