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 (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 (min (_configured_in, ChanCount (DataType::AUDIO, 2)));
498 ChanMapping mb_out_map (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 (bufs.count().n_midi() == 1 && natural_output_streams().get(DataType::MIDI) == 0) {
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 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
596 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
598 uint32_t idx = out_map[pc].get (*t, o, &valid);
599 if (valid && idx == out) {
606 bufs.get (*t, out).silence (nframes, offset);
612 if (collect_signal_nframes > 0) {
614 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
615 //std::cerr << " streams " << internal_output_streams().n_audio() << std::endl;
617 _signal_analysis_outputs.set_count(internal_output_streams());
619 for (uint32_t i = 0; i < internal_output_streams().n_audio(); ++i) {
620 _signal_analysis_outputs.get_audio(i).read_from(
622 collect_signal_nframes,
623 _signal_analysis_collected_nframes); // offset is for target buffer
626 _signal_analysis_collected_nframes += collect_signal_nframes;
627 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
629 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
630 _signal_analysis_collect_nframes_max = 0;
631 _signal_analysis_collected_nframes = 0;
633 AnalysisDataGathered(&_signal_analysis_inputs,
634 &_signal_analysis_outputs);
640 PluginInsert::silence (framecnt_t nframes)
646 ChanMapping in_map (natural_input_streams ());
647 ChanMapping out_map (natural_output_streams ());
649 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
650 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
655 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
657 if (_pending_active) {
658 /* run as normal if we are active or moving from inactive to active */
660 if (_session.transport_rolling() || _session.bounce_processing()) {
661 automation_run (bufs, start_frame, nframes);
663 connect_and_run (bufs, nframes, 0, false);
667 // TODO use mapping in bypassed mode ?!
668 // -> do we bypass the processor or the plugin
670 uint32_t in = input_streams ().n_audio ();
671 uint32_t out = output_streams().n_audio ();
673 if (has_no_audio_inputs() || in == 0) {
675 /* silence all (audio) outputs. Should really declick
676 * at the transitions of "active"
679 for (uint32_t n = 0; n < out; ++n) {
680 bufs.get_audio (n).silence (nframes);
683 } else if (out > in) {
685 /* not active, but something has make up for any channel count increase
686 * for now , simply replicate last buffer
688 for (uint32_t n = in; n < out; ++n) {
689 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
693 bufs.count().set_audio (out);
696 _active = _pending_active;
698 /* we have no idea whether the plugin generated silence or not, so mark
699 * all buffers appropriately.
704 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
706 Evoral::ControlEvent next_event (0, 0.0f);
707 framepos_t now = start;
708 framepos_t end = now + nframes;
709 framecnt_t offset = 0;
711 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
714 connect_and_run (bufs, nframes, offset, false);
718 if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
720 /* no events have a time within the relevant range */
722 connect_and_run (bufs, nframes, offset, true, now);
728 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
730 connect_and_run (bufs, cnt, offset, true, now);
736 if (!find_next_event (now, end, next_event)) {
741 /* cleanup anything that is left to do */
744 connect_and_run (bufs, nframes, offset, true, now);
749 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
751 if (param.type() != PluginAutomation)
754 if (_plugins.empty()) {
755 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
757 abort(); /*NOTREACHED*/
760 return _plugins[0]->default_value (param.id());
765 PluginInsert::can_reset_all_parameters ()
769 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
771 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
773 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
777 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
783 if (ac->automation_state() & Play) {
788 return all && (params > 0);
792 PluginInsert::reset_parameters_to_default ()
796 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
798 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
800 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
804 const float dflt = _plugins[0]->default_value (cid);
805 const float curr = _plugins[0]->get_parameter (cid);
811 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
816 if (ac->automation_state() & Play) {
821 ac->set_value (dflt, Controllable::NoGroup);
826 boost::shared_ptr<Plugin>
827 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
829 boost::shared_ptr<LadspaPlugin> lp;
830 boost::shared_ptr<LuaProc> lua;
832 boost::shared_ptr<LV2Plugin> lv2p;
834 #ifdef WINDOWS_VST_SUPPORT
835 boost::shared_ptr<WindowsVSTPlugin> vp;
838 boost::shared_ptr<LXVSTPlugin> lxvp;
840 #ifdef AUDIOUNIT_SUPPORT
841 boost::shared_ptr<AUPlugin> ap;
844 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
845 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
846 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
847 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
849 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
850 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
852 #ifdef WINDOWS_VST_SUPPORT
853 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
854 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
857 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
858 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
860 #ifdef AUDIOUNIT_SUPPORT
861 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
862 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
866 fatal << string_compose (_("programming error: %1"),
867 X_("unknown plugin type in PluginInsert::plugin_factory"))
869 abort(); /*NOTREACHED*/
870 return boost::shared_ptr<Plugin> ((Plugin*) 0);
874 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
875 if (num < _in_map.size()) {
876 bool changed = _in_map[num] != m;
879 PluginMapChanged (); /* EMIT SIGNAL */
885 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
886 if (num < _out_map.size()) {
887 bool changed = _out_map[num] != m;
890 PluginMapChanged (); /* EMIT SIGNAL */
896 PluginInsert::configure_io (ChanCount in, ChanCount out)
898 Match old_match = _match;
903 old_in = _configured_in;
904 old_out = _configured_out;
908 _configured_out = out;
910 /* get plugin configuration */
911 _match = private_can_support_io_configuration (in, out);
913 /* set the matching method and number of plugins that we will use to meet this configuration */
914 if (set_count (_match.plugins) == false) {
915 PluginIoReConfigure (); /* EMIT SIGNAL */
920 /* configure plugins */
921 switch (_match.method) {
924 if (_plugins.front()->configure_io (natural_input_streams(), out) == false) {
925 PluginIoReConfigure (); /* EMIT SIGNAL */
934 bool const r = _plugins.front()->can_support_io_configuration (in, dout, &useins);
936 assert (_match.strict_io || dout.n_audio() == out.n_audio()); // sans midi bypass
937 if (useins.n_audio() == 0) {
940 if (_plugins.front()->configure_io (useins, dout) == false) {
941 PluginIoReConfigure (); /* EMIT SIGNAL */
948 if (_plugins.front()->configure_io (in, out) == false) {
949 PluginIoReConfigure (); /* EMIT SIGNAL */
956 bool mapping_changed = false;
957 if (old_in == in && old_out == out && _configured
958 && old_match.method == _match.method
959 && _in_map.size() == _out_map.size()
960 && _in_map.size() == get_count ()
962 /* If the configuraton has not changed, keep the mapping */
963 } else if (_match.custom_cfg && _configured) {
964 /* strip dead wood */
965 for (uint32_t pc = 0; pc < get_count(); ++pc) {
968 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
969 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
971 uint32_t idx = _in_map[pc].get (*t, i, &valid);
972 if (valid && idx <= in.get (*t)) {
973 new_in.set (*t, i, idx);
976 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
978 uint32_t idx = _out_map[pc].get (*t, o, &valid);
979 if (valid && idx <= out.get (*t)) {
980 new_out.set (*t, o, idx);
984 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
985 mapping_changed = true;
987 _in_map[pc] = new_in;
988 _out_map[pc] = new_out;
991 /* generate a new mapping */
995 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
996 if (_match.method == Split) {
997 _in_map[pc] = ChanMapping ();
998 /* connect inputs in round-robin fashion */
999 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1000 const uint32_t cend = _configured_in.get (*t);
1001 if (cend == 0) { continue; }
1003 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
1004 _in_map[pc].set (*t, in, c);
1009 _in_map[pc] = ChanMapping (min (natural_input_streams (), in));
1011 _out_map[pc] = ChanMapping (min (natural_output_streams(), out));
1013 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1014 _in_map[pc].offset_to(*t, pc * natural_input_streams().get(*t));
1015 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1017 mapping_changed = true;
1021 if (mapping_changed) {
1022 PluginMapChanged (); /* EMIT SIGNAL */
1025 cout << "----<<----\n";
1026 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1027 cout << "Channel Map for " << name() << " plugin " << pc << "\n";
1028 cout << " * Inputs:\n" << _in_map[pc];
1029 cout << " * Outputs:\n" << _out_map[pc];
1031 cout << "---->>----\n";
1035 if (old_in != in || old_out != out
1036 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
1038 PluginIoReConfigure (); /* EMIT SIGNAL */
1041 // we don't know the analysis window size, so we must work with the
1042 // current buffer size here. each request for data fills in these
1043 // buffers and the analyser makes sure it gets enough data for the
1045 session().ensure_buffer_set (_signal_analysis_inputs, in);
1046 //_signal_analysis_inputs.set_count (in);
1048 session().ensure_buffer_set (_signal_analysis_outputs, out);
1049 //_signal_analysis_outputs.set_count (out);
1051 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
1054 return Processor::configure_io (in, out);
1057 /** Decide whether this PluginInsert can support a given IO configuration.
1058 * To do this, we run through a set of possible solutions in rough order of
1061 * @param in Required input channel count.
1062 * @param out Filled in with the output channel count if we return true.
1063 * @return true if the given IO configuration can be supported.
1066 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
1068 return private_can_support_io_configuration (in, out).method != Impossible;
1071 /** A private version of can_support_io_configuration which returns the method
1072 * by which the configuration can be matched, rather than just whether or not
1076 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1078 if (_plugins.empty()) {
1082 /* if a user specified a custom cfg, so be it. */
1085 return Match (ExactMatch, get_count(), false, true); // XXX
1088 /* try automatic configuration next */
1089 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
1092 PluginInfoPtr info = _plugins.front()->get_info();
1093 ChanCount inputs = info->n_inputs;
1094 ChanCount outputs = info->n_outputs;
1095 ChanCount midi_bypass;
1097 /* handle case strict-i/o */
1098 if (_strict_io && m.method != Impossible) {
1101 /* special case MIDI instruments */
1102 if (is_midi_instrument()) {
1103 // output = midi-bypass + at most master-out channels.
1104 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
1105 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
1106 out = min (out, max_out);
1113 /* replicate processor to match output count (generators and such)
1114 * at least enough to feed every output port. */
1115 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
1116 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1117 uint32_t nin = inputs.get (*t);
1118 if (nin == 0 || inx.get(*t) == 0) { continue; }
1119 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
1122 return Match (Replicate, f);
1130 if (inx == out) { return m; }
1133 if (inx.get(DataType::MIDI) == 1
1134 && out.get (DataType::MIDI) == 0
1135 && outputs.get(DataType::MIDI) == 0) {
1136 out += ChanCount (DataType::MIDI, 1);
1141 if (m.method != Impossible) {
1145 if (info->reconfigurable_io()) {
1147 bool const r = _plugins.front()->can_support_io_configuration (inx, out, &useins);
1149 // houston, we have a problem.
1150 return Match (Impossible, 0);
1152 return Match (Delegate, 1);
1155 // add at least as many plugins so that output count matches input count
1157 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1158 uint32_t nin = inputs.get (*t);
1159 uint32_t nout = outputs.get (*t);
1160 if (nin == 0 || inx.get(*t) == 0) { continue; }
1161 // prefer floor() so the count won't overly increase IFF (nin < nout)
1162 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
1164 if (f > 0 && outputs * f >= _configured_out) {
1166 return Match (Replicate, f);
1169 // add at least as many plugins needed to connect all inputs
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));
1177 return Match (Replicate, f);
1180 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
1182 PluginInsert::automatic_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
1184 if (_plugins.empty()) {
1188 PluginInfoPtr info = _plugins.front()->get_info();
1189 ChanCount in; in += inx;
1190 ChanCount midi_bypass;
1192 if (info->reconfigurable_io()) {
1193 /* Plugin has flexible I/O, so delegate to it */
1194 bool const r = _plugins.front()->can_support_io_configuration (in, out);
1196 return Match (Impossible, 0);
1198 return Match (Delegate, 1);
1201 ChanCount inputs = info->n_inputs;
1202 ChanCount outputs = info->n_outputs;
1204 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
1205 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
1206 midi_bypass.set(DataType::MIDI, 1);
1208 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
1209 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
1210 in.set(DataType::MIDI, 0);
1213 bool no_inputs = true;
1214 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1215 if (inputs.get (*t) != 0) {
1222 /* no inputs so we can take any input configuration since we throw it away */
1223 out = outputs + midi_bypass;
1224 return Match (NoInputs, 1);
1227 /* Plugin inputs match requested inputs exactly */
1229 out = outputs + midi_bypass;
1230 return Match (ExactMatch, 1);
1233 /* We may be able to run more than one copy of the plugin within this insert
1234 to cope with the insert having more inputs than the plugin.
1235 We allow replication only for plugins with either zero or 1 inputs and outputs
1236 for every valid data type.
1240 bool can_replicate = true;
1241 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1243 uint32_t nin = inputs.get (*t);
1245 // No inputs of this type
1246 if (nin == 0 && in.get(*t) == 0) {
1250 if (nin != 1 || outputs.get (*t) != 1) {
1251 can_replicate = false;
1255 // Potential factor not set yet
1257 f = in.get(*t) / nin;
1260 // Factor for this type does not match another type, can not replicate
1261 if (f != (in.get(*t) / nin)) {
1262 can_replicate = false;
1267 if (can_replicate) {
1268 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1269 out.set (*t, outputs.get(*t) * f);
1272 return Match (Replicate, f);
1275 /* If the processor has exactly one input of a given type, and
1276 the plugin has more, we can feed the single processor input
1277 to some or all of the plugin inputs. This is rather
1278 special-case-y, but the 1-to-many case is by far the
1279 simplest. How do I split thy 2 processor inputs to 3
1280 plugin inputs? Let me count the ways ...
1283 bool can_split = true;
1284 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1286 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
1287 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
1289 if (!can_split_type && !nothing_to_do_for_type) {
1295 out = outputs + midi_bypass;
1296 return Match (Split, 1);
1299 /* If the plugin has more inputs than we want, we can `hide' some of them
1300 by feeding them silence.
1303 bool could_hide = false;
1304 bool cannot_hide = false;
1305 ChanCount hide_channels;
1307 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1308 if (inputs.get(*t) > in.get(*t)) {
1309 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
1310 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
1312 } else if (inputs.get(*t) < in.get(*t)) {
1313 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
1318 if (could_hide && !cannot_hide) {
1319 out = outputs + midi_bypass;
1320 return Match (Hide, 1, false, false, hide_channels);
1323 midi_bypass.reset();
1324 return Match (Impossible, 0);
1329 PluginInsert::get_state ()
1331 return state (true);
1335 PluginInsert::state (bool full)
1337 XMLNode& node = Processor::state (full);
1339 node.add_property("type", _plugins[0]->state_node_name());
1340 node.add_property("unique-id", _plugins[0]->unique_id());
1341 node.add_property("count", string_compose("%1", _plugins.size()));
1343 /* remember actual i/o configuration (for later placeholder
1344 * in case the plugin goes missing) */
1345 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
1346 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
1348 /* save custom i/o config */
1349 node.add_property("custom", _custom_cfg ? "yes" : "no");
1351 assert (_custom_out == _configured_out); // redundant
1352 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1353 // TODO save _in_map[pc], _out_map[pc]
1357 _plugins[0]->set_insert_id(this->id());
1358 node.add_child_nocopy (_plugins[0]->get_state());
1360 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
1361 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
1363 node.add_child_nocopy (ac->get_state());
1371 PluginInsert::set_control_ids (const XMLNode& node, int version)
1373 const XMLNodeList& nlist = node.children();
1374 XMLNodeConstIterator iter;
1375 set<Evoral::Parameter>::const_iterator p;
1377 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
1378 if ((*iter)->name() == Controllable::xml_node_name) {
1379 const XMLProperty* prop;
1381 uint32_t p = (uint32_t)-1;
1383 if ((prop = (*iter)->property (X_("symbol"))) != 0) {
1384 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
1386 p = lv2plugin->port_index(prop->value().c_str());
1390 if (p == (uint32_t)-1 && (prop = (*iter)->property (X_("parameter"))) != 0) {
1391 p = atoi (prop->value());
1394 if (p != (uint32_t)-1) {
1396 /* this may create the new controllable */
1398 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
1400 #ifndef NO_PLUGIN_STATE
1404 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
1406 ac->set_state (**iter, version);
1415 PluginInsert::set_state(const XMLNode& node, int version)
1417 XMLNodeList nlist = node.children();
1418 XMLNodeIterator niter;
1419 XMLPropertyList plist;
1420 const XMLProperty *prop;
1421 ARDOUR::PluginType type;
1423 if ((prop = node.property ("type")) == 0) {
1424 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1428 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1429 type = ARDOUR::LADSPA;
1430 } else if (prop->value() == X_("lv2")) {
1432 } else if (prop->value() == X_("windows-vst")) {
1433 type = ARDOUR::Windows_VST;
1434 } else if (prop->value() == X_("lxvst")) {
1435 type = ARDOUR::LXVST;
1436 } else if (prop->value() == X_("audiounit")) {
1437 type = ARDOUR::AudioUnit;
1438 } else if (prop->value() == X_("luaproc")) {
1441 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1447 prop = node.property ("unique-id");
1450 #ifdef WINDOWS_VST_SUPPORT
1451 /* older sessions contain VST plugins with only an "id" field.
1454 if (type == ARDOUR::Windows_VST) {
1455 prop = node.property ("id");
1459 #ifdef LXVST_SUPPORT
1460 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1462 if (type == ARDOUR::LXVST) {
1463 prop = node.property ("id");
1469 error << _("Plugin has no unique ID field") << endmsg;
1474 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1476 /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1477 * allow to move sessions windows <> linux */
1478 #ifdef LXVST_SUPPORT
1479 if (plugin == 0 && type == ARDOUR::Windows_VST) {
1480 type = ARDOUR::LXVST;
1481 plugin = find_plugin (_session, prop->value(), type);
1485 #ifdef WINDOWS_VST_SUPPORT
1486 if (plugin == 0 && type == ARDOUR::LXVST) {
1487 type = ARDOUR::Windows_VST;
1488 plugin = find_plugin (_session, prop->value(), type);
1493 error << string_compose(
1494 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1495 "Perhaps it was removed or moved since it was last used."),
1501 if (type == ARDOUR::Lua) {
1502 XMLNode *ls = node.child (plugin->state_node_name().c_str());
1503 // we need to load the script to set the name and parameters.
1504 boost::shared_ptr<LuaProc> lp = boost::dynamic_pointer_cast<LuaProc>(plugin);
1506 lp->set_script_from_state (*ls);
1510 // The name of the PluginInsert comes from the plugin, nothing else
1511 _name = plugin->get_info()->name;
1515 // Processor::set_state() will set this, but too late
1516 // for it to be available when setting up plugin
1517 // state. We can't call Processor::set_state() until
1518 // the plugins themselves are created and added.
1522 if (_plugins.empty()) {
1523 /* if we are adding the first plugin, we will need to set
1524 up automatable controls.
1526 add_plugin (plugin);
1527 create_automatable_parameters ();
1528 set_control_ids (node, version);
1531 if ((prop = node.property ("count")) != 0) {
1532 sscanf (prop->value().c_str(), "%u", &count);
1535 if (_plugins.size() != count) {
1536 for (uint32_t n = 1; n < count; ++n) {
1537 add_plugin (plugin_factory (plugin));
1541 Processor::set_state (node, version);
1543 PBD::ID new_id = this->id();
1544 PBD::ID old_id = this->id();
1546 if ((prop = node.property ("id")) != 0) {
1547 old_id = prop->value ();
1550 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1552 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1553 and set all plugins to the same state.
1556 if ((*niter)->name() == plugin->state_node_name()) {
1558 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1559 /* Plugin state can include external files which are named after the ID.
1561 * If regenerate_xml_or_string_ids() is set, the ID will already have
1562 * been changed, so we need to use the old ID from the XML to load the
1563 * state and then update the ID.
1565 * When copying a plugin-state, route_ui takes care of of updating the ID,
1566 * but we need to call set_insert_id() to clear the cached plugin-state
1567 * and force a change.
1569 if (!regenerate_xml_or_string_ids ()) {
1570 (*i)->set_insert_id (new_id);
1572 (*i)->set_insert_id (old_id);
1575 (*i)->set_state (**niter, version);
1577 if (regenerate_xml_or_string_ids ()) {
1578 (*i)->set_insert_id (new_id);
1586 if (version < 3000) {
1588 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1589 this is all handled by Automatable
1592 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1593 if ((*niter)->name() == "Redirect") {
1594 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1595 Processor::set_state (**niter, version);
1600 set_parameter_state_2X (node, version);
1603 if ((prop = node.property (X_("custom"))) != 0) {
1604 _custom_cfg = string_is_affirmative (prop->value());
1607 XMLNodeList kids = node.children ();
1608 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
1609 if ((*i)->name() == X_("ConfiguredOutput")) {
1610 _custom_out = ChanCount(**i);
1612 // TODO restore mappings for all 0 .. count.
1617 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1621 (*i)->deactivate ();
1629 PluginInsert::update_id (PBD::ID id)
1632 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1633 (*i)->set_insert_id (id);
1638 PluginInsert::set_state_dir (const std::string& d)
1640 // state() only saves the state of the first plugin
1641 _plugins[0]->set_state_dir (d);
1645 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1647 XMLNodeList nlist = node.children();
1648 XMLNodeIterator niter;
1650 /* look for port automation node */
1652 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1654 if ((*niter)->name() != port_automation_node_name) {
1660 XMLNodeConstIterator iter;
1665 cnodes = (*niter)->children ("port");
1667 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1671 if ((cprop = child->property("number")) != 0) {
1672 port = cprop->value().c_str();
1674 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1678 sscanf (port, "%" PRIu32, &port_id);
1680 if (port_id >= _plugins[0]->parameter_count()) {
1681 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1685 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1686 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1688 if (c && c->alist()) {
1689 if (!child->children().empty()) {
1690 c->alist()->set_state (*child->children().front(), version);
1692 /* In some cases 2.X saves lists with min_yval and max_yval
1693 being FLT_MIN and FLT_MAX respectively. This causes problems
1694 in A3 because these min/max values are used to compute
1695 where GUI control points should be drawn. If we see such
1696 values, `correct' them to the min/max of the appropriate
1700 float min_y = c->alist()->get_min_y ();
1701 float max_y = c->alist()->get_max_y ();
1703 ParameterDescriptor desc;
1704 _plugins.front()->get_parameter_descriptor (port_id, desc);
1706 if (min_y == FLT_MIN) {
1710 if (max_y == FLT_MAX) {
1714 c->alist()->set_yrange (min_y, max_y);
1717 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1729 PluginInsert::describe_parameter (Evoral::Parameter param)
1731 if (param.type() == PluginAutomation) {
1732 return _plugins[0]->describe_parameter (param);
1733 } else if (param.type() == PluginPropertyAutomation) {
1734 boost::shared_ptr<AutomationControl> c(automation_control(param));
1735 if (c && !c->desc().label.empty()) {
1736 return c->desc().label;
1739 return Automatable::describe_parameter(param);
1743 PluginInsert::signal_latency() const
1745 if (_user_latency) {
1746 return _user_latency;
1749 return _plugins[0]->signal_latency ();
1753 PluginInsert::type ()
1755 return plugin()->get_info()->type;
1758 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
1759 const Evoral::Parameter& param,
1760 const ParameterDescriptor& desc,
1761 boost::shared_ptr<AutomationList> list)
1762 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1766 alist()->reset_default (desc.normal);
1768 list->set_interpolation(Evoral::ControlList::Discrete);
1773 set_flags(Controllable::Toggle);
1777 /** @param val `user' value */
1779 PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1782 _set_value (user_val, group_override);
1786 PluginInsert::PluginControl::set_value_unchecked (double user_val)
1788 /* used only by automation playback */
1789 _set_value (user_val, Controllable::NoGroup);
1793 PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
1795 /* FIXME: probably should be taking out some lock here.. */
1797 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1798 (*i)->set_parameter (_list->parameter().id(), user_val);
1801 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1803 iasp->set_parameter (_list->parameter().id(), user_val);
1806 AutomationControl::set_value (user_val, group_override);
1810 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
1812 AutomationControl::set_value (user_val, Controllable::NoGroup);
1816 PluginInsert::PluginControl::get_state ()
1820 XMLNode& node (AutomationControl::get_state());
1821 ss << parameter().id();
1822 node.add_property (X_("parameter"), ss.str());
1824 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
1826 node.add_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
1833 /** @return `user' val */
1835 PluginInsert::PluginControl::get_value () const
1837 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
1843 return plugin->get_parameter (_list->parameter().id());
1846 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
1847 const Evoral::Parameter& param,
1848 const ParameterDescriptor& desc,
1849 boost::shared_ptr<AutomationList> list)
1850 : AutomationControl (p->session(), param, desc, list)
1854 alist()->set_yrange (desc.lower, desc.upper);
1855 alist()->reset_default (desc.normal);
1859 set_flags(Controllable::Toggle);
1864 PluginInsert::PluginPropertyControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override*/)
1867 set_value_unchecked (user_val);
1872 PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
1874 /* Old numeric set_value(), coerce to appropriate datatype if possible.
1875 This is lossy, but better than nothing until Ardour's automation system
1876 can handle various datatypes all the way down. */
1877 const Variant value(_desc.datatype, user_val);
1878 if (value.type() == Variant::NOTHING) {
1879 error << "set_value(double) called for non-numeric property" << endmsg;
1883 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1884 (*i)->set_property(_list->parameter().id(), value);
1888 AutomationControl::set_value (user_val, Controllable::NoGroup);
1892 PluginInsert::PluginPropertyControl::get_state ()
1896 XMLNode& node (AutomationControl::get_state());
1897 ss << parameter().id();
1898 node.add_property (X_("property"), ss.str());
1899 node.remove_property (X_("value"));
1905 PluginInsert::PluginPropertyControl::get_value () const
1907 return _value.to_double();
1910 boost::shared_ptr<Plugin>
1911 PluginInsert::get_impulse_analysis_plugin()
1913 boost::shared_ptr<Plugin> ret;
1914 if (_impulseAnalysisPlugin.expired()) {
1915 ret = plugin_factory(_plugins[0]);
1916 ret->configure_io (internal_input_streams (), internal_output_streams ());
1917 _impulseAnalysisPlugin = ret;
1919 ret = _impulseAnalysisPlugin.lock();
1926 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1928 // called from outside the audio thread, so this should be safe
1929 // only do audio as analysis is (currently) only for audio plugins
1930 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, internal_input_streams().n_audio(), nframes);
1931 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, internal_output_streams().n_audio(), nframes);
1933 _signal_analysis_collected_nframes = 0;
1934 _signal_analysis_collect_nframes_max = nframes;
1937 /** Add a plugin to our list */
1939 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1941 plugin->set_insert_id (this->id());
1943 if (_plugins.empty()) {
1944 /* first (and probably only) plugin instance - connect to relevant signals
1947 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
1948 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1949 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1952 _plugins.push_back (plugin);
1956 PluginInsert::realtime_handle_transport_stopped ()
1958 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1959 (*i)->realtime_handle_transport_stopped ();
1964 PluginInsert::realtime_locate ()
1966 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1967 (*i)->realtime_locate ();
1972 PluginInsert::monitoring_changed ()
1974 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1975 (*i)->monitoring_changed ();
1980 PluginInsert::start_touch (uint32_t param_id)
1982 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1984 ac->start_touch (session().audible_frame());
1989 PluginInsert::end_touch (uint32_t param_id)
1991 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1993 ac->stop_touch (true, session().audible_frame());