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 << "Sidechain " << Session::next_name_id ();
212 n << "TO BE RESET FROM XML";
214 SideChain *sc = new SideChain (_session, n.str ());
215 _sidechain = boost::shared_ptr<SideChain> (sc);
216 _sidechain->activate ();
217 for (uint32_t n = 0; n < n_audio; ++n) {
218 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
220 for (uint32_t n = 0; n < n_midi; ++n) {
221 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
223 PluginConfigChanged (); /* EMIT SIGNAL */
228 PluginInsert::del_sidechain ()
234 _sc_playback_latency = 0;
235 _sc_capture_latency = 0;
236 PluginConfigChanged (); /* EMIT SIGNAL */
241 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
243 if (which.type() != PluginAutomation)
246 boost::shared_ptr<AutomationControl> c
247 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
250 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()));
255 PluginInsert::output_streams() const
257 assert (_configured);
258 return _configured_out;
262 PluginInsert::input_streams() const
264 assert (_configured);
265 return _configured_in;
269 PluginInsert::internal_streams() const
271 assert (_configured);
272 return _configured_internal;
276 PluginInsert::internal_output_streams() const
278 assert (!_plugins.empty());
280 PluginInfoPtr info = _plugins.front()->get_info();
282 if (info->reconfigurable_io()) {
283 ChanCount out = _plugins.front()->output_streams ();
284 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
287 ChanCount out = info->n_outputs;
288 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
289 out.set_audio (out.n_audio() * _plugins.size());
290 out.set_midi (out.n_midi() * _plugins.size());
296 PluginInsert::internal_input_streams() const
298 assert (!_plugins.empty());
302 PluginInfoPtr info = _plugins.front()->get_info();
304 if (info->reconfigurable_io()) {
305 in = _plugins.front()->input_streams();
310 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
312 if (_match.method == Split) {
314 /* we are splitting 1 processor input to multiple plugin inputs,
315 so we have a maximum of 1 stream of each type.
317 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
318 if (in.get (*t) > 1) {
324 } else if (_match.method == Hide) {
326 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
327 in.set (*t, in.get (*t) - _match.hide.get (*t));
333 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
334 in.set (*t, in.get (*t) * _plugins.size ());
342 PluginInsert::natural_output_streams() const
345 if (is_channelstrip ()) {
346 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
349 return _plugins[0]->get_info()->n_outputs;
353 PluginInsert::natural_input_streams() const
356 if (is_channelstrip ()) {
357 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
360 return _plugins[0]->get_info()->n_inputs;
364 PluginInsert::sidechain_input_pins() const
366 return _cached_sidechain_pins;
370 PluginInsert::has_no_inputs() const
372 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
376 PluginInsert::has_no_audio_inputs() const
378 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
382 PluginInsert::plugin_latency () const {
383 return _plugins.front()->signal_latency ();
387 PluginInsert::is_instrument() const
389 PluginInfoPtr pip = _plugins[0]->get_info();
390 return (pip->is_instrument ());
394 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
396 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
397 // collect possible configurations, prefer given in/out
398 _plugins[0]->can_support_io_configuration (in, out);
401 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
403 if (ppc.size () == 0) {
406 if (!strict_io () && ppc.size () == 1) {
410 if (strict_io () && ppc.size () == 1) {
411 // "stereo" is currently preferred default for instruments
412 if (ppc.find (2) != ppc.end ()) {
417 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
418 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
419 // pretending to be an "Instrument"
423 if (!is_instrument ()) {
430 PluginInsert::create_automatable_parameters ()
432 assert (!_plugins.empty());
434 boost::shared_ptr<Plugin> plugin = _plugins.front();
435 set<Evoral::Parameter> a = _plugins.front()->automatable ();
437 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
438 if (!plugin->parameter_is_control (i)) {
442 ParameterDescriptor desc;
443 plugin->get_parameter_descriptor(i, desc);
445 if (!plugin->parameter_is_input (i)) {
446 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
449 Evoral::Parameter param (PluginAutomation, 0, i);
451 const bool automatable = a.find(param) != a.end();
454 can_automate (param);
456 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
457 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
459 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
462 plugin->set_automation_control (i, c);
466 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
467 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
468 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
469 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
470 if (desc.datatype != Variant::NOTHING) {
471 boost::shared_ptr<AutomationList> list;
472 if (Variant::type_is_numeric(desc.datatype)) {
473 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
475 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
476 if (!Variant::type_is_numeric(desc.datatype)) {
477 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
483 _bypass_port = plugin->designated_bypass_port ();
485 /* special case VST effSetBypass */
486 if (_bypass_port == UINT32_MAX -1) {
487 // emulate VST Bypass
488 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
489 ParameterDescriptor desc;
490 desc.label = _("Plugin Enable");
495 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
496 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
500 if (_bypass_port != UINT32_MAX) {
501 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
502 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
503 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
504 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
507 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
510 /** Called when something outside of this host has modified a plugin
511 * parameter. Responsible for propagating the change to two places:
513 * 1) anything listening to the Control itself
514 * 2) any replicated plugins that make up this PluginInsert.
516 * The PluginInsert is connected to the ParameterChangedExternally signal for
517 * the first (primary) plugin, and here broadcasts that change to any others.
519 * XXX We should probably drop this whole replication idea (Paul, October 2015)
520 * since it isn't used by sensible plugin APIs (AU, LV2).
523 PluginInsert::parameter_changed_externally (uint32_t which, float val)
525 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
527 /* First propagation: alter the underlying value of the control,
528 * without telling the plugin(s) that own/use it to set it.
535 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
538 pc->catch_up_with_external_value (val);
541 /* Second propagation: tell all plugins except the first to
542 update the value of this parameter. For sane plugin APIs,
543 there are no other plugins, so this is a no-op in those
547 Plugins::iterator i = _plugins.begin();
549 /* don't set the first plugin, just all the slaves */
551 if (i != _plugins.end()) {
553 for (; i != _plugins.end(); ++i) {
554 (*i)->set_parameter (which, val);
560 PluginInsert::set_block_size (pframes_t nframes)
563 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
564 if ((*i)->set_block_size (nframes) != 0) {
572 PluginInsert::automation_run (samplepos_t start, pframes_t nframes)
574 // XXX does not work when rolling backwards
575 if (_loop_location && nframes > 0) {
576 const samplepos_t loop_start = _loop_location->start ();
577 const samplepos_t loop_end = _loop_location->end ();
578 const samplecnt_t looplen = loop_end - loop_start;
580 samplecnt_t remain = nframes;
581 samplepos_t start_pos = start;
584 if (start_pos >= loop_end) {
585 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
586 start_pos = loop_start + start_off;
588 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
590 Automatable::automation_run (start_pos, move);
596 Automatable::automation_run (start, nframes);
600 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
602 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
604 if (_loop_location && now < end) {
606 end = ceil (next_event.when);
608 const samplepos_t loop_end = _loop_location->end ();
609 assert (now < loop_end); // due to map_loop_range ()
610 if (end > loop_end) {
611 next_event.when = loop_end;
619 PluginInsert::activate ()
621 _timing_stats.reset ();
622 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
626 Processor::activate ();
627 /* when setting state e.g ProcessorBox::paste_processor_state ()
628 * the plugin is not yet owned by a route.
629 * but no matter. Route::add_processors() will call activate () again
634 if (_plugin_signal_latency != signal_latency ()) {
635 _plugin_signal_latency = signal_latency ();
641 PluginInsert::deactivate ()
644 if (is_nonbypassable ()) {
648 _timing_stats.reset ();
649 Processor::deactivate ();
651 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
654 if (_plugin_signal_latency != signal_latency ()) {
655 _plugin_signal_latency = signal_latency ();
661 PluginInsert::flush ()
663 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
669 PluginInsert::enable (bool yn)
671 if (_bypass_port == UINT32_MAX) {
678 if (!_pending_active) {
681 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
682 const double val = yn ? 1.0 : 0.0;
683 ac->set_value (val, Controllable::NoGroup);
685 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
686 /* special case VST.. bypass may fail */
687 if (_bypass_port == UINT32_MAX - 1) {
688 /* check if bypass worked */
689 if (ac->get_value () != val) {
690 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
691 // set plugin to enabled (not-byassed)
692 ac->set_value (1.0, Controllable::NoGroup);
693 // ..and use host-provided hard-bypass
708 PluginInsert::enabled () const
710 if (_bypass_port == UINT32_MAX) {
711 return Processor::enabled ();
713 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
714 return (ac->get_value () > 0 && _pending_active);
719 PluginInsert::bypassable () const
721 if (_bypass_port == UINT32_MAX) {
724 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
726 return !ac->automation_playback ();
731 PluginInsert::enable_changed ()
737 PluginInsert::bypassable_changed ()
739 BypassableChanged ();
743 PluginInsert::write_immediate_event (size_t size, const uint8_t* buf)
746 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
747 if (!(*i)->write_immediate_event (size, buf)) {
755 PluginInsert::preset_load_set_value (uint32_t p, float v)
757 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
762 if (ac->automation_state() & Play) {
767 ac->set_value (v, Controllable::NoGroup);
772 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
774 // TODO optimize: store "unconnected" in a fixed set.
775 // it only changes on reconfiguration.
776 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
777 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
779 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
780 mapped = true; // in-place Midi bypass
782 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
783 PinMappings::const_iterator i = out_map.find (pc);
784 if (i == out_map.end ()) {
787 const ChanMapping& outmap (i->second);
788 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
790 uint32_t idx = outmap.get (*t, o, &valid);
791 if (valid && idx == out) {
798 bufs.get (*t, out).silence (nframes, offset);
805 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
807 // TODO: atomically copy maps & _no_inplace
808 PinMappings in_map (_in_map);
809 PinMappings out_map (_out_map);
810 ChanMapping thru_map (_thru_map);
811 if (_mapping_changed) { // ToDo use a counters, increment until match.
812 _no_inplace = check_inplace ();
813 _mapping_changed = false;
816 if (_latency_changed) {
817 /* delaylines are configured with the max possible latency (as reported by the plugin)
818 * so this won't allocate memory (unless the plugin lied about its max latency)
819 * It may still 'click' though, since the fixed delaylines are not de-clicked.
820 * Then again plugin-latency changes are not click-free to begin with.
822 * This is also worst case, there is currently no concept of per-stream latency.
824 * e.g. Two identical latent plugins:
825 * 1st plugin: process left (latent), bypass right.
826 * 2nd plugin: bypass left, process right (latent).
827 * -> currently this yields 2 times latency of the plugin,
829 _latency_changed = false;
830 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
833 if (_match.method == Split && !_no_inplace) {
834 // TODO: also use this optimization if one source-buffer
835 // feeds _all_ *connected* inputs.
836 // currently this is *first* buffer to all only --
837 // see PluginInsert::check_inplace
838 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
839 if (_configured_internal.get (*t) == 0) {
843 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
844 assert (valid && first_idx == 0); // check_inplace ensures this
845 /* copy the first stream's buffer contents to the others */
846 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
847 uint32_t idx = in_map[0].get (*t, i, &valid);
850 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
854 /* the copy operation produces a linear monotonic input map */
855 in_map[0] = ChanMapping (natural_input_streams ());
858 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
859 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
865 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
867 boost::shared_ptr<AutomationControl> c
868 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
870 if (c->list() && c->automation_playback()) {
873 const float val = c->list()->rt_safe_eval (start, valid);
876 /* This is the ONLY place where we are
878 * AutomationControl::set_value_unchecked(). We
879 * know that the control is in
880 * automation playback mode, so no
881 * check on writable() is required
882 * (which must be done in AutomationControl::set_value()
885 c->set_value_unchecked(val);
892 /* Calculate if, and how many samples we need to collect for analysis */
893 samplecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
894 _signal_analysis_collected_nframes);
895 if (nframes < collect_signal_nframes) { // we might not get all samples now
896 collect_signal_nframes = nframes;
899 if (collect_signal_nframes > 0) {
901 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
902 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
903 //std::cerr << "filling buffer with " << collect_signal_nframes << " samples at " << _signal_analysis_collected_nframes << std::endl;
905 _signal_analysis_inputs.set_count(input_streams());
907 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
908 _signal_analysis_inputs.get_audio(i).read_from (
910 collect_signal_nframes,
911 _signal_analysis_collected_nframes); // offset is for target buffer
916 if (is_channelstrip ()) {
917 if (_configured_in.n_audio() > 0) {
918 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
919 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
921 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
923 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
924 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
930 // TODO optimize -- build maps once.
932 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
933 ARDOUR::ChanMapping used_outputs;
935 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
937 /* build used-output map */
938 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
939 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
940 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
942 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
944 used_outputs.set (*t, out_idx, 1); // mark as used
949 /* copy thru data to outputs before processing in-place */
950 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
951 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
953 uint32_t in_idx = thru_map.get (*t, out, &valid);
954 uint32_t m = out + natural_input_streams ().get (*t);
956 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
957 used_outputs.set (*t, out, 1); // mark as used
959 used_outputs.get (*t, out, &valid);
961 /* the plugin is expected to write here, but may not :(
962 * (e.g. drumgizmo w/o kit loaded)
964 inplace_bufs.get (*t, m).silence (nframes);
971 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
973 ARDOUR::ChanMapping i_in_map (natural_input_streams());
974 ARDOUR::ChanMapping i_out_map (out_map[pc]);
975 ARDOUR::ChanCount mapped;
977 /* map inputs sequentially */
978 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
979 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
981 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
982 uint32_t m = mapped.get (*t);
984 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
986 inplace_bufs.get (*t, m).silence (nframes, offset);
988 mapped.set (*t, m + 1);
992 /* outputs are mapped to inplace_bufs after the inputs */
993 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
994 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
997 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1002 /* all instances have completed, now copy data that was written
1003 * and zero unconnected buffers */
1004 ARDOUR::ChanMapping nonzero_out (used_outputs);
1005 if (has_midi_bypass ()) {
1006 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1008 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1009 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1011 used_outputs.get (*t, out, &valid);
1013 nonzero_out.get (*t, out, &valid);
1015 bufs.get (*t, out).silence (nframes, offset);
1018 uint32_t m = out + natural_input_streams ().get (*t);
1019 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
1024 /* in-place processing */
1026 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1027 if ((*i)->connect_and_run(bufs, start, end, speed, in_map[pc], out_map[pc], nframes, offset)) {
1031 // now silence unconnected outputs
1032 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1035 if (collect_signal_nframes > 0) {
1037 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
1038 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
1040 _signal_analysis_outputs.set_count(output_streams());
1042 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1043 _signal_analysis_outputs.get_audio(i).read_from(
1045 collect_signal_nframes,
1046 _signal_analysis_collected_nframes); // offset is for target buffer
1049 _signal_analysis_collected_nframes += collect_signal_nframes;
1050 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
1052 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
1053 _signal_analysis_collect_nframes_max = 0;
1054 _signal_analysis_collected_nframes = 0;
1056 AnalysisDataGathered(&_signal_analysis_inputs,
1057 &_signal_analysis_outputs);
1061 if (_plugin_signal_latency != signal_latency ()) {
1062 _plugin_signal_latency = signal_latency ();
1068 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1070 /* bypass the plugin(s) not the whole processor.
1071 * -> use mappings just like connect_and_run
1074 // TODO: atomically copy maps & _no_inplace
1075 const ChanMapping in_map (no_sc_input_map ());
1076 const ChanMapping out_map (output_map ());
1077 if (_mapping_changed) {
1078 _no_inplace = check_inplace ();
1079 _mapping_changed = false;
1082 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1083 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1086 ChanMapping thru_map (_thru_map);
1088 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1090 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1091 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1092 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
1095 ARDOUR::ChanMapping used_outputs;
1097 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1098 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1100 uint32_t in_idx = thru_map.get (*t, out, &valid);
1102 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1103 used_outputs.set (*t, out, 1); // mark as used
1107 // plugin no-op: assume every plugin has an internal identity map
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 src_idx = out_map.get_src (*t, out, &valid);
1115 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1119 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
1120 used_outputs.set (*t, out, 1); // mark as used
1123 // now silence all unused outputs
1124 if (has_midi_bypass ()) {
1125 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1127 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1128 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1130 used_outputs.get (*t, out, &valid);
1132 bufs.get (*t, out).silence (nframes, 0);
1137 if (_match.method == Split) {
1138 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1139 if (_configured_internal.get (*t) == 0) {
1142 // copy/feeds _all_ *connected* inputs, copy the first buffer
1144 uint32_t first_idx = in_map.get (*t, 0, &valid);
1145 assert (valid && first_idx == 0); // check_inplace ensures this
1146 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1147 uint32_t idx = in_map.get (*t, i, &valid);
1150 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
1156 // apply output map and/or monotonic but not identity i/o mappings
1157 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1158 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1160 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1162 bufs.get (*t, out).silence (nframes, 0);
1165 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1167 bufs.get (*t, out).silence (nframes, 0);
1170 if (in_idx != src_idx) {
1171 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
1179 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1181 automation_run (start_sample, nframes); // evaluate automation only
1184 // XXX delaybuffers need to be offset by nframes
1188 _delaybuffers.flush ();
1190 ChanMapping in_map (natural_input_streams ());
1191 ChanMapping out_map (natural_output_streams ());
1192 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1194 if (is_channelstrip ()) {
1195 if (_configured_in.n_audio() > 0) {
1196 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1200 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1201 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1206 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1209 // collect sidechain input for complete cycle (!)
1210 // TODO we need delaylines here for latency compensation
1211 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1214 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1215 _timing_stats.reset ();
1218 if (_pending_active) {
1219 _timing_stats.start ();
1220 /* run as normal if we are active or moving from inactive to active */
1222 if (_session.transport_rolling() || _session.bounce_processing()) {
1223 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1225 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1226 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1228 _timing_stats.update ();
1231 _timing_stats.reset ();
1232 // XXX should call ::silence() to run plugin(s) for consistent load.
1233 // We'll need to change this anyway when bypass can be automated
1234 bypass (bufs, nframes);
1235 automation_run (start_sample, nframes); // evaluate automation only
1236 _delaybuffers.flush ();
1239 _active = _pending_active;
1241 /* we have no idea whether the plugin generated silence or not, so mark
1242 * all buffers appropriately.
1247 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1249 Evoral::ControlEvent next_event (0, 0.0f);
1250 samplecnt_t offset = 0;
1252 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1255 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1259 /* map start back into loop-range, adjust end */
1260 map_loop_range (start, end);
1262 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1264 /* no events have a time within the relevant range */
1266 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1272 samplecnt_t cnt = min (((samplecnt_t) ceil (next_event.when) - start), (samplecnt_t) nframes);
1274 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1280 map_loop_range (start, end);
1282 if (!find_next_event (start, end, next_event)) {
1287 /* cleanup anything that is left to do */
1290 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1295 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1297 if (param.type() != PluginAutomation)
1300 if (_plugins.empty()) {
1301 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1303 abort(); /*NOTREACHED*/
1306 return _plugins[0]->default_value (param.id());
1311 PluginInsert::can_reset_all_parameters ()
1314 uint32_t params = 0;
1315 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1317 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1319 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1323 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1329 if (ac->automation_state() & Play) {
1334 return all && (params > 0);
1338 PluginInsert::reset_parameters_to_default ()
1342 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1344 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1346 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1350 const float dflt = _plugins[0]->default_value (cid);
1351 const float curr = _plugins[0]->get_parameter (cid);
1357 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1362 if (ac->automation_state() & Play) {
1367 ac->set_value (dflt, Controllable::NoGroup);
1372 boost::shared_ptr<Plugin>
1373 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1375 boost::shared_ptr<LadspaPlugin> lp;
1376 boost::shared_ptr<LuaProc> lua;
1378 boost::shared_ptr<LV2Plugin> lv2p;
1380 #ifdef WINDOWS_VST_SUPPORT
1381 boost::shared_ptr<WindowsVSTPlugin> vp;
1383 #ifdef LXVST_SUPPORT
1384 boost::shared_ptr<LXVSTPlugin> lxvp;
1386 #ifdef MACVST_SUPPORT
1387 boost::shared_ptr<MacVSTPlugin> mvp;
1389 #ifdef AUDIOUNIT_SUPPORT
1390 boost::shared_ptr<AUPlugin> ap;
1393 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1394 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1395 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1396 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1398 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1399 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1401 #ifdef WINDOWS_VST_SUPPORT
1402 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1403 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1405 #ifdef LXVST_SUPPORT
1406 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1407 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1409 #ifdef MACVST_SUPPORT
1410 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1411 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1413 #ifdef AUDIOUNIT_SUPPORT
1414 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1415 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1419 fatal << string_compose (_("programming error: %1"),
1420 X_("unknown plugin type in PluginInsert::plugin_factory"))
1422 abort(); /*NOTREACHED*/
1423 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1427 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1428 if (num < _in_map.size()) {
1429 bool changed = _in_map[num] != m;
1431 changed |= sanitize_maps ();
1433 PluginMapChanged (); /* EMIT SIGNAL */
1434 _mapping_changed = true;
1435 _session.set_dirty();
1441 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1442 if (num < _out_map.size()) {
1443 bool changed = _out_map[num] != m;
1445 changed |= sanitize_maps ();
1447 PluginMapChanged (); /* EMIT SIGNAL */
1448 _mapping_changed = true;
1449 _session.set_dirty();
1455 PluginInsert::set_thru_map (ChanMapping m) {
1456 bool changed = _thru_map != m;
1458 changed |= sanitize_maps ();
1460 PluginMapChanged (); /* EMIT SIGNAL */
1461 _mapping_changed = true;
1462 _session.set_dirty();
1467 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1468 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1470 if (_configured) { return false; }
1471 _configured_in = in;
1472 _configured_out = out;
1476 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1481 PluginInsert::input_map () const
1485 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1486 ChanMapping m (i->second);
1487 const ChanMapping::Mappings& mp ((*i).second.mappings());
1488 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1489 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1490 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1499 PluginInsert::no_sc_input_map () const
1503 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1504 ChanMapping m (i->second);
1505 const ChanMapping::Mappings& mp ((*i).second.mappings());
1506 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1507 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1508 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1509 if (i->first < ins) {
1510 rv.set (tm->first, i->first + pc * ins, i->second);
1519 PluginInsert::output_map () const
1523 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1524 ChanMapping m (i->second);
1525 const ChanMapping::Mappings& mp ((*i).second.mappings());
1526 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1527 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1528 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1532 if (has_midi_bypass ()) {
1533 rv.set (DataType::MIDI, 0, 0);
1540 PluginInsert::has_midi_bypass () const
1542 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1543 && natural_output_streams ().n_midi () == 0) {
1550 PluginInsert::has_midi_thru () const
1552 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1553 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1561 PluginInsert::is_channelstrip () const {
1562 return _plugins.front()->is_channelstrip();
1565 PluginInsert::is_nonbypassable () const {
1566 return _plugins.front()->is_nonbypassable ();
1571 PluginInsert::check_inplace ()
1573 bool inplace_ok = !_plugins.front()->inplace_broken ();
1575 if (_thru_map.n_total () > 0) {
1576 // TODO once midi-bypass is part of the mapping, ignore it
1580 if (_match.method == Split && inplace_ok) {
1581 assert (get_count() == 1);
1582 assert (_in_map.size () == 1);
1583 if (!_out_map[0].is_monotonic ()) {
1586 if (_configured_internal != _configured_in) {
1587 /* no sidechain -- TODO we could allow this with
1588 * some more logic in PluginInsert::connect_and_run().
1590 * PluginInsert::reset_map() already maps it.
1595 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1596 if (_configured_internal.get (*t) == 0) {
1600 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1601 if (!valid || first_idx != 0) {
1602 // so far only allow to copy the *first* stream's buffer to others
1605 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1606 uint32_t idx = _in_map[0].get (*t, i, &valid);
1607 if (valid && idx != first_idx) {
1616 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1621 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1622 if (!_in_map[pc].is_monotonic ()) {
1625 if (!_out_map[pc].is_monotonic ()) {
1631 /* check if every output is fed by the corresponding input
1633 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1634 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1636 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1638 ChanMapping in_map (input_map ());
1639 const ChanMapping::Mappings out_m (output_map ().mappings ());
1640 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1641 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1642 /* src-pin: c->first, out-port: c->second */
1644 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1645 if (valid && in_port != c->second) {
1653 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1654 return !inplace_ok; // no-inplace
1658 PluginInsert::sanitize_maps ()
1660 bool changed = false;
1661 /* strip dead wood */
1662 PinMappings new_ins;
1663 PinMappings new_outs;
1664 ChanMapping new_thru;
1666 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1668 ChanMapping new_out;
1669 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1670 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1672 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1673 if (valid && idx < _configured_internal.get (*t)) {
1674 new_in.set (*t, i, idx);
1677 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1679 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1680 if (valid && idx < _configured_out.get (*t)) {
1681 new_out.set (*t, o, idx);
1685 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1688 new_ins[pc] = new_in;
1689 new_outs[pc] = new_out;
1692 /* prevent dup output assignments */
1693 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1694 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1695 bool mapped = false;
1696 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1698 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1699 if (valid && mapped) {
1700 new_outs[pc].unset (*t, idx);
1708 /* remove excess thru */
1709 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1710 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1712 uint32_t idx = _thru_map.get (*t, o, &valid);
1713 if (valid && idx < _configured_internal.get (*t)) {
1714 new_thru.set (*t, o, idx);
1719 /* prevent out + thru, existing plugin outputs override thru */
1720 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1721 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1722 bool mapped = false;
1724 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1725 new_outs[pc].get_src (*t, o, &mapped);
1726 if (mapped) { break; }
1728 if (!mapped) { continue; }
1729 uint32_t idx = new_thru.get (*t, o, &valid);
1731 new_thru.unset (*t, idx);
1736 if (has_midi_bypass ()) {
1737 // TODO: include midi-bypass in the thru set,
1738 // remove dedicated handling.
1739 new_thru.unset (DataType::MIDI, 0);
1742 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1746 _out_map = new_outs;
1747 _thru_map = new_thru;
1753 PluginInsert::reset_map (bool emit)
1755 const PinMappings old_in (_in_map);
1756 const PinMappings old_out (_out_map);
1760 _thru_map = ChanMapping ();
1762 /* build input map */
1763 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1764 uint32_t sc = 0; // side-chain round-robin (all instances)
1766 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1767 const uint32_t nis = natural_input_streams ().get(*t);
1768 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1770 /* SC inputs are last in the plugin-insert.. */
1771 const uint32_t sc_start = _configured_in.get (*t);
1772 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1773 /* ...but may not be at the end of the plugin ports.
1774 * in case the side-chain is not the last port, shift connections back.
1775 * and connect to side-chain
1778 uint32_t ic = 0; // split inputs
1779 const uint32_t cend = _configured_in.get (*t);
1781 for (uint32_t in = 0; in < nis; ++in) {
1782 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1783 if (iod.is_sidechain) {
1784 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1785 if (sc_len > 0) {// side-chain may be hidden
1786 _in_map[pc].set (*t, in, sc_start + sc);
1787 sc = (sc + 1) % sc_len;
1791 if (_match.method == Split) {
1792 if (cend == 0) { continue; }
1793 if (_strict_io && ic + stride * pc >= cend) {
1796 /* connect *no* sidechain sinks in round-robin fashion */
1797 _in_map[pc].set (*t, in, ic + stride * pc);
1798 if (_strict_io && (ic + 1) == cend) {
1801 ic = (ic + 1) % cend;
1803 uint32_t s = in - shift;
1804 if (stride * pc + s < cend) {
1805 _in_map[pc].set (*t, in, s + stride * pc);
1813 /* build output map */
1815 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1816 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1817 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1818 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1823 if (old_in == _in_map && old_out == _out_map) {
1827 PluginMapChanged (); /* EMIT SIGNAL */
1828 _mapping_changed = true;
1829 _session.set_dirty();
1835 PluginInsert::configure_io (ChanCount in, ChanCount out)
1837 Match old_match = _match;
1839 ChanCount old_internal;
1843 old_pins = natural_input_streams();
1844 old_in = _configured_in;
1845 old_out = _configured_out;
1846 old_internal = _configured_internal;
1848 _configured_in = in;
1849 _configured_internal = in;
1850 _configured_out = out;
1853 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1854 * (currently _sidechain->configure_io always succeeds
1855 * since Processor::configure_io() succeeds)
1857 if (!_sidechain->configure_io (in, out)) {
1858 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1861 _configured_internal += _sidechain->input()->n_ports();
1863 // include (static_cast<Route*>owner())->name() ??
1864 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1867 /* get plugin configuration */
1868 _match = private_can_support_io_configuration (in, out);
1870 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1872 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1873 DEBUG_STR_APPEND(a, _match);
1874 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1878 /* set the matching method and number of plugins that we will use to meet this configuration */
1879 if (set_count (_match.plugins) == false) {
1880 PluginIoReConfigure (); /* EMIT SIGNAL */
1881 _configured = false;
1885 /* configure plugins */
1886 switch (_match.method) {
1889 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1890 PluginIoReConfigure (); /* EMIT SIGNAL */
1891 _configured = false;
1897 ChanCount din (_configured_internal);
1898 ChanCount dout (din); // hint
1900 if (_custom_sinks.n_total () > 0) {
1901 din = _custom_sinks;
1904 } else if (_preset_out.n_audio () > 0) {
1905 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1906 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1907 dout.set (DataType::AUDIO, 2);
1909 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1911 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1912 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1914 if (useins.n_audio() == 0) {
1917 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1919 if (_plugins.front()->configure_io (useins, dout) == false) {
1920 PluginIoReConfigure (); /* EMIT SIGNAL */
1921 _configured = false;
1925 _custom_sinks = din;
1930 if (_plugins.front()->configure_io (in, out) == false) {
1931 PluginIoReConfigure (); /* EMIT SIGNAL */
1932 _configured = false;
1938 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",
1940 _configured ? "Y" : "N",
1941 _maps_from_state ? "Y" : "N",
1942 old_in == in ? "==" : "!=",
1943 old_out == out ? "==" : "!=",
1944 old_pins == natural_input_streams () ? "==" : "!=",
1945 old_match.method == _match.method ? "==" : "!=",
1946 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1947 _in_map.size() == get_count () ? "==" : "!=",
1948 _out_map.size() == get_count () ? "==" : "!="
1951 bool mapping_changed = false;
1952 if (old_in == in && old_out == out
1954 && old_pins == natural_input_streams ()
1955 && old_match.method == _match.method
1956 && old_match.custom_cfg == _match.custom_cfg
1957 && _in_map.size() == _out_map.size()
1958 && _in_map.size() == get_count ()
1960 /* If the configuration has not changed, keep the mapping */
1961 mapping_changed = sanitize_maps ();
1962 } else if (_match.custom_cfg && _configured) {
1963 /* don't touch the map in manual mode */
1964 mapping_changed = sanitize_maps ();
1967 if (is_channelstrip ()) {
1968 /* fake channel map - for wire display */
1971 _thru_map = ChanMapping ();
1972 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1973 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1974 /* set "thru" map for in-place forward of audio */
1975 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1976 _thru_map.set (DataType::AUDIO, i, i);
1978 /* and midi (after implicit 1st channel bypass) */
1979 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1980 _thru_map.set (DataType::MIDI, i, i);
1984 if (_maps_from_state && old_in == in && old_out == out) {
1985 mapping_changed = true;
1988 /* generate a new mapping */
1989 mapping_changed = reset_map (false);
1991 _maps_from_state = false;
1994 if (mapping_changed) {
1995 PluginMapChanged (); /* EMIT SIGNAL */
1998 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2001 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2002 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2004 DEBUG_STR_APPEND(a, "----><----\n");
2006 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2007 DEBUG_STR_APPEND(a, " * Inputs:\n");
2008 DEBUG_STR_APPEND(a, _in_map[pc]);
2009 DEBUG_STR_APPEND(a, " * Outputs:\n");
2010 DEBUG_STR_APPEND(a, _out_map[pc]);
2012 DEBUG_STR_APPEND(a, " * Thru:\n");
2013 DEBUG_STR_APPEND(a, _thru_map);
2014 DEBUG_STR_APPEND(a, "-------->>--------\n");
2015 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2020 _no_inplace = check_inplace ();
2021 _mapping_changed = false;
2023 /* only the "noinplace_buffers" thread buffers need to be this large,
2024 * this can be optimized. other buffers are fine with
2025 * ChanCount::max (natural_input_streams (), natural_output_streams())
2026 * and route.cc's max (configured_in, configured_out)
2028 * no-inplace copies "thru" outputs (to emulate in-place) for
2029 * all outputs (to prevent overwrite) into a temporary space
2030 * which also holds input buffers (in case the plugin does process
2031 * in-place and overwrites those).
2033 * this buffers need to be at least as
2034 * natural_input_streams () + possible outputs.
2036 * sidechain inputs add a constraint on the input:
2037 * configured input + sidechain (=_configured_internal)
2039 * NB. this also satisfies
2040 * max (natural_input_streams(), natural_output_streams())
2041 * which is needed for silence runs
2043 _required_buffers = ChanCount::max (_configured_internal,
2044 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2046 if (old_in != in || old_out != out || old_internal != _configured_internal
2047 || old_pins != natural_input_streams ()
2048 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2050 PluginIoReConfigure (); /* EMIT SIGNAL */
2053 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2054 _latency_changed = true;
2056 // we don't know the analysis window size, so we must work with the
2057 // current buffer size here. each request for data fills in these
2058 // buffers and the analyser makes sure it gets enough data for the
2060 session().ensure_buffer_set (_signal_analysis_inputs, in);
2061 _signal_analysis_inputs.set_count (in);
2063 session().ensure_buffer_set (_signal_analysis_outputs, out);
2064 _signal_analysis_outputs.set_count (out);
2066 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2069 return Processor::configure_io (in, out);
2072 /** Decide whether this PluginInsert can support a given IO configuration.
2073 * To do this, we run through a set of possible solutions in rough order of
2076 * @param in Required input channel count.
2077 * @param out Filled in with the output channel count if we return true.
2078 * @return true if the given IO configuration can be supported.
2081 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2084 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2086 return private_can_support_io_configuration (in, out).method != Impossible;
2090 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2092 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2093 // preseed hint (for variable i/o)
2094 out.set (DataType::AUDIO, _preset_out.n_audio ());
2097 Match rv = internal_can_support_io_configuration (in, out);
2099 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2100 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2101 out.set (DataType::AUDIO, _preset_out.n_audio ());
2106 /** A private version of can_support_io_configuration which returns the method
2107 * by which the configuration can be matched, rather than just whether or not
2111 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2113 if (_plugins.empty()) {
2118 if (is_channelstrip ()) {
2120 return Match (ExactMatch, 1);
2124 /* if a user specified a custom cfg, so be it. */
2126 PluginInfoPtr info = _plugins.front()->get_info();
2128 if (info->reconfigurable_io()) {
2129 return Match (Delegate, 1, _strict_io, true);
2131 return Match (ExactMatch, get_count(), _strict_io, true);
2135 /* try automatic configuration */
2136 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2138 PluginInfoPtr info = _plugins.front()->get_info();
2139 ChanCount inputs = info->n_inputs;
2140 ChanCount outputs = info->n_outputs;
2142 /* handle case strict-i/o */
2143 if (_strict_io && m.method != Impossible) {
2146 /* special case MIDI instruments */
2147 if (is_instrument ()) {
2148 // output = midi-bypass + at most master-out channels.
2149 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2150 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2151 out = ChanCount::min (out, max_out);
2152 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2158 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2159 /* replicate processor to match output count (generators and such)
2160 * at least enough to feed every output port. */
2161 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2162 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2163 uint32_t nout = outputs.get (*t);
2164 if (nout == 0 || inx.get(*t) == 0) { continue; }
2165 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2168 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2169 return Match (Replicate, f, _strict_io);
2180 if (m.method != Impossible) {
2184 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2186 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2188 if (info->reconfigurable_io()) {
2191 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2192 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2193 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
2195 // houston, we have a problem.
2196 return Match (Impossible, 0);
2199 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2200 return Match (Delegate, 1, _strict_io);
2203 ChanCount midi_bypass;
2204 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2205 midi_bypass.set (DataType::MIDI, 1);
2208 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2210 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2211 uint32_t nin = ns_inputs.get (*t);
2212 uint32_t nout = outputs.get (*t);
2213 if (nin == 0 || inx.get(*t) == 0) { continue; }
2214 // prefer floor() so the count won't overly increase IFF (nin < nout)
2215 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2217 if (f > 0 && outputs * f >= _configured_out) {
2218 out = outputs * f + midi_bypass;
2219 return Match (Replicate, f, _strict_io);
2222 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2224 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2225 uint32_t nin = ns_inputs.get (*t);
2226 if (nin == 0 || inx.get(*t) == 0) { continue; }
2227 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2230 out = outputs * f + midi_bypass;
2231 return Match (Replicate, f, _strict_io);
2234 // add at least as many plugins needed to connect all inputs
2236 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2237 uint32_t nin = inputs.get (*t);
2238 if (nin == 0 || inx.get(*t) == 0) { continue; }
2239 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 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2247 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2249 if (_plugins.empty()) {
2253 PluginInfoPtr info = _plugins.front()->get_info();
2254 ChanCount in; in += inx;
2255 ChanCount midi_bypass;
2257 if (info->reconfigurable_io()) {
2258 /* Plugin has flexible I/O, so delegate to it
2259 * pre-seed outputs, plugin tries closest match
2262 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2263 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2264 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2266 return Match (Impossible, 0);
2269 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2270 return Match (Delegate, 1);
2273 ChanCount inputs = info->n_inputs;
2274 ChanCount outputs = info->n_outputs;
2275 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2277 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2278 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2279 midi_bypass.set (DataType::MIDI, 1);
2281 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2282 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2283 in.set(DataType::MIDI, 0);
2286 // add internally provided sidechain ports
2287 ChanCount insc = in + sidechain_input_ports ();
2289 bool no_inputs = true;
2290 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2291 if (inputs.get (*t) != 0) {
2298 /* no inputs so we can take any input configuration since we throw it away */
2299 out = outputs + midi_bypass;
2300 return Match (NoInputs, 1);
2303 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2304 if (inputs == insc) {
2305 out = outputs + midi_bypass;
2306 return Match (ExactMatch, 1);
2309 /* Plugin inputs matches without side-chain-pins */
2310 if (ns_inputs == in) {
2311 out = outputs + midi_bypass;
2312 return Match (ExactMatch, 1);
2315 /* We may be able to run more than one copy of the plugin within this insert
2316 to cope with the insert having more inputs than the plugin.
2317 We allow replication only for plugins with either zero or 1 inputs and outputs
2318 for every valid data type.
2322 bool can_replicate = true;
2323 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2325 // ignore side-chains
2326 uint32_t nin = ns_inputs.get (*t);
2328 // No inputs of this type
2329 if (nin == 0 && in.get(*t) == 0) {
2333 if (nin != 1 || outputs.get (*t) != 1) {
2334 can_replicate = false;
2338 // Potential factor not set yet
2340 f = in.get(*t) / nin;
2343 // Factor for this type does not match another type, can not replicate
2344 if (f != (in.get(*t) / nin)) {
2345 can_replicate = false;
2350 if (can_replicate && f > 0) {
2351 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2352 out.set (*t, outputs.get(*t) * f);
2355 return Match (Replicate, f);
2358 /* If the processor has exactly one input of a given type, and
2359 the plugin has more, we can feed the single processor input
2360 to some or all of the plugin inputs. This is rather
2361 special-case-y, but the 1-to-many case is by far the
2362 simplest. How do I split thy 2 processor inputs to 3
2363 plugin inputs? Let me count the ways ...
2366 bool can_split = true;
2367 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2369 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2370 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2372 if (!can_split_type && !nothing_to_do_for_type) {
2378 out = outputs + midi_bypass;
2379 return Match (Split, 1);
2382 /* If the plugin has more inputs than we want, we can `hide' some of them
2383 by feeding them silence.
2386 bool could_hide = false;
2387 bool cannot_hide = false;
2388 ChanCount hide_channels;
2390 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2391 if (inputs.get(*t) > in.get(*t)) {
2392 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2393 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2395 } else if (inputs.get(*t) < in.get(*t)) {
2396 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2401 if (could_hide && !cannot_hide) {
2402 out = outputs + midi_bypass;
2403 return Match (Hide, 1, false, false, hide_channels);
2406 return Match (Impossible, 0);
2411 PluginInsert::state ()
2413 XMLNode& node = Processor::state ();
2415 node.set_property("type", _plugins[0]->state_node_name());
2416 node.set_property("unique-id", _plugins[0]->unique_id());
2417 node.set_property("count", (uint32_t)_plugins.size());
2419 /* remember actual i/o configuration (for later placeholder
2420 * in case the plugin goes missing) */
2421 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2422 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2423 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2424 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2426 /* save custom i/o config */
2427 node.set_property("custom", _custom_cfg);
2428 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2430 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2431 node.add_child_nocopy (* _in_map[pc].state (tmp));
2432 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2433 node.add_child_nocopy (* _out_map[pc].state (tmp));
2435 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2438 node.add_child_nocopy (_sidechain->get_state ());
2441 _plugins[0]->set_insert_id(this->id());
2442 node.add_child_nocopy (_plugins[0]->get_state());
2444 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2445 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2447 node.add_child_nocopy (ac->get_state());
2455 PluginInsert::set_control_ids (const XMLNode& node, int version)
2457 const XMLNodeList& nlist = node.children();
2458 XMLNodeConstIterator iter;
2459 set<Evoral::Parameter>::const_iterator p;
2461 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2462 if ((*iter)->name() == Controllable::xml_node_name) {
2464 uint32_t p = (uint32_t)-1;
2467 if ((*iter)->get_property (X_("symbol"), str)) {
2468 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2470 p = lv2plugin->port_index(str.c_str());
2474 if (p == (uint32_t)-1) {
2475 (*iter)->get_property (X_("parameter"), p);
2478 if (p != (uint32_t)-1) {
2480 /* this may create the new controllable */
2482 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2484 #ifndef NO_PLUGIN_STATE
2488 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2490 ac->set_state (**iter, version);
2499 PluginInsert::set_state(const XMLNode& node, int version)
2501 XMLNodeList nlist = node.children();
2502 XMLNodeIterator niter;
2503 XMLPropertyList plist;
2504 ARDOUR::PluginType type;
2507 if (!node.get_property ("type", str)) {
2508 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2512 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2513 type = ARDOUR::LADSPA;
2514 } else if (str == X_("lv2")) {
2516 } else if (str == X_("windows-vst")) {
2517 type = ARDOUR::Windows_VST;
2518 } else if (str == X_("lxvst")) {
2519 type = ARDOUR::LXVST;
2520 } else if (str == X_("mac-vst")) {
2521 type = ARDOUR::MacVST;
2522 } else if (str == X_("audiounit")) {
2523 type = ARDOUR::AudioUnit;
2524 } else if (str == X_("luaproc")) {
2527 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2531 XMLProperty const * prop = node.property ("unique-id");
2534 #ifdef WINDOWS_VST_SUPPORT
2535 /* older sessions contain VST plugins with only an "id" field. */
2536 if (type == ARDOUR::Windows_VST) {
2537 prop = node.property ("id");
2541 #ifdef LXVST_SUPPORT
2542 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2543 if (type == ARDOUR::LXVST) {
2544 prop = node.property ("id");
2551 error << _("Plugin has no unique ID field") << endmsg;
2556 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2557 bool any_vst = false;
2559 /* treat VST plugins equivalent if they have the same uniqueID
2560 * allow to move sessions windows <> linux */
2561 #ifdef LXVST_SUPPORT
2562 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2563 type = ARDOUR::LXVST;
2564 plugin = find_plugin (_session, prop->value(), type);
2565 if (plugin) { any_vst = true; }
2569 #ifdef WINDOWS_VST_SUPPORT
2570 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2571 type = ARDOUR::Windows_VST;
2572 plugin = find_plugin (_session, prop->value(), type);
2573 if (plugin) { any_vst = true; }
2577 #ifdef MACVST_SUPPORT
2578 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2579 type = ARDOUR::MacVST;
2580 plugin = find_plugin (_session, prop->value(), type);
2581 if (plugin) { any_vst = true; }
2585 if (plugin == 0 && type == ARDOUR::Lua) {
2586 /* unique ID (sha1 of script) was not found,
2587 * load the plugin from the serialized version in the
2588 * session-file instead.
2590 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2591 XMLNode *ls = node.child (lp->state_node_name().c_str());
2593 lp->set_script_from_state (*ls);
2599 error << string_compose(
2600 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2601 "Perhaps it was removed or moved since it was last used."),
2607 // The name of the PluginInsert comes from the plugin, nothing else
2608 _name = plugin->get_info()->name;
2612 // Processor::set_state() will set this, but too late
2613 // for it to be available when setting up plugin
2614 // state. We can't call Processor::set_state() until
2615 // the plugins themselves are created and added.
2619 if (_plugins.empty()) {
2620 /* if we are adding the first plugin, we will need to set
2621 up automatable controls.
2623 add_plugin (plugin);
2624 create_automatable_parameters ();
2625 set_control_ids (node, version);
2628 node.get_property ("count", count);
2630 if (_plugins.size() != count) {
2631 for (uint32_t n = 1; n < count; ++n) {
2632 add_plugin (plugin_factory (plugin));
2636 Processor::set_state (node, version);
2638 PBD::ID new_id = this->id();
2639 PBD::ID old_id = this->id();
2641 node.get_property ("id", old_id);
2643 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2645 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2646 and set all plugins to the same state.
2649 if ( ((*niter)->name() == plugin->state_node_name())
2650 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2653 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2654 /* Plugin state can include external files which are named after the ID.
2656 * If regenerate_xml_or_string_ids() is set, the ID will already have
2657 * been changed, so we need to use the old ID from the XML to load the
2658 * state and then update the ID.
2660 * When copying a plugin-state, route_ui takes care of of updating the ID,
2661 * but we need to call set_insert_id() to clear the cached plugin-state
2662 * and force a change.
2664 if (!regenerate_xml_or_string_ids ()) {
2665 (*i)->set_insert_id (new_id);
2667 (*i)->set_insert_id (old_id);
2670 (*i)->set_state (**niter, version);
2672 if (regenerate_xml_or_string_ids ()) {
2673 (*i)->set_insert_id (new_id);
2677 /* when copying plugin state, notify UI */
2678 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2679 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2681 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2689 if (version < 3000) {
2691 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2692 this is all handled by Automatable
2695 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2696 if ((*niter)->name() == "Redirect") {
2697 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2698 Processor::set_state (**niter, version);
2703 set_parameter_state_2X (node, version);
2706 node.get_property (X_("custom"), _custom_cfg);
2708 uint32_t in_maps = 0;
2709 uint32_t out_maps = 0;
2710 XMLNodeList kids = node.children ();
2711 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2712 if ((*i)->name() == X_("ConfiguredInput")) {
2713 _configured_in = ChanCount(**i);
2715 if ((*i)->name() == X_("CustomSinks")) {
2716 _custom_sinks = ChanCount(**i);
2718 if ((*i)->name() == X_("ConfiguredOutput")) {
2719 _custom_out = ChanCount(**i);
2720 _configured_out = ChanCount(**i);
2722 if ((*i)->name() == X_("PresetOutput")) {
2723 _preset_out = ChanCount(**i);
2725 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2726 long pc = atol (&((*i)->name().c_str()[9]));
2727 if (pc >= 0 && pc <= (long) get_count()) {
2728 _in_map[pc] = ChanMapping (**i);
2732 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2733 long pc = atol (&((*i)->name().c_str()[10]));
2734 if (pc >= 0 && pc <= (long) get_count()) {
2735 _out_map[pc] = ChanMapping (**i);
2739 if ((*i)->name () == "ThruMap") {
2740 _thru_map = ChanMapping (**i);
2743 // sidechain is a Processor (IO)
2744 if ((*i)->name () == Processor::state_node_name) {
2748 if (!regenerate_xml_or_string_ids ()) {
2749 _sidechain->set_state (**i, version);
2754 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2755 _maps_from_state = true;
2758 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2762 (*i)->deactivate ();
2766 PluginConfigChanged (); /* EMIT SIGNAL */
2771 PluginInsert::update_id (PBD::ID id)
2774 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2775 (*i)->set_insert_id (id);
2780 PluginInsert::set_owner (SessionObject* o)
2782 Processor::set_owner (o);
2783 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2784 (*i)->set_owner (o);
2789 PluginInsert::set_state_dir (const std::string& d)
2791 // state() only saves the state of the first plugin
2792 _plugins[0]->set_state_dir (d);
2796 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2798 XMLNodeList nlist = node.children();
2799 XMLNodeIterator niter;
2801 /* look for port automation node */
2803 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2805 if ((*niter)->name() != port_automation_node_name) {
2810 XMLNodeConstIterator iter;
2814 cnodes = (*niter)->children ("port");
2816 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2820 if (!child->get_property("number", port_id)) {
2821 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2825 if (port_id >= _plugins[0]->parameter_count()) {
2826 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2830 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2831 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2833 if (c && c->alist()) {
2834 if (!child->children().empty()) {
2835 c->alist()->set_state (*child->children().front(), version);
2838 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2848 boost::shared_ptr<ReadOnlyControl>
2849 PluginInsert::control_output (uint32_t num) const
2851 CtrlOutMap::const_iterator i = _control_outputs.find (num);
2852 if (i == _control_outputs.end ()) {
2853 return boost::shared_ptr<ReadOnlyControl> ();
2860 PluginInsert::describe_parameter (Evoral::Parameter param)
2862 if (param.type() == PluginAutomation) {
2863 return _plugins[0]->describe_parameter (param);
2864 } else if (param.type() == PluginPropertyAutomation) {
2865 boost::shared_ptr<AutomationControl> c(automation_control(param));
2866 if (c && !c->desc().label.empty()) {
2867 return c->desc().label;
2870 return Automatable::describe_parameter(param);
2874 PluginInsert::signal_latency() const
2876 if (!_pending_active) {
2879 if (_user_latency) {
2880 return _user_latency;
2883 return _plugins[0]->signal_latency ();
2887 PluginInsert::type ()
2889 return plugin()->get_info()->type;
2892 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2893 const Evoral::Parameter& param,
2894 const ParameterDescriptor& desc,
2895 boost::shared_ptr<AutomationList> list)
2896 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2901 list->set_interpolation(Evoral::ControlList::Discrete);
2906 /** @param val `user' value */
2909 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2911 /* FIXME: probably should be taking out some lock here.. */
2913 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2914 (*i)->set_parameter (_list->parameter().id(), user_val);
2917 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2919 iasp->set_parameter (_list->parameter().id(), user_val);
2922 AutomationControl::actually_set_value (user_val, group_override);
2926 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2928 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2932 PluginInsert::PluginControl::get_state ()
2934 XMLNode& node (AutomationControl::get_state());
2935 node.set_property (X_("parameter"), parameter().id());
2937 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2939 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2946 /** @return `user' val */
2948 PluginInsert::PluginControl::get_value () const
2950 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2956 return plugin->get_parameter (_list->parameter().id());
2959 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2960 const Evoral::Parameter& param,
2961 const ParameterDescriptor& desc,
2962 boost::shared_ptr<AutomationList> list)
2963 : AutomationControl (p->session(), param, desc, list)
2969 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
2971 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2972 This is lossy, but better than nothing until Ardour's automation system
2973 can handle various datatypes all the way down. */
2974 const Variant value(_desc.datatype, user_val);
2975 if (value.type() == Variant::NOTHING) {
2976 error << "set_value(double) called for non-numeric property" << endmsg;
2980 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2981 (*i)->set_property(_list->parameter().id(), value);
2986 AutomationControl::actually_set_value (user_val, gcd);
2990 PluginInsert::PluginPropertyControl::get_state ()
2992 XMLNode& node (AutomationControl::get_state());
2993 node.set_property (X_("property"), parameter().id());
2994 node.remove_property (X_("value"));
3000 PluginInsert::PluginPropertyControl::get_value () const
3002 return _value.to_double();
3005 boost::shared_ptr<Plugin>
3006 PluginInsert::get_impulse_analysis_plugin()
3008 boost::shared_ptr<Plugin> ret;
3009 if (_impulseAnalysisPlugin.expired()) {
3010 // LV2 in particular uses various _session params
3011 // during init() -- most notably block_size..
3013 ret = plugin_factory(_plugins[0]);
3014 ChanCount out (internal_output_streams ());
3015 if (ret->get_info ()->reconfigurable_io ()) {
3016 // populate get_info ()->n_inputs and ->n_outputs
3018 ret->can_support_io_configuration (internal_input_streams (), out, &useins);
3019 assert (out == internal_output_streams ());
3021 ret->configure_io (internal_input_streams (), out);
3022 ret->set_owner (_owner);
3023 _impulseAnalysisPlugin = ret;
3025 ret = _impulseAnalysisPlugin.lock();
3032 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3034 // called from outside the audio thread, so this should be safe
3035 // only do audio as analysis is (currently) only for audio plugins
3036 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3037 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3039 _signal_analysis_collected_nframes = 0;
3040 _signal_analysis_collect_nframes_max = nframes;
3043 /** Add a plugin to our list */
3045 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3047 plugin->set_insert_id (this->id());
3048 plugin->set_owner (_owner);
3050 if (_plugins.empty()) {
3051 /* first (and probably only) plugin instance - connect to relevant signals */
3053 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3054 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3055 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3056 _custom_sinks = plugin->get_info()->n_inputs;
3057 // cache sidechain port count
3058 _cached_sidechain_pins.reset ();
3059 const ChanCount& nis (plugin->get_info()->n_inputs);
3060 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3061 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3062 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3063 if (iod.is_sidechain) {
3064 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3069 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3070 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3072 vst->set_insert (this, _plugins.size ());
3076 _plugins.push_back (plugin);
3080 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3083 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3084 if (! (*i)->load_preset (pr)) {
3092 PluginInsert::realtime_handle_transport_stopped ()
3094 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3095 (*i)->realtime_handle_transport_stopped ();
3100 PluginInsert::realtime_locate ()
3102 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3103 (*i)->realtime_locate ();
3108 PluginInsert::monitoring_changed ()
3110 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3111 (*i)->monitoring_changed ();
3116 PluginInsert::latency_changed ()
3118 // this is called in RT context, LatencyChanged is emitted after run()
3119 _latency_changed = true;
3120 // XXX This also needs a proper API not an owner() hack.
3122 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3126 PluginInsert::start_touch (uint32_t param_id)
3128 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3130 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3131 ac->start_touch (session().audible_sample());
3136 PluginInsert::end_touch (uint32_t param_id)
3138 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3140 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3141 ac->stop_touch (session().audible_sample());
3146 PluginInsert::get_stats (uint64_t& min, uint64_t& max, double& avg, double& dev) const
3148 /* TODO: consider taking a try/lock: Don't run concurrently with
3149 * TimingStats::update, TimingStats::reset.
3151 return _timing_stats.get_stats (min, max, avg, dev);
3155 PluginInsert::clear_stats ()
3157 g_atomic_int_set (&_stat_reset, 1);
3160 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3163 case PluginInsert::Impossible: o << "Impossible"; break;
3164 case PluginInsert::Delegate: o << "Delegate"; break;
3165 case PluginInsert::NoInputs: o << "NoInputs"; break;
3166 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3167 case PluginInsert::Replicate: o << "Replicate"; break;
3168 case PluginInsert::Split: o << "Split"; break;
3169 case PluginInsert::Hide: o << "Hide"; break;
3171 o << " cnt: " << m.plugins
3172 << (m.strict_io ? " strict-io" : "")
3173 << (m.custom_cfg ? " custom-cfg" : "");
3174 if (m.method == PluginInsert::Hide) {
3175 o << " hide: " << m.hide;