2 Copyright (C) 2008 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include "pbd/compose.h"
29 #include "pbd/error.h"
30 #include "pbd/pathscanner.h"
31 #include "pbd/xml++.h"
33 #include "ardour/ardour.h"
34 #include "ardour/session.h"
35 #include "ardour/audioengine.h"
36 #include "ardour/audio_buffer.h"
37 #include "ardour/lv2_event_buffer.h"
38 #include "ardour/lv2_plugin.h"
40 #include "pbd/stl_delete.h"
46 using namespace ARDOUR
;
49 URIMap
LV2Plugin::_uri_map
;
50 uint32_t LV2Plugin::_midi_event_type
= _uri_map
.uri_to_id(
51 "http://lv2plug.in/ns/ext/event",
52 "http://lv2plug.in/ns/ext/midi#MidiEvent");
54 LV2Plugin::LV2Plugin (AudioEngine
& e
, Session
& session
, LV2World
& world
, SLV2Plugin plugin
, nframes_t rate
)
59 init (world
, plugin
, rate
);
62 LV2Plugin::LV2Plugin (const LV2Plugin
&other
)
64 , _world(other
._world
)
67 init (other
._world
, other
._plugin
, other
._sample_rate
);
69 for (uint32_t i
= 0; i
< parameter_count(); ++i
) {
70 _control_data
[i
] = other
._shadow_data
[i
];
71 _shadow_data
[i
] = other
._shadow_data
[i
];
76 LV2Plugin::init (LV2World
& world
, SLV2Plugin plugin
, nframes_t rate
)
83 _latency_control_port
= 0;
84 _was_activated
= false;
86 _instance
= slv2_plugin_instantiate(plugin
, rate
, _features
);
87 _name
= slv2_plugin_get_name(plugin
);
89 _author
= slv2_plugin_get_author_name(plugin
);
92 error
<< _("LV2: Failed to instantiate plugin ") << slv2_plugin_get_uri(plugin
) << endl
;
93 throw failed_constructor();
96 if (slv2_plugin_has_feature(plugin
, world
.in_place_broken
)) {
97 error
<< string_compose(
98 _("LV2: \"%1\" cannot be used, since it cannot do inplace processing"),
99 slv2_value_as_string(_name
));
100 slv2_value_free(_name
);
101 slv2_value_free(_author
);
102 throw failed_constructor();
105 _instance_access_feature
.URI
= "http://lv2plug.in/ns/ext/instance-access";
106 _instance_access_feature
.data
= (void*)_instance
->lv2_handle
;
108 _data_access_extension_data
.extension_data
= _instance
->lv2_descriptor
->extension_data
;
109 _data_access_feature
.URI
= "http://lv2plug.in/ns/ext/data-access";
110 _data_access_feature
.data
= &_data_access_extension_data
;
112 _features
= (LV2_Feature
**)malloc(sizeof(LV2_Feature
*) * 4);
113 _features
[0] = &_instance_access_feature
;
114 _features
[1] = &_data_access_feature
;
115 _features
[2] = _uri_map
.feature();
120 const uint32_t num_ports
= slv2_plugin_get_num_ports(plugin
);
122 _control_data
= new float[num_ports
];
123 _shadow_data
= new float[num_ports
];
124 _defaults
= new float[num_ports
];
126 const bool latent
= slv2_plugin_has_latency(plugin
);
127 uint32_t latency_port
= (latent
? slv2_plugin_get_latency_port_index(plugin
) : 0);
129 for (uint32_t i
= 0; i
< num_ports
; ++i
) {
130 SLV2Port port
= slv2_plugin_get_port_by_index(plugin
, i
);
131 SLV2Value sym
= slv2_port_get_symbol(_plugin
, port
);
132 _port_indices
.insert(std::make_pair(slv2_value_as_string(sym
), i
));
133 if (parameter_is_control(i
)) {
135 slv2_port_get_range(plugin
, port
, &def
, NULL
, NULL
);
136 _defaults
[i
] = def
? slv2_value_as_float(def
) : 0.0f
;
137 slv2_value_free(def
);
139 slv2_instance_connect_port (_instance
, i
, &_control_data
[i
]);
141 if (latent
&& i
== latency_port
) {
142 _latency_control_port
= &_control_data
[i
];
143 *_latency_control_port
= 0;
146 if (parameter_is_input(i
)) {
147 _shadow_data
[i
] = default_value (i
);
154 SLV2UIs uis
= slv2_plugin_get_uis(_plugin
);
155 if (slv2_uis_size(uis
) > 0) {
156 for (unsigned i
=0; i
< slv2_uis_size(uis
); ++i
) {
157 SLV2UI ui
= slv2_uis_get_at(uis
, i
);
158 if (slv2_ui_is_a(ui
, _world
.gtk_gui
)) {
164 // if gtk gui is not available, try to find external gui
166 for (unsigned i
=0; i
< slv2_uis_size(uis
); ++i
) {
167 SLV2UI ui
= slv2_uis_get_at(uis
, i
);
168 if (slv2_ui_is_a(ui
, _world
.external_gui
)) {
176 latency_compute_run ();
179 LV2Plugin::~LV2Plugin ()
184 slv2_instance_free(_instance
);
185 slv2_value_free(_name
);
186 slv2_value_free(_author
);
188 delete [] _control_data
;
189 delete [] _shadow_data
;
193 LV2Plugin::is_external_ui() const
195 return slv2_ui_is_a(_ui
, _world
.external_gui
);
199 LV2Plugin::unique_id() const
201 return slv2_value_as_uri(slv2_plugin_get_uri(_plugin
));
206 LV2Plugin::default_value (uint32_t port
)
208 return _defaults
[port
];
212 LV2Plugin::port_symbol (uint32_t index
)
214 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, index
);
216 error
<< name() << ": Invalid port index " << index
<< endmsg
;
219 SLV2Value sym
= slv2_port_get_symbol(_plugin
, port
);
220 return slv2_value_as_string(sym
);
225 LV2Plugin::set_parameter (uint32_t which
, float val
)
227 if (which
< slv2_plugin_get_num_ports(_plugin
)) {
228 _shadow_data
[which
] = val
;
230 ParameterChanged (which
, val
); /* EMIT SIGNAL */
232 if (which
< parameter_count() && controls
[which
]) {
233 controls
[which
]->Changed ();
238 warning
<< string_compose (_("Illegal parameter number used with plugin \"%1\"."
239 "This is a bug in either %2 or the LV2 plugin (%3)"),
240 name(), PROGRAM_NAME
, unique_id()) << endmsg
;
245 LV2Plugin::get_parameter (uint32_t which
) const
247 if (parameter_is_input(which
)) {
248 return (float) _shadow_data
[which
];
250 return (float) _control_data
[which
];
256 LV2Plugin::nth_parameter (uint32_t n
, bool& ok
) const
262 for (c
= 0, x
= 0; x
< slv2_plugin_get_num_ports(_plugin
); ++x
) {
263 if (parameter_is_control (x
)) {
275 LV2Plugin::get_state()
277 XMLNode
*root
= new XMLNode(state_node_name());
280 LocaleGuard
lg (X_("POSIX"));
282 for (uint32_t i
= 0; i
< parameter_count(); ++i
){
284 if (parameter_is_input(i
) && parameter_is_control(i
)) {
285 child
= new XMLNode("Port");
286 /*snprintf(buf, sizeof(buf), "%u", i);
287 child->add_property("number", string(buf));*/
288 child
->add_property("symbol", port_symbol(i
));
289 snprintf(buf
, sizeof(buf
), "%+f", _shadow_data
[i
]);
290 child
->add_property("value", string(buf
));
291 root
->add_child_nocopy (*child
);
293 /*if (i < controls.size() && controls[i]) {
294 root->add_child_nocopy (controls[i]->get_state());
302 vector
<Plugin::PresetRecord
>
303 LV2Plugin::get_presets()
305 vector
<PresetRecord
> result
;
306 SLV2Results presets
= slv2_plugin_query_sparql(_plugin
,
307 "PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
308 "PREFIX dc: <http://dublincore.org/documents/dcmi-namespace/>\n"
309 "SELECT ?p ?name WHERE { <> lv2p:hasPreset ?p . ?p dc:title ?name }\n");
310 for (; !slv2_results_finished(presets
); slv2_results_next(presets
)) {
311 SLV2Value uri
= slv2_results_get_binding_value(presets
, 0);
312 SLV2Value name
= slv2_results_get_binding_value(presets
, 1);
313 PresetRecord
rec(slv2_value_as_string(uri
), slv2_value_as_string(name
));
314 result
.push_back(rec
);
315 this->presets
.insert(std::make_pair(slv2_value_as_string(uri
), rec
));
317 slv2_results_free(presets
);
322 LV2Plugin::load_preset(const string
& uri
)
324 const string query
= string(
325 "PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
326 "PREFIX dc: <http://dublincore.org/documents/dcmi-namespace/>\n"
327 "SELECT ?sym ?val WHERE { <") + uri
+ "> lv2:port ?port . "
328 " ?port lv2:symbol ?sym ; lv2p:value ?val . }";
329 SLV2Results values
= slv2_plugin_query_sparql(_plugin
, query
.c_str());
330 for (; !slv2_results_finished(values
); slv2_results_next(values
)) {
331 SLV2Value sym
= slv2_results_get_binding_value(values
, 0);
332 SLV2Value val
= slv2_results_get_binding_value(values
, 1);
333 if (slv2_value_is_float(val
)) {
334 uint32_t index
= _port_indices
[slv2_value_as_string(sym
)];
335 set_parameter(index
, slv2_value_as_float(val
));
338 slv2_results_free(values
);
343 LV2Plugin::save_preset (string
/*name*/)
349 LV2Plugin::has_editor() const
351 return (_ui
!= NULL
);
355 LV2Plugin::set_state(const XMLNode
& node
, int version
)
359 XMLNodeConstIterator iter
;
364 LocaleGuard
lg (X_("POSIX"));
366 if (node
.name() != state_node_name()) {
367 error
<< _("Bad node sent to LV2Plugin::set_state") << endmsg
;
372 nodes
= node
.children ("port");
374 nodes
= node
.children ("Port");
377 for (iter
= nodes
.begin(); iter
!= nodes
.end(); ++iter
){
381 if ((prop
= child
->property("symbol")) != 0) {
382 sym
= prop
->value().c_str();
384 warning
<< _("LV2: port has no symbol, ignored") << endmsg
;
388 map
<string
,uint32_t>::iterator i
= _port_indices
.find(sym
);
390 if (i
!= _port_indices
.end()) {
393 warning
<< _("LV2: port has unknown index, ignored") << endmsg
;
397 if ((prop
= child
->property("value")) != 0) {
398 value
= prop
->value().c_str();
400 warning
<< _("LV2: port has no value, ignored") << endmsg
;
404 set_parameter (port_id
, atof(value
));
407 latency_compute_run ();
413 LV2Plugin::get_parameter_descriptor (uint32_t which
, ParameterDescriptor
& desc
) const
415 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, which
);
417 SLV2Value def
, min
, max
;
418 slv2_port_get_range(_plugin
, port
, &def
, &min
, &max
);
420 desc
.integer_step
= slv2_port_has_property(_plugin
, port
, _world
.integer
);
421 desc
.toggled
= slv2_port_has_property(_plugin
, port
, _world
.toggled
);
422 desc
.logarithmic
= slv2_port_has_property(_plugin
, port
, _world
.logarithmic
);
423 desc
.sr_dependent
= slv2_port_has_property(_plugin
, port
, _world
.srate
);
424 desc
.label
= slv2_value_as_string(slv2_port_get_name(_plugin
, port
));
425 desc
.lower
= min
? slv2_value_as_float(min
) : 0.0f
;
426 desc
.upper
= max
? slv2_value_as_float(max
) : 1.0f
;
427 desc
.min_unbound
= false; // TODO (LV2 extension)
428 desc
.max_unbound
= false; // TODO (LV2 extension)
430 if (desc
.integer_step
) {
432 desc
.smallstep
= 0.1;
433 desc
.largestep
= 10.0;
435 const float delta
= desc
.upper
- desc
.lower
;
436 desc
.step
= delta
/ 1000.0f
;
437 desc
.smallstep
= delta
/ 10000.0f
;
438 desc
.largestep
= delta
/10.0f
;
441 slv2_value_free(def
);
442 slv2_value_free(min
);
443 slv2_value_free(max
);
450 LV2Plugin::describe_parameter (Evoral::Parameter which
)
452 if (which
.type() == PluginAutomation
&& which
.id() < parameter_count()) {
453 SLV2Value name
= slv2_port_get_name(_plugin
,
454 slv2_plugin_get_port_by_index(_plugin
, which
));
455 string
ret(slv2_value_as_string(name
));
456 slv2_value_free(name
);
464 LV2Plugin::signal_latency () const
466 if (_latency_control_port
) {
467 return (nframes_t
) floor (*_latency_control_port
);
473 set
<Evoral::Parameter
>
474 LV2Plugin::automatable () const
476 set
<Evoral::Parameter
> ret
;
478 for (uint32_t i
= 0; i
< parameter_count(); ++i
){
479 if (parameter_is_input(i
) && parameter_is_control(i
)) {
480 ret
.insert (ret
.end(), Evoral::Parameter(PluginAutomation
, 0, i
));
488 LV2Plugin::connect_and_run (BufferSet
& bufs
,
489 ChanMapping in_map
, ChanMapping out_map
,
490 nframes_t nframes
, nframes_t offset
)
492 cycles_t then
= get_cycles ();
494 uint32_t audio_in_index
= 0;
495 uint32_t audio_out_index
= 0;
496 uint32_t midi_in_index
= 0;
497 uint32_t midi_out_index
= 0;
498 for (uint32_t port_index
= 0; port_index
< parameter_count(); ++port_index
) {
499 if (parameter_is_audio(port_index
)) {
500 if (parameter_is_input(port_index
)) {
501 const uint32_t buf_index
= in_map
.get(DataType::AUDIO
, audio_in_index
++);
502 //cerr << port_index << " : " << " AUDIO IN " << buf_index << endl;
503 slv2_instance_connect_port(_instance
, port_index
,
504 bufs
.get_audio(buf_index
).data(offset
));
505 } else if (parameter_is_output(port_index
)) {
506 const uint32_t buf_index
= out_map
.get(DataType::AUDIO
, audio_out_index
++);
507 //cerr << port_index << " : " << " AUDIO OUT " << buf_index << endl;
508 slv2_instance_connect_port(_instance
, port_index
,
509 bufs
.get_audio(buf_index
).data(offset
));
511 } else if (parameter_is_midi(port_index
)) {
512 if (parameter_is_input(port_index
)) {
513 const uint32_t buf_index
= in_map
.get(DataType::MIDI
, midi_in_index
++);
514 //cerr << port_index << " : " << " MIDI IN " << buf_index << endl;
515 slv2_instance_connect_port(_instance
, port_index
,
516 bufs
.get_lv2_midi(true, buf_index
).data());
517 } else if (parameter_is_output(port_index
)) {
518 const uint32_t buf_index
= out_map
.get(DataType::MIDI
, midi_out_index
++);
519 //cerr << port_index << " : " << " MIDI OUT " << buf_index << endl;
520 slv2_instance_connect_port(_instance
, port_index
,
521 bufs
.get_lv2_midi(false, buf_index
).data());
523 } else if (!parameter_is_control(port_index
)) {
524 // Optional port (it'd better be if we've made it this far...)
525 slv2_instance_connect_port(_instance
, port_index
, NULL
);
532 for (uint32_t port_index
= 0; port_index
< parameter_count(); ++port_index
) {
533 if (parameter_is_midi(port_index
) && parameter_is_output(port_index
)) {
534 const uint32_t buf_index
= out_map
.get(DataType::MIDI
, midi_out_index
++);
535 bufs
.flush_lv2_midi(true, buf_index
);
539 cycles_t now
= get_cycles ();
540 set_cycles ((uint32_t) (now
- then
));
546 LV2Plugin::parameter_is_control (uint32_t param
) const
548 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
549 return slv2_port_is_a(_plugin
, port
, _world
.control_class
);
553 LV2Plugin::parameter_is_audio (uint32_t param
) const
555 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
556 return slv2_port_is_a(_plugin
, port
, _world
.audio_class
);
560 LV2Plugin::parameter_is_midi (uint32_t param
) const
562 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
563 return slv2_port_is_a(_plugin
, port
, _world
.event_class
);
564 // && slv2_port_supports_event(_plugin, port, _world.midi_class);
568 LV2Plugin::parameter_is_output (uint32_t param
) const
570 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
571 return slv2_port_is_a(_plugin
, port
, _world
.output_class
);
575 LV2Plugin::parameter_is_input (uint32_t param
) const
577 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
578 return slv2_port_is_a(_plugin
, port
, _world
.input_class
);
582 LV2Plugin::print_parameter (uint32_t param
, char *buf
, uint32_t len
) const
585 if (param
< parameter_count()) {
586 snprintf (buf
, len
, "%.3f", get_parameter (param
));
594 LV2Plugin::run (nframes_t nframes
)
596 for (uint32_t i
= 0; i
< parameter_count(); ++i
) {
597 if (parameter_is_control(i
) && parameter_is_input(i
)) {
598 _control_data
[i
] = _shadow_data
[i
];
602 slv2_instance_run(_instance
, nframes
);
606 LV2Plugin::latency_compute_run ()
608 if (!_latency_control_port
) {
612 /* we need to run the plugin so that it can set its latency
618 uint32_t port_index
= 0;
619 uint32_t in_index
= 0;
620 uint32_t out_index
= 0;
621 const nframes_t bufsize
= 1024;
622 float buffer
[bufsize
];
624 memset(buffer
,0,sizeof(float)*bufsize
);
626 /* Note that we've already required that plugins
627 be able to handle in-place processing.
632 while (port_index
< parameter_count()) {
633 if (parameter_is_audio (port_index
)) {
634 if (parameter_is_input (port_index
)) {
635 slv2_instance_connect_port (_instance
, port_index
, buffer
);
637 } else if (parameter_is_output (port_index
)) {
638 slv2_instance_connect_port (_instance
, port_index
, buffer
);
650 : world(slv2_world_new())
652 slv2_world_load_all(world
);
653 input_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_INPUT
);
654 output_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_OUTPUT
);
655 control_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_CONTROL
);
656 audio_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_AUDIO
);
657 event_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_EVENT
);
658 midi_class
= slv2_value_new_uri(world
, SLV2_EVENT_CLASS_MIDI
);
659 in_place_broken
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"inPlaceBroken");
660 integer
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"integer");
661 toggled
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"toggled");
662 srate
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"sampleRate");
663 gtk_gui
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/extensions/ui#GtkUI");
664 external_gui
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/extensions/ui#external");
665 logarithmic
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/dev/extportinfo#logarithmic");
668 LV2World::~LV2World()
670 slv2_value_free(input_class
);
671 slv2_value_free(output_class
);
672 slv2_value_free(control_class
);
673 slv2_value_free(audio_class
);
674 slv2_value_free(event_class
);
675 slv2_value_free(midi_class
);
676 slv2_value_free(in_place_broken
);
679 LV2PluginInfo::LV2PluginInfo (void* lv2_world
, void* slv2_plugin
)
680 : _lv2_world(lv2_world
)
681 , _slv2_plugin(slv2_plugin
)
685 LV2PluginInfo::~LV2PluginInfo()
690 LV2PluginInfo::load (Session
& session
)
695 plugin
.reset (new LV2Plugin (session
.engine(), session
,
696 *(LV2World
*)_lv2_world
, (SLV2Plugin
)_slv2_plugin
, session
.frame_rate()));
698 plugin
->set_info(PluginInfoPtr(new LV2PluginInfo(*this)));
702 catch (failed_constructor
&err
) {
703 return PluginPtr ((Plugin
*) 0);
710 LV2PluginInfo::discover (void* lv2_world
)
712 PluginInfoList
* plugs
= new PluginInfoList
;
714 LV2World
* world
= (LV2World
*)lv2_world
;
715 SLV2Plugins plugins
= slv2_world_get_all_plugins(world
->world
);
717 cerr
<< "LV2: Discovering " << slv2_plugins_size (plugins
) << " plugins" << endl
;
719 for (unsigned i
=0; i
< slv2_plugins_size(plugins
); ++i
) {
720 SLV2Plugin p
= slv2_plugins_get_at(plugins
, i
);
721 LV2PluginInfoPtr
info (new LV2PluginInfo(lv2_world
, p
));
723 SLV2Value name
= slv2_plugin_get_name(p
);
726 cerr
<< "LV2: invalid plugin\n";
732 info
->name
= string(slv2_value_as_string(name
));
733 slv2_value_free(name
);
735 SLV2PluginClass pclass
= slv2_plugin_get_class(p
);
736 SLV2Value label
= slv2_plugin_class_get_label(pclass
);
737 info
->category
= slv2_value_as_string(label
);
739 SLV2Value author_name
= slv2_plugin_get_author_name(p
);
740 info
->creator
= author_name
? string(slv2_value_as_string(author_name
)) : "Unknown";
741 slv2_value_free(author_name
);
743 info
->path
= "/NOPATH"; // Meaningless for LV2
745 info
->n_inputs
.set_audio(slv2_plugin_get_num_ports_of_class(p
,
746 world
->input_class
, world
->audio_class
, NULL
));
747 info
->n_inputs
.set_midi(slv2_plugin_get_num_ports_of_class(p
,
748 world
->input_class
, world
->event_class
, NULL
));
750 info
->n_outputs
.set_audio(slv2_plugin_get_num_ports_of_class(p
,
751 world
->output_class
, world
->audio_class
, NULL
));
752 info
->n_outputs
.set_midi(slv2_plugin_get_num_ports_of_class(p
,
753 world
->output_class
, world
->event_class
, NULL
));
755 info
->unique_id
= slv2_value_as_uri(slv2_plugin_get_uri(p
));
756 info
->index
= 0; // Meaningless for LV2
758 plugs
->push_back (info
);
761 cerr
<< "Done LV2 discovery" << endl
;