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)
75 , _pending_no_inplace (false)
77 /* the first is the master */
81 create_automatable_parameters ();
85 PluginInsert::~PluginInsert ()
90 PluginInsert::set_count (uint32_t num)
92 bool require_state = !_plugins.empty();
94 /* this is a bad idea.... we shouldn't do this while active.
95 only a route holding their redirect_lock should be calling this
100 } else if (num > _plugins.size()) {
101 uint32_t diff = num - _plugins.size();
103 for (uint32_t n = 0; n < diff; ++n) {
104 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
111 /* XXX do something */
115 } else if (num < _plugins.size()) {
116 uint32_t diff = _plugins.size() - num;
117 for (uint32_t n= 0; n < diff; ++n) {
127 PluginInsert::set_outputs (const ChanCount& c)
133 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
135 if (which.type() != PluginAutomation)
138 boost::shared_ptr<AutomationControl> c
139 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
142 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
147 PluginInsert::output_streams() const
149 assert (_configured);
150 return _configured_out;
154 PluginInsert::input_streams() const
156 assert (_configured);
157 return _configured_in;
161 PluginInsert::internal_output_streams() const
163 assert (!_plugins.empty());
165 PluginInfoPtr info = _plugins.front()->get_info();
167 if (info->reconfigurable_io()) {
168 ChanCount out = _plugins.front()->output_streams ();
169 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
172 ChanCount out = info->n_outputs;
173 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
174 out.set_audio (out.n_audio() * _plugins.size());
175 out.set_midi (out.n_midi() * _plugins.size());
181 PluginInsert::internal_input_streams() const
183 assert (!_plugins.empty());
187 PluginInfoPtr info = _plugins.front()->get_info();
189 if (info->reconfigurable_io()) {
190 assert (_plugins.size() == 1);
191 in = _plugins.front()->input_streams();
196 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
198 if (_match.method == Split) {
200 /* we are splitting 1 processor input to multiple plugin inputs,
201 so we have a maximum of 1 stream of each type.
203 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
204 if (in.get (*t) > 1) {
210 } else if (_match.method == Hide) {
212 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
213 in.set (*t, in.get (*t) - _match.hide.get (*t));
219 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
220 in.set (*t, in.get (*t) * _plugins.size ());
228 PluginInsert::natural_output_streams() const
230 return _plugins[0]->get_info()->n_outputs;
234 PluginInsert::natural_input_streams() const
236 return _plugins[0]->get_info()->n_inputs;
240 PluginInsert::has_no_inputs() const
242 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
246 PluginInsert::has_no_audio_inputs() const
248 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
252 PluginInsert::is_midi_instrument() const
254 /* XXX more finesse is possible here. VST plugins have a
255 a specific "instrument" flag, for example.
257 PluginInfoPtr pi = _plugins[0]->get_info();
259 return pi->n_inputs.n_midi() != 0 &&
260 pi->n_outputs.n_audio() > 0;
264 PluginInsert::create_automatable_parameters ()
266 assert (!_plugins.empty());
268 set<Evoral::Parameter> a = _plugins.front()->automatable ();
270 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
271 if (i->type() == PluginAutomation) {
273 Evoral::Parameter param(*i);
275 ParameterDescriptor desc;
276 _plugins.front()->get_parameter_descriptor(i->id(), desc);
278 can_automate (param);
279 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
280 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
282 _plugins.front()->set_automation_control (i->id(), c);
283 } else if (i->type() == PluginPropertyAutomation) {
284 Evoral::Parameter param(*i);
285 const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
286 if (desc.datatype != Variant::NOTHING) {
287 boost::shared_ptr<AutomationList> list;
288 if (Variant::type_is_numeric(desc.datatype)) {
289 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
291 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
296 /** Called when something outside of this host has modified a plugin
297 * parameter. Responsible for propagating the change to two places:
299 * 1) anything listening to the Control itself
300 * 2) any replicated plugins that make up this PluginInsert.
302 * The PluginInsert is connected to the ParameterChangedExternally signal for
303 * the first (primary) plugin, and here broadcasts that change to any others.
305 * XXX We should probably drop this whole replication idea (Paul, October 2015)
306 * since it isn't used by sensible plugin APIs (AU, LV2).
309 PluginInsert::parameter_changed_externally (uint32_t which, float val)
311 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
313 /* First propagation: alter the underlying value of the control,
314 * without telling the plugin(s) that own/use it to set it.
321 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
324 pc->catch_up_with_external_value (val);
327 /* Second propagation: tell all plugins except the first to
328 update the value of this parameter. For sane plugin APIs,
329 there are no other plugins, so this is a no-op in those
333 Plugins::iterator i = _plugins.begin();
335 /* don't set the first plugin, just all the slaves */
337 if (i != _plugins.end()) {
339 for (; i != _plugins.end(); ++i) {
340 (*i)->set_parameter (which, val);
346 PluginInsert::set_block_size (pframes_t nframes)
349 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
350 if ((*i)->set_block_size (nframes) != 0) {
358 PluginInsert::activate ()
360 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
364 Processor::activate ();
368 PluginInsert::deactivate ()
370 Processor::deactivate ();
372 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
378 PluginInsert::flush ()
380 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
386 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
388 PinMappings in_map (_in_map);
389 PinMappings out_map (_out_map);
392 // auto-detect if inplace processing is possible
393 // TODO: do this once. during configure_io and every time the
394 // plugin-count or mapping changes.
395 bool inplace_ok = true;
396 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
397 if (!in_map[pc].is_monotonic ()) {
400 if (!out_map[pc].is_monotonic ()) {
405 if (_pending_no_inplace != !inplace_ok) {
406 #ifndef NDEBUG // this 'cerr' needs to go ASAP.
407 cerr << name () << " automatically set : " << (inplace_ok ? "Use Inplace" : "No Inplace") << "\n"; // XXX
409 _pending_no_inplace = !inplace_ok;
413 _no_inplace = _pending_no_inplace || _plugins.front()->inplace_broken ();
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 if (old_in != in || old_out != out
1089 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1091 PluginIoReConfigure (); /* EMIT SIGNAL */
1094 // we don't know the analysis window size, so we must work with the
1095 // current buffer size here. each request for data fills in these
1096 // buffers and the analyser makes sure it gets enough data for the
1098 session().ensure_buffer_set (_signal_analysis_inputs, in);
1099 //_signal_analysis_inputs.set_count (in);
1101 session().ensure_buffer_set (_signal_analysis_outputs, out);
1102 //_signal_analysis_outputs.set_count (out);
1104 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1107 return Processor::configure_io (in, out);
1110 /** Decide whether this PluginInsert can support a given IO configuration.
1111 * To do this, we run through a set of possible solutions in rough order of
1114 * @param in Required input channel count.
1115 * @param out Filled in with the output channel count if we return true.
1116 * @return true if the given IO configuration can be supported.
1119 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1121 return private_can_support_io_configuration (in, out).method != Impossible;
1124 /** A private version of can_support_io_configuration which returns the method
1125 * by which the configuration can be matched, rather than just whether or not
1129 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1131 if (_plugins.empty()) {
1135 /* if a user specified a custom cfg, so be it. */
1138 return Match (ExactMatch, get_count(), false, true); // XXX
1141 /* try automatic configuration */
1142 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1144 PluginInfoPtr info = _plugins.front()->get_info();
1145 ChanCount inputs = info->n_inputs;
1146 ChanCount outputs = info->n_outputs;
1147 ChanCount midi_bypass;
1148 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1149 midi_bypass.set (DataType::MIDI, 1);
1152 /* handle case strict-i/o */
1153 if (_strict_io && m.method != Impossible) {
1156 /* special case MIDI instruments */
1157 if (is_midi_instrument()) {
1158 // output = midi-bypass + at most master-out channels.
1159 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1160 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1161 out = ChanCount::min (out, max_out);
1167 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
1168 /* replicate processor to match output count (generators and such)
1169 * at least enough to feed every output port. */
1170 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1171 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1172 uint32_t nin = inputs.get (*t);
1173 if (nin == 0 || inx.get(*t) == 0) { continue; }
1174 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1176 out = inx + midi_bypass;
1177 return Match (Replicate, f);
1186 out = inx + midi_bypass;
1187 if (inx.get(DataType::MIDI) == 1
1188 && out.get (DataType::MIDI) == 0
1189 && outputs.get(DataType::MIDI) == 0) {
1190 out += ChanCount (DataType::MIDI, 1);
1195 if (m.method != Impossible) {
1199 if (info->reconfigurable_io()) {
1201 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1203 // houston, we have a problem.
1204 return Match (Impossible, 0);
1206 return Match (Delegate, 1);
1209 // add at least as many plugins so that output count matches input count
1211 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1212 uint32_t nin = inputs.get (*t);
1213 uint32_t nout = outputs.get (*t);
1214 if (nin == 0 || inx.get(*t) == 0) { continue; }
1215 // prefer floor() so the count won't overly increase IFF (nin < nout)
1216 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1218 if (f > 0 && outputs * f >= _configured_out) {
1219 out = outputs * f + midi_bypass;
1220 return Match (Replicate, f);
1223 // add at least as many plugins needed to connect all inputs
1225 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1226 uint32_t nin = inputs.get (*t);
1227 if (nin == 0 || inx.get(*t) == 0) { continue; }
1228 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1230 out = outputs * f + midi_bypass;
1231 return Match (Replicate, f);
1234 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1236 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1238 if (_plugins.empty()) {
1242 PluginInfoPtr info = _plugins.front()->get_info();
1243 ChanCount in; in += inx;
1244 ChanCount midi_bypass;
1246 if (info->reconfigurable_io()) {
1247 /* Plugin has flexible I/O, so delegate to it */
1248 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1250 return Match (Impossible, 0);
1252 return Match (Delegate, 1);
1255 ChanCount inputs = info->n_inputs;
1256 ChanCount outputs = info->n_outputs;
1258 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1259 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
1260 midi_bypass.set (DataType::MIDI, 1);
1262 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1263 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
1264 in.set(DataType::MIDI, 0);
1267 bool no_inputs = true;
1268 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1269 if (inputs.get (*t) != 0) {
1276 /* no inputs so we can take any input configuration since we throw it away */
1277 out = outputs + midi_bypass;
1278 return Match (NoInputs, 1);
1281 /* Plugin inputs match requested inputs exactly */
1283 out = outputs + midi_bypass;
1284 return Match (ExactMatch, 1);
1287 /* We may be able to run more than one copy of the plugin within this insert
1288 to cope with the insert having more inputs than the plugin.
1289 We allow replication only for plugins with either zero or 1 inputs and outputs
1290 for every valid data type.
1294 bool can_replicate = true;
1295 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1297 uint32_t nin = inputs.get (*t);
1299 // No inputs of this type
1300 if (nin == 0 && in.get(*t) == 0) {
1304 if (nin != 1 || outputs.get (*t) != 1) {
1305 can_replicate = false;
1309 // Potential factor not set yet
1311 f = in.get(*t) / nin;
1314 // Factor for this type does not match another type, can not replicate
1315 if (f != (in.get(*t) / nin)) {
1316 can_replicate = false;
1321 if (can_replicate && f > 0) {
1322 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1323 out.set (*t, outputs.get(*t) * f);
1326 return Match (Replicate, f);
1329 /* If the processor has exactly one input of a given type, and
1330 the plugin has more, we can feed the single processor input
1331 to some or all of the plugin inputs. This is rather
1332 special-case-y, but the 1-to-many case is by far the
1333 simplest. How do I split thy 2 processor inputs to 3
1334 plugin inputs? Let me count the ways ...
1337 bool can_split = true;
1338 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1340 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
1341 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1343 if (!can_split_type && !nothing_to_do_for_type) {
1349 out = outputs + midi_bypass;
1350 return Match (Split, 1);
1353 /* If the plugin has more inputs than we want, we can `hide' some of them
1354 by feeding them silence.
1357 bool could_hide = false;
1358 bool cannot_hide = false;
1359 ChanCount hide_channels;
1361 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1362 if (inputs.get(*t) > in.get(*t)) {
1363 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1364 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1366 } else if (inputs.get(*t) < in.get(*t)) {
1367 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1372 if (could_hide && !cannot_hide) {
1373 out = outputs + midi_bypass;
1374 return Match (Hide, 1, false, false, hide_channels);
1377 return Match (Impossible, 0);
1382 PluginInsert::get_state ()
1384 return state (true);
1388 PluginInsert::state (bool full)
1390 XMLNode& node = Processor::state (full);
1392 node.add_property("type", _plugins[0]->state_node_name());
1393 node.add_property("unique-id", _plugins[0]->unique_id());
1394 node.add_property("count", string_compose("%1", _plugins.size()));
1396 /* remember actual i/o configuration (for later placeholder
1397 * in case the plugin goes missing) */
1398 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1399 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1401 /* save custom i/o config */
1402 node.add_property("custom", _custom_cfg ? "yes" : "no");
1404 assert (_custom_out == _configured_out); // redundant
1405 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1406 // TODO save _in_map[pc], _out_map[pc]
1410 _plugins[0]->set_insert_id(this->id());
1411 node.add_child_nocopy (_plugins[0]->get_state());
1413 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1414 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1416 node.add_child_nocopy (ac->get_state());
1424 PluginInsert::set_control_ids (const XMLNode& node, int version)
1426 const XMLNodeList& nlist = node.children();
1427 XMLNodeConstIterator iter;
1428 set<Evoral::Parameter>::const_iterator p;
1430 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1431 if ((*iter)->name() == Controllable::xml_node_name) {
1432 const XMLProperty* prop;
1434 uint32_t p = (uint32_t)-1;
1436 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1437 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1439 p = lv2plugin->port_index(prop->value().c_str());
1443 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1444 p = atoi (prop->value());
1447 if (p != (uint32_t)-1) {
1449 /* this may create the new controllable */
1451 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1453 #ifndef NO_PLUGIN_STATE
1457 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1459 ac->set_state (**iter, version);
1468 PluginInsert::set_state(const XMLNode& node, int version)
1470 XMLNodeList nlist = node.children();
1471 XMLNodeIterator niter;
1472 XMLPropertyList plist;
1473 const XMLProperty *prop;
1474 ARDOUR::PluginType type;
1476 if ((prop = node.property ("type")) == 0) {
1477 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1481 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1482 type = ARDOUR::LADSPA;
1483 } else if (prop->value() == X_("lv2")) {
1485 } else if (prop->value() == X_("windows-vst")) {
1486 type = ARDOUR::Windows_VST;
1487 } else if (prop->value() == X_("lxvst")) {
1488 type = ARDOUR::LXVST;
1489 } else if (prop->value() == X_("audiounit")) {
1490 type = ARDOUR::AudioUnit;
1491 } else if (prop->value() == X_("luaproc")) {
1494 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1500 prop = node.property ("unique-id");
1503 #ifdef WINDOWS_VST_SUPPORT
1504 /* older sessions contain VST plugins with only an "id" field.
1507 if (type == ARDOUR::Windows_VST) {
1508 prop = node.property ("id");
1512 #ifdef LXVST_SUPPORT
1513 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1515 if (type == ARDOUR::LXVST) {
1516 prop = node.property ("id");
1522 error << _("Plugin has no unique ID field") << endmsg;
1527 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1529 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1530 * allow to move sessions windows <> linux */
1531 #ifdef LXVST_SUPPORT
1532 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1533 type = ARDOUR::LXVST;
1534 plugin = find_plugin (_session, prop->value(), type);
1538 #ifdef WINDOWS_VST_SUPPORT
1539 if (plugin == 0 && type == ARDOUR::LXVST) {
1540 type = ARDOUR::Windows_VST;
1541 plugin = find_plugin (_session, prop->value(), type);
1546 error << string_compose(
1547 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1548 "Perhaps it was removed or moved since it was last used."),
1554 if (type == ARDOUR::Lua) {
1555 XMLNode *ls = node.child (plugin->state_node_name().c_str());
1556 // we need to load the script to set the name and parameters.
1557 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
1559 lp->set_script_from_state (*ls);
1563 // The name of the PluginInsert comes from the plugin, nothing else
1564 _name = plugin->get_info()->name;
1568 // Processor::set_state() will set this, but too late
1569 // for it to be available when setting up plugin
1570 // state. We can't call Processor::set_state() until
1571 // the plugins themselves are created and added.
1575 if (_plugins.empty()) {
1576 /* if we are adding the first plugin, we will need to set
1577 up automatable controls.
1579 add_plugin (plugin);
1580 create_automatable_parameters ();
1581 set_control_ids (node, version);
1584 if ((prop = node.property ("count")) != 0) {
1585 sscanf (prop->value().c_str(), "%u", &count);
1588 if (_plugins.size() != count) {
1589 for (uint32_t n = 1; n < count; ++n) {
1590 add_plugin (plugin_factory (plugin));
1594 Processor::set_state (node, version);
1596 PBD::ID new_id = this->id();
1597 PBD::ID old_id = this->id();
1599 if ((prop = node.property ("id")) != 0) {
1600 old_id = prop->value ();
1603 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1605 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1606 and set all plugins to the same state.
1609 if ((*niter)->name() == plugin->state_node_name()) {
1611 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1612 /* Plugin state can include external files which are named after the ID.
1614 * If regenerate_xml_or_string_ids() is set, the ID will already have
1615 * been changed, so we need to use the old ID from the XML to load the
1616 * state and then update the ID.
1618 * When copying a plugin-state, route_ui takes care of of updating the ID,
1619 * but we need to call set_insert_id() to clear the cached plugin-state
1620 * and force a change.
1622 if (!regenerate_xml_or_string_ids ()) {
1623 (*i)->set_insert_id (new_id);
1625 (*i)->set_insert_id (old_id);
1628 (*i)->set_state (**niter, version);
1630 if (regenerate_xml_or_string_ids ()) {
1631 (*i)->set_insert_id (new_id);
1639 if (version < 3000) {
1641 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1642 this is all handled by Automatable
1645 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1646 if ((*niter)->name() == "Redirect") {
1647 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1648 Processor::set_state (**niter, version);
1653 set_parameter_state_2X (node, version);
1656 if ((prop = node.property (X_("custom"))) != 0) {
1657 _custom_cfg = string_is_affirmative (prop->value());
1660 XMLNodeList kids = node.children ();
1661 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
1662 if ((*i)->name() == X_("ConfiguredOutput")) {
1663 _custom_out = ChanCount(**i);
1665 // TODO restore mappings for all 0 .. count.
1670 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1674 (*i)->deactivate ();
1682 PluginInsert::update_id (PBD::ID id)
1685 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1686 (*i)->set_insert_id (id);
1691 PluginInsert::set_state_dir (const std::string& d)
1693 // state() only saves the state of the first plugin
1694 _plugins[0]->set_state_dir (d);
1698 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1700 XMLNodeList nlist = node.children();
1701 XMLNodeIterator niter;
1703 /* look for port automation node */
1705 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1707 if ((*niter)->name() != port_automation_node_name) {
1713 XMLNodeConstIterator iter;
1718 cnodes = (*niter)->children ("port");
1720 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1724 if ((cprop = child->property("number")) != 0) {
1725 port = cprop->value().c_str();
1727 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1731 sscanf (port, "%" PRIu32, &port_id);
1733 if (port_id >= _plugins[0]->parameter_count()) {
1734 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1738 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1739 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1741 if (c && c->alist()) {
1742 if (!child->children().empty()) {
1743 c->alist()->set_state (*child->children().front(), version);
1745 /* In some cases 2.X saves lists with min_yval and max_yval
1746 being FLT_MIN and FLT_MAX respectively. This causes problems
1747 in A3 because these min/max values are used to compute
1748 where GUI control points should be drawn. If we see such
1749 values, `correct' them to the min/max of the appropriate
1753 float min_y = c->alist()->get_min_y ();
1754 float max_y = c->alist()->get_max_y ();
1756 ParameterDescriptor desc;
1757 _plugins.front()->get_parameter_descriptor (port_id, desc);
1759 if (min_y == FLT_MIN) {
1763 if (max_y == FLT_MAX) {
1767 c->alist()->set_yrange (min_y, max_y);
1770 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1782 PluginInsert::describe_parameter (Evoral::Parameter param)
1784 if (param.type() == PluginAutomation) {
1785 return _plugins[0]->describe_parameter (param);
1786 } else if (param.type() == PluginPropertyAutomation) {
1787 boost::shared_ptr<AutomationControl> c(automation_control(param));
1788 if (c && !c->desc().label.empty()) {
1789 return c->desc().label;
1792 return Automatable::describe_parameter(param);
1796 PluginInsert::signal_latency() const
1798 if (_user_latency) {
1799 return _user_latency;
1802 return _plugins[0]->signal_latency ();
1806 PluginInsert::type ()
1808 return plugin()->get_info()->type;
1811 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1812 const Evoral::Parameter& param,
1813 const ParameterDescriptor& desc,
1814 boost::shared_ptr<AutomationList> list)
1815 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1819 alist()->reset_default (desc.normal);
1821 list->set_interpolation(Evoral::ControlList::Discrete);
1826 set_flags(Controllable::Toggle);
1830 /** @param val `user' value */
1832 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1835 _set_value (user_val, group_override);
1839 PluginInsert::PluginControl::set_value_unchecked (double user_val)
1841 /* used only by automation playback */
1842 _set_value (user_val, Controllable::NoGroup);
1846 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1848 /* FIXME: probably should be taking out some lock here.. */
1850 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1851 (*i)->set_parameter (_list->parameter().id(), user_val);
1854 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1856 iasp->set_parameter (_list->parameter().id(), user_val);
1859 AutomationControl::set_value (user_val, group_override);
1863 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
1865 AutomationControl::set_value (user_val, Controllable::NoGroup);
1869 PluginInsert::PluginControl::get_state ()
1873 XMLNode& node (AutomationControl::get_state());
1874 ss << parameter().id();
1875 node.add_property (X_("parameter"), ss.str());
1877 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
1879 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
1886 /** @return `user' val */
1888 PluginInsert::PluginControl::get_value () const
1890 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
1896 return plugin->get_parameter (_list->parameter().id());
1899 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1900 const Evoral::Parameter& param,
1901 const ParameterDescriptor& desc,
1902 boost::shared_ptr<AutomationList> list)
1903 : AutomationControl (p->session(), param, desc, list)
1907 alist()->set_yrange (desc.lower, desc.upper);
1908 alist()->reset_default (desc.normal);
1912 set_flags(Controllable::Toggle);
1917 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
1920 set_value_unchecked (user_val);
1925 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
1927 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1928 This is lossy, but better than nothing until Ardour's automation system
1929 can handle various datatypes all the way down. */
1930 const Variant value(_desc.datatype, user_val);
1931 if (value.type() == Variant::NOTHING) {
1932 error << "set_value(double) called for non-numeric property" << endmsg;
1936 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1937 (*i)->set_property(_list->parameter().id(), value);
1941 AutomationControl::set_value (user_val, Controllable::NoGroup);
1945 PluginInsert::PluginPropertyControl::get_state ()
1949 XMLNode& node (AutomationControl::get_state());
1950 ss << parameter().id();
1951 node.add_property (X_("property"), ss.str());
1952 node.remove_property (X_("value"));
1958 PluginInsert::PluginPropertyControl::get_value () const
1960 return _value.to_double();
1963 boost::shared_ptr<Plugin>
1964 PluginInsert::get_impulse_analysis_plugin()
1966 boost::shared_ptr<Plugin> ret;
1967 if (_impulseAnalysisPlugin.expired()) {
1968 ret = plugin_factory(_plugins[0]);
1969 ret->configure_io (internal_input_streams (), internal_output_streams ());
1970 _impulseAnalysisPlugin = ret;
1972 ret = _impulseAnalysisPlugin.lock();
1979 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1981 // called from outside the audio thread, so this should be safe
1982 // only do audio as analysis is (currently) only for audio plugins
1983 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
1984 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
1986 _signal_analysis_collected_nframes = 0;
1987 _signal_analysis_collect_nframes_max = nframes;
1990 /** Add a plugin to our list */
1992 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1994 plugin->set_insert_id (this->id());
1996 if (_plugins.empty()) {
1997 /* first (and probably only) plugin instance - connect to relevant signals
2000 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
2001 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
2002 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
2005 _plugins.push_back (plugin);
2009 PluginInsert::realtime_handle_transport_stopped ()
2011 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2012 (*i)->realtime_handle_transport_stopped ();
2017 PluginInsert::realtime_locate ()
2019 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2020 (*i)->realtime_locate ();
2025 PluginInsert::monitoring_changed ()
2027 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2028 (*i)->monitoring_changed ();
2033 PluginInsert::start_touch (uint32_t param_id)
2035 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2037 ac->start_touch (session().audible_frame());
2042 PluginInsert::end_touch (uint32_t param_id)
2044 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
2046 ac->stop_touch (true, session().audible_frame());
2050 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
2053 case PluginInsert::Impossible: o << "Impossible"; break;
2054 case PluginInsert::Delegate: o << "Delegate"; break;
2055 case PluginInsert::NoInputs: o << "NoInputs"; break;
2056 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
2057 case PluginInsert::Replicate: o << "Replicate"; break;
2058 case PluginInsert::Split: o << "Split"; break;
2059 case PluginInsert::Hide: o << "Hide"; break;
2061 o << " cnt: " << m.plugins
2062 << (m.strict_io ? " strict-io" : "")
2063 << (m.custom_cfg ? " custom-cfg" : "");
2064 if (m.method == PluginInsert::Hide) {
2065 o << " hide: " << m.hide;