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 , _signal_analysis_collected_nframes(0)
71 , _signal_analysis_collect_nframes_max(0)
76 , _maps_from_state (false)
78 /* the first is the master */
82 create_automatable_parameters ();
83 const ChanCount& sc (sidechain_input_pins ());
84 if (sc.n_audio () > 0) {
85 add_sidechain (sc.n_audio ());
90 PluginInsert::~PluginInsert ()
95 PluginInsert::set_strict_io (bool b)
97 bool changed = _strict_io != b;
100 PluginConfigChanged (); /* EMIT SIGNAL */
105 PluginInsert::set_count (uint32_t num)
107 bool require_state = !_plugins.empty();
109 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
110 // we don't allow to replicate AUs
114 /* this is a bad idea.... we shouldn't do this while active.
115 * only a route holding their redirect_lock should be calling this
120 } else if (num > _plugins.size()) {
121 uint32_t diff = num - _plugins.size();
123 for (uint32_t n = 0; n < diff; ++n) {
124 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
128 XMLNode& state = _plugins[0]->get_state ();
129 p->set_state (state, Stateful::loading_state_version);
136 PluginConfigChanged (); /* EMIT SIGNAL */
138 } else if (num < _plugins.size()) {
139 uint32_t diff = _plugins.size() - num;
140 for (uint32_t n= 0; n < diff; ++n) {
143 PluginConfigChanged (); /* EMIT SIGNAL */
151 PluginInsert::set_sinks (const ChanCount& c)
154 /* no signal, change will only be visible after re-config */
158 PluginInsert::set_outputs (const ChanCount& c)
160 bool changed = (_custom_out != c) && _custom_cfg;
163 PluginConfigChanged (); /* EMIT SIGNAL */
168 PluginInsert::set_custom_cfg (bool b)
170 bool changed = _custom_cfg != b;
173 PluginConfigChanged (); /* EMIT SIGNAL */
178 PluginInsert::set_preset_out (const ChanCount& c)
180 bool changed = _preset_out != c;
182 if (changed && !_custom_cfg) {
183 PluginConfigChanged (); /* EMIT SIGNAL */
189 PluginInsert::add_sidechain (uint32_t n_audio)
191 // caller must hold process lock
195 std::ostringstream n;
197 n << "Sidechain " << Session::next_name_id ();
199 n << "TO BE RESET FROM XML";
201 SideChain *sc = new SideChain (_session, n.str ());
202 _sidechain = boost::shared_ptr<SideChain> (sc);
203 _sidechain->activate ();
204 for (uint32_t n = 0; n < n_audio; ++n) {
205 _sidechain->input()->add_port ("", owner()); // add a port, don't connect.
207 PluginConfigChanged (); /* EMIT SIGNAL */
212 PluginInsert::del_sidechain ()
218 PluginConfigChanged (); /* EMIT SIGNAL */
223 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
225 if (which.type() != PluginAutomation)
228 boost::shared_ptr<AutomationControl> c
229 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
232 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
237 PluginInsert::output_streams() const
239 assert (_configured);
240 return _configured_out;
244 PluginInsert::input_streams() const
246 assert (_configured);
247 return _configured_in;
251 PluginInsert::internal_streams() const
253 assert (_configured);
254 return _configured_internal;
258 PluginInsert::internal_output_streams() const
260 assert (!_plugins.empty());
262 PluginInfoPtr info = _plugins.front()->get_info();
264 if (info->reconfigurable_io()) {
265 ChanCount out = _plugins.front()->output_streams ();
266 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
269 ChanCount out = info->n_outputs;
270 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
271 out.set_audio (out.n_audio() * _plugins.size());
272 out.set_midi (out.n_midi() * _plugins.size());
278 PluginInsert::internal_input_streams() const
280 assert (!_plugins.empty());
284 PluginInfoPtr info = _plugins.front()->get_info();
286 if (info->reconfigurable_io()) {
287 in = _plugins.front()->input_streams();
292 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
294 if (_match.method == Split) {
296 /* we are splitting 1 processor input to multiple plugin inputs,
297 so we have a maximum of 1 stream of each type.
299 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
300 if (in.get (*t) > 1) {
306 } else if (_match.method == Hide) {
308 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
309 in.set (*t, in.get (*t) - _match.hide.get (*t));
315 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
316 in.set (*t, in.get (*t) * _plugins.size ());
324 PluginInsert::natural_output_streams() const
327 if (is_channelstrip ()) {
328 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
331 return _plugins[0]->get_info()->n_outputs;
335 PluginInsert::natural_input_streams() const
338 if (is_channelstrip ()) {
339 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
342 return _plugins[0]->get_info()->n_inputs;
346 PluginInsert::sidechain_input_pins() const
348 return _cached_sidechain_pins;
352 PluginInsert::has_no_inputs() const
354 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
358 PluginInsert::has_no_audio_inputs() const
360 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
364 PluginInsert::plugin_latency () const {
365 return _plugins.front()->signal_latency ();
369 PluginInsert::needs_midi_input() const
371 PluginInfoPtr pip = _plugins[0]->get_info();
372 if (pip->needs_midi_input ()) {
375 return pip->n_inputs.n_midi() != 0 && pip->n_outputs.n_audio() != 0;
379 PluginInsert::create_automatable_parameters ()
381 assert (!_plugins.empty());
383 set<Evoral::Parameter> a = _plugins.front()->automatable ();
385 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
386 if (i->type() == PluginAutomation) {
388 Evoral::Parameter param(*i);
390 ParameterDescriptor desc;
391 _plugins.front()->get_parameter_descriptor(i->id(), desc);
393 can_automate (param);
394 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
395 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
397 _plugins.front()->set_automation_control (i->id(), c);
398 } else if (i->type() == PluginPropertyAutomation) {
399 Evoral::Parameter param(*i);
400 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
401 if (desc.datatype != Variant::NOTHING) {
402 boost::shared_ptr<AutomationList> list;
403 if (Variant::type_is_numeric(desc.datatype)) {
404 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
406 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
411 /** Called when something outside of this host has modified a plugin
412 * parameter. Responsible for propagating the change to two places:
414 * 1) anything listening to the Control itself
415 * 2) any replicated plugins that make up this PluginInsert.
417 * The PluginInsert is connected to the ParameterChangedExternally signal for
418 * the first (primary) plugin, and here broadcasts that change to any others.
420 * XXX We should probably drop this whole replication idea (Paul, October 2015)
421 * since it isn't used by sensible plugin APIs (AU, LV2).
424 PluginInsert::parameter_changed_externally (uint32_t which, float val)
426 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
428 /* First propagation: alter the underlying value of the control,
429 * without telling the plugin(s) that own/use it to set it.
436 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
439 pc->catch_up_with_external_value (val);
442 /* Second propagation: tell all plugins except the first to
443 update the value of this parameter. For sane plugin APIs,
444 there are no other plugins, so this is a no-op in those
448 Plugins::iterator i = _plugins.begin();
450 /* don't set the first plugin, just all the slaves */
452 if (i != _plugins.end()) {
454 for (; i != _plugins.end(); ++i) {
455 (*i)->set_parameter (which, val);
461 PluginInsert::set_block_size (pframes_t nframes)
464 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
465 if ((*i)->set_block_size (nframes) != 0) {
473 PluginInsert::activate ()
475 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
479 Processor::activate ();
483 PluginInsert::deactivate ()
485 Processor::deactivate ();
487 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
493 PluginInsert::flush ()
495 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
501 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
503 // TODO: atomically copy maps & _no_inplace
504 PinMappings in_map (_in_map);
505 PinMappings out_map (_out_map);
506 ChanMapping thru_map (_thru_map);
507 if (_mapping_changed) { // ToDo use a counters, increment until match.
508 _no_inplace = check_inplace ();
509 _mapping_changed = false;
512 if (_latency_changed) {
513 /* delaylines are configured with the max possible latency (as reported by the plugin)
514 * so this won't allocate memory (unless the plugin lied about its max latency)
515 * It may still 'click' though, since the fixed delaylines are not de-clicked.
516 * Then again plugin-latency changes are not click-free to begin with.
518 * This is also worst case, there is currently no concept of per-stream latency.
520 * e.g. Two identical latent plugins:
521 * 1st plugin: process left (latent), bypass right.
522 * 2nd plugin: bypass left, process right (latent).
523 * -> currently this yields 2 times latency of the plugin,
525 _latency_changed = false;
526 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
529 if (_match.method == Split && !_no_inplace) {
530 // TODO: also use this optimization if one source-buffer
531 // feeds _all_ *connected* inputs.
532 // currently this is *first* buffer to all only --
533 // see PluginInsert::check_inplace
534 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
535 if (_configured_internal.get (*t) == 0) {
539 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
540 assert (valid && first_idx == 0); // check_inplace ensures this
541 /* copy the first stream's buffer contents to the others */
542 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
543 uint32_t idx = in_map[0].get (*t, i, &valid);
546 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
550 /* the copy operation produces a linear monotonic input map */
551 in_map[0] = ChanMapping (natural_input_streams ());
554 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
555 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
561 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
563 boost::shared_ptr<AutomationControl> c
564 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
566 if (c->list() && c->automation_playback()) {
569 const float val = c->list()->rt_safe_eval (now, valid);
572 /* This is the ONLY place where we are
574 * AutomationControl::set_value_unchecked(). We
575 * know that the control is in
576 * automation playback mode, so no
577 * check on writable() is required
578 * (which must be done in AutomationControl::set_value()
581 c->set_value_unchecked(val);
588 /* Calculate if, and how many frames we need to collect for analysis */
589 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
590 _signal_analysis_collected_nframes);
591 if (nframes < collect_signal_nframes) { // we might not get all frames now
592 collect_signal_nframes = nframes;
595 if (collect_signal_nframes > 0) {
597 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
598 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
599 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
601 _signal_analysis_inputs.set_count(internal_input_streams());
603 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
604 _signal_analysis_inputs.get_audio(i).read_from(
606 collect_signal_nframes,
607 _signal_analysis_collected_nframes); // offset is for target buffer
612 if (is_channelstrip ()) {
613 if (_configured_in.n_audio() > 0) {
614 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
615 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
617 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
619 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
620 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
626 // TODO optimize -- build maps once.
628 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
629 ARDOUR::ChanMapping used_outputs;
631 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
633 /* build used-output map */
634 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
635 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
636 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
638 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
640 used_outputs.set (*t, out_idx, 1); // mark as used
645 /* copy thru data to outputs before processing in-place */
646 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
647 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
649 uint32_t in_idx = thru_map.get (*t, out, &valid);
650 uint32_t m = out + natural_input_streams ().get (*t);
652 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
653 used_outputs.set (*t, out, 1); // mark as used
655 used_outputs.get (*t, out, &valid);
657 /* the plugin is expected to write here, but may not :(
658 * (e.g. drumgizmo w/o kit loaded)
660 inplace_bufs.get (*t, m).silence (nframes);
667 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
669 ARDOUR::ChanMapping i_in_map (natural_input_streams());
670 ARDOUR::ChanMapping i_out_map (out_map[pc]);
671 ARDOUR::ChanCount mapped;
673 /* map inputs sequentially */
674 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
675 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
677 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
678 uint32_t m = mapped.get (*t);
680 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
682 inplace_bufs.get (*t, m).silence (nframes, offset);
684 mapped.set (*t, m + 1);
688 /* outputs are mapped to inplace_bufs after the inputs */
689 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
690 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
693 if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
698 /* all instances have completed, now copy data that was written
699 * and zero unconnected buffers */
700 ARDOUR::ChanMapping nonzero_out (used_outputs);
701 if (has_midi_bypass ()) {
702 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
704 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
705 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
707 used_outputs.get (*t, out, &valid);
709 nonzero_out.get (*t, out, &valid);
711 bufs.get (*t, out).silence (nframes, offset);
714 uint32_t m = out + natural_input_streams ().get (*t);
715 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
720 /* in-place processing */
722 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
723 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
728 // TODO optimize: store "unconnected" in a fixed set.
729 // it only changes on reconfiguration.
730 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
731 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
733 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
734 mapped = true; // in-place Midi bypass
736 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
737 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
739 uint32_t idx = out_map[pc].get (*t, o, &valid);
740 if (valid && idx == out) {
747 bufs.get (*t, out).silence (nframes, offset);
753 if (collect_signal_nframes > 0) {
755 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
756 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
758 _signal_analysis_outputs.set_count(internal_output_streams());
760 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
761 _signal_analysis_outputs.get_audio(i).read_from(
763 collect_signal_nframes,
764 _signal_analysis_collected_nframes); // offset is for target buffer
767 _signal_analysis_collected_nframes += collect_signal_nframes;
768 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
770 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
771 _signal_analysis_collect_nframes_max = 0;
772 _signal_analysis_collected_nframes = 0;
774 AnalysisDataGathered(&_signal_analysis_inputs,
775 &_signal_analysis_outputs);
781 PluginInsert::silence (framecnt_t nframes)
787 _delaybuffers.flush ();
789 ChanMapping in_map (natural_input_streams ());
790 ChanMapping out_map (natural_output_streams ());
791 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
793 if (is_channelstrip ()) {
794 if (_configured_in.n_audio() > 0) {
795 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
799 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
800 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
805 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
807 if (_pending_active) {
808 /* run as normal if we are active or moving from inactive to active */
811 // collect sidechain input for complete cycle (!)
812 // TODO we need delaylines here for latency compensation
813 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
816 if (_session.transport_rolling() || _session.bounce_processing()) {
817 automation_run (bufs, start_frame, nframes);
819 connect_and_run (bufs, nframes, 0, false);
823 // TODO use mapping in bypassed mode ?!
824 // -> do we bypass the processor or the plugin
826 // TODO include sidechain??
828 uint32_t in = input_streams ().n_audio ();
829 uint32_t out = output_streams().n_audio ();
831 if (has_no_audio_inputs() || in == 0) {
833 /* silence all (audio) outputs. Should really declick
834 * at the transitions of "active"
837 for (uint32_t n = 0; n < out; ++n) {
838 bufs.get_audio (n).silence (nframes);
841 } else if (out > in) {
843 /* not active, but something has make up for any channel count increase
844 * for now , simply replicate last buffer
846 for (uint32_t n = in; n < out; ++n) {
847 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
851 bufs.count().set_audio (out);
854 _active = _pending_active;
856 /* we have no idea whether the plugin generated silence or not, so mark
857 * all buffers appropriately.
862 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
864 Evoral::ControlEvent next_event (0, 0.0f);
865 framepos_t now = start;
866 framepos_t end = now + nframes;
867 framecnt_t offset = 0;
869 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
872 connect_and_run (bufs, nframes, offset, false);
876 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
878 /* no events have a time within the relevant range */
880 connect_and_run (bufs, nframes, offset, true, now);
886 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
888 connect_and_run (bufs, cnt, offset, true, now);
894 if (!find_next_event (now, end, next_event)) {
899 /* cleanup anything that is left to do */
902 connect_and_run (bufs, nframes, offset, true, now);
907 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
909 if (param.type() != PluginAutomation)
912 if (_plugins.empty()) {
913 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
915 abort(); /*NOTREACHED*/
918 return _plugins[0]->default_value (param.id());
923 PluginInsert::can_reset_all_parameters ()
927 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
929 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
931 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
935 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
941 if (ac->automation_state() & Play) {
946 return all && (params > 0);
950 PluginInsert::reset_parameters_to_default ()
954 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
956 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
958 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
962 const float dflt = _plugins[0]->default_value (cid);
963 const float curr = _plugins[0]->get_parameter (cid);
969 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
974 if (ac->automation_state() & Play) {
979 ac->set_value (dflt, Controllable::NoGroup);
984 boost::shared_ptr<Plugin>
985 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
987 boost::shared_ptr<LadspaPlugin> lp;
988 boost::shared_ptr<LuaProc> lua;
990 boost::shared_ptr<LV2Plugin> lv2p;
992 #ifdef WINDOWS_VST_SUPPORT
993 boost::shared_ptr<WindowsVSTPlugin> vp;
996 boost::shared_ptr<LXVSTPlugin> lxvp;
998 #ifdef AUDIOUNIT_SUPPORT
999 boost::shared_ptr<AUPlugin> ap;
1002 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1003 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1004 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1005 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1007 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1008 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1010 #ifdef WINDOWS_VST_SUPPORT
1011 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1012 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1014 #ifdef LXVST_SUPPORT
1015 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1016 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1018 #ifdef AUDIOUNIT_SUPPORT
1019 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1020 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1024 fatal << string_compose (_("programming error: %1"),
1025 X_("unknown plugin type in PluginInsert::plugin_factory"))
1027 abort(); /*NOTREACHED*/
1028 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1032 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1033 if (num < _in_map.size()) {
1034 bool changed = _in_map[num] != m;
1036 changed |= sanitize_maps ();
1038 PluginMapChanged (); /* EMIT SIGNAL */
1039 _mapping_changed = true;
1040 _session.set_dirty();
1046 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1047 if (num < _out_map.size()) {
1048 bool changed = _out_map[num] != m;
1050 changed |= sanitize_maps ();
1052 PluginMapChanged (); /* EMIT SIGNAL */
1053 _mapping_changed = true;
1054 _session.set_dirty();
1060 PluginInsert::set_thru_map (ChanMapping m) {
1061 bool changed = _thru_map != m;
1063 changed |= sanitize_maps ();
1065 PluginMapChanged (); /* EMIT SIGNAL */
1066 _mapping_changed = true;
1067 _session.set_dirty();
1072 PluginInsert::input_map () const
1076 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1077 ChanMapping m (i->second);
1078 const ChanMapping::Mappings& mp ((*i).second.mappings());
1079 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1080 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1081 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1089 PluginInsert::output_map () const
1093 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1094 ChanMapping m (i->second);
1095 const ChanMapping::Mappings& mp ((*i).second.mappings());
1096 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1097 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1098 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1102 if (has_midi_bypass ()) {
1103 rv.set (DataType::MIDI, 0, 0);
1110 PluginInsert::has_midi_bypass () const
1112 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1113 && natural_output_streams ().n_midi () == 0) {
1120 PluginInsert::has_midi_thru () const
1122 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1123 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1131 PluginInsert::is_channelstrip () const {
1132 return _plugins.front()->is_channelstrip();
1137 PluginInsert::check_inplace ()
1139 bool inplace_ok = !_plugins.front()->inplace_broken ();
1141 if (_thru_map.n_total () > 0) {
1142 // TODO once midi-bypass is part of the mapping, ignore it
1146 if (_match.method == Split && inplace_ok) {
1147 assert (get_count() == 1);
1148 assert (_in_map.size () == 1);
1149 if (!_out_map[0].is_monotonic ()) {
1152 if (_configured_internal != _configured_in) {
1153 /* no sidechain -- TODO we could allow this with
1154 * some more logic in PluginInsert::connect_and_run().
1156 * PluginInsert::reset_map() already maps it.
1161 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1162 if (_configured_internal.get (*t) == 0) {
1166 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1167 if (!valid || first_idx != 0) {
1168 // so far only allow to copy the *first* stream's buffer to others
1171 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1172 uint32_t idx = _in_map[0].get (*t, i, &valid);
1173 if (valid && idx != first_idx) {
1182 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1187 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1188 if (!_in_map[pc].is_monotonic ()) {
1191 if (!_out_map[pc].is_monotonic ()) {
1195 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1196 return !inplace_ok; // no-inplace
1200 PluginInsert::sanitize_maps ()
1202 bool changed = false;
1203 /* strip dead wood */
1204 PinMappings new_ins;
1205 PinMappings new_outs;
1206 ChanMapping new_thru;
1208 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1210 ChanMapping new_out;
1211 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1212 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1214 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1215 if (valid && idx < _configured_internal.get (*t)) {
1216 new_in.set (*t, i, idx);
1219 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1221 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1222 if (valid && idx < _configured_out.get (*t)) {
1223 new_out.set (*t, o, idx);
1227 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1230 new_ins[pc] = new_in;
1231 new_outs[pc] = new_out;
1234 /* prevent dup output assignments */
1235 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1236 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1237 bool mapped = false;
1238 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1240 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1241 if (valid && mapped) {
1242 new_outs[pc].unset (*t, idx);
1250 /* remove excess thru */
1251 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1252 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1254 uint32_t idx = _thru_map.get (*t, o, &valid);
1255 if (valid && idx < _configured_internal.get (*t)) {
1256 new_thru.set (*t, o, idx);
1261 /* prevent out + thru, existing plugin outputs override thru */
1262 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1263 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1264 bool mapped = false;
1266 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1267 new_outs[pc].get_src (*t, o, &mapped);
1268 if (mapped) { break; }
1270 if (!mapped) { continue; }
1271 uint32_t idx = new_thru.get (*t, o, &valid);
1273 new_thru.unset (*t, idx);
1278 if (has_midi_bypass ()) {
1279 // TODO: include midi-bypass in the thru set,
1280 // remove dedicated handling.
1281 new_thru.unset (DataType::MIDI, 0);
1284 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1288 _out_map = new_outs;
1289 _thru_map = new_thru;
1295 PluginInsert::reset_map (bool emit)
1297 const PinMappings old_in (_in_map);
1298 const PinMappings old_out (_out_map);
1302 _thru_map = ChanMapping ();
1304 /* build input map */
1305 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1306 uint32_t sc = 0; // side-chain round-robin (all instances)
1308 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1309 const uint32_t nis = natural_input_streams ().get(*t);
1310 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1312 /* SC inputs are last in the plugin-insert.. */
1313 const uint32_t sc_start = _configured_in.get (*t);
1314 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1315 /* ...but may not be at the end of the plugin ports.
1316 * in case the side-chain is not the last port, shift connections back.
1317 * and connect to side-chain
1320 uint32_t ic = 0; // split inputs
1321 const uint32_t cend = _configured_in.get (*t);
1323 for (uint32_t in = 0; in < nis; ++in) {
1324 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1325 if (iod.is_sidechain) {
1326 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1327 if (sc_len > 0) {// side-chain may be hidden
1328 _in_map[pc].set (*t, in, sc_start + sc);
1329 sc = (sc + 1) % sc_len;
1333 if (_match.method == Split) {
1334 if (cend == 0) { continue; }
1335 if (_strict_io && ic + stride * pc >= cend) {
1338 /* connect *no* sidechain sinks in round-robin fashion */
1339 _in_map[pc].set (*t, in, ic + stride * pc);
1340 if (_strict_io && (ic + 1) == cend) {
1343 ic = (ic + 1) % cend;
1345 uint32_t s = in - shift;
1346 if (stride * pc + s < cend) {
1347 _in_map[pc].set (*t, in, s + stride * pc);
1355 /* build output map */
1357 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1358 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1359 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1360 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1365 if (old_in == _in_map && old_out == _out_map) {
1369 PluginMapChanged (); /* EMIT SIGNAL */
1370 _mapping_changed = true;
1371 _session.set_dirty();
1377 PluginInsert::configure_io (ChanCount in, ChanCount out)
1379 Match old_match = _match;
1381 ChanCount old_internal;
1385 old_pins = natural_input_streams();
1386 old_in = _configured_in;
1387 old_out = _configured_out;
1388 old_internal = _configured_internal;
1390 _configured_in = in;
1391 _configured_internal = in;
1392 _configured_out = out;
1395 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1396 * (currently _sidechain->configure_io always succeeds
1397 * since Processor::configure_io() succeeds)
1399 if (!_sidechain->configure_io (in, out)) {
1400 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1403 _configured_internal += _sidechain->input()->n_ports();
1405 // include (static_cast<Route*>owner())->name() ??
1406 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1409 /* get plugin configuration */
1410 _match = private_can_support_io_configuration (in, out);
1412 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1414 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1415 DEBUG_STR_APPEND(a, _match);
1416 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1420 /* set the matching method and number of plugins that we will use to meet this configuration */
1421 if (set_count (_match.plugins) == false) {
1422 PluginIoReConfigure (); /* EMIT SIGNAL */
1423 _configured = false;
1427 /* configure plugins */
1428 switch (_match.method) {
1431 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1432 PluginIoReConfigure (); /* EMIT SIGNAL */
1433 _configured = false;
1439 ChanCount din (_configured_internal);
1440 ChanCount dout (din); // hint
1442 if (_custom_sinks.n_total () > 0) {
1443 din = _custom_sinks;
1446 } else if (_preset_out.n_audio () > 0) {
1447 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1448 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1449 dout.set (DataType::AUDIO, 2);
1451 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1453 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1454 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1456 if (useins.n_audio() == 0) {
1459 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1461 if (_plugins.front()->configure_io (useins, dout) == false) {
1462 PluginIoReConfigure (); /* EMIT SIGNAL */
1463 _configured = false;
1467 _custom_sinks = din;
1472 if (_plugins.front()->configure_io (in, out) == false) {
1473 PluginIoReConfigure (); /* EMIT SIGNAL */
1474 _configured = false;
1480 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",
1482 _configured ? "Y" : "N",
1483 _maps_from_state ? "Y" : "N",
1484 old_in == in ? "==" : "!=",
1485 old_out == out ? "==" : "!=",
1486 old_pins == natural_input_streams () ? "==" : "!=",
1487 old_match.method == _match.method ? "==" : "!=",
1488 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1489 _in_map.size() == get_count () ? "==" : "!=",
1490 _out_map.size() == get_count () ? "==" : "!="
1493 bool mapping_changed = false;
1494 if (old_in == in && old_out == out
1496 && old_pins == natural_input_streams ()
1497 && old_match.method == _match.method
1498 && old_match.custom_cfg == _match.custom_cfg
1499 && _in_map.size() == _out_map.size()
1500 && _in_map.size() == get_count ()
1502 assert (_maps_from_state == false);
1503 /* If the configuration has not changed, keep the mapping */
1504 mapping_changed = sanitize_maps ();
1505 } else if (_match.custom_cfg && _configured) {
1506 assert (_maps_from_state == false);
1507 /* don't touch the map in manual mode */
1508 mapping_changed = sanitize_maps ();
1511 if (is_channelstrip ()) {
1512 /* fake channel map - for wire display */
1515 _thru_map = ChanMapping ();
1516 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1517 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1518 /* set "thru" map for in-place forward of audio */
1519 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1520 _thru_map.set (DataType::AUDIO, i, i);
1522 /* and midi (after implicit 1st channel bypass) */
1523 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1524 _thru_map.set (DataType::MIDI, i, i);
1528 if (_maps_from_state && old_in == in && old_out == out) {
1529 mapping_changed = true;
1532 /* generate a new mapping */
1533 mapping_changed = reset_map (false);
1535 _maps_from_state = false;
1538 if (mapping_changed) {
1539 PluginMapChanged (); /* EMIT SIGNAL */
1542 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1545 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1546 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1548 DEBUG_STR_APPEND(a, "----><----\n");
1550 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1551 DEBUG_STR_APPEND(a, " * Inputs:\n");
1552 DEBUG_STR_APPEND(a, _in_map[pc]);
1553 DEBUG_STR_APPEND(a, " * Outputs:\n");
1554 DEBUG_STR_APPEND(a, _out_map[pc]);
1556 DEBUG_STR_APPEND(a, " * Thru:\n");
1557 DEBUG_STR_APPEND(a, _thru_map);
1558 DEBUG_STR_APPEND(a, "-------->>--------\n");
1559 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1564 _no_inplace = check_inplace ();
1565 _mapping_changed = false;
1567 /* only the "noinplace_buffers" thread buffers need to be this large,
1568 * this can be optimized. other buffers are fine with
1569 * ChanCount::max (natural_input_streams (), natural_output_streams())
1570 * and route.cc's max (configured_in, configured_out)
1572 * no-inplace copies "thru" outputs (to emulate in-place) for
1573 * all outputs (to prevent overwrite) into a temporary space
1574 * which also holds input buffers (in case the plugin does process
1575 * in-place and overwrites those).
1577 * this buffers need to be at least as
1578 * natural_input_streams () + possible outputs.
1580 * sidechain inputs add a constraint on the input:
1581 * configured input + sidechain (=_configured_internal)
1583 * NB. this also satisfies
1584 * max (natural_input_streams(), natural_output_streams())
1585 * which is needed for silence runs
1587 _required_buffers = ChanCount::max (_configured_internal,
1588 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1590 if (old_in != in || old_out != out || old_internal != _configured_internal
1591 || old_pins != natural_input_streams ()
1592 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1594 PluginIoReConfigure (); /* EMIT SIGNAL */
1597 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
1598 _latency_changed = true;
1600 // we don't know the analysis window size, so we must work with the
1601 // current buffer size here. each request for data fills in these
1602 // buffers and the analyser makes sure it gets enough data for the
1604 session().ensure_buffer_set (_signal_analysis_inputs, in);
1605 //_signal_analysis_inputs.set_count (in);
1607 session().ensure_buffer_set (_signal_analysis_outputs, out);
1608 //_signal_analysis_outputs.set_count (out);
1610 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1613 return Processor::configure_io (in, out);
1616 /** Decide whether this PluginInsert can support a given IO configuration.
1617 * To do this, we run through a set of possible solutions in rough order of
1620 * @param in Required input channel count.
1621 * @param out Filled in with the output channel count if we return true.
1622 * @return true if the given IO configuration can be supported.
1625 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1628 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1630 return private_can_support_io_configuration (in, out).method != Impossible;
1634 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1636 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1637 // preseed hint (for variable i/o)
1638 out.set (DataType::AUDIO, _preset_out.n_audio ());
1641 Match rv = internal_can_support_io_configuration (in, out);
1643 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1644 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
1645 out.set (DataType::AUDIO, _preset_out.n_audio ());
1650 /** A private version of can_support_io_configuration which returns the method
1651 * by which the configuration can be matched, rather than just whether or not
1655 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1657 if (_plugins.empty()) {
1662 if (is_channelstrip ()) {
1664 return Match (ExactMatch, 1);
1668 /* if a user specified a custom cfg, so be it. */
1670 PluginInfoPtr info = _plugins.front()->get_info();
1672 if (info->reconfigurable_io()) {
1673 return Match (Delegate, 1, _strict_io, true);
1675 return Match (ExactMatch, get_count(), _strict_io, true);
1679 /* try automatic configuration */
1680 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1682 PluginInfoPtr info = _plugins.front()->get_info();
1683 ChanCount inputs = info->n_inputs;
1684 ChanCount outputs = info->n_outputs;
1686 /* handle case strict-i/o */
1687 if (_strict_io && m.method != Impossible) {
1690 /* special case MIDI instruments */
1691 if (needs_midi_input ()) {
1692 // output = midi-bypass + at most master-out channels.
1693 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1694 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1695 out = ChanCount::min (out, max_out);
1696 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
1702 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1703 /* replicate processor to match output count (generators and such)
1704 * at least enough to feed every output port. */
1705 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1706 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1707 uint32_t nout = outputs.get (*t);
1708 if (nout == 0 || inx.get(*t) == 0) { continue; }
1709 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1712 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
1713 return Match (Replicate, f, _strict_io);
1724 if (m.method != Impossible) {
1728 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1730 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
1732 if (info->reconfigurable_io()) {
1735 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1736 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1737 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
1739 // houston, we have a problem.
1740 return Match (Impossible, 0);
1742 return Match (Delegate, 1, _strict_io);
1745 ChanCount midi_bypass;
1746 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1747 midi_bypass.set (DataType::MIDI, 1);
1750 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1752 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1753 uint32_t nin = ns_inputs.get (*t);
1754 uint32_t nout = outputs.get (*t);
1755 if (nin == 0 || inx.get(*t) == 0) { continue; }
1756 // prefer floor() so the count won't overly increase IFF (nin < nout)
1757 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1759 if (f > 0 && outputs * f >= _configured_out) {
1760 out = outputs * f + midi_bypass;
1761 return Match (Replicate, f, _strict_io);
1764 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1766 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1767 uint32_t nin = ns_inputs.get (*t);
1768 if (nin == 0 || inx.get(*t) == 0) { continue; }
1769 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1772 out = outputs * f + midi_bypass;
1773 return Match (Replicate, f, _strict_io);
1776 // add at least as many plugins needed to connect all inputs
1778 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1779 uint32_t nin = inputs.get (*t);
1780 if (nin == 0 || inx.get(*t) == 0) { continue; }
1781 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1783 out = outputs * f + midi_bypass;
1784 return Match (Replicate, f, _strict_io);
1787 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1789 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1791 if (_plugins.empty()) {
1795 PluginInfoPtr info = _plugins.front()->get_info();
1796 ChanCount in; in += inx;
1797 ChanCount midi_bypass;
1799 if (info->reconfigurable_io()) {
1800 /* Plugin has flexible I/O, so delegate to it
1801 * pre-seed outputs, plugin tries closest match
1804 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1805 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1806 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
1808 return Match (Impossible, 0);
1810 return Match (Delegate, 1);
1813 ChanCount inputs = info->n_inputs;
1814 ChanCount outputs = info->n_outputs;
1815 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1817 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1818 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
1819 midi_bypass.set (DataType::MIDI, 1);
1821 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1822 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
1823 in.set(DataType::MIDI, 0);
1826 // add internally provided sidechain ports
1827 ChanCount insc = in + sidechain_input_ports ();
1829 bool no_inputs = true;
1830 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1831 if (inputs.get (*t) != 0) {
1838 /* no inputs so we can take any input configuration since we throw it away */
1839 out = outputs + midi_bypass;
1840 return Match (NoInputs, 1);
1843 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1844 if (inputs == insc) {
1845 out = outputs + midi_bypass;
1846 return Match (ExactMatch, 1);
1849 /* Plugin inputs matches without side-chain-pins */
1850 if (ns_inputs == in) {
1851 out = outputs + midi_bypass;
1852 return Match (ExactMatch, 1);
1855 /* We may be able to run more than one copy of the plugin within this insert
1856 to cope with the insert having more inputs than the plugin.
1857 We allow replication only for plugins with either zero or 1 inputs and outputs
1858 for every valid data type.
1862 bool can_replicate = true;
1863 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1865 // ignore side-chains
1866 uint32_t nin = ns_inputs.get (*t);
1868 // No inputs of this type
1869 if (nin == 0 && in.get(*t) == 0) {
1873 if (nin != 1 || outputs.get (*t) != 1) {
1874 can_replicate = false;
1878 // Potential factor not set yet
1880 f = in.get(*t) / nin;
1883 // Factor for this type does not match another type, can not replicate
1884 if (f != (in.get(*t) / nin)) {
1885 can_replicate = false;
1890 if (can_replicate && f > 0) {
1891 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1892 out.set (*t, outputs.get(*t) * f);
1895 return Match (Replicate, f);
1898 /* If the processor has exactly one input of a given type, and
1899 the plugin has more, we can feed the single processor input
1900 to some or all of the plugin inputs. This is rather
1901 special-case-y, but the 1-to-many case is by far the
1902 simplest. How do I split thy 2 processor inputs to 3
1903 plugin inputs? Let me count the ways ...
1906 bool can_split = true;
1907 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1909 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
1910 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1912 if (!can_split_type && !nothing_to_do_for_type) {
1918 out = outputs + midi_bypass;
1919 return Match (Split, 1);
1922 /* If the plugin has more inputs than we want, we can `hide' some of them
1923 by feeding them silence.
1926 bool could_hide = false;
1927 bool cannot_hide = false;
1928 ChanCount hide_channels;
1930 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1931 if (inputs.get(*t) > in.get(*t)) {
1932 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1933 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1935 } else if (inputs.get(*t) < in.get(*t)) {
1936 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1941 if (could_hide && !cannot_hide) {
1942 out = outputs + midi_bypass;
1943 return Match (Hide, 1, false, false, hide_channels);
1946 return Match (Impossible, 0);
1951 PluginInsert::get_state ()
1953 return state (true);
1957 PluginInsert::state (bool full)
1959 XMLNode& node = Processor::state (full);
1961 node.add_property("type", _plugins[0]->state_node_name());
1962 node.add_property("unique-id", _plugins[0]->unique_id());
1963 node.add_property("count", string_compose("%1", _plugins.size()));
1965 /* remember actual i/o configuration (for later placeholder
1966 * in case the plugin goes missing) */
1967 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1968 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
1969 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1970 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
1972 /* save custom i/o config */
1973 node.add_property("custom", _custom_cfg ? "yes" : "no");
1974 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1976 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
1977 node.add_child_nocopy (* _in_map[pc].state (tmp));
1978 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
1979 node.add_child_nocopy (* _out_map[pc].state (tmp));
1981 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
1984 node.add_child_nocopy (_sidechain->state (full));
1987 _plugins[0]->set_insert_id(this->id());
1988 node.add_child_nocopy (_plugins[0]->get_state());
1990 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1991 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1993 node.add_child_nocopy (ac->get_state());
2001 PluginInsert::set_control_ids (const XMLNode& node, int version)
2003 const XMLNodeList& nlist = node.children();
2004 XMLNodeConstIterator iter;
2005 set<Evoral::Parameter>::const_iterator p;
2007 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2008 if ((*iter)->name() == Controllable::xml_node_name) {
2009 XMLProperty const * prop;
2011 uint32_t p = (uint32_t)-1;
2013 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
2014 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2016 p = lv2plugin->port_index(prop->value().c_str());
2020 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
2021 p = atoi (prop->value());
2024 if (p != (uint32_t)-1) {
2026 /* this may create the new controllable */
2028 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2030 #ifndef NO_PLUGIN_STATE
2034 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2036 ac->set_state (**iter, version);
2045 PluginInsert::set_state(const XMLNode& node, int version)
2047 XMLNodeList nlist = node.children();
2048 XMLNodeIterator niter;
2049 XMLPropertyList plist;
2050 XMLProperty const * prop;
2051 ARDOUR::PluginType type;
2053 if ((prop = node.property ("type")) == 0) {
2054 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2058 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
2059 type = ARDOUR::LADSPA;
2060 } else if (prop->value() == X_("lv2")) {
2062 } else if (prop->value() == X_("windows-vst")) {
2063 type = ARDOUR::Windows_VST;
2064 } else if (prop->value() == X_("lxvst")) {
2065 type = ARDOUR::LXVST;
2066 } else if (prop->value() == X_("audiounit")) {
2067 type = ARDOUR::AudioUnit;
2068 } else if (prop->value() == X_("luaproc")) {
2071 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2077 prop = node.property ("unique-id");
2080 #ifdef WINDOWS_VST_SUPPORT
2081 /* older sessions contain VST plugins with only an "id" field.
2084 if (type == ARDOUR::Windows_VST) {
2085 prop = node.property ("id");
2089 #ifdef LXVST_SUPPORT
2090 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2092 if (type == ARDOUR::LXVST) {
2093 prop = node.property ("id");
2099 error << _("Plugin has no unique ID field") << endmsg;
2104 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2106 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2107 * allow to move sessions windows <> linux */
2108 #ifdef LXVST_SUPPORT
2109 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2110 type = ARDOUR::LXVST;
2111 plugin = find_plugin (_session, prop->value(), type);
2115 #ifdef WINDOWS_VST_SUPPORT
2116 if (plugin == 0 && type == ARDOUR::LXVST) {
2117 type = ARDOUR::Windows_VST;
2118 plugin = find_plugin (_session, prop->value(), type);
2122 if (plugin == 0 && type == ARDOUR::Lua) {
2123 /* unique ID (sha1 of script) was not found,
2124 * load the plugin from the serialized version in the
2125 * session-file instead.
2127 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2128 XMLNode *ls = node.child (lp->state_node_name().c_str());
2130 lp->set_script_from_state (*ls);
2136 error << string_compose(
2137 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2138 "Perhaps it was removed or moved since it was last used."),
2144 // The name of the PluginInsert comes from the plugin, nothing else
2145 _name = plugin->get_info()->name;
2149 // Processor::set_state() will set this, but too late
2150 // for it to be available when setting up plugin
2151 // state. We can't call Processor::set_state() until
2152 // the plugins themselves are created and added.
2156 if (_plugins.empty()) {
2157 /* if we are adding the first plugin, we will need to set
2158 up automatable controls.
2160 add_plugin (plugin);
2161 create_automatable_parameters ();
2162 set_control_ids (node, version);
2165 if ((prop = node.property ("count")) != 0) {
2166 sscanf (prop->value().c_str(), "%u", &count);
2169 if (_plugins.size() != count) {
2170 for (uint32_t n = 1; n < count; ++n) {
2171 add_plugin (plugin_factory (plugin));
2175 Processor::set_state (node, version);
2177 PBD::ID new_id = this->id();
2178 PBD::ID old_id = this->id();
2180 if ((prop = node.property ("id")) != 0) {
2181 old_id = prop->value ();
2184 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2186 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2187 and set all plugins to the same state.
2190 if ((*niter)->name() == plugin->state_node_name()) {
2192 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2193 /* Plugin state can include external files which are named after the ID.
2195 * If regenerate_xml_or_string_ids() is set, the ID will already have
2196 * been changed, so we need to use the old ID from the XML to load the
2197 * state and then update the ID.
2199 * When copying a plugin-state, route_ui takes care of of updating the ID,
2200 * but we need to call set_insert_id() to clear the cached plugin-state
2201 * and force a change.
2203 if (!regenerate_xml_or_string_ids ()) {
2204 (*i)->set_insert_id (new_id);
2206 (*i)->set_insert_id (old_id);
2209 (*i)->set_state (**niter, version);
2211 if (regenerate_xml_or_string_ids ()) {
2212 (*i)->set_insert_id (new_id);
2220 if (version < 3000) {
2222 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2223 this is all handled by Automatable
2226 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2227 if ((*niter)->name() == "Redirect") {
2228 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2229 Processor::set_state (**niter, version);
2234 set_parameter_state_2X (node, version);
2237 if ((prop = node.property (X_("custom"))) != 0) {
2238 _custom_cfg = string_is_affirmative (prop->value());
2241 uint32_t in_maps = 0;
2242 uint32_t out_maps = 0;
2243 XMLNodeList kids = node.children ();
2244 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2245 if ((*i)->name() == X_("ConfiguredInput")) {
2246 _configured_in = ChanCount(**i);
2248 if ((*i)->name() == X_("CustomSinks")) {
2249 _custom_sinks = ChanCount(**i);
2251 if ((*i)->name() == X_("ConfiguredOutput")) {
2252 _custom_out = ChanCount(**i);
2253 _configured_out = ChanCount(**i);
2255 if ((*i)->name() == X_("PresetOutput")) {
2256 _preset_out = ChanCount(**i);
2258 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2259 long pc = atol (&((*i)->name().c_str()[9]));
2260 if (pc >= 0 && pc <= (long) get_count()) {
2261 _in_map[pc] = ChanMapping (**i);
2265 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2266 long pc = atol (&((*i)->name().c_str()[10]));
2267 if (pc >= 0 && pc <= (long) get_count()) {
2268 _out_map[pc] = ChanMapping (**i);
2272 if ((*i)->name () == "ThruMap") {
2273 _thru_map = ChanMapping (**i);
2276 // sidechain is a Processor (IO)
2277 if ((*i)->name () == Processor::state_node_name) {
2281 _sidechain->set_state (**i, version);
2285 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2286 _maps_from_state = true;
2289 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2293 (*i)->deactivate ();
2297 PluginConfigChanged (); /* EMIT SIGNAL */
2302 PluginInsert::update_id (PBD::ID id)
2305 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2306 (*i)->set_insert_id (id);
2311 PluginInsert::set_state_dir (const std::string& d)
2313 // state() only saves the state of the first plugin
2314 _plugins[0]->set_state_dir (d);
2318 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2320 XMLNodeList nlist = node.children();
2321 XMLNodeIterator niter;
2323 /* look for port automation node */
2325 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2327 if ((*niter)->name() != port_automation_node_name) {
2332 XMLProperty const * cprop;
2333 XMLNodeConstIterator iter;
2338 cnodes = (*niter)->children ("port");
2340 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2344 if ((cprop = child->property("number")) != 0) {
2345 port = cprop->value().c_str();
2347 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2351 sscanf (port, "%" PRIu32, &port_id);
2353 if (port_id >= _plugins[0]->parameter_count()) {
2354 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2358 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2359 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2361 if (c && c->alist()) {
2362 if (!child->children().empty()) {
2363 c->alist()->set_state (*child->children().front(), version);
2365 /* In some cases 2.X saves lists with min_yval and max_yval
2366 being FLT_MIN and FLT_MAX respectively. This causes problems
2367 in A3 because these min/max values are used to compute
2368 where GUI control points should be drawn. If we see such
2369 values, `correct' them to the min/max of the appropriate
2373 float min_y = c->alist()->get_min_y ();
2374 float max_y = c->alist()->get_max_y ();
2376 ParameterDescriptor desc;
2377 _plugins.front()->get_parameter_descriptor (port_id, desc);
2379 if (min_y == FLT_MIN) {
2383 if (max_y == FLT_MAX) {
2387 c->alist()->set_yrange (min_y, max_y);
2390 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2402 PluginInsert::describe_parameter (Evoral::Parameter param)
2404 if (param.type() == PluginAutomation) {
2405 return _plugins[0]->describe_parameter (param);
2406 } else if (param.type() == PluginPropertyAutomation) {
2407 boost::shared_ptr<AutomationControl> c(automation_control(param));
2408 if (c && !c->desc().label.empty()) {
2409 return c->desc().label;
2412 return Automatable::describe_parameter(param);
2416 PluginInsert::signal_latency() const
2418 if (_user_latency) {
2419 return _user_latency;
2422 return _plugins[0]->signal_latency ();
2426 PluginInsert::type ()
2428 return plugin()->get_info()->type;
2431 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2432 const Evoral::Parameter& param,
2433 const ParameterDescriptor& desc,
2434 boost::shared_ptr<AutomationList> list)
2435 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2439 alist()->reset_default (desc.normal);
2441 list->set_interpolation(Evoral::ControlList::Discrete);
2446 set_flags(Controllable::Toggle);
2450 /** @param val `user' value */
2452 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2455 _set_value (user_val, group_override);
2459 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2461 /* used only by automation playback */
2462 _set_value (user_val, Controllable::NoGroup);
2466 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2468 /* FIXME: probably should be taking out some lock here.. */
2470 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2471 (*i)->set_parameter (_list->parameter().id(), user_val);
2474 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2476 iasp->set_parameter (_list->parameter().id(), user_val);
2479 AutomationControl::set_value (user_val, group_override);
2483 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2485 AutomationControl::set_value (user_val, Controllable::NoGroup);
2489 PluginInsert::PluginControl::get_state ()
2493 XMLNode& node (AutomationControl::get_state());
2494 ss << parameter().id();
2495 node.add_property (X_("parameter"), ss.str());
2497 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2499 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2506 /** @return `user' val */
2508 PluginInsert::PluginControl::get_value () const
2510 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2516 return plugin->get_parameter (_list->parameter().id());
2519 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2520 const Evoral::Parameter& param,
2521 const ParameterDescriptor& desc,
2522 boost::shared_ptr<AutomationList> list)
2523 : AutomationControl (p->session(), param, desc, list)
2527 alist()->set_yrange (desc.lower, desc.upper);
2528 alist()->reset_default (desc.normal);
2532 set_flags(Controllable::Toggle);
2537 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2540 set_value_unchecked (user_val);
2545 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2547 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2548 This is lossy, but better than nothing until Ardour's automation system
2549 can handle various datatypes all the way down. */
2550 const Variant value(_desc.datatype, user_val);
2551 if (value.type() == Variant::NOTHING) {
2552 error << "set_value(double) called for non-numeric property" << endmsg;
2556 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2557 (*i)->set_property(_list->parameter().id(), value);
2561 AutomationControl::set_value (user_val, Controllable::NoGroup);
2565 PluginInsert::PluginPropertyControl::get_state ()
2569 XMLNode& node (AutomationControl::get_state());
2570 ss << parameter().id();
2571 node.add_property (X_("property"), ss.str());
2572 node.remove_property (X_("value"));
2578 PluginInsert::PluginPropertyControl::get_value () const
2580 return _value.to_double();
2583 boost::shared_ptr<Plugin>
2584 PluginInsert::get_impulse_analysis_plugin()
2586 boost::shared_ptr<Plugin> ret;
2587 if (_impulseAnalysisPlugin.expired()) {
2588 // LV2 in particular uses various _session params
2589 // during init() -- most notably block_size..
2591 ret = plugin_factory(_plugins[0]);
2592 ret->configure_io (internal_input_streams (), internal_output_streams ());
2593 _impulseAnalysisPlugin = ret;
2595 ret = _impulseAnalysisPlugin.lock();
2602 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2604 // called from outside the audio thread, so this should be safe
2605 // only do audio as analysis is (currently) only for audio plugins
2606 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2607 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2609 _signal_analysis_collected_nframes = 0;
2610 _signal_analysis_collect_nframes_max = nframes;
2613 /** Add a plugin to our list */
2615 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2617 plugin->set_insert_id (this->id());
2619 if (_plugins.empty()) {
2620 /* first (and probably only) plugin instance - connect to relevant signals */
2622 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2623 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2624 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2625 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2626 _custom_sinks = plugin->get_info()->n_inputs;
2627 // cache sidechain port count
2628 _cached_sidechain_pins.reset ();
2629 const ChanCount& nis (plugin->get_info()->n_inputs);
2630 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2631 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2632 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2633 if (iod.is_sidechain) {
2634 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2639 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2640 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2642 vst->set_insert (this, _plugins.size ());
2645 _plugins.push_back (plugin);
2649 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
2652 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2653 if (! (*i)->load_preset (pr)) {
2661 PluginInsert::realtime_handle_transport_stopped ()
2663 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2664 (*i)->realtime_handle_transport_stopped ();
2669 PluginInsert::realtime_locate ()
2671 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2672 (*i)->realtime_locate ();
2677 PluginInsert::monitoring_changed ()
2679 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2680 (*i)->monitoring_changed ();
2685 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2687 // this is called in RT context, LatencyChanged is emitted after run()
2688 _latency_changed = true;
2692 PluginInsert::start_touch (uint32_t param_id)
2694 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2696 ac->start_touch (session().audible_frame());
2701 PluginInsert::end_touch (uint32_t param_id)
2703 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2705 ac->stop_touch (true, session().audible_frame());
2709 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2712 case PluginInsert::Impossible: o << "Impossible"; break;
2713 case PluginInsert::Delegate: o << "Delegate"; break;
2714 case PluginInsert::NoInputs: o << "NoInputs"; break;
2715 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2716 case PluginInsert::Replicate: o << "Replicate"; break;
2717 case PluginInsert::Split: o << "Split"; break;
2718 case PluginInsert::Hide: o << "Hide"; break;
2720 o << " cnt: " << m.plugins
2721 << (m.strict_io ? " strict-io" : "")
2722 << (m.custom_cfg ? " custom-cfg" : "");
2723 if (m.method == PluginInsert::Hide) {
2724 o << " hide: " << m.hide;