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/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"
53 #ifdef AUDIOUNIT_SUPPORT
54 #include "ardour/audio_unit.h"
57 #include "ardour/session.h"
58 #include "ardour/types.h"
63 using namespace ARDOUR;
66 const string PluginInsert::port_automation_node_name = "PortAutomation";
68 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
69 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
70 , _sc_playback_latency (0)
71 , _sc_capture_latency (0)
72 , _signal_analysis_collected_nframes(0)
73 , _signal_analysis_collect_nframes_max(0)
78 , _maps_from_state (false)
80 /* the first is the master */
84 create_automatable_parameters ();
85 const ChanCount& sc (sidechain_input_pins ());
86 if (sc.n_audio () > 0) {
87 add_sidechain (sc.n_audio ());
92 PluginInsert::~PluginInsert ()
97 PluginInsert::set_strict_io (bool b)
99 bool changed = _strict_io != b;
102 PluginConfigChanged (); /* EMIT SIGNAL */
107 PluginInsert::set_count (uint32_t num)
109 bool require_state = !_plugins.empty();
111 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
112 // we don't allow to replicate AUs
116 /* this is a bad idea.... we shouldn't do this while active.
117 * only a route holding their redirect_lock should be calling this
122 } else if (num > _plugins.size()) {
123 uint32_t diff = num - _plugins.size();
125 for (uint32_t n = 0; n < diff; ++n) {
126 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
130 XMLNode& state = _plugins[0]->get_state ();
131 p->set_state (state, Stateful::loading_state_version);
138 PluginConfigChanged (); /* EMIT SIGNAL */
140 } else if (num < _plugins.size()) {
141 uint32_t diff = _plugins.size() - num;
142 for (uint32_t n= 0; n < diff; ++n) {
145 PluginConfigChanged (); /* EMIT SIGNAL */
153 PluginInsert::set_sinks (const ChanCount& c)
156 /* no signal, change will only be visible after re-config */
160 PluginInsert::set_outputs (const ChanCount& c)
162 bool changed = (_custom_out != c) && _custom_cfg;
165 PluginConfigChanged (); /* EMIT SIGNAL */
170 PluginInsert::set_custom_cfg (bool b)
172 bool changed = _custom_cfg != b;
175 PluginConfigChanged (); /* EMIT SIGNAL */
180 PluginInsert::set_preset_out (const ChanCount& c)
182 bool changed = _preset_out != c;
184 if (changed && !_custom_cfg) {
185 PluginConfigChanged (); /* EMIT SIGNAL */
191 PluginInsert::add_sidechain (uint32_t n_audio)
193 // caller must hold process lock
197 std::ostringstream n;
199 n << "Sidechain " << Session::next_name_id ();
201 n << "TO BE RESET FROM XML";
203 SideChain *sc = new SideChain (_session, n.str ());
204 _sidechain = boost::shared_ptr<SideChain> (sc);
205 _sidechain->activate ();
206 for (uint32_t n = 0; n < n_audio; ++n) {
207 _sidechain->input()->add_port ("", owner()); // add a port, don't connect.
209 PluginConfigChanged (); /* EMIT SIGNAL */
214 PluginInsert::del_sidechain ()
220 _sc_playback_latency = 0;
221 _sc_capture_latency = 0;
222 PluginConfigChanged (); /* EMIT SIGNAL */
227 PluginInsert::set_sidechain_latency (uint32_t capture, uint32_t playback)
230 (_sc_playback_latency != playback || _sc_capture_latency != capture)) {
231 _sc_capture_latency = capture;
232 _sc_playback_latency = playback;
233 LatencyRange pl; pl.min = pl.max = playback;
234 LatencyRange cl; cl.min = cl.max = capture;
235 DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: capture %2 playback; %3\n", _sidechain->name (), capture, playback));
236 PortSet& ps (_sidechain->input ()->ports ());
237 for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
238 p->set_private_latency_range (pl, true);
239 p->set_private_latency_range (cl, false);
245 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
247 if (which.type() != PluginAutomation)
250 boost::shared_ptr<AutomationControl> c
251 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
254 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
259 PluginInsert::output_streams() const
261 assert (_configured);
262 return _configured_out;
266 PluginInsert::input_streams() const
268 assert (_configured);
269 return _configured_in;
273 PluginInsert::internal_streams() const
275 assert (_configured);
276 return _configured_internal;
280 PluginInsert::internal_output_streams() const
282 assert (!_plugins.empty());
284 PluginInfoPtr info = _plugins.front()->get_info();
286 if (info->reconfigurable_io()) {
287 ChanCount out = _plugins.front()->output_streams ();
288 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
291 ChanCount out = info->n_outputs;
292 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
293 out.set_audio (out.n_audio() * _plugins.size());
294 out.set_midi (out.n_midi() * _plugins.size());
300 PluginInsert::internal_input_streams() const
302 assert (!_plugins.empty());
306 PluginInfoPtr info = _plugins.front()->get_info();
308 if (info->reconfigurable_io()) {
309 in = _plugins.front()->input_streams();
314 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
316 if (_match.method == Split) {
318 /* we are splitting 1 processor input to multiple plugin inputs,
319 so we have a maximum of 1 stream of each type.
321 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
322 if (in.get (*t) > 1) {
328 } else if (_match.method == Hide) {
330 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
331 in.set (*t, in.get (*t) - _match.hide.get (*t));
337 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
338 in.set (*t, in.get (*t) * _plugins.size ());
346 PluginInsert::natural_output_streams() const
349 if (is_channelstrip ()) {
350 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
353 return _plugins[0]->get_info()->n_outputs;
357 PluginInsert::natural_input_streams() const
360 if (is_channelstrip ()) {
361 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
364 return _plugins[0]->get_info()->n_inputs;
368 PluginInsert::sidechain_input_pins() const
370 return _cached_sidechain_pins;
374 PluginInsert::has_no_inputs() const
376 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
380 PluginInsert::has_no_audio_inputs() const
382 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
386 PluginInsert::plugin_latency () const {
387 return _plugins.front()->signal_latency ();
391 PluginInsert::needs_midi_input() const
393 PluginInfoPtr pip = _plugins[0]->get_info();
394 if (pip->needs_midi_input ()) {
397 return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
401 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
403 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
404 // collect possible configurations, prefer given in/out
405 _plugins[0]->can_support_io_configuration (in, out);
408 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
410 if (ppc.size () == 0) {
413 if (!strict_io () && ppc.size () == 1) {
417 if (strict_io () && ppc.size () == 1) {
418 // "stereo" is currently preferred default for instruments
419 if (ppc.find (2) != ppc.end ()) {
423 if (!needs_midi_input ()) {
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) || !plugin->parameter_is_input (i)) {
441 Evoral::Parameter param (PluginAutomation, 0, i);
443 ParameterDescriptor desc;
444 plugin->get_parameter_descriptor(i, desc);
446 const bool automatable = a.find(param) != a.end();
449 can_automate (param);
451 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
452 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
454 c->set_flags (Controllable::Flag ((int)c->flags() | Controllable::NotAutomatable));
457 plugin->set_automation_control (i, c);
460 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
461 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
462 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
463 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
464 if (desc.datatype != Variant::NOTHING) {
465 boost::shared_ptr<AutomationList> list;
466 if (Variant::type_is_numeric(desc.datatype)) {
467 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
469 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
473 /** Called when something outside of this host has modified a plugin
474 * parameter. Responsible for propagating the change to two places:
476 * 1) anything listening to the Control itself
477 * 2) any replicated plugins that make up this PluginInsert.
479 * The PluginInsert is connected to the ParameterChangedExternally signal for
480 * the first (primary) plugin, and here broadcasts that change to any others.
482 * XXX We should probably drop this whole replication idea (Paul, October 2015)
483 * since it isn't used by sensible plugin APIs (AU, LV2).
486 PluginInsert::parameter_changed_externally (uint32_t which, float val)
488 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
490 /* First propagation: alter the underlying value of the control,
491 * without telling the plugin(s) that own/use it to set it.
498 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
501 pc->catch_up_with_external_value (val);
504 /* Second propagation: tell all plugins except the first to
505 update the value of this parameter. For sane plugin APIs,
506 there are no other plugins, so this is a no-op in those
510 Plugins::iterator i = _plugins.begin();
512 /* don't set the first plugin, just all the slaves */
514 if (i != _plugins.end()) {
516 for (; i != _plugins.end(); ++i) {
517 (*i)->set_parameter (which, val);
523 PluginInsert::set_block_size (pframes_t nframes)
526 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
527 if ((*i)->set_block_size (nframes) != 0) {
535 PluginInsert::activate ()
537 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
541 Processor::activate ();
545 PluginInsert::deactivate ()
547 Processor::deactivate ();
549 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
555 PluginInsert::flush ()
557 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
563 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, framecnt_t nframes, framecnt_t offset) const
565 // TODO optimize: store "unconnected" in a fixed set.
566 // it only changes on reconfiguration.
567 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
568 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
570 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
571 mapped = true; // in-place Midi bypass
573 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
574 PinMappings::const_iterator i = out_map.find (pc);
575 if (i == out_map.end ()) {
578 const ChanMapping& outmap (i->second);
579 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
581 uint32_t idx = outmap.get (*t, o, &valid);
582 if (valid && idx == out) {
589 bufs.get (*t, out).silence (nframes, offset);
596 PluginInsert::connect_and_run (BufferSet& bufs, framepos_t start, framepos_t end, double speed, pframes_t nframes, framecnt_t offset, bool with_auto)
598 // TODO: atomically copy maps & _no_inplace
599 PinMappings in_map (_in_map);
600 PinMappings out_map (_out_map);
601 ChanMapping thru_map (_thru_map);
602 if (_mapping_changed) { // ToDo use a counters, increment until match.
603 _no_inplace = check_inplace ();
604 _mapping_changed = false;
607 if (_latency_changed) {
608 /* delaylines are configured with the max possible latency (as reported by the plugin)
609 * so this won't allocate memory (unless the plugin lied about its max latency)
610 * It may still 'click' though, since the fixed delaylines are not de-clicked.
611 * Then again plugin-latency changes are not click-free to begin with.
613 * This is also worst case, there is currently no concept of per-stream latency.
615 * e.g. Two identical latent plugins:
616 * 1st plugin: process left (latent), bypass right.
617 * 2nd plugin: bypass left, process right (latent).
618 * -> currently this yields 2 times latency of the plugin,
620 _latency_changed = false;
621 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
624 if (_match.method == Split && !_no_inplace) {
625 // TODO: also use this optimization if one source-buffer
626 // feeds _all_ *connected* inputs.
627 // currently this is *first* buffer to all only --
628 // see PluginInsert::check_inplace
629 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
630 if (_configured_internal.get (*t) == 0) {
634 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
635 assert (valid && first_idx == 0); // check_inplace ensures this
636 /* copy the first stream's buffer contents to the others */
637 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
638 uint32_t idx = in_map[0].get (*t, i, &valid);
641 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
645 /* the copy operation produces a linear monotonic input map */
646 in_map[0] = ChanMapping (natural_input_streams ());
649 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
650 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
656 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
658 boost::shared_ptr<AutomationControl> c
659 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
661 if (c->list() && c->automation_playback()) {
664 const float val = c->list()->rt_safe_eval (start, valid);
667 /* This is the ONLY place where we are
669 * AutomationControl::set_value_unchecked(). We
670 * know that the control is in
671 * automation playback mode, so no
672 * check on writable() is required
673 * (which must be done in AutomationControl::set_value()
676 c->set_value_unchecked(val);
683 /* Calculate if, and how many frames we need to collect for analysis */
684 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
685 _signal_analysis_collected_nframes);
686 if (nframes < collect_signal_nframes) { // we might not get all frames now
687 collect_signal_nframes = nframes;
690 if (collect_signal_nframes > 0) {
692 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
693 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
694 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
696 _signal_analysis_inputs.set_count(input_streams());
698 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
699 _signal_analysis_inputs.get_audio(i).read_from (
701 collect_signal_nframes,
702 _signal_analysis_collected_nframes); // offset is for target buffer
707 if (is_channelstrip ()) {
708 if (_configured_in.n_audio() > 0) {
709 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
710 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
712 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
714 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
715 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
721 // TODO optimize -- build maps once.
723 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
724 ARDOUR::ChanMapping used_outputs;
726 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
728 /* build used-output map */
729 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
730 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
731 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
733 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
735 used_outputs.set (*t, out_idx, 1); // mark as used
740 /* copy thru data to outputs before processing in-place */
741 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
742 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
744 uint32_t in_idx = thru_map.get (*t, out, &valid);
745 uint32_t m = out + natural_input_streams ().get (*t);
747 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
748 used_outputs.set (*t, out, 1); // mark as used
750 used_outputs.get (*t, out, &valid);
752 /* the plugin is expected to write here, but may not :(
753 * (e.g. drumgizmo w/o kit loaded)
755 inplace_bufs.get (*t, m).silence (nframes);
762 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
764 ARDOUR::ChanMapping i_in_map (natural_input_streams());
765 ARDOUR::ChanMapping i_out_map (out_map[pc]);
766 ARDOUR::ChanCount mapped;
768 /* map inputs sequentially */
769 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
770 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
772 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
773 uint32_t m = mapped.get (*t);
775 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
777 inplace_bufs.get (*t, m).silence (nframes, offset);
779 mapped.set (*t, m + 1);
783 /* outputs are mapped to inplace_bufs after the inputs */
784 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
785 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
788 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
793 /* all instances have completed, now copy data that was written
794 * and zero unconnected buffers */
795 ARDOUR::ChanMapping nonzero_out (used_outputs);
796 if (has_midi_bypass ()) {
797 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
799 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
800 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
802 used_outputs.get (*t, out, &valid);
804 nonzero_out.get (*t, out, &valid);
806 bufs.get (*t, out).silence (nframes, offset);
809 uint32_t m = out + natural_input_streams ().get (*t);
810 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
815 /* in-place processing */
817 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
818 if ((*i)->connect_and_run(bufs, start, end, speed, in_map[pc], out_map[pc], nframes, offset)) {
822 // now silence unconnected outputs
823 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
826 if (collect_signal_nframes > 0) {
828 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
829 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
831 _signal_analysis_outputs.set_count(output_streams());
833 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
834 _signal_analysis_outputs.get_audio(i).read_from(
836 collect_signal_nframes,
837 _signal_analysis_collected_nframes); // offset is for target buffer
840 _signal_analysis_collected_nframes += collect_signal_nframes;
841 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
843 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
844 _signal_analysis_collect_nframes_max = 0;
845 _signal_analysis_collected_nframes = 0;
847 AnalysisDataGathered(&_signal_analysis_inputs,
848 &_signal_analysis_outputs);
854 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
856 /* bypass the plugin(s) not the whole processor.
857 * -> use mappings just like connect_and_run
860 // TODO: atomically copy maps & _no_inplace
861 const ChanMapping in_map (no_sc_input_map ());
862 const ChanMapping out_map (output_map ());
863 if (_mapping_changed) {
864 _no_inplace = check_inplace ();
865 _mapping_changed = false;
868 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
869 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
872 ChanMapping thru_map (_thru_map);
874 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
876 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
877 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
878 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
881 ARDOUR::ChanMapping used_outputs;
883 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
884 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
886 uint32_t in_idx = thru_map.get (*t, out, &valid);
888 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
889 used_outputs.set (*t, out, 1); // mark as used
893 // plugin no-op: assume every plugin has an internal identity map
894 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
895 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
897 uint32_t src_idx = out_map.get_src (*t, out, &valid);
901 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
905 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
906 used_outputs.set (*t, out, 1); // mark as used
909 // now silence all unused outputs
910 if (has_midi_bypass ()) {
911 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
913 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
914 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
916 used_outputs.get (*t, out, &valid);
918 bufs.get (*t, out).silence (nframes, 0);
923 if (_match.method == Split) {
924 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
925 if (_configured_internal.get (*t) == 0) {
928 // copy/feeds _all_ *connected* inputs, copy the first buffer
930 uint32_t first_idx = in_map.get (*t, 0, &valid);
931 assert (valid && first_idx == 0); // check_inplace ensures this
932 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
933 uint32_t idx = in_map.get (*t, i, &valid);
936 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
942 // apply output map and/or monotonic but not identity i/o mappings
943 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
944 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
946 uint32_t src_idx = out_map.get_src (*t, out, &valid);
948 bufs.get (*t, out).silence (nframes, 0);
951 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
953 bufs.get (*t, out).silence (nframes, 0);
956 if (in_idx != src_idx) {
957 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
965 PluginInsert::silence (framecnt_t nframes, framepos_t start_frame)
971 _delaybuffers.flush ();
973 ChanMapping in_map (natural_input_streams ());
974 ChanMapping out_map (natural_output_streams ());
975 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
977 if (is_channelstrip ()) {
978 if (_configured_in.n_audio() > 0) {
979 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_frame, start_frame + nframes, 1.0, in_map, out_map, nframes, 0);
983 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
984 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_frame, start_frame + nframes, 1.0, in_map, out_map, nframes, 0);
989 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
992 // collect sidechain input for complete cycle (!)
993 // TODO we need delaylines here for latency compensation
994 _sidechain->run (bufs, start_frame, end_frame, speed, nframes, true);
997 if (_pending_active) {
998 /* run as normal if we are active or moving from inactive to active */
1000 if (_session.transport_rolling() || _session.bounce_processing()) {
1001 automation_run (bufs, start_frame, end_frame, speed, nframes);
1003 connect_and_run (bufs, start_frame, end_frame, speed, nframes, 0, false);
1007 bypass (bufs, nframes);
1008 _delaybuffers.flush ();
1011 _active = _pending_active;
1013 /* we have no idea whether the plugin generated silence or not, so mark
1014 * all buffers appropriately.
1019 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, framepos_t end, double speed, pframes_t nframes)
1021 Evoral::ControlEvent next_event (0, 0.0f);
1022 framecnt_t offset = 0;
1024 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1027 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1031 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1033 /* no events have a time within the relevant range */
1035 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1041 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - start), (framecnt_t) nframes);
1043 connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
1049 if (!find_next_event (start, end, next_event)) {
1054 /* cleanup anything that is left to do */
1057 connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
1062 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1064 if (param.type() != PluginAutomation)
1067 if (_plugins.empty()) {
1068 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1070 abort(); /*NOTREACHED*/
1073 return _plugins[0]->default_value (param.id());
1078 PluginInsert::can_reset_all_parameters ()
1081 uint32_t params = 0;
1082 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1084 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1086 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1090 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1096 if (ac->automation_state() & Play) {
1101 return all && (params > 0);
1105 PluginInsert::reset_parameters_to_default ()
1109 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1111 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1113 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1117 const float dflt = _plugins[0]->default_value (cid);
1118 const float curr = _plugins[0]->get_parameter (cid);
1124 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1129 if (ac->automation_state() & Play) {
1134 ac->set_value (dflt, Controllable::NoGroup);
1139 boost::shared_ptr<Plugin>
1140 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1142 boost::shared_ptr<LadspaPlugin> lp;
1143 boost::shared_ptr<LuaProc> lua;
1145 boost::shared_ptr<LV2Plugin> lv2p;
1147 #ifdef WINDOWS_VST_SUPPORT
1148 boost::shared_ptr<WindowsVSTPlugin> vp;
1150 #ifdef LXVST_SUPPORT
1151 boost::shared_ptr<LXVSTPlugin> lxvp;
1153 #ifdef AUDIOUNIT_SUPPORT
1154 boost::shared_ptr<AUPlugin> ap;
1157 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1158 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1159 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1160 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1162 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1163 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1165 #ifdef WINDOWS_VST_SUPPORT
1166 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1167 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1169 #ifdef LXVST_SUPPORT
1170 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1171 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1173 #ifdef AUDIOUNIT_SUPPORT
1174 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1175 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1179 fatal << string_compose (_("programming error: %1"),
1180 X_("unknown plugin type in PluginInsert::plugin_factory"))
1182 abort(); /*NOTREACHED*/
1183 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1187 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1188 if (num < _in_map.size()) {
1189 bool changed = _in_map[num] != m;
1191 changed |= sanitize_maps ();
1193 PluginMapChanged (); /* EMIT SIGNAL */
1194 _mapping_changed = true;
1195 _session.set_dirty();
1201 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1202 if (num < _out_map.size()) {
1203 bool changed = _out_map[num] != m;
1205 changed |= sanitize_maps ();
1207 PluginMapChanged (); /* EMIT SIGNAL */
1208 _mapping_changed = true;
1209 _session.set_dirty();
1215 PluginInsert::set_thru_map (ChanMapping m) {
1216 bool changed = _thru_map != m;
1218 changed |= sanitize_maps ();
1220 PluginMapChanged (); /* EMIT SIGNAL */
1221 _mapping_changed = true;
1222 _session.set_dirty();
1227 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1228 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1230 if (_configured) { return false; }
1231 _configured_in = in;
1232 _configured_out = out;
1236 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1241 PluginInsert::input_map () const
1245 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1246 ChanMapping m (i->second);
1247 const ChanMapping::Mappings& mp ((*i).second.mappings());
1248 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1249 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1250 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1259 PluginInsert::no_sc_input_map () const
1263 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1264 ChanMapping m (i->second);
1265 const ChanMapping::Mappings& mp ((*i).second.mappings());
1266 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1267 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1268 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1269 if (i->second < ins) {
1270 rv.set (tm->first, i->first + pc * ins, i->second);
1279 PluginInsert::output_map () const
1283 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1284 ChanMapping m (i->second);
1285 const ChanMapping::Mappings& mp ((*i).second.mappings());
1286 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1287 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1288 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1292 if (has_midi_bypass ()) {
1293 rv.set (DataType::MIDI, 0, 0);
1300 PluginInsert::has_midi_bypass () const
1302 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1303 && natural_output_streams ().n_midi () == 0) {
1310 PluginInsert::has_midi_thru () const
1312 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1313 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1321 PluginInsert::is_channelstrip () const {
1322 return _plugins.front()->is_channelstrip();
1327 PluginInsert::check_inplace ()
1329 bool inplace_ok = !_plugins.front()->inplace_broken ();
1331 if (_thru_map.n_total () > 0) {
1332 // TODO once midi-bypass is part of the mapping, ignore it
1336 if (_match.method == Split && inplace_ok) {
1337 assert (get_count() == 1);
1338 assert (_in_map.size () == 1);
1339 if (!_out_map[0].is_monotonic ()) {
1342 if (_configured_internal != _configured_in) {
1343 /* no sidechain -- TODO we could allow this with
1344 * some more logic in PluginInsert::connect_and_run().
1346 * PluginInsert::reset_map() already maps it.
1351 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1352 if (_configured_internal.get (*t) == 0) {
1356 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1357 if (!valid || first_idx != 0) {
1358 // so far only allow to copy the *first* stream's buffer to others
1361 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1362 uint32_t idx = _in_map[0].get (*t, i, &valid);
1363 if (valid && idx != first_idx) {
1372 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1377 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1378 if (!_in_map[pc].is_monotonic ()) {
1381 if (!_out_map[pc].is_monotonic ()) {
1387 /* check if every output is fed by the corresponding input
1389 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1390 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1392 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1394 ChanMapping in_map (input_map ());
1395 const ChanMapping::Mappings out_m (output_map ().mappings ());
1396 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1397 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1398 /* src-pin: c->first, out-port: c->second */
1400 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1401 if (valid && in_port != c->second) {
1409 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1410 return !inplace_ok; // no-inplace
1414 PluginInsert::sanitize_maps ()
1416 bool changed = false;
1417 /* strip dead wood */
1418 PinMappings new_ins;
1419 PinMappings new_outs;
1420 ChanMapping new_thru;
1422 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1424 ChanMapping new_out;
1425 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1426 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1428 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1429 if (valid && idx < _configured_internal.get (*t)) {
1430 new_in.set (*t, i, idx);
1433 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1435 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1436 if (valid && idx < _configured_out.get (*t)) {
1437 new_out.set (*t, o, idx);
1441 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1444 new_ins[pc] = new_in;
1445 new_outs[pc] = new_out;
1448 /* prevent dup output assignments */
1449 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1450 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1451 bool mapped = false;
1452 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1454 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1455 if (valid && mapped) {
1456 new_outs[pc].unset (*t, idx);
1464 /* remove excess thru */
1465 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1466 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1468 uint32_t idx = _thru_map.get (*t, o, &valid);
1469 if (valid && idx < _configured_internal.get (*t)) {
1470 new_thru.set (*t, o, idx);
1475 /* prevent out + thru, existing plugin outputs override thru */
1476 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1477 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1478 bool mapped = false;
1480 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1481 new_outs[pc].get_src (*t, o, &mapped);
1482 if (mapped) { break; }
1484 if (!mapped) { continue; }
1485 uint32_t idx = new_thru.get (*t, o, &valid);
1487 new_thru.unset (*t, idx);
1492 if (has_midi_bypass ()) {
1493 // TODO: include midi-bypass in the thru set,
1494 // remove dedicated handling.
1495 new_thru.unset (DataType::MIDI, 0);
1498 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1502 _out_map = new_outs;
1503 _thru_map = new_thru;
1509 PluginInsert::reset_map (bool emit)
1511 const PinMappings old_in (_in_map);
1512 const PinMappings old_out (_out_map);
1516 _thru_map = ChanMapping ();
1518 /* build input map */
1519 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1520 uint32_t sc = 0; // side-chain round-robin (all instances)
1522 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1523 const uint32_t nis = natural_input_streams ().get(*t);
1524 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1526 /* SC inputs are last in the plugin-insert.. */
1527 const uint32_t sc_start = _configured_in.get (*t);
1528 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1529 /* ...but may not be at the end of the plugin ports.
1530 * in case the side-chain is not the last port, shift connections back.
1531 * and connect to side-chain
1534 uint32_t ic = 0; // split inputs
1535 const uint32_t cend = _configured_in.get (*t);
1537 for (uint32_t in = 0; in < nis; ++in) {
1538 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1539 if (iod.is_sidechain) {
1540 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1541 if (sc_len > 0) {// side-chain may be hidden
1542 _in_map[pc].set (*t, in, sc_start + sc);
1543 sc = (sc + 1) % sc_len;
1547 if (_match.method == Split) {
1548 if (cend == 0) { continue; }
1549 if (_strict_io && ic + stride * pc >= cend) {
1552 /* connect *no* sidechain sinks in round-robin fashion */
1553 _in_map[pc].set (*t, in, ic + stride * pc);
1554 if (_strict_io && (ic + 1) == cend) {
1557 ic = (ic + 1) % cend;
1559 uint32_t s = in - shift;
1560 if (stride * pc + s < cend) {
1561 _in_map[pc].set (*t, in, s + stride * pc);
1569 /* build output map */
1571 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1572 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1573 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1574 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1579 if (old_in == _in_map && old_out == _out_map) {
1583 PluginMapChanged (); /* EMIT SIGNAL */
1584 _mapping_changed = true;
1585 _session.set_dirty();
1591 PluginInsert::configure_io (ChanCount in, ChanCount out)
1593 Match old_match = _match;
1595 ChanCount old_internal;
1599 old_pins = natural_input_streams();
1600 old_in = _configured_in;
1601 old_out = _configured_out;
1602 old_internal = _configured_internal;
1604 _configured_in = in;
1605 _configured_internal = in;
1606 _configured_out = out;
1609 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1610 * (currently _sidechain->configure_io always succeeds
1611 * since Processor::configure_io() succeeds)
1613 if (!_sidechain->configure_io (in, out)) {
1614 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1617 _configured_internal += _sidechain->input()->n_ports();
1619 // include (static_cast<Route*>owner())->name() ??
1620 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1623 /* get plugin configuration */
1624 _match = private_can_support_io_configuration (in, out);
1626 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1628 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1629 DEBUG_STR_APPEND(a, _match);
1630 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1634 /* set the matching method and number of plugins that we will use to meet this configuration */
1635 if (set_count (_match.plugins) == false) {
1636 PluginIoReConfigure (); /* EMIT SIGNAL */
1637 _configured = false;
1641 /* configure plugins */
1642 switch (_match.method) {
1645 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1646 PluginIoReConfigure (); /* EMIT SIGNAL */
1647 _configured = false;
1653 ChanCount din (_configured_internal);
1654 ChanCount dout (din); // hint
1656 if (_custom_sinks.n_total () > 0) {
1657 din = _custom_sinks;
1660 } else if (_preset_out.n_audio () > 0) {
1661 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1662 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1663 dout.set (DataType::AUDIO, 2);
1665 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1667 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1668 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1670 if (useins.n_audio() == 0) {
1673 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1675 if (_plugins.front()->configure_io (useins, dout) == false) {
1676 PluginIoReConfigure (); /* EMIT SIGNAL */
1677 _configured = false;
1681 _custom_sinks = din;
1686 if (_plugins.front()->configure_io (in, out) == false) {
1687 PluginIoReConfigure (); /* EMIT SIGNAL */
1688 _configured = false;
1694 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",
1696 _configured ? "Y" : "N",
1697 _maps_from_state ? "Y" : "N",
1698 old_in == in ? "==" : "!=",
1699 old_out == out ? "==" : "!=",
1700 old_pins == natural_input_streams () ? "==" : "!=",
1701 old_match.method == _match.method ? "==" : "!=",
1702 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1703 _in_map.size() == get_count () ? "==" : "!=",
1704 _out_map.size() == get_count () ? "==" : "!="
1707 bool mapping_changed = false;
1708 if (old_in == in && old_out == out
1710 && old_pins == natural_input_streams ()
1711 && old_match.method == _match.method
1712 && old_match.custom_cfg == _match.custom_cfg
1713 && _in_map.size() == _out_map.size()
1714 && _in_map.size() == get_count ()
1716 assert (_maps_from_state == false);
1717 /* If the configuration has not changed, keep the mapping */
1718 mapping_changed = sanitize_maps ();
1719 } else if (_match.custom_cfg && _configured) {
1720 assert (_maps_from_state == false);
1721 /* don't touch the map in manual mode */
1722 mapping_changed = sanitize_maps ();
1725 if (is_channelstrip ()) {
1726 /* fake channel map - for wire display */
1729 _thru_map = ChanMapping ();
1730 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1731 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1732 /* set "thru" map for in-place forward of audio */
1733 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1734 _thru_map.set (DataType::AUDIO, i, i);
1736 /* and midi (after implicit 1st channel bypass) */
1737 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1738 _thru_map.set (DataType::MIDI, i, i);
1742 if (_maps_from_state && old_in == in && old_out == out) {
1743 mapping_changed = true;
1746 /* generate a new mapping */
1747 mapping_changed = reset_map (false);
1749 _maps_from_state = false;
1752 if (mapping_changed) {
1753 PluginMapChanged (); /* EMIT SIGNAL */
1756 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1759 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1760 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1762 DEBUG_STR_APPEND(a, "----><----\n");
1764 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1765 DEBUG_STR_APPEND(a, " * Inputs:\n");
1766 DEBUG_STR_APPEND(a, _in_map[pc]);
1767 DEBUG_STR_APPEND(a, " * Outputs:\n");
1768 DEBUG_STR_APPEND(a, _out_map[pc]);
1770 DEBUG_STR_APPEND(a, " * Thru:\n");
1771 DEBUG_STR_APPEND(a, _thru_map);
1772 DEBUG_STR_APPEND(a, "-------->>--------\n");
1773 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1778 _no_inplace = check_inplace ();
1779 _mapping_changed = false;
1781 /* only the "noinplace_buffers" thread buffers need to be this large,
1782 * this can be optimized. other buffers are fine with
1783 * ChanCount::max (natural_input_streams (), natural_output_streams())
1784 * and route.cc's max (configured_in, configured_out)
1786 * no-inplace copies "thru" outputs (to emulate in-place) for
1787 * all outputs (to prevent overwrite) into a temporary space
1788 * which also holds input buffers (in case the plugin does process
1789 * in-place and overwrites those).
1791 * this buffers need to be at least as
1792 * natural_input_streams () + possible outputs.
1794 * sidechain inputs add a constraint on the input:
1795 * configured input + sidechain (=_configured_internal)
1797 * NB. this also satisfies
1798 * max (natural_input_streams(), natural_output_streams())
1799 * which is needed for silence runs
1801 _required_buffers = ChanCount::max (_configured_internal,
1802 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1804 if (old_in != in || old_out != out || old_internal != _configured_internal
1805 || old_pins != natural_input_streams ()
1806 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1808 PluginIoReConfigure (); /* EMIT SIGNAL */
1811 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
1812 _latency_changed = true;
1814 // we don't know the analysis window size, so we must work with the
1815 // current buffer size here. each request for data fills in these
1816 // buffers and the analyser makes sure it gets enough data for the
1818 session().ensure_buffer_set (_signal_analysis_inputs, in);
1819 _signal_analysis_inputs.set_count (in);
1821 session().ensure_buffer_set (_signal_analysis_outputs, out);
1822 _signal_analysis_outputs.set_count (out);
1824 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1827 return Processor::configure_io (in, out);
1830 /** Decide whether this PluginInsert can support a given IO configuration.
1831 * To do this, we run through a set of possible solutions in rough order of
1834 * @param in Required input channel count.
1835 * @param out Filled in with the output channel count if we return true.
1836 * @return true if the given IO configuration can be supported.
1839 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1842 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1844 return private_can_support_io_configuration (in, out).method != Impossible;
1848 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1850 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1851 // preseed hint (for variable i/o)
1852 out.set (DataType::AUDIO, _preset_out.n_audio ());
1855 Match rv = internal_can_support_io_configuration (in, out);
1857 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1858 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
1859 out.set (DataType::AUDIO, _preset_out.n_audio ());
1864 /** A private version of can_support_io_configuration which returns the method
1865 * by which the configuration can be matched, rather than just whether or not
1869 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1871 if (_plugins.empty()) {
1876 if (is_channelstrip ()) {
1878 return Match (ExactMatch, 1);
1882 /* if a user specified a custom cfg, so be it. */
1884 PluginInfoPtr info = _plugins.front()->get_info();
1886 if (info->reconfigurable_io()) {
1887 return Match (Delegate, 1, _strict_io, true);
1889 return Match (ExactMatch, get_count(), _strict_io, true);
1893 /* try automatic configuration */
1894 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1896 PluginInfoPtr info = _plugins.front()->get_info();
1897 ChanCount inputs = info->n_inputs;
1898 ChanCount outputs = info->n_outputs;
1900 /* handle case strict-i/o */
1901 if (_strict_io && m.method != Impossible) {
1904 /* special case MIDI instruments */
1905 if (needs_midi_input ()) {
1906 // output = midi-bypass + at most master-out channels.
1907 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1908 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1909 out = ChanCount::min (out, max_out);
1910 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
1916 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1917 /* replicate processor to match output count (generators and such)
1918 * at least enough to feed every output port. */
1919 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1920 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1921 uint32_t nout = outputs.get (*t);
1922 if (nout == 0 || inx.get(*t) == 0) { continue; }
1923 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1926 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
1927 return Match (Replicate, f, _strict_io);
1938 if (m.method != Impossible) {
1942 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1944 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
1946 if (info->reconfigurable_io()) {
1949 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1950 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1951 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
1953 // houston, we have a problem.
1954 return Match (Impossible, 0);
1957 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
1958 return Match (Delegate, 1, _strict_io);
1961 ChanCount midi_bypass;
1962 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1963 midi_bypass.set (DataType::MIDI, 1);
1966 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1968 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1969 uint32_t nin = ns_inputs.get (*t);
1970 uint32_t nout = outputs.get (*t);
1971 if (nin == 0 || inx.get(*t) == 0) { continue; }
1972 // prefer floor() so the count won't overly increase IFF (nin < nout)
1973 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1975 if (f > 0 && outputs * f >= _configured_out) {
1976 out = outputs * f + midi_bypass;
1977 return Match (Replicate, f, _strict_io);
1980 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1982 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1983 uint32_t nin = ns_inputs.get (*t);
1984 if (nin == 0 || inx.get(*t) == 0) { continue; }
1985 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1988 out = outputs * f + midi_bypass;
1989 return Match (Replicate, f, _strict_io);
1992 // add at least as many plugins needed to connect all inputs
1994 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1995 uint32_t nin = inputs.get (*t);
1996 if (nin == 0 || inx.get(*t) == 0) { continue; }
1997 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1999 out = outputs * f + midi_bypass;
2000 return Match (Replicate, f, _strict_io);
2003 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2005 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2007 if (_plugins.empty()) {
2011 PluginInfoPtr info = _plugins.front()->get_info();
2012 ChanCount in; in += inx;
2013 ChanCount midi_bypass;
2015 if (info->reconfigurable_io()) {
2016 /* Plugin has flexible I/O, so delegate to it
2017 * pre-seed outputs, plugin tries closest match
2020 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2021 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2022 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
2024 return Match (Impossible, 0);
2027 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2028 return Match (Delegate, 1);
2031 ChanCount inputs = info->n_inputs;
2032 ChanCount outputs = info->n_outputs;
2033 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2035 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2036 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2037 midi_bypass.set (DataType::MIDI, 1);
2039 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2040 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2041 in.set(DataType::MIDI, 0);
2044 // add internally provided sidechain ports
2045 ChanCount insc = in + sidechain_input_ports ();
2047 bool no_inputs = true;
2048 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2049 if (inputs.get (*t) != 0) {
2056 /* no inputs so we can take any input configuration since we throw it away */
2057 out = outputs + midi_bypass;
2058 return Match (NoInputs, 1);
2061 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2062 if (inputs == insc) {
2063 out = outputs + midi_bypass;
2064 return Match (ExactMatch, 1);
2067 /* Plugin inputs matches without side-chain-pins */
2068 if (ns_inputs == in) {
2069 out = outputs + midi_bypass;
2070 return Match (ExactMatch, 1);
2073 /* We may be able to run more than one copy of the plugin within this insert
2074 to cope with the insert having more inputs than the plugin.
2075 We allow replication only for plugins with either zero or 1 inputs and outputs
2076 for every valid data type.
2080 bool can_replicate = true;
2081 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
2083 // ignore side-chains
2084 uint32_t nin = ns_inputs.get (*t);
2086 // No inputs of this type
2087 if (nin == 0 && in.get(*t) == 0) {
2091 if (nin != 1 || outputs.get (*t) != 1) {
2092 can_replicate = false;
2096 // Potential factor not set yet
2098 f = in.get(*t) / nin;
2101 // Factor for this type does not match another type, can not replicate
2102 if (f != (in.get(*t) / nin)) {
2103 can_replicate = false;
2108 if (can_replicate && f > 0) {
2109 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2110 out.set (*t, outputs.get(*t) * f);
2113 return Match (Replicate, f);
2116 /* If the processor has exactly one input of a given type, and
2117 the plugin has more, we can feed the single processor input
2118 to some or all of the plugin inputs. This is rather
2119 special-case-y, but the 1-to-many case is by far the
2120 simplest. How do I split thy 2 processor inputs to 3
2121 plugin inputs? Let me count the ways ...
2124 bool can_split = true;
2125 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2127 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2128 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2130 if (!can_split_type && !nothing_to_do_for_type) {
2136 out = outputs + midi_bypass;
2137 return Match (Split, 1);
2140 /* If the plugin has more inputs than we want, we can `hide' some of them
2141 by feeding them silence.
2144 bool could_hide = false;
2145 bool cannot_hide = false;
2146 ChanCount hide_channels;
2148 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2149 if (inputs.get(*t) > in.get(*t)) {
2150 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2151 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2153 } else if (inputs.get(*t) < in.get(*t)) {
2154 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2159 if (could_hide && !cannot_hide) {
2160 out = outputs + midi_bypass;
2161 return Match (Hide, 1, false, false, hide_channels);
2164 return Match (Impossible, 0);
2169 PluginInsert::get_state ()
2171 return state (true);
2175 PluginInsert::state (bool full)
2177 XMLNode& node = Processor::state (full);
2179 node.add_property("type", _plugins[0]->state_node_name());
2180 node.add_property("unique-id", _plugins[0]->unique_id());
2181 node.add_property("count", string_compose("%1", _plugins.size()));
2183 /* remember actual i/o configuration (for later placeholder
2184 * in case the plugin goes missing) */
2185 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2186 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2187 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2188 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2190 /* save custom i/o config */
2191 node.add_property("custom", _custom_cfg ? "yes" : "no");
2192 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2194 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2195 node.add_child_nocopy (* _in_map[pc].state (tmp));
2196 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2197 node.add_child_nocopy (* _out_map[pc].state (tmp));
2199 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2202 node.add_child_nocopy (_sidechain->state (full));
2205 _plugins[0]->set_insert_id(this->id());
2206 node.add_child_nocopy (_plugins[0]->get_state());
2208 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2209 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2211 node.add_child_nocopy (ac->get_state());
2219 PluginInsert::set_control_ids (const XMLNode& node, int version)
2221 const XMLNodeList& nlist = node.children();
2222 XMLNodeConstIterator iter;
2223 set<Evoral::Parameter>::const_iterator p;
2225 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2226 if ((*iter)->name() == Controllable::xml_node_name) {
2227 XMLProperty const * prop;
2229 uint32_t p = (uint32_t)-1;
2231 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
2232 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2234 p = lv2plugin->port_index(prop->value().c_str());
2238 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
2239 p = atoi (prop->value());
2242 if (p != (uint32_t)-1) {
2244 /* this may create the new controllable */
2246 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2248 #ifndef NO_PLUGIN_STATE
2252 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2254 ac->set_state (**iter, version);
2263 PluginInsert::set_state(const XMLNode& node, int version)
2265 XMLNodeList nlist = node.children();
2266 XMLNodeIterator niter;
2267 XMLPropertyList plist;
2268 XMLProperty const * prop;
2269 ARDOUR::PluginType type;
2271 if ((prop = node.property ("type")) == 0) {
2272 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2276 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
2277 type = ARDOUR::LADSPA;
2278 } else if (prop->value() == X_("lv2")) {
2280 } else if (prop->value() == X_("windows-vst")) {
2281 type = ARDOUR::Windows_VST;
2282 } else if (prop->value() == X_("lxvst")) {
2283 type = ARDOUR::LXVST;
2284 } else if (prop->value() == X_("audiounit")) {
2285 type = ARDOUR::AudioUnit;
2286 } else if (prop->value() == X_("luaproc")) {
2289 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2295 prop = node.property ("unique-id");
2298 #ifdef WINDOWS_VST_SUPPORT
2299 /* older sessions contain VST plugins with only an "id" field.
2302 if (type == ARDOUR::Windows_VST) {
2303 prop = node.property ("id");
2307 #ifdef LXVST_SUPPORT
2308 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2310 if (type == ARDOUR::LXVST) {
2311 prop = node.property ("id");
2317 error << _("Plugin has no unique ID field") << endmsg;
2322 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2324 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2325 * allow to move sessions windows <> linux */
2326 #ifdef LXVST_SUPPORT
2327 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2328 type = ARDOUR::LXVST;
2329 plugin = find_plugin (_session, prop->value(), type);
2333 #ifdef WINDOWS_VST_SUPPORT
2334 if (plugin == 0 && type == ARDOUR::LXVST) {
2335 type = ARDOUR::Windows_VST;
2336 plugin = find_plugin (_session, prop->value(), type);
2340 if (plugin == 0 && type == ARDOUR::Lua) {
2341 /* unique ID (sha1 of script) was not found,
2342 * load the plugin from the serialized version in the
2343 * session-file instead.
2345 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2346 XMLNode *ls = node.child (lp->state_node_name().c_str());
2348 lp->set_script_from_state (*ls);
2354 error << string_compose(
2355 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2356 "Perhaps it was removed or moved since it was last used."),
2362 // The name of the PluginInsert comes from the plugin, nothing else
2363 _name = plugin->get_info()->name;
2367 // Processor::set_state() will set this, but too late
2368 // for it to be available when setting up plugin
2369 // state. We can't call Processor::set_state() until
2370 // the plugins themselves are created and added.
2374 if (_plugins.empty()) {
2375 /* if we are adding the first plugin, we will need to set
2376 up automatable controls.
2378 add_plugin (plugin);
2379 create_automatable_parameters ();
2380 set_control_ids (node, version);
2383 if ((prop = node.property ("count")) != 0) {
2384 sscanf (prop->value().c_str(), "%u", &count);
2387 if (_plugins.size() != count) {
2388 for (uint32_t n = 1; n < count; ++n) {
2389 add_plugin (plugin_factory (plugin));
2393 Processor::set_state (node, version);
2395 PBD::ID new_id = this->id();
2396 PBD::ID old_id = this->id();
2398 if ((prop = node.property ("id")) != 0) {
2399 old_id = prop->value ();
2402 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2404 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2405 and set all plugins to the same state.
2408 if ((*niter)->name() == plugin->state_node_name()) {
2410 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2411 /* Plugin state can include external files which are named after the ID.
2413 * If regenerate_xml_or_string_ids() is set, the ID will already have
2414 * been changed, so we need to use the old ID from the XML to load the
2415 * state and then update the ID.
2417 * When copying a plugin-state, route_ui takes care of of updating the ID,
2418 * but we need to call set_insert_id() to clear the cached plugin-state
2419 * and force a change.
2421 if (!regenerate_xml_or_string_ids ()) {
2422 (*i)->set_insert_id (new_id);
2424 (*i)->set_insert_id (old_id);
2427 (*i)->set_state (**niter, version);
2429 if (regenerate_xml_or_string_ids ()) {
2430 (*i)->set_insert_id (new_id);
2438 if (version < 3000) {
2440 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2441 this is all handled by Automatable
2444 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2445 if ((*niter)->name() == "Redirect") {
2446 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2447 Processor::set_state (**niter, version);
2452 set_parameter_state_2X (node, version);
2455 if ((prop = node.property (X_("custom"))) != 0) {
2456 _custom_cfg = string_is_affirmative (prop->value());
2459 uint32_t in_maps = 0;
2460 uint32_t out_maps = 0;
2461 XMLNodeList kids = node.children ();
2462 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2463 if ((*i)->name() == X_("ConfiguredInput")) {
2464 _configured_in = ChanCount(**i);
2466 if ((*i)->name() == X_("CustomSinks")) {
2467 _custom_sinks = ChanCount(**i);
2469 if ((*i)->name() == X_("ConfiguredOutput")) {
2470 _custom_out = ChanCount(**i);
2471 _configured_out = ChanCount(**i);
2473 if ((*i)->name() == X_("PresetOutput")) {
2474 _preset_out = ChanCount(**i);
2476 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2477 long pc = atol (&((*i)->name().c_str()[9]));
2478 if (pc >= 0 && pc <= (long) get_count()) {
2479 _in_map[pc] = ChanMapping (**i);
2483 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2484 long pc = atol (&((*i)->name().c_str()[10]));
2485 if (pc >= 0 && pc <= (long) get_count()) {
2486 _out_map[pc] = ChanMapping (**i);
2490 if ((*i)->name () == "ThruMap") {
2491 _thru_map = ChanMapping (**i);
2494 // sidechain is a Processor (IO)
2495 if ((*i)->name () == Processor::state_node_name) {
2499 _sidechain->set_state (**i, version);
2503 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2504 _maps_from_state = true;
2507 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2511 (*i)->deactivate ();
2515 PluginConfigChanged (); /* EMIT SIGNAL */
2520 PluginInsert::update_id (PBD::ID id)
2523 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2524 (*i)->set_insert_id (id);
2529 PluginInsert::set_state_dir (const std::string& d)
2531 // state() only saves the state of the first plugin
2532 _plugins[0]->set_state_dir (d);
2536 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2538 XMLNodeList nlist = node.children();
2539 XMLNodeIterator niter;
2541 /* look for port automation node */
2543 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2545 if ((*niter)->name() != port_automation_node_name) {
2550 XMLProperty const * cprop;
2551 XMLNodeConstIterator iter;
2556 cnodes = (*niter)->children ("port");
2558 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2562 if ((cprop = child->property("number")) != 0) {
2563 port = cprop->value().c_str();
2565 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2569 sscanf (port, "%" PRIu32, &port_id);
2571 if (port_id >= _plugins[0]->parameter_count()) {
2572 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2576 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2577 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2579 if (c && c->alist()) {
2580 if (!child->children().empty()) {
2581 c->alist()->set_state (*child->children().front(), version);
2583 /* In some cases 2.X saves lists with min_yval and max_yval
2584 being FLT_MIN and FLT_MAX respectively. This causes problems
2585 in A3 because these min/max values are used to compute
2586 where GUI control points should be drawn. If we see such
2587 values, `correct' them to the min/max of the appropriate
2591 float min_y = c->alist()->get_min_y ();
2592 float max_y = c->alist()->get_max_y ();
2594 ParameterDescriptor desc;
2595 _plugins.front()->get_parameter_descriptor (port_id, desc);
2597 if (min_y == FLT_MIN) {
2601 if (max_y == FLT_MAX) {
2605 c->alist()->set_yrange (min_y, max_y);
2608 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2620 PluginInsert::describe_parameter (Evoral::Parameter param)
2622 if (param.type() == PluginAutomation) {
2623 return _plugins[0]->describe_parameter (param);
2624 } else if (param.type() == PluginPropertyAutomation) {
2625 boost::shared_ptr<AutomationControl> c(automation_control(param));
2626 if (c && !c->desc().label.empty()) {
2627 return c->desc().label;
2630 return Automatable::describe_parameter(param);
2634 PluginInsert::signal_latency() const
2636 if (_user_latency) {
2637 return _user_latency;
2640 return _plugins[0]->signal_latency ();
2644 PluginInsert::type ()
2646 return plugin()->get_info()->type;
2649 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2650 const Evoral::Parameter& param,
2651 const ParameterDescriptor& desc,
2652 boost::shared_ptr<AutomationList> list)
2653 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2657 alist()->reset_default (desc.normal);
2659 list->set_interpolation(Evoral::ControlList::Discrete);
2664 /** @param val `user' value */
2667 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2669 /* FIXME: probably should be taking out some lock here.. */
2671 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2672 (*i)->set_parameter (_list->parameter().id(), user_val);
2675 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2677 iasp->set_parameter (_list->parameter().id(), user_val);
2680 AutomationControl::actually_set_value (user_val, group_override);
2684 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2686 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
2690 PluginInsert::PluginControl::get_state ()
2694 XMLNode& node (AutomationControl::get_state());
2695 ss << parameter().id();
2696 node.add_property (X_("parameter"), ss.str());
2698 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2700 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2707 /** @return `user' val */
2709 PluginInsert::PluginControl::get_value () const
2711 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2717 return plugin->get_parameter (_list->parameter().id());
2720 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2721 const Evoral::Parameter& param,
2722 const ParameterDescriptor& desc,
2723 boost::shared_ptr<AutomationList> list)
2724 : AutomationControl (p->session(), param, desc, list)
2728 alist()->set_yrange (desc.lower, desc.upper);
2729 alist()->reset_default (desc.normal);
2734 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
2736 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2737 This is lossy, but better than nothing until Ardour's automation system
2738 can handle various datatypes all the way down. */
2739 const Variant value(_desc.datatype, user_val);
2740 if (value.type() == Variant::NOTHING) {
2741 error << "set_value(double) called for non-numeric property" << endmsg;
2745 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2746 (*i)->set_property(_list->parameter().id(), value);
2751 AutomationControl::actually_set_value (user_val, gcd);
2755 PluginInsert::PluginPropertyControl::get_state ()
2759 XMLNode& node (AutomationControl::get_state());
2760 ss << parameter().id();
2761 node.add_property (X_("property"), ss.str());
2762 node.remove_property (X_("value"));
2768 PluginInsert::PluginPropertyControl::get_value () const
2770 return _value.to_double();
2773 boost::shared_ptr<Plugin>
2774 PluginInsert::get_impulse_analysis_plugin()
2776 boost::shared_ptr<Plugin> ret;
2777 if (_impulseAnalysisPlugin.expired()) {
2778 // LV2 in particular uses various _session params
2779 // during init() -- most notably block_size..
2781 ret = plugin_factory(_plugins[0]);
2782 ret->configure_io (internal_input_streams (), internal_output_streams ());
2783 _impulseAnalysisPlugin = ret;
2785 ret = _impulseAnalysisPlugin.lock();
2792 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2794 // called from outside the audio thread, so this should be safe
2795 // only do audio as analysis is (currently) only for audio plugins
2796 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
2797 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
2799 _signal_analysis_collected_nframes = 0;
2800 _signal_analysis_collect_nframes_max = nframes;
2803 /** Add a plugin to our list */
2805 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2807 plugin->set_insert_id (this->id());
2809 if (_plugins.empty()) {
2810 /* first (and probably only) plugin instance - connect to relevant signals */
2812 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2813 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2814 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2815 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2816 _custom_sinks = plugin->get_info()->n_inputs;
2817 // cache sidechain port count
2818 _cached_sidechain_pins.reset ();
2819 const ChanCount& nis (plugin->get_info()->n_inputs);
2820 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2821 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2822 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2823 if (iod.is_sidechain) {
2824 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2829 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2830 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2832 vst->set_insert (this, _plugins.size ());
2835 _plugins.push_back (plugin);
2839 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
2842 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2843 if (! (*i)->load_preset (pr)) {
2851 PluginInsert::realtime_handle_transport_stopped ()
2853 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2854 (*i)->realtime_handle_transport_stopped ();
2859 PluginInsert::realtime_locate ()
2861 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2862 (*i)->realtime_locate ();
2867 PluginInsert::monitoring_changed ()
2869 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2870 (*i)->monitoring_changed ();
2875 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2877 // this is called in RT context, LatencyChanged is emitted after run()
2878 _latency_changed = true;
2882 PluginInsert::start_touch (uint32_t param_id)
2884 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2886 ac->start_touch (session().audible_frame());
2891 PluginInsert::end_touch (uint32_t param_id)
2893 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2895 ac->stop_touch (true, session().audible_frame());
2899 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2902 case PluginInsert::Impossible: o << "Impossible"; break;
2903 case PluginInsert::Delegate: o << "Delegate"; break;
2904 case PluginInsert::NoInputs: o << "NoInputs"; break;
2905 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2906 case PluginInsert::Replicate: o << "Replicate"; break;
2907 case PluginInsert::Split: o << "Split"; break;
2908 case PluginInsert::Hide: o << "Hide"; break;
2910 o << " cnt: " << m.plugins
2911 << (m.strict_io ? " strict-io" : "")
2912 << (m.custom_cfg ? " custom-cfg" : "");
2913 if (m.method == PluginInsert::Hide) {
2914 o << " hide: " << m.hide;