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"
48 #ifdef HAVE_AUDIOUNITS
49 #include "ardour/audio_unit.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/session.h"
54 #include "ardour/types.h"
59 using namespace ARDOUR
;
62 const string
PluginInsert::port_automation_node_name
= "PortAutomation";
64 PluginInsert::PluginInsert (Session
& s
, boost::shared_ptr
<Plugin
> plug
)
65 : Processor (s
, (plug
? plug
->name() : string ("toBeRenamed")))
66 , _signal_analysis_collected_nframes(0)
67 , _signal_analysis_collect_nframes_max(0)
70 /* the first is the master */
74 create_automatable_parameters ();
76 Glib::Mutex::Lock
em (_session
.engine().process_lock());
77 IO::PortCountChanged (max(input_streams(), output_streams()));
82 PluginInsert::set_count (uint32_t num
)
84 bool require_state
= !_plugins
.empty();
86 /* this is a bad idea.... we shouldn't do this while active.
87 only a route holding their redirect_lock should be calling this
92 } else if (num
> _plugins
.size()) {
93 uint32_t diff
= num
- _plugins
.size();
95 for (uint32_t n
= 0; n
< diff
; ++n
) {
96 add_plugin_with_activation (plugin_factory (_plugins
[0]));
99 /* XXX do something */
103 } else if (num
< _plugins
.size()) {
104 uint32_t diff
= _plugins
.size() - num
;
105 for (uint32_t n
= 0; n
< diff
; ++n
) {
113 PluginInsert::~PluginInsert ()
118 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which
, AutoState s
)
120 if (which
.type() != PluginAutomation
)
123 boost::shared_ptr
<AutomationControl
> c
124 = boost::dynamic_pointer_cast
<AutomationControl
>(control (which
));
127 _plugins
[0]->set_parameter (which
.id(), c
->list()->eval (_session
.transport_frame()));
132 PluginInsert::output_streams() const
134 ChanCount out
= _plugins
.front()->get_info()->n_outputs
;
136 if (out
== ChanCount::INFINITE
) {
137 return _plugins
.front()->output_streams ();
139 out
.set_audio (out
.n_audio() * _plugins
.size());
140 out
.set_midi (out
.n_midi() * _plugins
.size());
146 PluginInsert::input_streams() const
148 ChanCount in
= _plugins
[0]->get_info()->n_inputs
;
152 /* we are splitting 1 processor input to multiple plugin inputs,
153 so we have a maximum of 1 stream of each type.
155 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
156 if (in
.get (*t
) > 1) {
162 } else if (in
== ChanCount::INFINITE
) {
163 return _plugins
[0]->input_streams ();
165 in
.set_audio (in
.n_audio() * _plugins
.size());
166 in
.set_midi (in
.n_midi() * _plugins
.size());
172 PluginInsert::natural_output_streams() const
174 return _plugins
[0]->get_info()->n_outputs
;
178 PluginInsert::natural_input_streams() const
180 return _plugins
[0]->get_info()->n_inputs
;
184 PluginInsert::has_no_inputs() const
186 return _plugins
[0]->get_info()->n_inputs
== ChanCount::ZERO
;
190 PluginInsert::has_no_audio_inputs() const
192 return _plugins
[0]->get_info()->n_inputs
.n_audio() == 0;
196 PluginInsert::is_midi_instrument() const
198 /* XXX more finesse is possible here. VST plugins have a
199 a specific "instrument" flag, for example.
201 PluginInfoPtr pi
= _plugins
[0]->get_info();
203 return pi
->n_inputs
.n_midi() != 0 &&
204 pi
->n_outputs
.n_audio() > 0;
208 PluginInsert::create_automatable_parameters ()
210 assert (!_plugins
.empty());
212 set
<Evoral::Parameter
> a
= _plugins
.front()->automatable ();
214 Plugin::ParameterDescriptor desc
;
216 for (set
<Evoral::Parameter
>::iterator i
= a
.begin(); i
!= a
.end(); ++i
) {
217 if (i
->type() == PluginAutomation
) {
219 Evoral::Parameter
param(*i
);
221 _plugins
.front()->get_parameter_descriptor(i
->id(), desc
);
223 /* the Parameter belonging to the actual plugin doesn't have its range set
224 but we want the Controllable related to this Parameter to have those limits.
227 param
.set_range (desc
.lower
, desc
.upper
, _plugins
.front()->default_value(i
->id()), desc
.toggled
);
228 can_automate (param
);
229 boost::shared_ptr
<AutomationList
> list(new AutomationList(param
));
230 add_control (boost::shared_ptr
<AutomationControl
> (new PluginControl(this, param
, list
)));
236 PluginInsert::parameter_changed (Evoral::Parameter which
, float val
)
238 if (which
.type() != PluginAutomation
)
241 Plugins::iterator i
= _plugins
.begin();
243 /* don't set the first plugin, just all the slaves */
245 if (i
!= _plugins
.end()) {
247 for (; i
!= _plugins
.end(); ++i
) {
248 (*i
)->set_parameter (which
, val
);
254 PluginInsert::set_block_size (pframes_t nframes
)
257 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
258 if ((*i
)->set_block_size (nframes
) != 0) {
266 PluginInsert::activate ()
268 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
272 Processor::activate ();
276 PluginInsert::deactivate ()
278 Processor::deactivate ();
280 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
286 PluginInsert::flush ()
288 for (vector
<boost::shared_ptr
<Plugin
> >::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
294 PluginInsert::connect_and_run (BufferSet
& bufs
, pframes_t nframes
, framecnt_t offset
, bool with_auto
, framepos_t now
)
296 // Calculate if, and how many frames we need to collect for analysis
297 framecnt_t collect_signal_nframes
= (_signal_analysis_collect_nframes_max
-
298 _signal_analysis_collected_nframes
);
299 if (nframes
< collect_signal_nframes
) { // we might not get all frames now
300 collect_signal_nframes
= nframes
;
303 ChanMapping
in_map(input_streams());
304 ChanMapping
out_map(output_streams());
307 /* fix the input mapping so that we have maps for each of the plugin's inputs */
308 in_map
= ChanMapping (natural_input_streams ());
310 /* copy the first stream's buffer contents to the others */
311 /* XXX: audio only */
312 Sample
const * mono
= bufs
.get_audio (in_map
.get (DataType::AUDIO
, 0)).data (offset
);
313 for (uint32_t i
= input_streams().n_audio(); i
< natural_input_streams().n_audio(); ++i
) {
314 memcpy (bufs
.get_audio (in_map
.get (DataType::AUDIO
, i
)).data() + offset
, mono
+ offset
, sizeof (Sample
) * (nframes
- offset
));
318 /* Note that we've already required that plugins
319 be able to handle in-place processing.
326 for (Controls::iterator li
= controls().begin(); li
!= controls().end(); ++li
, ++n
) {
328 boost::shared_ptr
<AutomationControl
> c
329 = boost::dynamic_pointer_cast
<AutomationControl
>(li
->second
);
331 if (c
->parameter().type() == PluginAutomation
&& c
->automation_playback()) {
334 const float val
= c
->list()->rt_safe_eval (now
, valid
);
344 if (collect_signal_nframes
> 0) {
346 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
347 //std::cerr << " streams " << input_streams().n_audio() << std::endl;
348 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
350 _signal_analysis_inputs
.set_count(input_streams());
352 for (uint32_t i
= 0; i
< input_streams().n_audio(); ++i
) {
353 _signal_analysis_inputs
.get_audio(i
).read_from(
355 collect_signal_nframes
,
356 _signal_analysis_collected_nframes
); // offset is for target buffer
361 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
362 (*i
)->connect_and_run(bufs
, in_map
, out_map
, nframes
, offset
);
363 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
364 in_map
.offset_to(*t
, natural_input_streams().get(*t
));
365 out_map
.offset_to(*t
, natural_output_streams().get(*t
));
369 if (collect_signal_nframes
> 0) {
371 //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
372 //std::cerr << " streams " << output_streams().n_audio() << std::endl;
374 _signal_analysis_outputs
.set_count(output_streams());
376 for (uint32_t i
= 0; i
< output_streams().n_audio(); ++i
) {
377 _signal_analysis_outputs
.get_audio(i
).read_from(
379 collect_signal_nframes
,
380 _signal_analysis_collected_nframes
); // offset is for target buffer
383 _signal_analysis_collected_nframes
+= collect_signal_nframes
;
384 assert(_signal_analysis_collected_nframes
<= _signal_analysis_collect_nframes_max
);
386 if (_signal_analysis_collected_nframes
== _signal_analysis_collect_nframes_max
) {
387 _signal_analysis_collect_nframes_max
= 0;
388 _signal_analysis_collected_nframes
= 0;
390 AnalysisDataGathered(&_signal_analysis_inputs
,
391 &_signal_analysis_outputs
);
394 /* leave remaining channel buffers alone */
398 PluginInsert::silence (framecnt_t nframes
)
404 ChanMapping
in_map(input_streams());
405 ChanMapping
out_map(output_streams());
408 /* fix the input mapping so that we have maps for each of the plugin's inputs */
409 in_map
= ChanMapping (natural_input_streams ());
412 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
413 (*i
)->connect_and_run (_session
.get_silent_buffers ((*i
)->get_info()->n_inputs
), in_map
, out_map
, nframes
, 0);
418 PluginInsert::run (BufferSet
& bufs
, framepos_t
/*start_frame*/, framepos_t
/*end_frame*/, pframes_t nframes
, bool)
420 if (_pending_active
) {
421 /* run as normal if we are active or moving from inactive to active */
423 if (_session
.transport_rolling()) {
424 automation_run (bufs
, nframes
);
426 connect_and_run (bufs
, nframes
, 0, false);
431 if (has_no_audio_inputs()) {
433 /* silence all (audio) outputs. Should really declick
434 * at the transitions of "active"
437 uint32_t out
= _plugins
[0]->get_info()->n_outputs
.n_audio();
439 for (uint32_t n
= 0; n
< out
; ++n
) {
440 bufs
.get_audio (n
).silence (nframes
);
443 bufs
.count().set_audio (out
);
447 /* does this need to be done with MIDI? it appears not */
449 uint32_t in
= _plugins
[0]->get_info()->n_inputs
.n_audio();
450 uint32_t out
= _plugins
[0]->get_info()->n_outputs
.n_audio();
454 /* not active, but something has make up for any channel count increase */
456 for (uint32_t n
= out
- in
; n
< out
; ++n
) {
457 memcpy (bufs
.get_audio(n
).data(), bufs
.get_audio(in
- 1).data(), sizeof (Sample
) * nframes
);
461 bufs
.count().set_audio (out
);
465 _active
= _pending_active
;
469 PluginInsert::set_parameter (Evoral::Parameter param
, float val
)
471 if (param
.type() != PluginAutomation
) {
475 /* the others will be set from the event triggered by this */
477 _plugins
[0]->set_parameter (param
.id(), val
);
479 boost::shared_ptr
<AutomationControl
> ac
480 = boost::dynamic_pointer_cast
<AutomationControl
>(control(param
));
485 warning
<< "set_parameter called for nonexistant parameter "
486 << EventTypeMap::instance().to_symbol(param
) << endmsg
;
489 _session
.set_dirty();
493 PluginInsert::get_parameter (Evoral::Parameter param
)
495 if (param
.type() != PluginAutomation
) {
498 assert (!_plugins
.empty ());
499 return _plugins
[0]->get_parameter (param
.id());
504 PluginInsert::automation_run (BufferSet
& bufs
, pframes_t nframes
)
506 Evoral::ControlEvent
next_event (0, 0.0f
);
507 framepos_t now
= _session
.transport_frame ();
508 framepos_t end
= now
+ nframes
;
509 framecnt_t offset
= 0;
511 Glib::Mutex::Lock
lm (control_lock(), Glib::TRY_LOCK
);
514 connect_and_run (bufs
, nframes
, offset
, false);
518 if (!find_next_event (now
, end
, next_event
) || requires_fixed_sized_buffers()) {
520 /* no events have a time within the relevant range */
522 connect_and_run (bufs
, nframes
, offset
, true, now
);
528 framecnt_t cnt
= min (((framecnt_t
) ceil (next_event
.when
) - now
), (framecnt_t
) nframes
);
530 connect_and_run (bufs
, cnt
, offset
, true, now
);
536 if (!find_next_event (now
, end
, next_event
)) {
541 /* cleanup anything that is left to do */
544 connect_and_run (bufs
, nframes
, offset
, true, now
);
549 PluginInsert::default_parameter_value (const Evoral::Parameter
& param
)
551 if (param
.type() != PluginAutomation
)
554 if (_plugins
.empty()) {
555 fatal
<< _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
560 return _plugins
[0]->default_value (param
.id());
563 boost::shared_ptr
<Plugin
>
564 PluginInsert::plugin_factory (boost::shared_ptr
<Plugin
> other
)
566 boost::shared_ptr
<LadspaPlugin
> lp
;
568 boost::shared_ptr
<LV2Plugin
> lv2p
;
571 boost::shared_ptr
<VSTPlugin
> vp
;
573 #ifdef HAVE_AUDIOUNITS
574 boost::shared_ptr
<AUPlugin
> ap
;
577 if ((lp
= boost::dynamic_pointer_cast
<LadspaPlugin
> (other
)) != 0) {
578 return boost::shared_ptr
<Plugin
> (new LadspaPlugin (*lp
));
580 } else if ((lv2p
= boost::dynamic_pointer_cast
<LV2Plugin
> (other
)) != 0) {
581 return boost::shared_ptr
<Plugin
> (new LV2Plugin (*lv2p
));
584 } else if ((vp
= boost::dynamic_pointer_cast
<VSTPlugin
> (other
)) != 0) {
585 return boost::shared_ptr
<Plugin
> (new VSTPlugin (*vp
));
587 #ifdef HAVE_AUDIOUNITS
588 } else if ((ap
= boost::dynamic_pointer_cast
<AUPlugin
> (other
)) != 0) {
589 return boost::shared_ptr
<Plugin
> (new AUPlugin (*ap
));
593 fatal
<< string_compose (_("programming error: %1"),
594 X_("unknown plugin type in PluginInsert::plugin_factory"))
597 return boost::shared_ptr
<Plugin
> ((Plugin
*) 0);
601 PluginInsert::configure_io (ChanCount in
, ChanCount out
)
603 if (set_count (count_for_configuration (in
, out
)) == false) {
604 set_splitting (false);
608 if (_plugins
.front()->get_info()->n_inputs
<= in
) {
609 set_splitting (false);
610 if (_plugins
.front()->configure_io (in
, out
) == false) {
614 /* we must be splitting a single processor input to
615 multiple plugin inputs
617 set_splitting (true);
618 _plugins
.front()->configure_io (_plugins
.front()->get_info()->n_inputs
, out
);
621 // we don't know the analysis window size, so we must work with the
622 // current buffer size here. each request for data fills in these
623 // buffers and the analyser makes sure it gets enough data for the
625 session().ensure_buffer_set (_signal_analysis_inputs
, in
);
626 //_signal_analysis_inputs.set_count (in);
628 session().ensure_buffer_set (_signal_analysis_outputs
, out
);
629 //_signal_analysis_outputs.set_count (out);
631 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
633 return Processor::configure_io (in
, out
);
637 PluginInsert::can_support_io_configuration (const ChanCount
& in
, ChanCount
& out
) const
639 // Plugin has flexible I/O, so delegate to it
640 if (_plugins
.front()->reconfigurable_io()) {
641 return _plugins
.front()->can_support_io_configuration (in
, out
);
644 ChanCount inputs
= _plugins
[0]->get_info()->n_inputs
;
645 ChanCount outputs
= _plugins
[0]->get_info()->n_outputs
;
647 bool no_inputs
= true;
648 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
649 if (inputs
.get (*t
) != 0) {
656 /* no inputs so we can take any input configuration since we throw it away */
661 // Plugin inputs match requested inputs exactly
667 // See if replication is possible
668 // We allow replication only for plugins with either zero or 1 inputs and outputs
669 // for every valid data type.
671 bool can_replicate
= true;
672 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
674 uint32_t nin
= inputs
.get (*t
);
676 // No inputs of this type
677 if (nin
== 0 && in
.get(*t
) == 0) {
681 if (nin
!= 1 || outputs
.get (*t
) != 1) {
682 can_replicate
= false;
686 // Potential factor not set yet
689 f
= in
.get(*t
) / nin
;
692 // Factor for this type does not match another type, can not replicate
693 if (f
!= (in
.get(*t
) / nin
)) {
694 can_replicate
= false;
700 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
701 out
.set (*t
, outputs
.get(*t
) * f
);
706 /* If the processor has exactly one input of a given type, and
707 the plugin has more, we can feed the single processor input
708 to some or all of the plugin inputs. This is rather
709 special-case-y, but the 1-to-many case is by far the
710 simplest. How do I split thy 2 processor inputs to 3
711 plugin inputs? Let me count the ways ...
714 bool can_split
= true;
715 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
717 bool const can_split_type
= (in
.get (*t
) == 1 && inputs
.get (*t
) > 1);
718 bool const nothing_to_do_for_type
= (in
.get (*t
) == 0 && inputs
.get (*t
) == 0);
720 if (!can_split_type
&& !nothing_to_do_for_type
) {
733 /* Number of plugin instances required to support a given channel configuration.
737 PluginInsert::count_for_configuration (ChanCount in
, ChanCount
/*out*/) const
739 if (_plugins
.front()->reconfigurable_io()) {
740 /* plugin has flexible I/O, so the answer is always 1 */
741 /* this could change if we ever decide to replicate AU's */
745 // FIXME: take 'out' into consideration
747 ChanCount outputs
= _plugins
[0]->get_info()->n_outputs
;
748 ChanCount inputs
= _plugins
[0]->get_info()->n_inputs
;
750 if (inputs
.n_total() == 0) {
751 /* instrument plugin, always legal, but throws away any existing streams */
755 if (inputs
.n_total() == 1 && outputs
== inputs
756 && ((inputs
.n_audio() == 0 && in
.n_audio() == 0)
757 || (inputs
.n_midi() == 0 && in
.n_midi() == 0))) {
758 /* mono plugin, replicate as needed to match in */
768 /* more plugin inputs than processor inputs, so we are splitting */
772 // assumes in is valid, so we must be replicating
773 if (inputs
.n_total() < in
.n_total()
774 && (in
.n_total() % inputs
.n_total() == 0)) {
776 return in
.n_total() / inputs
.n_total();
784 PluginInsert::get_state(void)
790 PluginInsert::state (bool full
)
792 XMLNode
& node
= Processor::state (full
);
794 node
.add_property("type", _plugins
[0]->state_node_name());
795 node
.add_property("unique-id", _plugins
[0]->unique_id());
796 node
.add_property("count", string_compose("%1", _plugins
.size()));
797 node
.add_child_nocopy (_plugins
[0]->get_state());
799 for (Controls::iterator c
= controls().begin(); c
!= controls().end(); ++c
) {
800 boost::shared_ptr
<AutomationControl
> ac
= boost::dynamic_pointer_cast
<AutomationControl
> ((*c
).second
);
802 node
.add_child_nocopy (ac
->get_state());
810 PluginInsert::set_control_ids (const XMLNode
& node
, int version
)
812 const XMLNodeList
& nlist
= node
.children();
813 XMLNodeConstIterator iter
;
814 set
<Evoral::Parameter
>::const_iterator p
;
816 for (iter
= nlist
.begin(); iter
!= nlist
.end(); ++iter
) {
817 if ((*iter
)->name() == Controllable::xml_node_name
) {
818 const XMLProperty
* prop
;
820 if ((prop
= (*iter
)->property (X_("parameter"))) != 0) {
821 uint32_t p
= atoi (prop
->value());
822 boost::shared_ptr
<Evoral::Control
> c
= control (Evoral::Parameter (PluginAutomation
, 0, p
));
826 boost::shared_ptr
<AutomationControl
> ac
= boost::dynamic_pointer_cast
<AutomationControl
> (c
);
828 ac
->set_state (**iter
, version
);
836 PluginInsert::set_state(const XMLNode
& node
, int version
)
838 XMLNodeList nlist
= node
.children();
839 XMLNodeIterator niter
;
840 XMLPropertyList plist
;
841 const XMLProperty
*prop
;
842 ARDOUR::PluginType type
;
844 if ((prop
= node
.property ("type")) == 0) {
845 error
<< _("XML node describing plugin is missing the `type' field") << endmsg
;
849 if (prop
->value() == X_("ladspa") || prop
->value() == X_("Ladspa")) { /* handle old school sessions */
850 type
= ARDOUR::LADSPA
;
851 } else if (prop
->value() == X_("lv2")) {
853 } else if (prop
->value() == X_("vst")) {
855 } else if (prop
->value() == X_("audiounit")) {
856 type
= ARDOUR::AudioUnit
;
858 error
<< string_compose (_("unknown plugin type %1 in plugin insert state"),
864 prop
= node
.property ("unique-id");
868 /* older sessions contain VST plugins with only an "id" field.
871 if (type
== ARDOUR::VST
) {
872 prop
= node
.property ("id");
878 error
<< _("Plugin has no unique ID field") << endmsg
;
883 boost::shared_ptr
<Plugin
> plugin
= find_plugin (_session
, prop
->value(), type
);
886 error
<< string_compose(
887 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
888 "Perhaps it was removed or moved since it was last used."),
894 // The name of the PluginInsert comes from the plugin, nothing else
895 _name
= plugin
->get_info()->name
;
899 // Processor::set_state() will set this, but too late
900 // for it to be available when setting up plugin
901 // state. We can't call Processor::set_state() until
902 // the plugins themselves are created and added.
904 if ((prop
= node
.property ("id")) != 0) {
908 if (_plugins
.empty()) {
909 /* if we are adding the first plugin, we will need to set
910 up automatable controls.
913 create_automatable_parameters ();
914 set_control_ids (node
, version
);
917 if ((prop
= node
.property ("count")) != 0) {
918 sscanf (prop
->value().c_str(), "%u", &count
);
921 if (_plugins
.size() != count
) {
922 for (uint32_t n
= 1; n
< count
; ++n
) {
923 add_plugin (plugin_factory (plugin
));
927 Processor::set_state (node
, version
);
929 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
931 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
932 and set all plugins to the same state.
935 if ((*niter
)->name() == plugin
->state_node_name()) {
937 plugin
->set_state (**niter
, version
);
939 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
940 (*i
)->set_state (**niter
, version
);
947 if (version
< 3000) {
949 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
950 this is all handled by Automatable
953 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
954 if ((*niter
)->name() == "Redirect") {
955 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
956 Processor::set_state (**niter
, version
);
961 set_parameter_state_2X (node
, version
);
964 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
972 /* catch up on I/O */
975 Glib::Mutex::Lock
em (_session
.engine().process_lock());
976 IO::PortCountChanged (max(input_streams(), output_streams()));
983 PluginInsert::set_parameter_state_2X (const XMLNode
& node
, int version
)
985 XMLNodeList nlist
= node
.children();
986 XMLNodeIterator niter
;
988 /* look for port automation node */
990 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
992 if ((*niter
)->name() != port_automation_node_name
) {
998 XMLNodeConstIterator iter
;
1003 cnodes
= (*niter
)->children ("port");
1005 for (iter
= cnodes
.begin(); iter
!= cnodes
.end(); ++iter
){
1009 if ((cprop
= child
->property("number")) != 0) {
1010 port
= cprop
->value().c_str();
1012 warning
<< _("PluginInsert: Auto: no ladspa port number") << endmsg
;
1016 sscanf (port
, "%" PRIu32
, &port_id
);
1018 if (port_id
>= _plugins
[0]->parameter_count()) {
1019 warning
<< _("PluginInsert: Auto: port id out of range") << endmsg
;
1023 boost::shared_ptr
<AutomationControl
> c
= boost::dynamic_pointer_cast
<AutomationControl
>(
1024 control(Evoral::Parameter(PluginAutomation
, 0, port_id
), true));
1027 if (!child
->children().empty()) {
1028 c
->alist()->set_state (*child
->children().front(), version
);
1030 /* In some cases 2.X saves lists with min_yval and max_yval
1031 being FLT_MIN and FLT_MAX respectively. This causes problems
1032 in A3 because these min/max values are used to compute
1033 where GUI control points should be drawn. If we see such
1034 values, `correct' them to the min/max of the appropriate
1038 float min_y
= c
->alist()->get_min_y ();
1039 float max_y
= c
->alist()->get_max_y ();
1041 Plugin::ParameterDescriptor desc
;
1042 _plugins
.front()->get_parameter_descriptor (port_id
, desc
);
1044 if (min_y
== FLT_MIN
) {
1048 if (max_y
== FLT_MAX
) {
1052 c
->alist()->set_yrange (min_y
, max_y
);
1055 error
<< string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id
) << endmsg
;
1067 PluginInsert::describe_parameter (Evoral::Parameter param
)
1069 if (param
.type() != PluginAutomation
) {
1070 return Automatable::describe_parameter(param
);
1073 return _plugins
[0]->describe_parameter (param
);
1077 PluginInsert::signal_latency() const
1079 if (_user_latency
) {
1080 return _user_latency
;
1083 return _plugins
[0]->signal_latency ();
1087 PluginInsert::type ()
1089 return plugin()->get_info()->type
;
1092 PluginInsert::PluginControl::PluginControl (PluginInsert
* p
, const Evoral::Parameter
¶m
, boost::shared_ptr
<AutomationList
> list
)
1093 : AutomationControl (p
->session(), param
, list
, p
->describe_parameter(param
))
1096 Plugin::ParameterDescriptor desc
;
1097 p
->plugin(0)->get_parameter_descriptor (param
.id(), desc
);
1098 _logarithmic
= desc
.logarithmic
;
1099 _sr_dependent
= desc
.sr_dependent
;
1100 _toggled
= desc
.toggled
;
1103 /** @param val `user' value */
1105 PluginInsert::PluginControl::set_value (double user_val
)
1107 /* FIXME: probably should be taking out some lock here.. */
1109 double const plugin_val
= user_to_plugin (user_val
);
1111 for (Plugins::iterator i
= _plugin
->_plugins
.begin(); i
!= _plugin
->_plugins
.end(); ++i
) {
1112 (*i
)->set_parameter (_list
->parameter().id(), plugin_val
);
1115 boost::shared_ptr
<Plugin
> iasp
= _plugin
->_impulseAnalysisPlugin
.lock();
1117 iasp
->set_parameter (_list
->parameter().id(), plugin_val
);
1120 AutomationControl::set_value (user_val
);
1124 PluginInsert::PluginControl::user_to_plugin (double val
) const
1126 /* no known transformations at this time */
1131 PluginInsert::PluginControl::user_to_ui (double val
) const
1145 PluginInsert::PluginControl::ui_to_user (double val
) const
1154 /** Convert plugin values to UI values. See pbd/controllable.h */
1156 PluginInsert::PluginControl::plugin_to_ui (double val
) const
1158 return user_to_ui (plugin_to_user (val
));
1162 PluginInsert::PluginControl::plugin_to_user (double val
) const
1164 /* no known transformations at this time */
1169 PluginInsert::PluginControl::get_state ()
1173 XMLNode
& node (AutomationControl::get_state());
1174 ss
<< parameter().id();
1175 node
.add_property (X_("parameter"), ss
.str());
1180 /** @return `user' val */
1182 PluginInsert::PluginControl::get_value () const
1184 /* FIXME: probably should be taking out some lock here.. */
1186 return plugin_to_user (_plugin
->get_parameter (_list
->parameter()));
1189 boost::shared_ptr
<Plugin
>
1190 PluginInsert::get_impulse_analysis_plugin()
1192 boost::shared_ptr
<Plugin
> ret
;
1193 if (_impulseAnalysisPlugin
.expired()) {
1194 ret
= plugin_factory(_plugins
[0]);
1195 _impulseAnalysisPlugin
= ret
;
1197 ret
= _impulseAnalysisPlugin
.lock();
1204 PluginInsert::collect_signal_for_analysis (framecnt_t nframes
)
1206 // called from outside the audio thread, so this should be safe
1207 // only do audio as analysis is (currently) only for audio plugins
1208 _signal_analysis_inputs
.ensure_buffers( DataType::AUDIO
, input_streams().n_audio(), nframes
);
1209 _signal_analysis_outputs
.ensure_buffers( DataType::AUDIO
, output_streams().n_audio(), nframes
);
1211 _signal_analysis_collected_nframes
= 0;
1212 _signal_analysis_collect_nframes_max
= nframes
;
1215 /** Add a plugin to our list and activate it if we have already been activated */
1217 PluginInsert::add_plugin_with_activation (boost::shared_ptr
<Plugin
> plugin
)
1219 plugin
->set_insert_info (this);
1220 _plugins
.push_back (plugin
);
1222 plugin
->activate ();
1226 /** Add a plugin to our list */
1228 PluginInsert::add_plugin (boost::shared_ptr
<Plugin
> plugin
)
1230 plugin
->set_insert_info (this);
1231 _plugins
.push_back (plugin
);
1235 PluginInsert::realtime_handle_transport_stopped ()
1237 for (Plugins::iterator i
= _plugins
.begin(); i
!= _plugins
.end(); ++i
) {
1238 (*i
)->realtime_handle_transport_stopped ();
1243 PluginInsert::set_splitting (bool s
)
1245 if (_splitting
== s
) {
1250 SplittingChanged (); /* EMIT SIGNAL */