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/event_type_map.h"
34 #include "ardour/ladspa_plugin.h"
35 #include "ardour/plugin.h"
36 #include "ardour/plugin_insert.h"
37 #include "ardour/port.h"
38 #include "ardour/route.h"
41 #include "ardour/lv2_plugin.h"
45 #include "ardour/vst_plugin.h"
49 #include "ardour/lxvst_plugin.h"
52 #ifdef HAVE_AUDIOUNITS
53 #include "ardour/audio_unit.h"
56 #include "ardour/audioengine.h"
57 #include "ardour/session.h"
58 #include "ardour/types.h"
63 using namespace ARDOUR;
66 const string PluginInsert::port_automation_node_name = "PortAutomation";
68 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
69 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
70 , _signal_analysis_collected_nframes(0)
71 , _signal_analysis_collect_nframes_max(0)
72 , _matching_method (Impossible)
74 /* the first is the master */
78 create_automatable_parameters ();
80 Glib::Mutex::Lock em (_session.engine().process_lock());
81 IO::PortCountChanged (max(input_streams(), output_streams()));
86 PluginInsert::set_count (uint32_t num)
88 bool require_state = !_plugins.empty();
90 /* this is a bad idea.... we shouldn't do this while active.
91 only a route holding their redirect_lock should be calling this
96 } else if (num > _plugins.size()) {
97 uint32_t diff = num - _plugins.size();
99 for (uint32_t n = 0; n < diff; ++n) {
100 add_plugin_with_activation (plugin_factory (_plugins[0]));
103 /* XXX do something */
107 } else if (num < _plugins.size()) {
108 uint32_t diff = _plugins.size() - num;
109 for (uint32_t n= 0; n < diff; ++n) {
117 PluginInsert::~PluginInsert ()
122 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
124 if (which.type() != PluginAutomation)
127 boost::shared_ptr<AutomationControl> c
128 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
131 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
136 PluginInsert::output_streams() const
138 ChanCount out = _plugins.front()->get_info()->n_outputs;
140 if (out == ChanCount::INFINITE) {
141 return _plugins.front()->output_streams ();
143 out.set_audio (out.n_audio() * _plugins.size());
144 out.set_midi (out.n_midi() * _plugins.size());
150 PluginInsert::input_streams() const
152 ChanCount in = _plugins[0]->get_info()->n_inputs;
154 if (_matching_method == Split) {
156 /* we are splitting 1 processor input to multiple plugin inputs,
157 so we have a maximum of 1 stream of each type.
159 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
160 if (in.get (*t) > 1) {
166 } else if (in == ChanCount::INFINITE) {
168 return _plugins[0]->input_streams ();
172 in.set_audio (in.n_audio() * _plugins.size());
173 in.set_midi (in.n_midi() * _plugins.size());
180 PluginInsert::natural_output_streams() const
182 return _plugins[0]->get_info()->n_outputs;
186 PluginInsert::natural_input_streams() const
188 return _plugins[0]->get_info()->n_inputs;
192 PluginInsert::has_no_inputs() const
194 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
198 PluginInsert::has_no_audio_inputs() const
200 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
204 PluginInsert::is_midi_instrument() const
206 /* XXX more finesse is possible here. VST plugins have a
207 a specific "instrument" flag, for example.
209 PluginInfoPtr pi = _plugins[0]->get_info();
211 return pi->n_inputs.n_midi() != 0 &&
212 pi->n_outputs.n_audio() > 0;
216 PluginInsert::create_automatable_parameters ()
218 assert (!_plugins.empty());
220 set<Evoral::Parameter> a = _plugins.front()->automatable ();
222 Plugin::ParameterDescriptor desc;
224 for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
225 if (i->type() == PluginAutomation) {
227 Evoral::Parameter param(*i);
229 _plugins.front()->get_parameter_descriptor(i->id(), desc);
231 /* the Parameter belonging to the actual plugin doesn't have its range set
232 but we want the Controllable related to this Parameter to have those limits.
235 param.set_range (desc.lower, desc.upper, _plugins.front()->default_value(i->id()), desc.toggled);
236 can_automate (param);
237 boost::shared_ptr<AutomationList> list(new AutomationList(param));
238 add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, list)));
244 PluginInsert::parameter_changed (Evoral::Parameter which, float val)
246 if (which.type() != PluginAutomation)
249 Plugins::iterator i = _plugins.begin();
251 /* don't set the first plugin, just all the slaves */
253 if (i != _plugins.end()) {
255 for (; i != _plugins.end(); ++i) {
256 (*i)->set_parameter (which, val);
262 PluginInsert::set_block_size (pframes_t nframes)
265 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
266 if ((*i)->set_block_size (nframes) != 0) {
274 PluginInsert::activate ()
276 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
280 Processor::activate ();
284 PluginInsert::deactivate ()
286 Processor::deactivate ();
288 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
294 PluginInsert::flush ()
296 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
302 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
304 // Calculate if, and how many frames we need to collect for analysis
305 framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
306 _signal_analysis_collected_nframes);
307 if (nframes < collect_signal_nframes) { // we might not get all frames now
308 collect_signal_nframes = nframes;
311 ChanMapping in_map(input_streams());
312 ChanMapping out_map(output_streams());
314 if (_matching_method == Split) {
315 /* fix the input mapping so that we have maps for each of the plugin's inputs */
316 in_map = ChanMapping (natural_input_streams ());
318 /* copy the first stream's buffer contents to the others */
319 /* XXX: audio only */
320 Sample const * mono = bufs.get_audio (in_map.get (DataType::AUDIO, 0)).data (offset);
321 for (uint32_t i = input_streams().n_audio(); i < natural_input_streams().n_audio(); ++i) {
322 memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i)).data (offset), mono, sizeof (Sample) * nframes);
326 /* Note that we've already required that plugins
327 be able to handle in-place processing.
334 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
336 boost::shared_ptr<AutomationControl> c
337 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
339 if (c->parameter().type() == PluginAutomation && c->automation_playback()) {
342 const float val = c->list()->rt_safe_eval (now, valid);
352 if (collect_signal_nframes > 0) {
354 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
355 //std::cerr << " streams " << input_streams().n_audio() << std::endl;
356 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
358 _signal_analysis_inputs.set_count(input_streams());
360 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
361 _signal_analysis_inputs.get_audio(i).read_from(
363 collect_signal_nframes,
364 _signal_analysis_collected_nframes); // offset is for target buffer
369 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
370 (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
371 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
372 in_map.offset_to(*t, natural_input_streams().get(*t));
373 out_map.offset_to(*t, natural_output_streams().get(*t));
377 if (collect_signal_nframes > 0) {
379 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
380 //std::cerr << " streams " << output_streams().n_audio() << std::endl;
382 _signal_analysis_outputs.set_count(output_streams());
384 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
385 _signal_analysis_outputs.get_audio(i).read_from(
387 collect_signal_nframes,
388 _signal_analysis_collected_nframes); // offset is for target buffer
391 _signal_analysis_collected_nframes += collect_signal_nframes;
392 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
394 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
395 _signal_analysis_collect_nframes_max = 0;
396 _signal_analysis_collected_nframes = 0;
398 AnalysisDataGathered(&_signal_analysis_inputs,
399 &_signal_analysis_outputs);
402 /* leave remaining channel buffers alone */
406 PluginInsert::silence (framecnt_t nframes)
412 ChanMapping in_map(input_streams());
413 ChanMapping out_map(output_streams());
415 if (_matching_method == Split) {
416 /* fix the input mapping so that we have maps for each of the plugin's inputs */
417 in_map = ChanMapping (natural_input_streams ());
420 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
421 (*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
426 PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
428 if (_pending_active) {
429 /* run as normal if we are active or moving from inactive to active */
431 if (_session.transport_rolling()) {
432 automation_run (bufs, nframes);
434 connect_and_run (bufs, nframes, 0, false);
439 if (has_no_audio_inputs()) {
441 /* silence all (audio) outputs. Should really declick
442 * at the transitions of "active"
445 uint32_t out = _plugins[0]->get_info()->n_outputs.n_audio();
447 for (uint32_t n = 0; n < out; ++n) {
448 bufs.get_audio (n).silence (nframes);
451 bufs.count().set_audio (out);
455 /* does this need to be done with MIDI? it appears not */
457 uint32_t in = _plugins[0]->get_info()->n_inputs.n_audio();
458 uint32_t out = _plugins[0]->get_info()->n_outputs.n_audio();
462 /* not active, but something has make up for any channel count increase */
464 for (uint32_t n = out - in; n < out; ++n) {
465 memcpy (bufs.get_audio(n).data(), bufs.get_audio(in - 1).data(), sizeof (Sample) * nframes);
469 bufs.count().set_audio (out);
473 _active = _pending_active;
477 PluginInsert::set_parameter (Evoral::Parameter param, float val)
479 if (param.type() != PluginAutomation) {
483 /* the others will be set from the event triggered by this */
485 _plugins[0]->set_parameter (param.id(), val);
487 boost::shared_ptr<AutomationControl> ac
488 = boost::dynamic_pointer_cast<AutomationControl>(control(param));
493 warning << "set_parameter called for nonexistant parameter "
494 << EventTypeMap::instance().to_symbol(param) << endmsg;
497 _session.set_dirty();
501 PluginInsert::get_parameter (Evoral::Parameter param)
503 if (param.type() != PluginAutomation) {
506 assert (!_plugins.empty ());
507 return _plugins[0]->get_parameter (param.id());
512 PluginInsert::automation_run (BufferSet& bufs, pframes_t nframes)
514 Evoral::ControlEvent next_event (0, 0.0f);
515 framepos_t now = _session.transport_frame ();
516 framepos_t end = now + nframes;
517 framecnt_t offset = 0;
519 Glib::Mutex::Lock lm (control_lock(), Glib::TRY_LOCK);
522 connect_and_run (bufs, nframes, offset, false);
526 if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
528 /* no events have a time within the relevant range */
530 connect_and_run (bufs, nframes, offset, true, now);
536 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
538 connect_and_run (bufs, cnt, offset, true, now);
544 if (!find_next_event (now, end, next_event)) {
549 /* cleanup anything that is left to do */
552 connect_and_run (bufs, nframes, offset, true, now);
557 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
559 if (param.type() != PluginAutomation)
562 if (_plugins.empty()) {
563 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
568 return _plugins[0]->default_value (param.id());
571 boost::shared_ptr<Plugin>
572 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
574 boost::shared_ptr<LadspaPlugin> lp;
576 boost::shared_ptr<LV2Plugin> lv2p;
579 boost::shared_ptr<VSTPlugin> vp;
582 boost::shared_ptr<LXVSTPlugin> lxvp;
584 #ifdef HAVE_AUDIOUNITS
585 boost::shared_ptr<AUPlugin> ap;
588 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
589 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
591 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
592 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
595 } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
596 return boost::shared_ptr<Plugin> (new VSTPlugin (*vp));
599 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
600 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
602 #ifdef HAVE_AUDIOUNITS
603 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
604 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
608 fatal << string_compose (_("programming error: %1"),
609 X_("unknown plugin type in PluginInsert::plugin_factory"))
612 return boost::shared_ptr<Plugin> ((Plugin*) 0);
616 PluginInsert::configure_io (ChanCount in, ChanCount out)
618 MatchingMethod old_matching_method = _matching_method;
620 /* set the matching method and number of plugins that we will use to meet this configuration */
621 pair<MatchingMethod, int32_t> const r = private_can_support_io_configuration (in, out);
622 _matching_method = r.first;
623 if (set_count (r.second) == false) {
627 /* a signal needs emitting if we start or stop splitting */
628 if (old_matching_method != _matching_method && (old_matching_method == Split || _matching_method == Split)) {
629 SplittingChanged (); /* EMIT SIGNAL */
632 /* configure plugins */
633 switch (_matching_method) {
635 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
641 if (_plugins.front()->configure_io (in, out) == false) {
647 // we don't know the analysis window size, so we must work with the
648 // current buffer size here. each request for data fills in these
649 // buffers and the analyser makes sure it gets enough data for the
651 session().ensure_buffer_set (_signal_analysis_inputs, in);
652 //_signal_analysis_inputs.set_count (in);
654 session().ensure_buffer_set (_signal_analysis_outputs, out);
655 //_signal_analysis_outputs.set_count (out);
657 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
659 return Processor::configure_io (in, out);
662 /** Decide whether this PluginInsert can support a given IO configuration.
663 * To do this, we run through a set of possible solutions in rough order of
666 * @param in Required input channel count.
667 * @param out Filled in with the output channel count if we return true.
668 * @return true if the given IO configuration can be supported.
671 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
673 return private_can_support_io_configuration (in, out).first != Impossible;
676 /** A private version of can_support_io_configuration which returns the method
677 * by which the configuration can be matched, rather than just whether or not
680 pair<PluginInsert::MatchingMethod, int32_t>
681 PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCount& out) const
683 if (_plugins.front()->reconfigurable_io()) {
684 /* Plugin has flexible I/O, so delegate to it */
685 bool const r = _plugins.front()->can_support_io_configuration (in, out);
687 return make_pair (Impossible, 0);
690 return make_pair (Delegate, 1);
693 ChanCount inputs = _plugins[0]->get_info()->n_inputs;
694 ChanCount outputs = _plugins[0]->get_info()->n_outputs;
696 bool no_inputs = true;
697 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
698 if (inputs.get (*t) != 0) {
705 /* no inputs so we can take any input configuration since we throw it away */
707 return make_pair (NoInputs, 1);
710 /* Plugin inputs match requested inputs exactly */
713 return make_pair (ExactMatch, 1);
716 /* We may be able to run more than one copy of the plugin within this insert
717 to cope with the insert having more inputs than the plugin.
718 We allow replication only for plugins with either zero or 1 inputs and outputs
719 for every valid data type.
723 bool can_replicate = true;
724 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
726 uint32_t nin = inputs.get (*t);
728 // No inputs of this type
729 if (nin == 0 && in.get(*t) == 0) {
733 if (nin != 1 || outputs.get (*t) != 1) {
734 can_replicate = false;
738 // Potential factor not set yet
740 f = in.get(*t) / nin;
743 // Factor for this type does not match another type, can not replicate
744 if (f != (in.get(*t) / nin)) {
745 can_replicate = false;
751 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
752 out.set (*t, outputs.get(*t) * f);
754 return make_pair (Replicate, f);
757 /* If the processor has exactly one input of a given type, and
758 the plugin has more, we can feed the single processor input
759 to some or all of the plugin inputs. This is rather
760 special-case-y, but the 1-to-many case is by far the
761 simplest. How do I split thy 2 processor inputs to 3
762 plugin inputs? Let me count the ways ...
765 bool can_split = true;
766 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
768 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
769 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
771 if (!can_split_type && !nothing_to_do_for_type) {
778 return make_pair (Split, 1);
781 return make_pair (Impossible, 0);
785 PluginInsert::get_state ()
791 PluginInsert::state (bool full)
793 XMLNode& node = Processor::state (full);
795 node.add_property("type", _plugins[0]->state_node_name());
796 node.add_property("unique-id", _plugins[0]->unique_id());
797 node.add_property("count", string_compose("%1", _plugins.size()));
798 node.add_child_nocopy (_plugins[0]->get_state());
800 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
801 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
803 node.add_child_nocopy (ac->get_state());
811 PluginInsert::set_control_ids (const XMLNode& node, int version)
813 const XMLNodeList& nlist = node.children();
814 XMLNodeConstIterator iter;
815 set<Evoral::Parameter>::const_iterator p;
817 for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
818 if ((*iter)->name() == Controllable::xml_node_name) {
819 const XMLProperty* prop;
821 if ((prop = (*iter)->property (X_("parameter"))) != 0) {
822 uint32_t p = atoi (prop->value());
823 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
827 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
829 ac->set_state (**iter, version);
837 PluginInsert::set_state(const XMLNode& node, int version)
839 XMLNodeList nlist = node.children();
840 XMLNodeIterator niter;
841 XMLPropertyList plist;
842 const XMLProperty *prop;
843 ARDOUR::PluginType type;
845 if ((prop = node.property ("type")) == 0) {
846 error << _("XML node describing plugin is missing the `type' field") << endmsg;
850 if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
851 type = ARDOUR::LADSPA;
852 } else if (prop->value() == X_("lv2")) {
854 } else if (prop->value() == X_("vst")) {
856 } else if (prop->value() == X_("lxvst")) {
857 type = ARDOUR::LXVST;
858 } else if (prop->value() == X_("audiounit")) {
859 type = ARDOUR::AudioUnit;
861 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
867 prop = node.property ("unique-id");
871 /* older sessions contain VST plugins with only an "id" field.
874 if (type == ARDOUR::VST) {
875 prop = node.property ("id");
880 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
882 if (type == ARDOUR::LXVST) {
883 prop = node.property ("id");
889 error << _("Plugin has no unique ID field") << endmsg;
894 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
897 error << string_compose(
898 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
899 "Perhaps it was removed or moved since it was last used."),
905 // The name of the PluginInsert comes from the plugin, nothing else
906 _name = plugin->get_info()->name;
910 // Processor::set_state() will set this, but too late
911 // for it to be available when setting up plugin
912 // state. We can't call Processor::set_state() until
913 // the plugins themselves are created and added.
915 if ((prop = node.property ("id")) != 0) {
919 if (_plugins.empty()) {
920 /* if we are adding the first plugin, we will need to set
921 up automatable controls.
924 create_automatable_parameters ();
925 set_control_ids (node, version);
928 if ((prop = node.property ("count")) != 0) {
929 sscanf (prop->value().c_str(), "%u", &count);
932 if (_plugins.size() != count) {
933 for (uint32_t n = 1; n < count; ++n) {
934 add_plugin (plugin_factory (plugin));
938 Processor::set_state (node, version);
940 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
942 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
943 and set all plugins to the same state.
946 if ((*niter)->name() == plugin->state_node_name()) {
948 plugin->set_state (**niter, version);
950 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
951 (*i)->set_state (**niter, version);
958 if (version < 3000) {
960 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
961 this is all handled by Automatable
964 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
965 if ((*niter)->name() == "Redirect") {
966 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
967 Processor::set_state (**niter, version);
972 set_parameter_state_2X (node, version);
975 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
983 /* catch up on I/O */
986 Glib::Mutex::Lock em (_session.engine().process_lock());
987 IO::PortCountChanged (max(input_streams(), output_streams()));
994 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
996 XMLNodeList nlist = node.children();
997 XMLNodeIterator niter;
999 /* look for port automation node */
1001 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1003 if ((*niter)->name() != port_automation_node_name) {
1009 XMLNodeConstIterator iter;
1014 cnodes = (*niter)->children ("port");
1016 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1020 if ((cprop = child->property("number")) != 0) {
1021 port = cprop->value().c_str();
1023 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1027 sscanf (port, "%" PRIu32, &port_id);
1029 if (port_id >= _plugins[0]->parameter_count()) {
1030 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1034 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1035 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1038 if (!child->children().empty()) {
1039 c->alist()->set_state (*child->children().front(), version);
1041 /* In some cases 2.X saves lists with min_yval and max_yval
1042 being FLT_MIN and FLT_MAX respectively. This causes problems
1043 in A3 because these min/max values are used to compute
1044 where GUI control points should be drawn. If we see such
1045 values, `correct' them to the min/max of the appropriate
1049 float min_y = c->alist()->get_min_y ();
1050 float max_y = c->alist()->get_max_y ();
1052 Plugin::ParameterDescriptor desc;
1053 _plugins.front()->get_parameter_descriptor (port_id, desc);
1055 if (min_y == FLT_MIN) {
1059 if (max_y == FLT_MAX) {
1063 c->alist()->set_yrange (min_y, max_y);
1066 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1078 PluginInsert::describe_parameter (Evoral::Parameter param)
1080 if (param.type() != PluginAutomation) {
1081 return Automatable::describe_parameter(param);
1084 return _plugins[0]->describe_parameter (param);
1088 PluginInsert::signal_latency() const
1090 if (_user_latency) {
1091 return _user_latency;
1094 return _plugins[0]->signal_latency ();
1098 PluginInsert::type ()
1100 return plugin()->get_info()->type;
1103 PluginInsert::PluginControl::PluginControl (PluginInsert* p, const Evoral::Parameter ¶m, boost::shared_ptr<AutomationList> list)
1104 : AutomationControl (p->session(), param, list, p->describe_parameter(param))
1107 Plugin::ParameterDescriptor desc;
1108 p->plugin(0)->get_parameter_descriptor (param.id(), desc);
1109 _logarithmic = desc.logarithmic;
1110 _sr_dependent = desc.sr_dependent;
1111 _toggled = desc.toggled;
1114 /** @param val `user' value */
1116 PluginInsert::PluginControl::set_value (double user_val)
1118 /* FIXME: probably should be taking out some lock here.. */
1120 double const plugin_val = user_to_plugin (user_val);
1122 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1123 (*i)->set_parameter (_list->parameter().id(), plugin_val);
1126 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1128 iasp->set_parameter (_list->parameter().id(), plugin_val);
1131 AutomationControl::set_value (user_val);
1135 PluginInsert::PluginControl::user_to_plugin (double val) const
1137 /* no known transformations at this time */
1142 PluginInsert::PluginControl::user_to_ui (double val) const
1156 PluginInsert::PluginControl::ui_to_user (double val) const
1165 /** Convert plugin values to UI values. See pbd/controllable.h */
1167 PluginInsert::PluginControl::plugin_to_ui (double val) const
1169 return user_to_ui (plugin_to_user (val));
1173 PluginInsert::PluginControl::plugin_to_user (double val) const
1175 /* no known transformations at this time */
1180 PluginInsert::PluginControl::get_state ()
1184 XMLNode& node (AutomationControl::get_state());
1185 ss << parameter().id();
1186 node.add_property (X_("parameter"), ss.str());
1191 /** @return `user' val */
1193 PluginInsert::PluginControl::get_value () const
1195 /* FIXME: probably should be taking out some lock here.. */
1197 return plugin_to_user (_plugin->get_parameter (_list->parameter()));
1200 boost::shared_ptr<Plugin>
1201 PluginInsert::get_impulse_analysis_plugin()
1203 boost::shared_ptr<Plugin> ret;
1204 if (_impulseAnalysisPlugin.expired()) {
1205 ret = plugin_factory(_plugins[0]);
1206 _impulseAnalysisPlugin = ret;
1208 ret = _impulseAnalysisPlugin.lock();
1215 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1217 // called from outside the audio thread, so this should be safe
1218 // only do audio as analysis is (currently) only for audio plugins
1219 _signal_analysis_inputs.ensure_buffers( DataType::AUDIO, input_streams().n_audio(), nframes);
1220 _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1222 _signal_analysis_collected_nframes = 0;
1223 _signal_analysis_collect_nframes_max = nframes;
1226 /** Add a plugin to our list and activate it if we have already been activated */
1228 PluginInsert::add_plugin_with_activation (boost::shared_ptr<Plugin> plugin)
1230 plugin->set_insert_info (this);
1231 _plugins.push_back (plugin);
1233 plugin->activate ();
1237 /** Add a plugin to our list */
1239 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1241 plugin->set_insert_info (this);
1242 _plugins.push_back (plugin);
1246 PluginInsert::realtime_handle_transport_stopped ()
1248 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1249 (*i)->realtime_handle_transport_stopped ();