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 Ardour or the LV2 plugin (%2)"),
240 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
;
371 nodes
= node
.children ("Port");
373 for (iter
= nodes
.begin(); iter
!= nodes
.end(); ++iter
){
377 if ((prop
= child
->property("symbol")) != 0) {
378 sym
= prop
->value().c_str();
380 warning
<< _("LV2: port has no symbol, ignored") << endmsg
;
384 map
<string
,uint32_t>::iterator i
= _port_indices
.find(sym
);
385 if (i
!= _port_indices
.end()) {
388 warning
<< _("LV2: port has unknown index, ignored") << endmsg
;
392 if ((prop
= child
->property("value")) != 0) {
393 value
= prop
->value().c_str();
395 warning
<< _("LV2: port has no value, ignored") << endmsg
;
399 set_parameter (port_id
, atof(value
));
402 latency_compute_run ();
408 LV2Plugin::get_parameter_descriptor (uint32_t which
, ParameterDescriptor
& desc
) const
410 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, which
);
412 SLV2Value def
, min
, max
;
413 slv2_port_get_range(_plugin
, port
, &def
, &min
, &max
);
415 desc
.integer_step
= slv2_port_has_property(_plugin
, port
, _world
.integer
);
416 desc
.toggled
= slv2_port_has_property(_plugin
, port
, _world
.toggled
);
417 desc
.logarithmic
= slv2_port_has_property(_plugin
, port
, _world
.logarithmic
);
418 desc
.sr_dependent
= slv2_port_has_property(_plugin
, port
, _world
.srate
);
419 desc
.label
= slv2_value_as_string(slv2_port_get_name(_plugin
, port
));
420 desc
.lower
= min
? slv2_value_as_float(min
) : 0.0f
;
421 desc
.upper
= max
? slv2_value_as_float(max
) : 1.0f
;
422 desc
.min_unbound
= false; // TODO (LV2 extension)
423 desc
.max_unbound
= false; // TODO (LV2 extension)
425 if (desc
.integer_step
) {
427 desc
.smallstep
= 0.1;
428 desc
.largestep
= 10.0;
430 const float delta
= desc
.upper
- desc
.lower
;
431 desc
.step
= delta
/ 1000.0f
;
432 desc
.smallstep
= delta
/ 10000.0f
;
433 desc
.largestep
= delta
/10.0f
;
436 slv2_value_free(def
);
437 slv2_value_free(min
);
438 slv2_value_free(max
);
445 LV2Plugin::describe_parameter (Evoral::Parameter which
)
447 if (which
.type() == PluginAutomation
&& which
.id() < parameter_count()) {
448 SLV2Value name
= slv2_port_get_name(_plugin
,
449 slv2_plugin_get_port_by_index(_plugin
, which
));
450 string
ret(slv2_value_as_string(name
));
451 slv2_value_free(name
);
459 LV2Plugin::signal_latency () const
461 if (_latency_control_port
) {
462 return (nframes_t
) floor (*_latency_control_port
);
468 set
<Evoral::Parameter
>
469 LV2Plugin::automatable () const
471 set
<Evoral::Parameter
> ret
;
473 for (uint32_t i
= 0; i
< parameter_count(); ++i
){
474 if (parameter_is_input(i
) && parameter_is_control(i
)) {
475 ret
.insert (ret
.end(), Evoral::Parameter(PluginAutomation
, 0, i
));
483 LV2Plugin::connect_and_run (BufferSet
& bufs
,
484 ChanMapping in_map
, ChanMapping out_map
,
485 nframes_t nframes
, nframes_t offset
)
487 cycles_t then
= get_cycles ();
489 uint32_t audio_in_index
= 0;
490 uint32_t audio_out_index
= 0;
491 uint32_t midi_in_index
= 0;
492 uint32_t midi_out_index
= 0;
493 for (uint32_t port_index
= 0; port_index
< parameter_count(); ++port_index
) {
494 if (parameter_is_audio(port_index
)) {
495 if (parameter_is_input(port_index
)) {
496 const uint32_t buf_index
= in_map
.get(DataType::AUDIO
, audio_in_index
++);
497 //cerr << port_index << " : " << " AUDIO IN " << buf_index << endl;
498 slv2_instance_connect_port(_instance
, port_index
,
499 bufs
.get_audio(buf_index
).data(offset
));
500 } else if (parameter_is_output(port_index
)) {
501 const uint32_t buf_index
= out_map
.get(DataType::AUDIO
, audio_out_index
++);
502 //cerr << port_index << " : " << " AUDIO OUT " << buf_index << endl;
503 slv2_instance_connect_port(_instance
, port_index
,
504 bufs
.get_audio(buf_index
).data(offset
));
506 } else if (parameter_is_midi(port_index
)) {
507 if (parameter_is_input(port_index
)) {
508 const uint32_t buf_index
= in_map
.get(DataType::MIDI
, midi_in_index
++);
509 //cerr << port_index << " : " << " MIDI IN " << buf_index << endl;
510 slv2_instance_connect_port(_instance
, port_index
,
511 bufs
.get_lv2_midi(true, buf_index
).data());
512 } else if (parameter_is_output(port_index
)) {
513 const uint32_t buf_index
= out_map
.get(DataType::MIDI
, midi_out_index
++);
514 //cerr << port_index << " : " << " MIDI OUT " << buf_index << endl;
515 slv2_instance_connect_port(_instance
, port_index
,
516 bufs
.get_lv2_midi(false, buf_index
).data());
518 } else if (!parameter_is_control(port_index
)) {
519 // Optional port (it'd better be if we've made it this far...)
520 slv2_instance_connect_port(_instance
, port_index
, NULL
);
527 for (uint32_t port_index
= 0; port_index
< parameter_count(); ++port_index
) {
528 if (parameter_is_midi(port_index
) && parameter_is_output(port_index
)) {
529 const uint32_t buf_index
= out_map
.get(DataType::MIDI
, midi_out_index
++);
530 bufs
.flush_lv2_midi(true, buf_index
);
534 cycles_t now
= get_cycles ();
535 set_cycles ((uint32_t) (now
- then
));
541 LV2Plugin::parameter_is_control (uint32_t param
) const
543 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
544 return slv2_port_is_a(_plugin
, port
, _world
.control_class
);
548 LV2Plugin::parameter_is_audio (uint32_t param
) const
550 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
551 return slv2_port_is_a(_plugin
, port
, _world
.audio_class
);
555 LV2Plugin::parameter_is_midi (uint32_t param
) const
557 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
558 return slv2_port_is_a(_plugin
, port
, _world
.event_class
);
559 // && slv2_port_supports_event(_plugin, port, _world.midi_class);
563 LV2Plugin::parameter_is_output (uint32_t param
) const
565 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
566 return slv2_port_is_a(_plugin
, port
, _world
.output_class
);
570 LV2Plugin::parameter_is_input (uint32_t param
) const
572 SLV2Port port
= slv2_plugin_get_port_by_index(_plugin
, param
);
573 return slv2_port_is_a(_plugin
, port
, _world
.input_class
);
577 LV2Plugin::print_parameter (uint32_t param
, char *buf
, uint32_t len
) const
580 if (param
< parameter_count()) {
581 snprintf (buf
, len
, "%.3f", get_parameter (param
));
589 LV2Plugin::run (nframes_t nframes
)
591 for (uint32_t i
= 0; i
< parameter_count(); ++i
) {
592 if (parameter_is_control(i
) && parameter_is_input(i
)) {
593 _control_data
[i
] = _shadow_data
[i
];
597 slv2_instance_run(_instance
, nframes
);
601 LV2Plugin::latency_compute_run ()
603 if (!_latency_control_port
) {
607 /* we need to run the plugin so that it can set its latency
613 uint32_t port_index
= 0;
614 uint32_t in_index
= 0;
615 uint32_t out_index
= 0;
616 const nframes_t bufsize
= 1024;
617 float buffer
[bufsize
];
619 memset(buffer
,0,sizeof(float)*bufsize
);
621 /* Note that we've already required that plugins
622 be able to handle in-place processing.
627 while (port_index
< parameter_count()) {
628 if (parameter_is_audio (port_index
)) {
629 if (parameter_is_input (port_index
)) {
630 slv2_instance_connect_port (_instance
, port_index
, buffer
);
632 } else if (parameter_is_output (port_index
)) {
633 slv2_instance_connect_port (_instance
, port_index
, buffer
);
645 : world(slv2_world_new())
647 slv2_world_load_all(world
);
648 input_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_INPUT
);
649 output_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_OUTPUT
);
650 control_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_CONTROL
);
651 audio_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_AUDIO
);
652 event_class
= slv2_value_new_uri(world
, SLV2_PORT_CLASS_EVENT
);
653 midi_class
= slv2_value_new_uri(world
, SLV2_EVENT_CLASS_MIDI
);
654 in_place_broken
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"inPlaceBroken");
655 integer
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"integer");
656 toggled
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"toggled");
657 srate
= slv2_value_new_uri(world
, SLV2_NAMESPACE_LV2
"sampleRate");
658 gtk_gui
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/extensions/ui#GtkUI");
659 external_gui
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/extensions/ui#external");
660 logarithmic
= slv2_value_new_uri(world
, "http://lv2plug.in/ns/dev/extportinfo#logarithmic");
663 LV2World::~LV2World()
665 slv2_value_free(input_class
);
666 slv2_value_free(output_class
);
667 slv2_value_free(control_class
);
668 slv2_value_free(audio_class
);
669 slv2_value_free(event_class
);
670 slv2_value_free(midi_class
);
671 slv2_value_free(in_place_broken
);
674 LV2PluginInfo::LV2PluginInfo (void* lv2_world
, void* slv2_plugin
)
675 : _lv2_world(lv2_world
)
676 , _slv2_plugin(slv2_plugin
)
680 LV2PluginInfo::~LV2PluginInfo()
685 LV2PluginInfo::load (Session
& session
)
690 plugin
.reset (new LV2Plugin (session
.engine(), session
,
691 *(LV2World
*)_lv2_world
, (SLV2Plugin
)_slv2_plugin
, session
.frame_rate()));
693 plugin
->set_info(PluginInfoPtr(new LV2PluginInfo(*this)));
697 catch (failed_constructor
&err
) {
698 return PluginPtr ((Plugin
*) 0);
705 LV2PluginInfo::discover (void* lv2_world
)
707 PluginInfoList
* plugs
= new PluginInfoList
;
709 LV2World
* world
= (LV2World
*)lv2_world
;
710 SLV2Plugins plugins
= slv2_world_get_all_plugins(world
->world
);
712 cerr
<< "LV2: Discovering " << slv2_plugins_size (plugins
) << " plugins" << endl
;
714 for (unsigned i
=0; i
< slv2_plugins_size(plugins
); ++i
) {
715 SLV2Plugin p
= slv2_plugins_get_at(plugins
, i
);
716 LV2PluginInfoPtr
info (new LV2PluginInfo(lv2_world
, p
));
718 SLV2Value name
= slv2_plugin_get_name(p
);
721 cerr
<< "LV2: invalid plugin\n";
727 info
->name
= string(slv2_value_as_string(name
));
728 slv2_value_free(name
);
730 SLV2PluginClass pclass
= slv2_plugin_get_class(p
);
731 SLV2Value label
= slv2_plugin_class_get_label(pclass
);
732 info
->category
= slv2_value_as_string(label
);
734 SLV2Value author_name
= slv2_plugin_get_author_name(p
);
735 info
->creator
= author_name
? string(slv2_value_as_string(author_name
)) : "Unknown";
736 slv2_value_free(author_name
);
738 info
->path
= "/NOPATH"; // Meaningless for LV2
740 info
->n_inputs
.set_audio(slv2_plugin_get_num_ports_of_class(p
,
741 world
->input_class
, world
->audio_class
, NULL
));
742 info
->n_inputs
.set_midi(slv2_plugin_get_num_ports_of_class(p
,
743 world
->input_class
, world
->event_class
, NULL
));
745 info
->n_outputs
.set_audio(slv2_plugin_get_num_ports_of_class(p
,
746 world
->output_class
, world
->audio_class
, NULL
));
747 info
->n_outputs
.set_midi(slv2_plugin_get_num_ports_of_class(p
,
748 world
->output_class
, world
->event_class
, NULL
));
750 info
->unique_id
= slv2_value_as_uri(slv2_plugin_get_uri(p
));
751 info
->index
= 0; // Meaningless for LV2
753 plugs
->push_back (info
);
756 cerr
<< "Done LV2 discovery" << endl
;