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"
41 #include "ardour/lv2_plugin.h"
44 #ifdef WINDOWS_VST_SUPPORT
45 #include "ardour/windows_vst_plugin.h"
49 #include "ardour/lxvst_plugin.h"
52 #ifdef AUDIOUNIT_SUPPORT
53 #include "ardour/audio_unit.h"
56 #include "ardour/session.h"
57 #include "ardour/types.h"
62 using namespace ARDOUR;
65 const string PluginInsert::port_automation_node_name = "PortAutomation";
67 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
68 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
69 , _signal_analysis_collected_nframes(0)
70 , _signal_analysis_collect_nframes_max(0)
76 /* the first is the master */
80 create_automatable_parameters ();
84 PluginInsert::~PluginInsert ()
89 PluginInsert::set_strict_io (bool b)
91 bool changed = _strict_io != b;
94 PluginConfigChanged (); /* EMIT SIGNAL */
99 PluginInsert::set_count (uint32_t num)
101 bool require_state = !_plugins.empty();
103 /* this is a bad idea.... we shouldn't do this while active.
104 only a route holding their redirect_lock should be calling this
109 } else if (num > _plugins.size()) {
110 uint32_t diff = num - _plugins.size();
112 for (uint32_t n = 0; n < diff; ++n) {
113 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
120 /* XXX do something */
123 PluginConfigChanged (); /* EMIT SIGNAL */
125 } else if (num < _plugins.size()) {
126 uint32_t diff = _plugins.size() - num;
127 for (uint32_t n= 0; n < diff; ++n) {
130 PluginConfigChanged (); /* EMIT SIGNAL */
138 PluginInsert::set_outputs (const ChanCount& c)
140 bool changed = (_custom_out != c) && _custom_cfg;
143 PluginConfigChanged (); /* EMIT SIGNAL */
148 PluginInsert::set_custom_cfg (bool b)
150 bool changed = _custom_cfg != b;
153 PluginConfigChanged (); /* EMIT SIGNAL */
158 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
160 if (which.type() != PluginAutomation)
163 boost::shared_ptr<AutomationControl> c
164 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
167 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
172 PluginInsert::output_streams() const
174 assert (_configured);
175 return _configured_out;
179 PluginInsert::input_streams() const
181 assert (_configured);
182 return _configured_in;
186 PluginInsert::internal_output_streams() const
188 assert (!_plugins.empty());
190 PluginInfoPtr info = _plugins.front()->get_info();
192 if (info->reconfigurable_io()) {
193 ChanCount out = _plugins.front()->output_streams ();
194 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
197 ChanCount out = info->n_outputs;
198 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
199 out.set_audio (out.n_audio() * _plugins.size());
200 out.set_midi (out.n_midi() * _plugins.size());
206 PluginInsert::internal_input_streams() const
208 assert (!_plugins.empty());
212 PluginInfoPtr info = _plugins.front()->get_info();
214 if (info->reconfigurable_io()) {
215 assert (_plugins.size() == 1);
216 in = _plugins.front()->input_streams();
221 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
223 if (_match.method == Split) {
225 /* we are splitting 1 processor input to multiple plugin inputs,
226 so we have a maximum of 1 stream of each type.
228 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
229 if (in.get (*t) > 1) {
235 } else if (_match.method == Hide) {
237 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
238 in.set (*t, in.get (*t) - _match.hide.get (*t));
244 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
245 in.set (*t, in.get (*t) * _plugins.size ());
253 PluginInsert::natural_output_streams() const
255 return _plugins[0]->get_info()->n_outputs;
259 PluginInsert::natural_input_streams() const
261 return _plugins[0]->get_info()->n_inputs;
265 PluginInsert::has_no_inputs() const
267 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
271 PluginInsert::has_no_audio_inputs() const
273 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
277 PluginInsert::is_midi_instrument() const
279 /* XXX more finesse is possible here. VST plugins have a
280 a specific "instrument" flag, for example.
282 PluginInfoPtr pi = _plugins[0]->get_info();
284 return pi->n_inputs.n_midi() != 0 &&
285 pi->n_outputs.n_audio() > 0;
289 PluginInsert::create_automatable_parameters ()
291 assert (!_plugins.empty());
293 set<Evoral::Parameter> a = _plugins.front()->automatable ();
295 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
296 if (i->type() == PluginAutomation) {
298 Evoral::Parameter param(*i);
300 ParameterDescriptor desc;
301 _plugins.front()->get_parameter_descriptor(i->id(), desc);
303 can_automate (param);
304 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
305 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
307 _plugins.front()->set_automation_control (i->id(), c);
308 } else if (i->type() == PluginPropertyAutomation) {
309 Evoral::Parameter param(*i);
310 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
311 if (desc.datatype != Variant::NOTHING) {
312 boost::shared_ptr<AutomationList> list;
313 if (Variant::type_is_numeric(desc.datatype)) {
314 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
316 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
321 /** Called when something outside of this host has modified a plugin
322 * parameter. Responsible for propagating the change to two places:
324 * 1) anything listening to the Control itself
325 * 2) any replicated plugins that make up this PluginInsert.
327 * The PluginInsert is connected to the ParameterChangedExternally signal for
328 * the first (primary) plugin, and here broadcasts that change to any others.
330 * XXX We should probably drop this whole replication idea (Paul, October 2015)
331 * since it isn't used by sensible plugin APIs (AU, LV2).
334 PluginInsert::parameter_changed_externally (uint32_t which, float val)
336 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
338 /* First propagation: alter the underlying value of the control,
339 * without telling the plugin(s) that own/use it to set it.
346 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
349 pc->catch_up_with_external_value (val);
352 /* Second propagation: tell all plugins except the first to
353 update the value of this parameter. For sane plugin APIs,
354 there are no other plugins, so this is a no-op in those
358 Plugins::iterator i = _plugins.begin();
360 /* don't set the first plugin, just all the slaves */
362 if (i != _plugins.end()) {
364 for (; i != _plugins.end(); ++i) {
365 (*i)->set_parameter (which, val);
371 PluginInsert::set_block_size (pframes_t nframes)
374 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
375 if ((*i)->set_block_size (nframes) != 0) {
383 PluginInsert::activate ()
385 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
389 Processor::activate ();
393 PluginInsert::deactivate ()
395 Processor::deactivate ();
397 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
403 PluginInsert::flush ()
405 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
411 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
413 PinMappings in_map (_in_map);
414 PinMappings out_map (_out_map);
417 // TODO optimize special case.
418 // Currently this never triggers because the in_map for "Split" triggeres no_inplace.
419 if (_match.method == Split && !_no_inplace) {
420 assert (in_map.size () == 1);
421 in_map[0] = ChanMapping (ChanCount::max (natural_input_streams (), _configured_in));
422 ChanCount const in_streams = internal_input_streams ();
423 /* copy the first stream's audio buffer contents to the others */
425 uint32_t first_idx = in_map[0].get (DataType::AUDIO, 0, &valid);
427 for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
428 uint32_t idx = in_map[0].get (DataType::AUDIO, i, &valid);
430 bufs.get_audio(idx).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
437 bufs.set_count(ChanCount::max(bufs.count(), _configured_in));
438 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
444 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
446 boost::shared_ptr<AutomationControl> c
447 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
449 if (c->list() && c->automation_playback()) {
452 const float val = c->list()->rt_safe_eval (now, valid);
455 /* This is the ONLY place where we are
457 * AutomationControl::set_value_unchecked(). We
458 * know that the control is in
459 * automation playback mode, so no
460 * check on writable() is required
461 * (which must be done in AutomationControl::set_value()
464 c->set_value_unchecked(val);
471 /* Calculate if, and how many frames we need to collect for analysis */
472 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
473 _signal_analysis_collected_nframes);
474 if (nframes < collect_signal_nframes) { // we might not get all frames now
475 collect_signal_nframes = nframes;
478 if (collect_signal_nframes > 0) {
480 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
481 //std::cerr << " streams " << internal_input_streams().n_audio() << std::endl;
482 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
484 _signal_analysis_inputs.set_count(internal_input_streams());
486 for (uint32_t i = 0; i < internal_input_streams().n_audio(); ++i) {
487 _signal_analysis_inputs.get_audio(i).read_from(
489 collect_signal_nframes,
490 _signal_analysis_collected_nframes); // offset is for target buffer
495 if (_plugins.front()->is_channelstrip() ) {
496 if (_configured_in.n_audio() > 0) {
497 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
498 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
500 _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
502 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
503 bufs.get (DataType::AUDIO, out).silence (nframes, offset);
509 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
510 ARDOUR::ChanMapping used_outputs;
513 // TODO optimize this flow. prepare during configure_io()
514 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
516 ARDOUR::ChanMapping i_in_map (natural_input_streams());
517 ARDOUR::ChanMapping i_out_map;
518 ARDOUR::ChanCount mapped;
519 ARDOUR::ChanCount backmap;
521 // map inputs sequentially
522 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
523 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
525 uint32_t in_idx = in_map[pc].get (*t, in, &valid);
526 uint32_t m = mapped.get (*t);
528 inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset);
530 inplace_bufs.get (*t, m).silence (nframes, offset);
532 mapped.set (*t, m + 1);
536 // TODO use map_offset_to() instead ??
540 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
541 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
542 uint32_t m = mapped.get (*t);
543 inplace_bufs.get (*t, m).silence (nframes, offset);
544 i_out_map.set (*t, out, m);
545 mapped.set (*t, m + 1);
549 if ((*i)->connect_and_run(inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
554 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
555 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
556 uint32_t m = backmap.get (*t);
558 uint32_t out_idx = out_map[pc].get (*t, out, &valid);
560 bufs.get (*t, out_idx).read_from (inplace_bufs.get (*t, m), nframes, offset, offset);
561 used_outputs.set (*t, out_idx, 1); // mark as used
563 backmap.set (*t, m + 1);
567 /* all instances have completed, now clear outputs that have not been written to.
568 * (except midi bypass)
570 if (has_midi_bypass ()) {
571 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
573 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
574 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
576 used_outputs.get (*t, out, &valid);
577 if (valid) { continue; }
578 bufs.get (*t, out).silence (nframes, offset);
584 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
585 if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
590 // TODO optimize: store "unconnected" in a fixed set.
591 // it only changes on reconfiguration.
592 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
593 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
595 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
596 mapped = true; // in-place Midi bypass
598 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
599 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
601 uint32_t idx = out_map[pc].get (*t, o, &valid);
602 if (valid && idx == out) {
609 bufs.get (*t, out).silence (nframes, offset);
615 if (collect_signal_nframes > 0) {
617 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
618 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
620 _signal_analysis_outputs.set_count(internal_output_streams());
622 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
623 _signal_analysis_outputs.get_audio(i).read_from(
625 collect_signal_nframes,
626 _signal_analysis_collected_nframes); // offset is for target buffer
629 _signal_analysis_collected_nframes += collect_signal_nframes;
630 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
632 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
633 _signal_analysis_collect_nframes_max = 0;
634 _signal_analysis_collected_nframes = 0;
636 AnalysisDataGathered(&_signal_analysis_inputs,
637 &_signal_analysis_outputs);
643 PluginInsert::silence (framecnt_t nframes)
649 ChanMapping in_map (natural_input_streams ());
650 ChanMapping out_map (natural_output_streams ());
652 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
653 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
658 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
660 if (_pending_active) {
661 /* run as normal if we are active or moving from inactive to active */
663 if (_session.transport_rolling() || _session.bounce_processing()) {
664 automation_run (bufs, start_frame, nframes);
666 connect_and_run (bufs, nframes, 0, false);
670 // TODO use mapping in bypassed mode ?!
671 // -> do we bypass the processor or the plugin
673 uint32_t in = input_streams ().n_audio ();
674 uint32_t out = output_streams().n_audio ();
676 if (has_no_audio_inputs() || in == 0) {
678 /* silence all (audio) outputs. Should really declick
679 * at the transitions of "active"
682 for (uint32_t n = 0; n < out; ++n) {
683 bufs.get_audio (n).silence (nframes);
686 } else if (out > in) {
688 /* not active, but something has make up for any channel count increase
689 * for now , simply replicate last buffer
691 for (uint32_t n = in; n < out; ++n) {
692 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
696 bufs.count().set_audio (out);
699 _active = _pending_active;
701 /* we have no idea whether the plugin generated silence or not, so mark
702 * all buffers appropriately.
707 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
709 Evoral::ControlEvent next_event (0, 0.0f);
710 framepos_t now = start;
711 framepos_t end = now + nframes;
712 framecnt_t offset = 0;
714 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
717 connect_and_run (bufs, nframes, offset, false);
721 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
723 /* no events have a time within the relevant range */
725 connect_and_run (bufs, nframes, offset, true, now);
731 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
733 connect_and_run (bufs, cnt, offset, true, now);
739 if (!find_next_event (now, end, next_event)) {
744 /* cleanup anything that is left to do */
747 connect_and_run (bufs, nframes, offset, true, now);
752 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
754 if (param.type() != PluginAutomation)
757 if (_plugins.empty()) {
758 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
760 abort(); /*NOTREACHED*/
763 return _plugins[0]->default_value (param.id());
768 PluginInsert::can_reset_all_parameters ()
772 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
774 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
776 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
780 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
786 if (ac->automation_state() & Play) {
791 return all && (params > 0);
795 PluginInsert::reset_parameters_to_default ()
799 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
801 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
803 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
807 const float dflt = _plugins[0]->default_value (cid);
808 const float curr = _plugins[0]->get_parameter (cid);
814 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
819 if (ac->automation_state() & Play) {
824 ac->set_value (dflt, Controllable::NoGroup);
829 boost::shared_ptr<Plugin>
830 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
832 boost::shared_ptr<LadspaPlugin> lp;
833 boost::shared_ptr<LuaProc> lua;
835 boost::shared_ptr<LV2Plugin> lv2p;
837 #ifdef WINDOWS_VST_SUPPORT
838 boost::shared_ptr<WindowsVSTPlugin> vp;
841 boost::shared_ptr<LXVSTPlugin> lxvp;
843 #ifdef AUDIOUNIT_SUPPORT
844 boost::shared_ptr<AUPlugin> ap;
847 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
848 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
849 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
850 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
852 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
853 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
855 #ifdef WINDOWS_VST_SUPPORT
856 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
857 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
860 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
861 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
863 #ifdef AUDIOUNIT_SUPPORT
864 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
865 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
869 fatal << string_compose (_("programming error: %1"),
870 X_("unknown plugin type in PluginInsert::plugin_factory"))
872 abort(); /*NOTREACHED*/
873 return boost::shared_ptr<Plugin> ((Plugin*) 0);
877 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
878 if (num < _in_map.size()) {
879 bool changed = _in_map[num] != m;
882 PluginMapChanged (); /* EMIT SIGNAL */
888 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
889 if (num < _out_map.size()) {
890 bool changed = _out_map[num] != m;
893 PluginMapChanged (); /* EMIT SIGNAL */
899 PluginInsert::input_map () const
903 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
904 ChanMapping m (i->second);
905 const ChanMapping::Mappings& mp ((*i).second.mappings());
906 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
907 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
908 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
916 PluginInsert::output_map () const
920 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
921 ChanMapping m (i->second);
922 const ChanMapping::Mappings& mp ((*i).second.mappings());
923 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
924 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
925 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
929 if (has_midi_bypass ()) {
930 rv.set (DataType::MIDI, 0, 0);
937 PluginInsert::has_midi_bypass () const
939 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1 && natural_output_streams ().n_midi () == 0) {
946 PluginInsert::configure_io (ChanCount in, ChanCount out)
948 Match old_match = _match;
953 old_in = _configured_in;
954 old_out = _configured_out;
958 _configured_out = out;
960 /* get plugin configuration */
961 _match = private_can_support_io_configuration (in, out);
962 #ifndef NDEBUG // XXX
963 cout << "Match '" << name() << "': " << _match;
966 /* set the matching method and number of plugins that we will use to meet this configuration */
967 if (set_count (_match.plugins) == false) {
968 PluginIoReConfigure (); /* EMIT SIGNAL */
973 /* configure plugins */
974 switch (_match.method) {
977 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
978 PluginIoReConfigure (); /* EMIT SIGNAL */
987 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
989 assert (_match.strict_io || dout.n_audio() == out.n_audio()); // sans midi bypass
990 if (useins.n_audio() == 0) {
993 if (_plugins.front()->configure_io (useins, dout) == false) {
994 PluginIoReConfigure (); /* EMIT SIGNAL */
1001 if (_plugins.front()->configure_io (in, out) == false) {
1002 PluginIoReConfigure (); /* EMIT SIGNAL */
1003 _configured = false;
1009 bool mapping_changed = false;
1010 if (old_in == in && old_out == out && _configured
1011 && old_match.method == _match.method
1012 && _in_map.size() == _out_map.size()
1013 && _in_map.size() == get_count ()
1015 /* If the configuraton has not changed, keep the mapping */
1016 } else if (_match.custom_cfg && _configured) {
1017 /* strip dead wood */
1018 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1020 ChanMapping new_out;
1021 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1022 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1024 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1025 if (valid && idx <= in.get (*t)) {
1026 new_in.set (*t, i, idx);
1029 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1031 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1032 if (valid && idx <= out.get (*t)) {
1033 new_out.set (*t, o, idx);
1037 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1038 mapping_changed = true;
1040 _in_map[pc] = new_in;
1041 _out_map[pc] = new_out;
1044 /* generate a new mapping */
1048 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1049 if (_match.method == Split) {
1050 _in_map[pc] = ChanMapping ();
1051 /* connect inputs in round-robin fashion */
1052 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1053 const uint32_t cend = _configured_in.get (*t);
1054 if (cend == 0) { continue; }
1056 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
1057 _in_map[pc].set (*t, in, c);
1062 _in_map[pc] = ChanMapping (ChanCount::min (natural_input_streams (), in));
1064 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), out));
1066 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1067 _in_map[pc].offset_to(*t, pc * natural_input_streams().get(*t));
1068 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1070 mapping_changed = true;
1074 if (mapping_changed) {
1075 PluginMapChanged (); /* EMIT SIGNAL */
1076 #ifndef NDEBUG // XXX
1078 cout << "----<<----\n";
1079 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1080 cout << "Channel Map for " << name() << " plugin " << pc << "\n";
1081 cout << " * Inputs:\n" << _in_map[pc];
1082 cout << " * Outputs:\n" << _out_map[pc];
1084 cout << "---->>----\n";
1088 // auto-detect if inplace processing is possible
1089 bool inplace_ok = true;
1090 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1091 if (!_in_map[pc].is_monotonic ()) {
1094 if (!_out_map[pc].is_monotonic ()) {
1098 _no_inplace = !inplace_ok || _plugins.front()->inplace_broken ();
1100 if (old_in != in || old_out != out
1101 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1103 PluginIoReConfigure (); /* EMIT SIGNAL */
1106 // we don't know the analysis window size, so we must work with the
1107 // current buffer size here. each request for data fills in these
1108 // buffers and the analyser makes sure it gets enough data for the
1110 session().ensure_buffer_set (_signal_analysis_inputs, in);
1111 //_signal_analysis_inputs.set_count (in);
1113 session().ensure_buffer_set (_signal_analysis_outputs, out);
1114 //_signal_analysis_outputs.set_count (out);
1116 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1119 return Processor::configure_io (in, out);
1122 /** Decide whether this PluginInsert can support a given IO configuration.
1123 * To do this, we run through a set of possible solutions in rough order of
1126 * @param in Required input channel count.
1127 * @param out Filled in with the output channel count if we return true.
1128 * @return true if the given IO configuration can be supported.
1131 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1133 return private_can_support_io_configuration (in, out).method != Impossible;
1136 /** A private version of can_support_io_configuration which returns the method
1137 * by which the configuration can be matched, rather than just whether or not
1141 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1143 if (_plugins.empty()) {
1147 /* if a user specified a custom cfg, so be it. */
1150 return Match (ExactMatch, get_count(), false, true); // XXX
1153 /* try automatic configuration */
1154 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1156 PluginInfoPtr info = _plugins.front()->get_info();
1157 ChanCount inputs = info->n_inputs;
1158 ChanCount outputs = info->n_outputs;
1159 ChanCount midi_bypass;
1160 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1161 midi_bypass.set (DataType::MIDI, 1);
1164 /* handle case strict-i/o */
1165 if (_strict_io && m.method != Impossible) {
1168 /* special case MIDI instruments */
1169 if (is_midi_instrument()) {
1170 // output = midi-bypass + at most master-out channels.
1171 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1172 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1173 out = ChanCount::min (out, max_out);
1179 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1180 /* replicate processor to match output count (generators and such)
1181 * at least enough to feed every output port. */
1182 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1183 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1184 uint32_t nin = inputs.get (*t);
1185 if (nin == 0 || inx.get(*t) == 0) { continue; }
1186 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1188 out = inx + midi_bypass;
1189 return Match (Replicate, f);
1198 out = inx + midi_bypass;
1199 if (inx.get(DataType::MIDI) == 1
1200 && out.get (DataType::MIDI) == 0
1201 && outputs.get(DataType::MIDI) == 0) {
1202 out += ChanCount (DataType::MIDI, 1);
1207 if (m.method != Impossible) {
1211 if (info->reconfigurable_io()) {
1213 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1215 // houston, we have a problem.
1216 return Match (Impossible, 0);
1218 return Match (Delegate, 1);
1221 // add at least as many plugins so that output count matches input count
1223 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1224 uint32_t nin = inputs.get (*t);
1225 uint32_t nout = outputs.get (*t);
1226 if (nin == 0 || inx.get(*t) == 0) { continue; }
1227 // prefer floor() so the count won't overly increase IFF (nin < nout)
1228 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1230 if (f > 0 && outputs * f >= _configured_out) {
1231 out = outputs * f + midi_bypass;
1232 return Match (Replicate, f);
1235 // add at least as many plugins needed to connect all inputs
1237 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1238 uint32_t nin = inputs.get (*t);
1239 if (nin == 0 || inx.get(*t) == 0) { continue; }
1240 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1242 out = outputs * f + midi_bypass;
1243 return Match (Replicate, f);
1246 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1248 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1250 if (_plugins.empty()) {
1254 PluginInfoPtr info = _plugins.front()->get_info();
1255 ChanCount in; in += inx;
1256 ChanCount midi_bypass;
1258 if (info->reconfigurable_io()) {
1259 /* Plugin has flexible I/O, so delegate to it */
1260 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1262 return Match (Impossible, 0);
1264 return Match (Delegate, 1);
1267 ChanCount inputs = info->n_inputs;
1268 ChanCount outputs = info->n_outputs;
1270 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1271 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
1272 midi_bypass.set (DataType::MIDI, 1);
1274 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1275 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
1276 in.set(DataType::MIDI, 0);
1279 bool no_inputs = true;
1280 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1281 if (inputs.get (*t) != 0) {
1288 /* no inputs so we can take any input configuration since we throw it away */
1289 out = outputs + midi_bypass;
1290 return Match (NoInputs, 1);
1293 /* Plugin inputs match requested inputs exactly */
1295 out = outputs + midi_bypass;
1296 return Match (ExactMatch, 1);
1299 /* We may be able to run more than one copy of the plugin within this insert
1300 to cope with the insert having more inputs than the plugin.
1301 We allow replication only for plugins with either zero or 1 inputs and outputs
1302 for every valid data type.
1306 bool can_replicate = true;
1307 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1309 uint32_t nin = inputs.get (*t);
1311 // No inputs of this type
1312 if (nin == 0 && in.get(*t) == 0) {
1316 if (nin != 1 || outputs.get (*t) != 1) {
1317 can_replicate = false;
1321 // Potential factor not set yet
1323 f = in.get(*t) / nin;
1326 // Factor for this type does not match another type, can not replicate
1327 if (f != (in.get(*t) / nin)) {
1328 can_replicate = false;
1333 if (can_replicate && f > 0) {
1334 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1335 out.set (*t, outputs.get(*t) * f);
1338 return Match (Replicate, f);
1341 /* If the processor has exactly one input of a given type, and
1342 the plugin has more, we can feed the single processor input
1343 to some or all of the plugin inputs. This is rather
1344 special-case-y, but the 1-to-many case is by far the
1345 simplest. How do I split thy 2 processor inputs to 3
1346 plugin inputs? Let me count the ways ...
1349 bool can_split = true;
1350 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1352 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
1353 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1355 if (!can_split_type && !nothing_to_do_for_type) {
1361 out = outputs + midi_bypass;
1362 return Match (Split, 1);
1365 /* If the plugin has more inputs than we want, we can `hide' some of them
1366 by feeding them silence.
1369 bool could_hide = false;
1370 bool cannot_hide = false;
1371 ChanCount hide_channels;
1373 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1374 if (inputs.get(*t) > in.get(*t)) {
1375 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1376 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1378 } else if (inputs.get(*t) < in.get(*t)) {
1379 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1384 if (could_hide && !cannot_hide) {
1385 out = outputs + midi_bypass;
1386 return Match (Hide, 1, false, false, hide_channels);
1389 return Match (Impossible, 0);
1394 PluginInsert::get_state ()
1396 return state (true);
1400 PluginInsert::state (bool full)
1402 XMLNode& node = Processor::state (full);
1404 node.add_property("type", _plugins[0]->state_node_name());
1405 node.add_property("unique-id", _plugins[0]->unique_id());
1406 node.add_property("count", string_compose("%1", _plugins.size()));
1408 /* remember actual i/o configuration (for later placeholder
1409 * in case the plugin goes missing) */
1410 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1411 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1413 /* save custom i/o config */
1414 node.add_property("custom", _custom_cfg ? "yes" : "no");
1416 assert (_custom_out == _configured_out); // redundant
1417 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1418 // TODO save _in_map[pc], _out_map[pc]
1422 _plugins[0]->set_insert_id(this->id());
1423 node.add_child_nocopy (_plugins[0]->get_state());
1425 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1426 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1428 node.add_child_nocopy (ac->get_state());
1436 PluginInsert::set_control_ids (const XMLNode& node, int version)
1438 const XMLNodeList& nlist = node.children();
1439 XMLNodeConstIterator iter;
1440 set<Evoral::Parameter>::const_iterator p;
1442 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1443 if ((*iter)->name() == Controllable::xml_node_name) {
1444 const XMLProperty* prop;
1446 uint32_t p = (uint32_t)-1;
1448 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1449 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1451 p = lv2plugin->port_index(prop->value().c_str());
1455 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1456 p = atoi (prop->value());
1459 if (p != (uint32_t)-1) {
1461 /* this may create the new controllable */
1463 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1465 #ifndef NO_PLUGIN_STATE
1469 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1471 ac->set_state (**iter, version);
1480 PluginInsert::set_state(const XMLNode& node, int version)
1482 XMLNodeList nlist = node.children();
1483 XMLNodeIterator niter;
1484 XMLPropertyList plist;
1485 const XMLProperty *prop;
1486 ARDOUR::PluginType type;
1488 if ((prop = node.property ("type")) == 0) {
1489 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1493 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1494 type = ARDOUR::LADSPA;
1495 } else if (prop->value() == X_("lv2")) {
1497 } else if (prop->value() == X_("windows-vst")) {
1498 type = ARDOUR::Windows_VST;
1499 } else if (prop->value() == X_("lxvst")) {
1500 type = ARDOUR::LXVST;
1501 } else if (prop->value() == X_("audiounit")) {
1502 type = ARDOUR::AudioUnit;
1503 } else if (prop->value() == X_("luaproc")) {
1506 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1512 prop = node.property ("unique-id");
1515 #ifdef WINDOWS_VST_SUPPORT
1516 /* older sessions contain VST plugins with only an "id" field.
1519 if (type == ARDOUR::Windows_VST) {
1520 prop = node.property ("id");
1524 #ifdef LXVST_SUPPORT
1525 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1527 if (type == ARDOUR::LXVST) {
1528 prop = node.property ("id");
1534 error << _("Plugin has no unique ID field") << endmsg;
1539 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1541 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1542 * allow to move sessions windows <> linux */
1543 #ifdef LXVST_SUPPORT
1544 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1545 type = ARDOUR::LXVST;
1546 plugin = find_plugin (_session, prop->value(), type);
1550 #ifdef WINDOWS_VST_SUPPORT
1551 if (plugin == 0 && type == ARDOUR::LXVST) {
1552 type = ARDOUR::Windows_VST;
1553 plugin = find_plugin (_session, prop->value(), type);
1558 error << string_compose(
1559 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1560 "Perhaps it was removed or moved since it was last used."),
1566 if (type == ARDOUR::Lua) {
1567 XMLNode *ls = node.child (plugin->state_node_name().c_str());
1568 // we need to load the script to set the name and parameters.
1569 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
1571 lp->set_script_from_state (*ls);
1575 // The name of the PluginInsert comes from the plugin, nothing else
1576 _name = plugin->get_info()->name;
1580 // Processor::set_state() will set this, but too late
1581 // for it to be available when setting up plugin
1582 // state. We can't call Processor::set_state() until
1583 // the plugins themselves are created and added.
1587 if (_plugins.empty()) {
1588 /* if we are adding the first plugin, we will need to set
1589 up automatable controls.
1591 add_plugin (plugin);
1592 create_automatable_parameters ();
1593 set_control_ids (node, version);
1596 if ((prop = node.property ("count")) != 0) {
1597 sscanf (prop->value().c_str(), "%u", &count);
1600 if (_plugins.size() != count) {
1601 for (uint32_t n = 1; n < count; ++n) {
1602 add_plugin (plugin_factory (plugin));
1606 Processor::set_state (node, version);
1608 PBD::ID new_id = this->id();
1609 PBD::ID old_id = this->id();
1611 if ((prop = node.property ("id")) != 0) {
1612 old_id = prop->value ();
1615 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1617 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1618 and set all plugins to the same state.
1621 if ((*niter)->name() == plugin->state_node_name()) {
1623 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1624 /* Plugin state can include external files which are named after the ID.
1626 * If regenerate_xml_or_string_ids() is set, the ID will already have
1627 * been changed, so we need to use the old ID from the XML to load the
1628 * state and then update the ID.
1630 * When copying a plugin-state, route_ui takes care of of updating the ID,
1631 * but we need to call set_insert_id() to clear the cached plugin-state
1632 * and force a change.
1634 if (!regenerate_xml_or_string_ids ()) {
1635 (*i)->set_insert_id (new_id);
1637 (*i)->set_insert_id (old_id);
1640 (*i)->set_state (**niter, version);
1642 if (regenerate_xml_or_string_ids ()) {
1643 (*i)->set_insert_id (new_id);
1651 if (version < 3000) {
1653 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1654 this is all handled by Automatable
1657 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1658 if ((*niter)->name() == "Redirect") {
1659 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1660 Processor::set_state (**niter, version);
1665 set_parameter_state_2X (node, version);
1668 if ((prop = node.property (X_("custom"))) != 0) {
1669 _custom_cfg = string_is_affirmative (prop->value());
1672 XMLNodeList kids = node.children ();
1673 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
1674 if ((*i)->name() == X_("ConfiguredOutput")) {
1675 _custom_out = ChanCount(**i);
1677 // TODO restore mappings for all 0 .. count.
1682 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1686 (*i)->deactivate ();
1694 PluginInsert::update_id (PBD::ID id)
1697 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1698 (*i)->set_insert_id (id);
1703 PluginInsert::set_state_dir (const std::string& d)
1705 // state() only saves the state of the first plugin
1706 _plugins[0]->set_state_dir (d);
1710 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1712 XMLNodeList nlist = node.children();
1713 XMLNodeIterator niter;
1715 /* look for port automation node */
1717 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1719 if ((*niter)->name() != port_automation_node_name) {
1725 XMLNodeConstIterator iter;
1730 cnodes = (*niter)->children ("port");
1732 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1736 if ((cprop = child->property("number")) != 0) {
1737 port = cprop->value().c_str();
1739 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1743 sscanf (port, "%" PRIu32, &port_id);
1745 if (port_id >= _plugins[0]->parameter_count()) {
1746 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1750 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1751 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1753 if (c && c->alist()) {
1754 if (!child->children().empty()) {
1755 c->alist()->set_state (*child->children().front(), version);
1757 /* In some cases 2.X saves lists with min_yval and max_yval
1758 being FLT_MIN and FLT_MAX respectively. This causes problems
1759 in A3 because these min/max values are used to compute
1760 where GUI control points should be drawn. If we see such
1761 values, `correct' them to the min/max of the appropriate
1765 float min_y = c->alist()->get_min_y ();
1766 float max_y = c->alist()->get_max_y ();
1768 ParameterDescriptor desc;
1769 _plugins.front()->get_parameter_descriptor (port_id, desc);
1771 if (min_y == FLT_MIN) {
1775 if (max_y == FLT_MAX) {
1779 c->alist()->set_yrange (min_y, max_y);
1782 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1794 PluginInsert::describe_parameter (Evoral::Parameter param)
1796 if (param.type() == PluginAutomation) {
1797 return _plugins[0]->describe_parameter (param);
1798 } else if (param.type() == PluginPropertyAutomation) {
1799 boost::shared_ptr<AutomationControl> c(automation_control(param));
1800 if (c && !c->desc().label.empty()) {
1801 return c->desc().label;
1804 return Automatable::describe_parameter(param);
1808 PluginInsert::signal_latency() const
1810 if (_user_latency) {
1811 return _user_latency;
1814 return _plugins[0]->signal_latency ();
1818 PluginInsert::type ()
1820 return plugin()->get_info()->type;
1823 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1824 const Evoral::Parameter& param,
1825 const ParameterDescriptor& desc,
1826 boost::shared_ptr<AutomationList> list)
1827 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1831 alist()->reset_default (desc.normal);
1833 list->set_interpolation(Evoral::ControlList::Discrete);
1838 set_flags(Controllable::Toggle);
1842 /** @param val `user' value */
1844 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1847 _set_value (user_val, group_override);
1851 PluginInsert::PluginControl::set_value_unchecked (double user_val)
1853 /* used only by automation playback */
1854 _set_value (user_val, Controllable::NoGroup);
1858 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1860 /* FIXME: probably should be taking out some lock here.. */
1862 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1863 (*i)->set_parameter (_list->parameter().id(), user_val);
1866 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1868 iasp->set_parameter (_list->parameter().id(), user_val);
1871 AutomationControl::set_value (user_val, group_override);
1875 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
1877 AutomationControl::set_value (user_val, Controllable::NoGroup);
1881 PluginInsert::PluginControl::get_state ()
1885 XMLNode& node (AutomationControl::get_state());
1886 ss << parameter().id();
1887 node.add_property (X_("parameter"), ss.str());
1889 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
1891 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
1898 /** @return `user' val */
1900 PluginInsert::PluginControl::get_value () const
1902 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
1908 return plugin->get_parameter (_list->parameter().id());
1911 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1912 const Evoral::Parameter& param,
1913 const ParameterDescriptor& desc,
1914 boost::shared_ptr<AutomationList> list)
1915 : AutomationControl (p->session(), param, desc, list)
1919 alist()->set_yrange (desc.lower, desc.upper);
1920 alist()->reset_default (desc.normal);
1924 set_flags(Controllable::Toggle);
1929 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
1932 set_value_unchecked (user_val);
1937 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
1939 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1940 This is lossy, but better than nothing until Ardour's automation system
1941 can handle various datatypes all the way down. */
1942 const Variant value(_desc.datatype, user_val);
1943 if (value.type() == Variant::NOTHING) {
1944 error << "set_value(double) called for non-numeric property" << endmsg;
1948 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1949 (*i)->set_property(_list->parameter().id(), value);
1953 AutomationControl::set_value (user_val, Controllable::NoGroup);
1957 PluginInsert::PluginPropertyControl::get_state ()
1961 XMLNode& node (AutomationControl::get_state());
1962 ss << parameter().id();
1963 node.add_property (X_("property"), ss.str());
1964 node.remove_property (X_("value"));
1970 PluginInsert::PluginPropertyControl::get_value () const
1972 return _value.to_double();
1975 boost::shared_ptr<Plugin>
1976 PluginInsert::get_impulse_analysis_plugin()
1978 boost::shared_ptr<Plugin> ret;
1979 if (_impulseAnalysisPlugin.expired()) {
1980 ret = plugin_factory(_plugins[0]);
1981 ret->configure_io (internal_input_streams (), internal_output_streams ());
1982 _impulseAnalysisPlugin = ret;
1984 ret = _impulseAnalysisPlugin.lock();
1991 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1993 // called from outside the audio thread, so this should be safe
1994 // only do audio as analysis is (currently) only for audio plugins
1995 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
1996 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
1998 _signal_analysis_collected_nframes = 0;
1999 _signal_analysis_collect_nframes_max = nframes;
2002 /** Add a plugin to our list */
2004 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
2006 plugin->set_insert_id (this->id());
2008 if (_plugins.empty()) {
2009 /* first (and probably only) plugin instance - connect to relevant signals
2012 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2013 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2014 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2017 _plugins.push_back (plugin);
2021 PluginInsert::realtime_handle_transport_stopped ()
2023 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2024 (*i)->realtime_handle_transport_stopped ();
2029 PluginInsert::realtime_locate ()
2031 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2032 (*i)->realtime_locate ();
2037 PluginInsert::monitoring_changed ()
2039 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2040 (*i)->monitoring_changed ();
2045 PluginInsert::start_touch (uint32_t param_id)
2047 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2049 ac->start_touch (session().audible_frame());
2054 PluginInsert::end_touch (uint32_t param_id)
2056 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2058 ac->stop_touch (true, session().audible_frame());
2062 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2065 case PluginInsert::Impossible: o << "Impossible"; break;
2066 case PluginInsert::Delegate: o << "Delegate"; break;
2067 case PluginInsert::NoInputs: o << "NoInputs"; break;
2068 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2069 case PluginInsert::Replicate: o << "Replicate"; break;
2070 case PluginInsert::Split: o << "Split"; break;
2071 case PluginInsert::Hide: o << "Hide"; break;
2073 o << " cnt: " << m.plugins
2074 << (m.strict_io ? " strict-io" : "")
2075 << (m.custom_cfg ? " custom-cfg" : "");
2076 if (m.method == PluginInsert::Hide) {
2077 o << " hide: " << m.hide;