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::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, framecnt_t nframes, framecnt_t offset) const
503 // TODO optimize: store "unconnected" in a fixed set.
504 // it only changes on reconfiguration.
505 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
506 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
508 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
509 mapped = true; // in-place Midi bypass
511 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
512 PinMappings::const_iterator i = out_map.find (pc);
513 if (i == out_map.end ()) {
516 const ChanMapping& outmap (i->second);
517 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
519 uint32_t idx = outmap.get (*t, o, &valid);
520 if (valid && idx == out) {
527 bufs.get (*t, out).silence (nframes, offset);
534 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
536 // TODO: atomically copy maps & _no_inplace
537 PinMappings in_map (_in_map);
538 PinMappings out_map (_out_map);
539 ChanMapping thru_map (_thru_map);
540 if (_mapping_changed) { // ToDo use a counters, increment until match.
541 _no_inplace = check_inplace ();
542 _mapping_changed = false;
545 if (_latency_changed) {
546 /* delaylines are configured with the max possible latency (as reported by the plugin)
547 * so this won't allocate memory (unless the plugin lied about its max latency)
548 * It may still 'click' though, since the fixed delaylines are not de-clicked.
549 * Then again plugin-latency changes are not click-free to begin with.
551 * This is also worst case, there is currently no concept of per-stream latency.
553 * e.g. Two identical latent plugins:
554 * 1st plugin: process left (latent), bypass right.
555 * 2nd plugin: bypass left, process right (latent).
556 * -> currently this yields 2 times latency of the plugin,
558 _latency_changed = false;
559 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
562 if (_match.method == Split && !_no_inplace) {
563 // TODO: also use this optimization if one source-buffer
564 // feeds _all_ *connected* inputs.
565 // currently this is *first* buffer to all only --
566 // see PluginInsert::check_inplace
567 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
568 if (_configured_internal.get (*t) == 0) {
572 uint32_t first_idx = in_map[0].get (*t, 0, &valid);
573 assert (valid && first_idx == 0); // check_inplace ensures this
574 /* copy the first stream's buffer contents to the others */
575 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
576 uint32_t idx = in_map[0].get (*t, i, &valid);
579 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, offset, offset);
583 /* the copy operation produces a linear monotonic input map */
584 in_map[0] = ChanMapping (natural_input_streams ());
587 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
588 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
594 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
596 boost::shared_ptr<AutomationControl> c
597 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
599 if (c->list() && c->automation_playback()) {
602 const float val = c->list()->rt_safe_eval (now, valid);
605 /* This is the ONLY place where we are
607 * AutomationControl::set_value_unchecked(). We
608 * know that the control is in
609 * automation playback mode, so no
610 * check on writable() is required
611 * (which must be done in AutomationControl::set_value()
614 c->set_value_unchecked(val);
621 /* Calculate if, and how many frames we need to collect for analysis */
622 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
623 _signal_analysis_collected_nframes);
624 if (nframes < collect_signal_nframes) { // we might not get all frames now
625 collect_signal_nframes = nframes;
628 if (collect_signal_nframes > 0) {
630 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
631 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
632 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
634 _signal_analysis_inputs.set_count(internal_input_streams());
636 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
637 _signal_analysis_inputs.get_audio(i).read_from(
639 collect_signal_nframes,
640 _signal_analysis_collected_nframes); // offset is for target buffer
645 if (is_channelstrip ()) {
646 if (_configured_in.n_audio() > 0) {
647 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
648 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
650 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
652 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
653 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
659 // TODO optimize -- build maps once.
661 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
662 ARDOUR::ChanMapping used_outputs;
664 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
666 /* build used-output map */
667 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
668 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
669 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
671 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
673 used_outputs.set (*t, out_idx, 1); // mark as used
678 /* copy thru data to outputs before processing in-place */
679 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
680 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
682 uint32_t in_idx = thru_map.get (*t, out, &valid);
683 uint32_t m = out + natural_input_streams ().get (*t);
685 _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset);
686 used_outputs.set (*t, out, 1); // mark as used
688 used_outputs.get (*t, out, &valid);
690 /* the plugin is expected to write here, but may not :(
691 * (e.g. drumgizmo w/o kit loaded)
693 inplace_bufs.get (*t, m).silence (nframes);
700 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
702 ARDOUR::ChanMapping i_in_map (natural_input_streams());
703 ARDOUR::ChanMapping i_out_map (out_map[pc]);
704 ARDOUR::ChanCount mapped;
706 /* map inputs sequentially */
707 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
708 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
710 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
711 uint32_t m = mapped.get (*t);
713 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
715 inplace_bufs.get (*t, m).silence (nframes, offset);
717 mapped.set (*t, m + 1);
721 /* outputs are mapped to inplace_bufs after the inputs */
722 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
723 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
726 if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
731 /* all instances have completed, now copy data that was written
732 * and zero unconnected buffers */
733 ARDOUR::ChanMapping nonzero_out (used_outputs);
734 if (has_midi_bypass ()) {
735 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
737 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
738 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
740 used_outputs.get (*t, out, &valid);
742 nonzero_out.get (*t, out, &valid);
744 bufs.get (*t, out).silence (nframes, offset);
747 uint32_t m = out + natural_input_streams ().get (*t);
748 bufs.get (*t, out).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
753 /* in-place processing */
755 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
756 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
760 // now silence unconnected outputs
761 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
764 if (collect_signal_nframes > 0) {
766 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
767 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
769 _signal_analysis_outputs.set_count(internal_output_streams());
771 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
772 _signal_analysis_outputs.get_audio(i).read_from(
774 collect_signal_nframes,
775 _signal_analysis_collected_nframes); // offset is for target buffer
778 _signal_analysis_collected_nframes += collect_signal_nframes;
779 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
781 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
782 _signal_analysis_collect_nframes_max = 0;
783 _signal_analysis_collected_nframes = 0;
785 AnalysisDataGathered(&_signal_analysis_inputs,
786 &_signal_analysis_outputs);
792 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
794 /* bypass the plugin(s) not the whole processor.
795 * -> use mappings just like connect_and_run
798 // TODO: atomically copy maps & _no_inplace
799 ChanMapping in_map (input_map ());
800 ChanMapping out_map (output_map ());
801 if (_mapping_changed) {
802 _no_inplace = check_inplace ();
803 _mapping_changed = false;
806 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
807 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
810 ChanMapping thru_map (_thru_map);
812 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
814 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
815 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
816 inplace_bufs.get (*t, in).read_from (bufs.get (*t, in), nframes, 0, 0);
819 ARDOUR::ChanMapping used_outputs;
821 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
822 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
824 uint32_t in_idx = thru_map.get (*t, out, &valid);
826 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
827 used_outputs.set (*t, out, 1); // mark as used
831 // plugin no-op: assume every plugin has an internal identity map
832 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
833 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
835 uint32_t src_idx = out_map.get_src (*t, out, &valid);
839 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
843 bufs.get (*t, out).read_from (inplace_bufs.get (*t, in_idx), nframes, 0, 0);
844 used_outputs.set (*t, out, 1); // mark as used
847 // now silence all unused outputs
848 if (has_midi_bypass ()) {
849 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
851 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
852 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
854 used_outputs.get (*t, out, &valid);
856 bufs.get (*t, out).silence (nframes, 0);
861 if (_match.method == Split) {
862 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
863 if (_configured_internal.get (*t) == 0) {
866 // copy/feeds _all_ *connected* inputs, copy the first buffer
868 uint32_t first_idx = in_map.get (*t, 0, &valid);
869 assert (valid && first_idx == 0); // check_inplace ensures this
870 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
871 uint32_t idx = in_map.get (*t, i, &valid);
874 bufs.get (*t, i).read_from (bufs.get (*t, first_idx), nframes, 0, 0);
880 // apply output map and/or monotonic but not identity i/o mappings
881 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
882 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
884 uint32_t src_idx = out_map.get_src (*t, out, &valid);
886 bufs.get (*t, out).silence (nframes, 0);
889 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
891 bufs.get (*t, out).silence (nframes, 0);
894 if (in_idx != src_idx) {
895 bufs.get (*t, out).read_from (bufs.get (*t, in_idx), nframes, 0, 0);
903 PluginInsert::silence (framecnt_t nframes)
909 _delaybuffers.flush ();
911 ChanMapping in_map (natural_input_streams ());
912 ChanMapping out_map (natural_output_streams ());
913 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
915 if (is_channelstrip ()) {
916 if (_configured_in.n_audio() > 0) {
917 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
921 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
922 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
927 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
929 if (_pending_active) {
930 /* run as normal if we are active or moving from inactive to active */
933 // collect sidechain input for complete cycle (!)
934 // TODO we need delaylines here for latency compensation
935 _sidechain->run (bufs, start_frame, end_frame, nframes, true);
938 if (_session.transport_rolling() || _session.bounce_processing()) {
939 automation_run (bufs, start_frame, nframes);
941 connect_and_run (bufs, nframes, 0, false);
945 bypass (bufs, nframes);
946 _delaybuffers.flush ();
949 _active = _pending_active;
951 /* we have no idea whether the plugin generated silence or not, so mark
952 * all buffers appropriately.
957 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
959 Evoral::ControlEvent next_event (0, 0.0f);
960 framepos_t now = start;
961 framepos_t end = now + nframes;
962 framecnt_t offset = 0;
964 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
967 connect_and_run (bufs, nframes, offset, false);
971 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
973 /* no events have a time within the relevant range */
975 connect_and_run (bufs, nframes, offset, true, now);
981 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
983 connect_and_run (bufs, cnt, offset, true, now);
989 if (!find_next_event (now, end, next_event)) {
994 /* cleanup anything that is left to do */
997 connect_and_run (bufs, nframes, offset, true, now);
1002 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1004 if (param.type() != PluginAutomation)
1007 if (_plugins.empty()) {
1008 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1010 abort(); /*NOTREACHED*/
1013 return _plugins[0]->default_value (param.id());
1018 PluginInsert::can_reset_all_parameters ()
1021 uint32_t params = 0;
1022 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1024 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1026 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1030 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1036 if (ac->automation_state() & Play) {
1041 return all && (params > 0);
1045 PluginInsert::reset_parameters_to_default ()
1049 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1051 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1053 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1057 const float dflt = _plugins[0]->default_value (cid);
1058 const float curr = _plugins[0]->get_parameter (cid);
1064 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1069 if (ac->automation_state() & Play) {
1074 ac->set_value (dflt, Controllable::NoGroup);
1079 boost::shared_ptr<Plugin>
1080 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1082 boost::shared_ptr<LadspaPlugin> lp;
1083 boost::shared_ptr<LuaProc> lua;
1085 boost::shared_ptr<LV2Plugin> lv2p;
1087 #ifdef WINDOWS_VST_SUPPORT
1088 boost::shared_ptr<WindowsVSTPlugin> vp;
1090 #ifdef LXVST_SUPPORT
1091 boost::shared_ptr<LXVSTPlugin> lxvp;
1093 #ifdef AUDIOUNIT_SUPPORT
1094 boost::shared_ptr<AUPlugin> ap;
1097 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1098 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1099 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1100 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1102 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1103 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1105 #ifdef WINDOWS_VST_SUPPORT
1106 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1107 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1109 #ifdef LXVST_SUPPORT
1110 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1111 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1113 #ifdef AUDIOUNIT_SUPPORT
1114 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1115 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1119 fatal << string_compose (_("programming error: %1"),
1120 X_("unknown plugin type in PluginInsert::plugin_factory"))
1122 abort(); /*NOTREACHED*/
1123 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1127 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1128 if (num < _in_map.size()) {
1129 bool changed = _in_map[num] != m;
1131 changed |= sanitize_maps ();
1133 PluginMapChanged (); /* EMIT SIGNAL */
1134 _mapping_changed = true;
1135 _session.set_dirty();
1141 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1142 if (num < _out_map.size()) {
1143 bool changed = _out_map[num] != m;
1145 changed |= sanitize_maps ();
1147 PluginMapChanged (); /* EMIT SIGNAL */
1148 _mapping_changed = true;
1149 _session.set_dirty();
1155 PluginInsert::set_thru_map (ChanMapping m) {
1156 bool changed = _thru_map != m;
1158 changed |= sanitize_maps ();
1160 PluginMapChanged (); /* EMIT SIGNAL */
1161 _mapping_changed = true;
1162 _session.set_dirty();
1167 PluginInsert::input_map () const
1171 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1172 ChanMapping m (i->second);
1173 const ChanMapping::Mappings& mp ((*i).second.mappings());
1174 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1175 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1176 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1184 PluginInsert::output_map () const
1188 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1189 ChanMapping m (i->second);
1190 const ChanMapping::Mappings& mp ((*i).second.mappings());
1191 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1192 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1193 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1197 if (has_midi_bypass ()) {
1198 rv.set (DataType::MIDI, 0, 0);
1205 PluginInsert::has_midi_bypass () const
1207 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1208 && natural_output_streams ().n_midi () == 0) {
1215 PluginInsert::has_midi_thru () const
1217 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1218 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1226 PluginInsert::is_channelstrip () const {
1227 return _plugins.front()->is_channelstrip();
1232 PluginInsert::check_inplace ()
1234 bool inplace_ok = !_plugins.front()->inplace_broken ();
1236 if (_thru_map.n_total () > 0) {
1237 // TODO once midi-bypass is part of the mapping, ignore it
1241 if (_match.method == Split && inplace_ok) {
1242 assert (get_count() == 1);
1243 assert (_in_map.size () == 1);
1244 if (!_out_map[0].is_monotonic ()) {
1247 if (_configured_internal != _configured_in) {
1248 /* no sidechain -- TODO we could allow this with
1249 * some more logic in PluginInsert::connect_and_run().
1251 * PluginInsert::reset_map() already maps it.
1256 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1257 if (_configured_internal.get (*t) == 0) {
1261 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1262 if (!valid || first_idx != 0) {
1263 // so far only allow to copy the *first* stream's buffer to others
1266 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1267 uint32_t idx = _in_map[0].get (*t, i, &valid);
1268 if (valid && idx != first_idx) {
1277 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1282 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1283 if (!_in_map[pc].is_monotonic ()) {
1286 if (!_out_map[pc].is_monotonic ()) {
1290 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1291 return !inplace_ok; // no-inplace
1295 PluginInsert::sanitize_maps ()
1297 bool changed = false;
1298 /* strip dead wood */
1299 PinMappings new_ins;
1300 PinMappings new_outs;
1301 ChanMapping new_thru;
1303 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1305 ChanMapping new_out;
1306 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1307 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1309 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1310 if (valid && idx < _configured_internal.get (*t)) {
1311 new_in.set (*t, i, idx);
1314 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1316 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1317 if (valid && idx < _configured_out.get (*t)) {
1318 new_out.set (*t, o, idx);
1322 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1325 new_ins[pc] = new_in;
1326 new_outs[pc] = new_out;
1329 /* prevent dup output assignments */
1330 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1331 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1332 bool mapped = false;
1333 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1335 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1336 if (valid && mapped) {
1337 new_outs[pc].unset (*t, idx);
1345 /* remove excess thru */
1346 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1347 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1349 uint32_t idx = _thru_map.get (*t, o, &valid);
1350 if (valid && idx < _configured_internal.get (*t)) {
1351 new_thru.set (*t, o, idx);
1356 /* prevent out + thru, existing plugin outputs override thru */
1357 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1358 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1359 bool mapped = false;
1361 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1362 new_outs[pc].get_src (*t, o, &mapped);
1363 if (mapped) { break; }
1365 if (!mapped) { continue; }
1366 uint32_t idx = new_thru.get (*t, o, &valid);
1368 new_thru.unset (*t, idx);
1373 if (has_midi_bypass ()) {
1374 // TODO: include midi-bypass in the thru set,
1375 // remove dedicated handling.
1376 new_thru.unset (DataType::MIDI, 0);
1379 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1383 _out_map = new_outs;
1384 _thru_map = new_thru;
1390 PluginInsert::reset_map (bool emit)
1392 const PinMappings old_in (_in_map);
1393 const PinMappings old_out (_out_map);
1397 _thru_map = ChanMapping ();
1399 /* build input map */
1400 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1401 uint32_t sc = 0; // side-chain round-robin (all instances)
1403 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1404 const uint32_t nis = natural_input_streams ().get(*t);
1405 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1407 /* SC inputs are last in the plugin-insert.. */
1408 const uint32_t sc_start = _configured_in.get (*t);
1409 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1410 /* ...but may not be at the end of the plugin ports.
1411 * in case the side-chain is not the last port, shift connections back.
1412 * and connect to side-chain
1415 uint32_t ic = 0; // split inputs
1416 const uint32_t cend = _configured_in.get (*t);
1418 for (uint32_t in = 0; in < nis; ++in) {
1419 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1420 if (iod.is_sidechain) {
1421 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1422 if (sc_len > 0) {// side-chain may be hidden
1423 _in_map[pc].set (*t, in, sc_start + sc);
1424 sc = (sc + 1) % sc_len;
1428 if (_match.method == Split) {
1429 if (cend == 0) { continue; }
1430 if (_strict_io && ic + stride * pc >= cend) {
1433 /* connect *no* sidechain sinks in round-robin fashion */
1434 _in_map[pc].set (*t, in, ic + stride * pc);
1435 if (_strict_io && (ic + 1) == cend) {
1438 ic = (ic + 1) % cend;
1440 uint32_t s = in - shift;
1441 if (stride * pc + s < cend) {
1442 _in_map[pc].set (*t, in, s + stride * pc);
1450 /* build output map */
1452 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1453 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1454 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1455 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1460 if (old_in == _in_map && old_out == _out_map) {
1464 PluginMapChanged (); /* EMIT SIGNAL */
1465 _mapping_changed = true;
1466 _session.set_dirty();
1472 PluginInsert::configure_io (ChanCount in, ChanCount out)
1474 Match old_match = _match;
1476 ChanCount old_internal;
1480 old_pins = natural_input_streams();
1481 old_in = _configured_in;
1482 old_out = _configured_out;
1483 old_internal = _configured_internal;
1485 _configured_in = in;
1486 _configured_internal = in;
1487 _configured_out = out;
1490 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1491 * (currently _sidechain->configure_io always succeeds
1492 * since Processor::configure_io() succeeds)
1494 if (!_sidechain->configure_io (in, out)) {
1495 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1498 _configured_internal += _sidechain->input()->n_ports();
1500 // include (static_cast<Route*>owner())->name() ??
1501 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1504 /* get plugin configuration */
1505 _match = private_can_support_io_configuration (in, out);
1507 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1509 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1510 DEBUG_STR_APPEND(a, _match);
1511 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1515 /* set the matching method and number of plugins that we will use to meet this configuration */
1516 if (set_count (_match.plugins) == false) {
1517 PluginIoReConfigure (); /* EMIT SIGNAL */
1518 _configured = false;
1522 /* configure plugins */
1523 switch (_match.method) {
1526 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
1527 PluginIoReConfigure (); /* EMIT SIGNAL */
1528 _configured = false;
1534 ChanCount din (_configured_internal);
1535 ChanCount dout (din); // hint
1537 if (_custom_sinks.n_total () > 0) {
1538 din = _custom_sinks;
1541 } else if (_preset_out.n_audio () > 0) {
1542 dout.set (DataType::AUDIO, _preset_out.n_audio ());
1543 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
1544 dout.set (DataType::AUDIO, 2);
1546 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1548 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup : %2 %3\n", name(), din, dout));
1549 bool const r = _plugins.front()->can_support_io_configuration (din, dout, &useins);
1551 if (useins.n_audio() == 0) {
1554 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3\n", name(), useins, dout));
1556 if (_plugins.front()->configure_io (useins, dout) == false) {
1557 PluginIoReConfigure (); /* EMIT SIGNAL */
1558 _configured = false;
1562 _custom_sinks = din;
1567 if (_plugins.front()->configure_io (in, out) == false) {
1568 PluginIoReConfigure (); /* EMIT SIGNAL */
1569 _configured = false;
1575 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",
1577 _configured ? "Y" : "N",
1578 _maps_from_state ? "Y" : "N",
1579 old_in == in ? "==" : "!=",
1580 old_out == out ? "==" : "!=",
1581 old_pins == natural_input_streams () ? "==" : "!=",
1582 old_match.method == _match.method ? "==" : "!=",
1583 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
1584 _in_map.size() == get_count () ? "==" : "!=",
1585 _out_map.size() == get_count () ? "==" : "!="
1588 bool mapping_changed = false;
1589 if (old_in == in && old_out == out
1591 && old_pins == natural_input_streams ()
1592 && old_match.method == _match.method
1593 && old_match.custom_cfg == _match.custom_cfg
1594 && _in_map.size() == _out_map.size()
1595 && _in_map.size() == get_count ()
1597 assert (_maps_from_state == false);
1598 /* If the configuration has not changed, keep the mapping */
1599 mapping_changed = sanitize_maps ();
1600 } else if (_match.custom_cfg && _configured) {
1601 assert (_maps_from_state == false);
1602 /* don't touch the map in manual mode */
1603 mapping_changed = sanitize_maps ();
1606 if (is_channelstrip ()) {
1607 /* fake channel map - for wire display */
1610 _thru_map = ChanMapping ();
1611 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
1612 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
1613 /* set "thru" map for in-place forward of audio */
1614 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
1615 _thru_map.set (DataType::AUDIO, i, i);
1617 /* and midi (after implicit 1st channel bypass) */
1618 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
1619 _thru_map.set (DataType::MIDI, i, i);
1623 if (_maps_from_state && old_in == in && old_out == out) {
1624 mapping_changed = true;
1627 /* generate a new mapping */
1628 mapping_changed = reset_map (false);
1630 _maps_from_state = false;
1633 if (mapping_changed) {
1634 PluginMapChanged (); /* EMIT SIGNAL */
1637 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1640 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
1641 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1643 DEBUG_STR_APPEND(a, "----><----\n");
1645 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
1646 DEBUG_STR_APPEND(a, " * Inputs:\n");
1647 DEBUG_STR_APPEND(a, _in_map[pc]);
1648 DEBUG_STR_APPEND(a, " * Outputs:\n");
1649 DEBUG_STR_APPEND(a, _out_map[pc]);
1651 DEBUG_STR_APPEND(a, " * Thru:\n");
1652 DEBUG_STR_APPEND(a, _thru_map);
1653 DEBUG_STR_APPEND(a, "-------->>--------\n");
1654 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1659 _no_inplace = check_inplace ();
1660 _mapping_changed = false;
1662 /* only the "noinplace_buffers" thread buffers need to be this large,
1663 * this can be optimized. other buffers are fine with
1664 * ChanCount::max (natural_input_streams (), natural_output_streams())
1665 * and route.cc's max (configured_in, configured_out)
1667 * no-inplace copies "thru" outputs (to emulate in-place) for
1668 * all outputs (to prevent overwrite) into a temporary space
1669 * which also holds input buffers (in case the plugin does process
1670 * in-place and overwrites those).
1672 * this buffers need to be at least as
1673 * natural_input_streams () + possible outputs.
1675 * sidechain inputs add a constraint on the input:
1676 * configured input + sidechain (=_configured_internal)
1678 * NB. this also satisfies
1679 * max (natural_input_streams(), natural_output_streams())
1680 * which is needed for silence runs
1682 _required_buffers = ChanCount::max (_configured_internal,
1683 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
1685 if (old_in != in || old_out != out || old_internal != _configured_internal
1686 || old_pins != natural_input_streams ()
1687 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1689 PluginIoReConfigure (); /* EMIT SIGNAL */
1692 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
1693 _latency_changed = true;
1695 // we don't know the analysis window size, so we must work with the
1696 // current buffer size here. each request for data fills in these
1697 // buffers and the analyser makes sure it gets enough data for the
1699 session().ensure_buffer_set (_signal_analysis_inputs, in);
1700 //_signal_analysis_inputs.set_count (in);
1702 session().ensure_buffer_set (_signal_analysis_outputs, out);
1703 //_signal_analysis_outputs.set_count (out);
1705 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1708 return Processor::configure_io (in, out);
1711 /** Decide whether this PluginInsert can support a given IO configuration.
1712 * To do this, we run through a set of possible solutions in rough order of
1715 * @param in Required input channel count.
1716 * @param out Filled in with the output channel count if we return true.
1717 * @return true if the given IO configuration can be supported.
1720 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1723 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
1725 return private_can_support_io_configuration (in, out).method != Impossible;
1729 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
1731 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1732 // preseed hint (for variable i/o)
1733 out.set (DataType::AUDIO, _preset_out.n_audio ());
1736 Match rv = internal_can_support_io_configuration (in, out);
1738 if (!_custom_cfg && _preset_out.n_audio () > 0) {
1739 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
1740 out.set (DataType::AUDIO, _preset_out.n_audio ());
1745 /** A private version of can_support_io_configuration which returns the method
1746 * by which the configuration can be matched, rather than just whether or not
1750 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1752 if (_plugins.empty()) {
1757 if (is_channelstrip ()) {
1759 return Match (ExactMatch, 1);
1763 /* if a user specified a custom cfg, so be it. */
1765 PluginInfoPtr info = _plugins.front()->get_info();
1767 if (info->reconfigurable_io()) {
1768 return Match (Delegate, 1, _strict_io, true);
1770 return Match (ExactMatch, get_count(), _strict_io, true);
1774 /* try automatic configuration */
1775 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1777 PluginInfoPtr info = _plugins.front()->get_info();
1778 ChanCount inputs = info->n_inputs;
1779 ChanCount outputs = info->n_outputs;
1781 /* handle case strict-i/o */
1782 if (_strict_io && m.method != Impossible) {
1785 /* special case MIDI instruments */
1786 if (needs_midi_input ()) {
1787 // output = midi-bypass + at most master-out channels.
1788 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1789 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1790 out = ChanCount::min (out, max_out);
1791 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
1797 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1798 /* replicate processor to match output count (generators and such)
1799 * at least enough to feed every output port. */
1800 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1801 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1802 uint32_t nout = outputs.get (*t);
1803 if (nout == 0 || inx.get(*t) == 0) { continue; }
1804 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
1807 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
1808 return Match (Replicate, f, _strict_io);
1819 if (m.method != Impossible) {
1823 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1825 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
1827 if (info->reconfigurable_io()) {
1830 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1831 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1832 bool const r = _plugins.front()->can_support_io_configuration (inx + sidechain_input_pins (), out, &useins);
1834 // houston, we have a problem.
1835 return Match (Impossible, 0);
1837 return Match (Delegate, 1, _strict_io);
1840 ChanCount midi_bypass;
1841 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1842 midi_bypass.set (DataType::MIDI, 1);
1845 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
1847 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1848 uint32_t nin = ns_inputs.get (*t);
1849 uint32_t nout = outputs.get (*t);
1850 if (nin == 0 || inx.get(*t) == 0) { continue; }
1851 // prefer floor() so the count won't overly increase IFF (nin < nout)
1852 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1854 if (f > 0 && outputs * f >= _configured_out) {
1855 out = outputs * f + midi_bypass;
1856 return Match (Replicate, f, _strict_io);
1859 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
1861 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1862 uint32_t nin = ns_inputs.get (*t);
1863 if (nin == 0 || inx.get(*t) == 0) { continue; }
1864 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1867 out = outputs * f + midi_bypass;
1868 return Match (Replicate, f, _strict_io);
1871 // add at least as many plugins needed to connect all inputs
1873 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1874 uint32_t nin = inputs.get (*t);
1875 if (nin == 0 || inx.get(*t) == 0) { continue; }
1876 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1878 out = outputs * f + midi_bypass;
1879 return Match (Replicate, f, _strict_io);
1882 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1884 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1886 if (_plugins.empty()) {
1890 PluginInfoPtr info = _plugins.front()->get_info();
1891 ChanCount in; in += inx;
1892 ChanCount midi_bypass;
1894 if (info->reconfigurable_io()) {
1895 /* Plugin has flexible I/O, so delegate to it
1896 * pre-seed outputs, plugin tries closest match
1899 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
1900 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
1901 bool const r = _plugins.front()->can_support_io_configuration (in + sidechain_input_pins (), out);
1903 return Match (Impossible, 0);
1905 return Match (Delegate, 1);
1908 ChanCount inputs = info->n_inputs;
1909 ChanCount outputs = info->n_outputs;
1910 ChanCount ns_inputs = inputs - sidechain_input_pins ();
1912 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1913 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
1914 midi_bypass.set (DataType::MIDI, 1);
1916 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1917 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
1918 in.set(DataType::MIDI, 0);
1921 // add internally provided sidechain ports
1922 ChanCount insc = in + sidechain_input_ports ();
1924 bool no_inputs = true;
1925 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1926 if (inputs.get (*t) != 0) {
1933 /* no inputs so we can take any input configuration since we throw it away */
1934 out = outputs + midi_bypass;
1935 return Match (NoInputs, 1);
1938 /* Plugin inputs match requested inputs + side-chain-ports exactly */
1939 if (inputs == insc) {
1940 out = outputs + midi_bypass;
1941 return Match (ExactMatch, 1);
1944 /* Plugin inputs matches without side-chain-pins */
1945 if (ns_inputs == in) {
1946 out = outputs + midi_bypass;
1947 return Match (ExactMatch, 1);
1950 /* We may be able to run more than one copy of the plugin within this insert
1951 to cope with the insert having more inputs than the plugin.
1952 We allow replication only for plugins with either zero or 1 inputs and outputs
1953 for every valid data type.
1957 bool can_replicate = true;
1958 for (DataType::iterator t = DataType::begin(); t != DataType::end() && can_replicate; ++t) {
1960 // ignore side-chains
1961 uint32_t nin = ns_inputs.get (*t);
1963 // No inputs of this type
1964 if (nin == 0 && in.get(*t) == 0) {
1968 if (nin != 1 || outputs.get (*t) != 1) {
1969 can_replicate = false;
1973 // Potential factor not set yet
1975 f = in.get(*t) / nin;
1978 // Factor for this type does not match another type, can not replicate
1979 if (f != (in.get(*t) / nin)) {
1980 can_replicate = false;
1985 if (can_replicate && f > 0) {
1986 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1987 out.set (*t, outputs.get(*t) * f);
1990 return Match (Replicate, f);
1993 /* If the processor has exactly one input of a given type, and
1994 the plugin has more, we can feed the single processor input
1995 to some or all of the plugin inputs. This is rather
1996 special-case-y, but the 1-to-many case is by far the
1997 simplest. How do I split thy 2 processor inputs to 3
1998 plugin inputs? Let me count the ways ...
2001 bool can_split = true;
2002 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2004 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2005 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2007 if (!can_split_type && !nothing_to_do_for_type) {
2013 out = outputs + midi_bypass;
2014 return Match (Split, 1);
2017 /* If the plugin has more inputs than we want, we can `hide' some of them
2018 by feeding them silence.
2021 bool could_hide = false;
2022 bool cannot_hide = false;
2023 ChanCount hide_channels;
2025 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2026 if (inputs.get(*t) > in.get(*t)) {
2027 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2028 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2030 } else if (inputs.get(*t) < in.get(*t)) {
2031 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2036 if (could_hide && !cannot_hide) {
2037 out = outputs + midi_bypass;
2038 return Match (Hide, 1, false, false, hide_channels);
2041 return Match (Impossible, 0);
2046 PluginInsert::get_state ()
2048 return state (true);
2052 PluginInsert::state (bool full)
2054 XMLNode& node = Processor::state (full);
2056 node.add_property("type", _plugins[0]->state_node_name());
2057 node.add_property("unique-id", _plugins[0]->unique_id());
2058 node.add_property("count", string_compose("%1", _plugins.size()));
2060 /* remember actual i/o configuration (for later placeholder
2061 * in case the plugin goes missing) */
2062 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2063 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2064 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2065 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2067 /* save custom i/o config */
2068 node.add_property("custom", _custom_cfg ? "yes" : "no");
2069 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2071 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2072 node.add_child_nocopy (* _in_map[pc].state (tmp));
2073 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2074 node.add_child_nocopy (* _out_map[pc].state (tmp));
2076 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2079 node.add_child_nocopy (_sidechain->state (full));
2082 _plugins[0]->set_insert_id(this->id());
2083 node.add_child_nocopy (_plugins[0]->get_state());
2085 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2086 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2088 node.add_child_nocopy (ac->get_state());
2096 PluginInsert::set_control_ids (const XMLNode& node, int version)
2098 const XMLNodeList& nlist = node.children();
2099 XMLNodeConstIterator iter;
2100 set<Evoral::Parameter>::const_iterator p;
2102 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
2103 if ((*iter)->name() == Controllable::xml_node_name) {
2104 XMLProperty const * prop;
2106 uint32_t p = (uint32_t)-1;
2108 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
2109 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2111 p = lv2plugin->port_index(prop->value().c_str());
2115 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
2116 p = atoi (prop->value());
2119 if (p != (uint32_t)-1) {
2121 /* this may create the new controllable */
2123 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2125 #ifndef NO_PLUGIN_STATE
2129 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2131 ac->set_state (**iter, version);
2140 PluginInsert::set_state(const XMLNode& node, int version)
2142 XMLNodeList nlist = node.children();
2143 XMLNodeIterator niter;
2144 XMLPropertyList plist;
2145 XMLProperty const * prop;
2146 ARDOUR::PluginType type;
2148 if ((prop = node.property ("type")) == 0) {
2149 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2153 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
2154 type = ARDOUR::LADSPA;
2155 } else if (prop->value() == X_("lv2")) {
2157 } else if (prop->value() == X_("windows-vst")) {
2158 type = ARDOUR::Windows_VST;
2159 } else if (prop->value() == X_("lxvst")) {
2160 type = ARDOUR::LXVST;
2161 } else if (prop->value() == X_("audiounit")) {
2162 type = ARDOUR::AudioUnit;
2163 } else if (prop->value() == X_("luaproc")) {
2166 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
2172 prop = node.property ("unique-id");
2175 #ifdef WINDOWS_VST_SUPPORT
2176 /* older sessions contain VST plugins with only an "id" field.
2179 if (type == ARDOUR::Windows_VST) {
2180 prop = node.property ("id");
2184 #ifdef LXVST_SUPPORT
2185 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2187 if (type == ARDOUR::LXVST) {
2188 prop = node.property ("id");
2194 error << _("Plugin has no unique ID field") << endmsg;
2199 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2201 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
2202 * allow to move sessions windows <> linux */
2203 #ifdef LXVST_SUPPORT
2204 if (plugin == 0 && type == ARDOUR::Windows_VST) {
2205 type = ARDOUR::LXVST;
2206 plugin = find_plugin (_session, prop->value(), type);
2210 #ifdef WINDOWS_VST_SUPPORT
2211 if (plugin == 0 && type == ARDOUR::LXVST) {
2212 type = ARDOUR::Windows_VST;
2213 plugin = find_plugin (_session, prop->value(), type);
2217 if (plugin == 0 && type == ARDOUR::Lua) {
2218 /* unique ID (sha1 of script) was not found,
2219 * load the plugin from the serialized version in the
2220 * session-file instead.
2222 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2223 XMLNode *ls = node.child (lp->state_node_name().c_str());
2225 lp->set_script_from_state (*ls);
2231 error << string_compose(
2232 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2233 "Perhaps it was removed or moved since it was last used."),
2239 // The name of the PluginInsert comes from the plugin, nothing else
2240 _name = plugin->get_info()->name;
2244 // Processor::set_state() will set this, but too late
2245 // for it to be available when setting up plugin
2246 // state. We can't call Processor::set_state() until
2247 // the plugins themselves are created and added.
2251 if (_plugins.empty()) {
2252 /* if we are adding the first plugin, we will need to set
2253 up automatable controls.
2255 add_plugin (plugin);
2256 create_automatable_parameters ();
2257 set_control_ids (node, version);
2260 if ((prop = node.property ("count")) != 0) {
2261 sscanf (prop->value().c_str(), "%u", &count);
2264 if (_plugins.size() != count) {
2265 for (uint32_t n = 1; n < count; ++n) {
2266 add_plugin (plugin_factory (plugin));
2270 Processor::set_state (node, version);
2272 PBD::ID new_id = this->id();
2273 PBD::ID old_id = this->id();
2275 if ((prop = node.property ("id")) != 0) {
2276 old_id = prop->value ();
2279 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2281 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2282 and set all plugins to the same state.
2285 if ((*niter)->name() == plugin->state_node_name()) {
2287 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2288 /* Plugin state can include external files which are named after the ID.
2290 * If regenerate_xml_or_string_ids() is set, the ID will already have
2291 * been changed, so we need to use the old ID from the XML to load the
2292 * state and then update the ID.
2294 * When copying a plugin-state, route_ui takes care of of updating the ID,
2295 * but we need to call set_insert_id() to clear the cached plugin-state
2296 * and force a change.
2298 if (!regenerate_xml_or_string_ids ()) {
2299 (*i)->set_insert_id (new_id);
2301 (*i)->set_insert_id (old_id);
2304 (*i)->set_state (**niter, version);
2306 if (regenerate_xml_or_string_ids ()) {
2307 (*i)->set_insert_id (new_id);
2315 if (version < 3000) {
2317 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2318 this is all handled by Automatable
2321 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2322 if ((*niter)->name() == "Redirect") {
2323 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2324 Processor::set_state (**niter, version);
2329 set_parameter_state_2X (node, version);
2332 if ((prop = node.property (X_("custom"))) != 0) {
2333 _custom_cfg = string_is_affirmative (prop->value());
2336 uint32_t in_maps = 0;
2337 uint32_t out_maps = 0;
2338 XMLNodeList kids = node.children ();
2339 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2340 if ((*i)->name() == X_("ConfiguredInput")) {
2341 _configured_in = ChanCount(**i);
2343 if ((*i)->name() == X_("CustomSinks")) {
2344 _custom_sinks = ChanCount(**i);
2346 if ((*i)->name() == X_("ConfiguredOutput")) {
2347 _custom_out = ChanCount(**i);
2348 _configured_out = ChanCount(**i);
2350 if ((*i)->name() == X_("PresetOutput")) {
2351 _preset_out = ChanCount(**i);
2353 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2354 long pc = atol (&((*i)->name().c_str()[9]));
2355 if (pc >= 0 && pc <= (long) get_count()) {
2356 _in_map[pc] = ChanMapping (**i);
2360 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2361 long pc = atol (&((*i)->name().c_str()[10]));
2362 if (pc >= 0 && pc <= (long) get_count()) {
2363 _out_map[pc] = ChanMapping (**i);
2367 if ((*i)->name () == "ThruMap") {
2368 _thru_map = ChanMapping (**i);
2371 // sidechain is a Processor (IO)
2372 if ((*i)->name () == Processor::state_node_name) {
2376 _sidechain->set_state (**i, version);
2380 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2381 _maps_from_state = true;
2384 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2388 (*i)->deactivate ();
2392 PluginConfigChanged (); /* EMIT SIGNAL */
2397 PluginInsert::update_id (PBD::ID id)
2400 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2401 (*i)->set_insert_id (id);
2406 PluginInsert::set_state_dir (const std::string& d)
2408 // state() only saves the state of the first plugin
2409 _plugins[0]->set_state_dir (d);
2413 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2415 XMLNodeList nlist = node.children();
2416 XMLNodeIterator niter;
2418 /* look for port automation node */
2420 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2422 if ((*niter)->name() != port_automation_node_name) {
2427 XMLProperty const * cprop;
2428 XMLNodeConstIterator iter;
2433 cnodes = (*niter)->children ("port");
2435 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2439 if ((cprop = child->property("number")) != 0) {
2440 port = cprop->value().c_str();
2442 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2446 sscanf (port, "%" PRIu32, &port_id);
2448 if (port_id >= _plugins[0]->parameter_count()) {
2449 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2453 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2454 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2456 if (c && c->alist()) {
2457 if (!child->children().empty()) {
2458 c->alist()->set_state (*child->children().front(), version);
2460 /* In some cases 2.X saves lists with min_yval and max_yval
2461 being FLT_MIN and FLT_MAX respectively. This causes problems
2462 in A3 because these min/max values are used to compute
2463 where GUI control points should be drawn. If we see such
2464 values, `correct' them to the min/max of the appropriate
2468 float min_y = c->alist()->get_min_y ();
2469 float max_y = c->alist()->get_max_y ();
2471 ParameterDescriptor desc;
2472 _plugins.front()->get_parameter_descriptor (port_id, desc);
2474 if (min_y == FLT_MIN) {
2478 if (max_y == FLT_MAX) {
2482 c->alist()->set_yrange (min_y, max_y);
2485 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2497 PluginInsert::describe_parameter (Evoral::Parameter param)
2499 if (param.type() == PluginAutomation) {
2500 return _plugins[0]->describe_parameter (param);
2501 } else if (param.type() == PluginPropertyAutomation) {
2502 boost::shared_ptr<AutomationControl> c(automation_control(param));
2503 if (c && !c->desc().label.empty()) {
2504 return c->desc().label;
2507 return Automatable::describe_parameter(param);
2511 PluginInsert::signal_latency() const
2513 if (_user_latency) {
2514 return _user_latency;
2517 return _plugins[0]->signal_latency ();
2521 PluginInsert::type ()
2523 return plugin()->get_info()->type;
2526 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
2527 const Evoral::Parameter& param,
2528 const ParameterDescriptor& desc,
2529 boost::shared_ptr<AutomationList> list)
2530 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
2534 alist()->reset_default (desc.normal);
2536 list->set_interpolation(Evoral::ControlList::Discrete);
2541 set_flags(Controllable::Toggle);
2545 /** @param val `user' value */
2547 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2550 _set_value (user_val, group_override);
2554 PluginInsert::PluginControl::set_value_unchecked (double user_val)
2556 /* used only by automation playback */
2557 _set_value (user_val, Controllable::NoGroup);
2561 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
2563 /* FIXME: probably should be taking out some lock here.. */
2565 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2566 (*i)->set_parameter (_list->parameter().id(), user_val);
2569 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
2571 iasp->set_parameter (_list->parameter().id(), user_val);
2574 AutomationControl::set_value (user_val, group_override);
2578 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
2580 AutomationControl::set_value (user_val, Controllable::NoGroup);
2584 PluginInsert::PluginControl::get_state ()
2588 XMLNode& node (AutomationControl::get_state());
2589 ss << parameter().id();
2590 node.add_property (X_("parameter"), ss.str());
2592 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
2594 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
2601 /** @return `user' val */
2603 PluginInsert::PluginControl::get_value () const
2605 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
2611 return plugin->get_parameter (_list->parameter().id());
2614 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
2615 const Evoral::Parameter& param,
2616 const ParameterDescriptor& desc,
2617 boost::shared_ptr<AutomationList> list)
2618 : AutomationControl (p->session(), param, desc, list)
2622 alist()->set_yrange (desc.lower, desc.upper);
2623 alist()->reset_default (desc.normal);
2627 set_flags(Controllable::Toggle);
2632 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
2635 set_value_unchecked (user_val);
2640 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
2642 /* Old numeric set_value(), coerce to appropriate datatype if possible.
2643 This is lossy, but better than nothing until Ardour's automation system
2644 can handle various datatypes all the way down. */
2645 const Variant value(_desc.datatype, user_val);
2646 if (value.type() == Variant::NOTHING) {
2647 error << "set_value(double) called for non-numeric property" << endmsg;
2651 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
2652 (*i)->set_property(_list->parameter().id(), value);
2656 AutomationControl::set_value (user_val, Controllable::NoGroup);
2660 PluginInsert::PluginPropertyControl::get_state ()
2664 XMLNode& node (AutomationControl::get_state());
2665 ss << parameter().id();
2666 node.add_property (X_("property"), ss.str());
2667 node.remove_property (X_("value"));
2673 PluginInsert::PluginPropertyControl::get_value () const
2675 return _value.to_double();
2678 boost::shared_ptr<Plugin>
2679 PluginInsert::get_impulse_analysis_plugin()
2681 boost::shared_ptr<Plugin> ret;
2682 if (_impulseAnalysisPlugin.expired()) {
2683 // LV2 in particular uses various _session params
2684 // during init() -- most notably block_size..
2686 ret = plugin_factory(_plugins[0]);
2687 ret->configure_io (internal_input_streams (), internal_output_streams ());
2688 _impulseAnalysisPlugin = ret;
2690 ret = _impulseAnalysisPlugin.lock();
2697 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
2699 // called from outside the audio thread, so this should be safe
2700 // only do audio as analysis is (currently) only for audio plugins
2701 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
2702 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
2704 _signal_analysis_collected_nframes = 0;
2705 _signal_analysis_collect_nframes_max = nframes;
2708 /** Add a plugin to our list */
2710 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2712 plugin->set_insert_id (this->id());
2714 if (_plugins.empty()) {
2715 /* first (and probably only) plugin instance - connect to relevant signals */
2717 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2718 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2719 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2720 plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2));
2721 _custom_sinks = plugin->get_info()->n_inputs;
2722 // cache sidechain port count
2723 _cached_sidechain_pins.reset ();
2724 const ChanCount& nis (plugin->get_info()->n_inputs);
2725 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2726 for (uint32_t in = 0; in < nis.get (*t); ++in) {
2727 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
2728 if (iod.is_sidechain) {
2729 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
2734 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2735 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
2737 vst->set_insert (this, _plugins.size ());
2740 _plugins.push_back (plugin);
2744 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
2747 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2748 if (! (*i)->load_preset (pr)) {
2756 PluginInsert::realtime_handle_transport_stopped ()
2758 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2759 (*i)->realtime_handle_transport_stopped ();
2764 PluginInsert::realtime_locate ()
2766 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2767 (*i)->realtime_locate ();
2772 PluginInsert::monitoring_changed ()
2774 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2775 (*i)->monitoring_changed ();
2780 PluginInsert::latency_changed (framecnt_t, framecnt_t)
2782 // this is called in RT context, LatencyChanged is emitted after run()
2783 _latency_changed = true;
2787 PluginInsert::start_touch (uint32_t param_id)
2789 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2791 ac->start_touch (session().audible_frame());
2796 PluginInsert::end_touch (uint32_t param_id)
2798 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2800 ac->stop_touch (true, session().audible_frame());
2804 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2807 case PluginInsert::Impossible: o << "Impossible"; break;
2808 case PluginInsert::Delegate: o << "Delegate"; break;
2809 case PluginInsert::NoInputs: o << "NoInputs"; break;
2810 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2811 case PluginInsert::Replicate: o << "Replicate"; break;
2812 case PluginInsert::Split: o << "Split"; break;
2813 case PluginInsert::Hide: o << "Hide"; break;
2815 o << " cnt: " << m.plugins
2816 << (m.strict_io ? " strict-io" : "")
2817 << (m.custom_cfg ? " custom-cfg" : "");
2818 if (m.method == PluginInsert::Hide) {
2819 o << " hide: " << m.hide;