2 Copyright (C) 2008-2012 Paul Davis
3 Author: David Robillard
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 <giomm/file.h>
29 #include <glib/gprintf.h>
32 #include <boost/utility.hpp>
34 #include "pbd/compose.h"
35 #include "pbd/error.h"
36 #include "pbd/xml++.h"
38 #include "libardour-config.h"
40 #include "ardour/audio_buffer.h"
41 #include "ardour/audioengine.h"
42 #include "ardour/debug.h"
43 #include "ardour/lv2_plugin.h"
44 #include "ardour/session.h"
45 #include "ardour/tempo.h"
46 #include "ardour/types.h"
47 #include "ardour/utils.h"
48 #include "ardour/worker.h"
53 #include <lilv/lilv.h>
55 #include "lv2/lv2plug.in/ns/ext/atom/atom.h"
56 #include "lv2/lv2plug.in/ns/ext/atom/forge.h"
57 #include "lv2/lv2plug.in/ns/ext/log/log.h"
58 #include "lv2/lv2plug.in/ns/ext/midi/midi.h"
59 #include "lv2/lv2plug.in/ns/ext/port-props/port-props.h"
60 #include "lv2/lv2plug.in/ns/ext/presets/presets.h"
61 #include "lv2/lv2plug.in/ns/ext/state/state.h"
62 #include "lv2/lv2plug.in/ns/ext/time/time.h"
63 #include "lv2/lv2plug.in/ns/ext/worker/worker.h"
64 #include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
66 #include "lv2/lv2plug.in/ns/ext/buf-size/buf-size.h"
67 #include "lv2/lv2plug.in/ns/ext/options/options.h"
70 #include "lv2_evbuf.h"
73 #include <suil/suil.h>
76 /** The number of MIDI buffers that will fit in a UI/worker comm buffer.
77 This needs to be roughly the number of cycles the UI will get around to
78 actually processing the traffic. Lower values are flakier but save memory.
80 static const size_t NBUFS = 4;
83 using namespace ARDOUR;
86 URIMap LV2Plugin::_uri_map;
88 LV2Plugin::URIDs LV2Plugin::urids = {
89 _uri_map.uri_to_id(LV2_ATOM__Chunk),
90 _uri_map.uri_to_id(LV2_ATOM__Path),
91 _uri_map.uri_to_id(LV2_ATOM__Sequence),
92 _uri_map.uri_to_id(LV2_ATOM__eventTransfer),
93 _uri_map.uri_to_id(LV2_LOG__Error),
94 _uri_map.uri_to_id(LV2_LOG__Note),
95 _uri_map.uri_to_id(LV2_LOG__Warning),
96 _uri_map.uri_to_id(LV2_MIDI__MidiEvent),
97 _uri_map.uri_to_id(LV2_TIME__Position),
98 _uri_map.uri_to_id(LV2_TIME__bar),
99 _uri_map.uri_to_id(LV2_TIME__barBeat),
100 _uri_map.uri_to_id(LV2_TIME__beatUnit),
101 _uri_map.uri_to_id(LV2_TIME__beatsPerBar),
102 _uri_map.uri_to_id(LV2_TIME__beatsPerMinute),
103 _uri_map.uri_to_id(LV2_TIME__frame),
104 _uri_map.uri_to_id(LV2_TIME__speed)
107 class LV2World : boost::noncopyable {
114 LilvNode* atom_AtomPort;
115 LilvNode* atom_Chunk;
116 LilvNode* atom_Sequence;
117 LilvNode* atom_bufferType;
118 LilvNode* atom_eventTransfer;
119 LilvNode* atom_supports;
120 LilvNode* ev_EventPort;
121 LilvNode* ext_logarithmic;
122 LilvNode* lv2_AudioPort;
123 LilvNode* lv2_ControlPort;
124 LilvNode* lv2_InputPort;
125 LilvNode* lv2_OutputPort;
126 LilvNode* lv2_enumeration;
127 LilvNode* lv2_inPlaceBroken;
128 LilvNode* lv2_integer;
129 LilvNode* lv2_sampleRate;
130 LilvNode* lv2_toggled;
131 LilvNode* midi_MidiEvent;
132 LilvNode* rdfs_comment;
133 LilvNode* time_Position;
135 LilvNode* ui_external;
138 static LV2World _world;
140 /* worker extension */
142 /** Called by the plugin to schedule non-RT work. */
143 static LV2_Worker_Status
144 work_schedule(LV2_Worker_Schedule_Handle handle,
148 LV2Plugin* plugin = (LV2Plugin*)handle;
149 if (plugin->session().engine().freewheeling()) {
150 // Freewheeling, do the work immediately in this (audio) thread
151 return (LV2_Worker_Status)plugin->work(size, data);
153 // Enqueue message for the worker thread
154 return plugin->worker()->schedule(size, data) ?
155 LV2_WORKER_SUCCESS : LV2_WORKER_ERR_UNKNOWN;
159 /** Called by the plugin to respond to non-RT work. */
160 static LV2_Worker_Status
161 work_respond(LV2_Worker_Respond_Handle handle,
165 LV2Plugin* plugin = (LV2Plugin*)handle;
166 if (plugin->session().engine().freewheeling()) {
167 // Freewheeling, respond immediately in this (audio) thread
168 return (LV2_Worker_Status)plugin->work_response(size, data);
170 // Enqueue response for the worker
171 return plugin->worker()->respond(size, data) ?
172 LV2_WORKER_SUCCESS : LV2_WORKER_ERR_UNKNOWN;
179 log_vprintf(LV2_Log_Handle /*handle*/,
185 const int ret = g_vasprintf(&str, fmt, args);
186 if (type == LV2Plugin::urids.log_Error) {
187 error << str << endmsg;
188 } else if (type == LV2Plugin::urids.log_Warning) {
189 warning << str << endmsg;
190 } else if (type == LV2Plugin::urids.log_Note) {
191 info << str << endmsg;
193 // TODO: Toggleable log:Trace message support
198 log_printf(LV2_Log_Handle handle,
200 const char* fmt, ...)
204 const int ret = log_vprintf(handle, type, fmt, args);
209 struct LV2Plugin::Impl {
210 Impl() : plugin(0), ui(0), ui_type(0), name(0), author(0), instance(0)
215 /** Find the LV2 input port with the given designation.
216 * If found, bufptrs[port_index] will be set to bufptr.
218 const LilvPort* designated_input (const char* uri, void** bufptrs[], void** bufptr);
220 const LilvPlugin* plugin;
222 const LilvNode* ui_type;
225 LilvInstance* instance;
226 const LV2_Worker_Interface* work_iface;
228 LV2_Atom_Forge forge;
231 LV2Plugin::LV2Plugin (AudioEngine& engine,
233 const void* c_plugin,
235 : Plugin (engine, session)
242 init(c_plugin, rate);
245 LV2Plugin::LV2Plugin (const LV2Plugin& other)
251 , _insert_id(other._insert_id)
253 init(other._impl->plugin, other._sample_rate);
255 for (uint32_t i = 0; i < parameter_count(); ++i) {
256 _control_data[i] = other._shadow_data[i];
257 _shadow_data[i] = other._shadow_data[i];
262 LV2Plugin::init(const void* c_plugin, framecnt_t rate)
264 DEBUG_TRACE(DEBUG::LV2, "init\n");
266 _impl->plugin = (const LilvPlugin*)c_plugin;
268 _impl->ui_type = NULL;
273 _atom_ev_buffers = 0;
275 _bpm_control_port = 0;
276 _freewheel_control_port = 0;
277 _latency_control_port = 0;
278 _next_cycle_start = std::numeric_limits<framepos_t>::max();
279 _next_cycle_speed = 1.0;
280 _block_length = _engine.frames_per_cycle();
281 _seq_size = _engine.raw_buffer_size(DataType::MIDI);
283 _was_activated = false;
284 _has_state_interface = false;
286 _instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
287 _data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
288 _make_path_feature.URI = LV2_STATE__makePath;
289 _log_feature.URI = LV2_LOG__log;
290 _work_schedule_feature.URI = LV2_WORKER__schedule;
291 _work_schedule_feature.data = NULL;
292 _def_state_feature.URI = LV2_STATE_PREFIX "loadDefaultState"; // Post LV2-1.2.0
293 _def_state_feature.data = NULL;
295 const LilvPlugin* plugin = _impl->plugin;
297 LilvNode* state_iface_uri = lilv_new_uri(_world.world, LV2_STATE__interface);
298 LilvNode* state_uri = lilv_new_uri(_world.world, LV2_STATE_URI);
299 _has_state_interface =
300 // What plugins should have (lv2:extensionData state:Interface)
301 lilv_plugin_has_extension_data(plugin, state_iface_uri)
302 // What some outdated/incorrect ones have
303 || lilv_plugin_has_feature(plugin, state_uri);
304 lilv_node_free(state_uri);
305 lilv_node_free(state_iface_uri);
307 _features = (LV2_Feature**)calloc(11, sizeof(LV2_Feature*));
308 _features[0] = &_instance_access_feature;
309 _features[1] = &_data_access_feature;
310 _features[2] = &_make_path_feature;
311 _features[3] = _uri_map.uri_map_feature();
312 _features[4] = _uri_map.urid_map_feature();
313 _features[5] = _uri_map.urid_unmap_feature();
314 _features[6] = &_log_feature;
316 unsigned n_features = 7;
318 _features[n_features++] = &_def_state_feature;
321 lv2_atom_forge_init(&_impl->forge, _uri_map.urid_map());
324 LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int);
325 LV2_Options_Option options[] = {
326 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__minBlockLength),
327 sizeof(int32_t), atom_Int, &_block_length },
328 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__maxBlockLength),
329 sizeof(int32_t), atom_Int, &_block_length },
330 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__sequenceSize),
331 sizeof(int32_t), atom_Int, &_seq_size },
332 { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL }
335 _options_feature.URI = LV2_OPTIONS__options;
336 _options_feature.data = options;
337 _features[n_features++] = &_options_feature;
340 LV2_State_Make_Path* make_path = (LV2_State_Make_Path*)malloc(
341 sizeof(LV2_State_Make_Path));
342 make_path->handle = this;
343 make_path->path = &lv2_state_make_path;
344 _make_path_feature.data = make_path;
346 LV2_Log_Log* log = (LV2_Log_Log*)malloc(sizeof(LV2_Log_Log));
348 log->printf = &log_printf;
349 log->vprintf = &log_vprintf;
350 _log_feature.data = log;
352 LilvNode* worker_schedule = lilv_new_uri(_world.world, LV2_WORKER__schedule);
353 if (lilv_plugin_has_feature(plugin, worker_schedule)) {
354 LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc(
355 sizeof(LV2_Worker_Schedule));
356 size_t buf_size = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS;
357 _worker = new Worker(this, buf_size);
358 schedule->handle = this;
359 schedule->schedule_work = work_schedule;
360 _work_schedule_feature.data = schedule;
361 _features[n_features++] = &_work_schedule_feature;
363 lilv_node_free(worker_schedule);
365 _impl->instance = lilv_plugin_instantiate(plugin, rate, _features);
366 _impl->name = lilv_plugin_get_name(plugin);
367 _impl->author = lilv_plugin_get_author_name(plugin);
369 if (_impl->instance == 0) {
370 error << _("LV2: Failed to instantiate plugin ") << uri() << endmsg;
371 throw failed_constructor();
374 _instance_access_feature.data = (void*)_impl->instance->lv2_handle;
375 _data_access_extension_data.extension_data = _impl->instance->lv2_descriptor->extension_data;
376 _data_access_feature.data = &_data_access_extension_data;
378 LilvNode* worker_iface_uri = lilv_new_uri(_world.world, LV2_WORKER__interface);
379 if (lilv_plugin_has_extension_data(plugin, worker_iface_uri)) {
380 _impl->work_iface = (const LV2_Worker_Interface*)extension_data(
381 LV2_WORKER__interface);
383 lilv_node_free(worker_iface_uri);
385 if (lilv_plugin_has_feature(plugin, _world.lv2_inPlaceBroken)) {
386 error << string_compose(
387 _("LV2: \"%1\" cannot be used, since it cannot do inplace processing"),
388 lilv_node_as_string(_impl->name)) << endmsg;
389 lilv_node_free(_impl->name);
390 lilv_node_free(_impl->author);
391 throw failed_constructor();
395 // Load default state
396 LilvState* state = lilv_state_new_from_world(
397 _world.world, _uri_map.urid_map(), lilv_plugin_get_uri(_impl->plugin));
398 if (state && _has_state_interface) {
399 lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
405 const uint32_t num_ports = this->num_ports();
406 for (uint32_t i = 0; i < num_ports; ++i) {
407 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, i);
410 if (lilv_port_is_a(_impl->plugin, port, _world.lv2_OutputPort)) {
411 flags |= PORT_OUTPUT;
412 } else if (lilv_port_is_a(_impl->plugin, port, _world.lv2_InputPort)) {
415 error << string_compose(
416 "LV2: \"%1\" port %2 is neither input nor output",
417 lilv_node_as_string(_impl->name), i) << endmsg;
418 throw failed_constructor();
421 if (lilv_port_is_a(_impl->plugin, port, _world.lv2_ControlPort)) {
422 flags |= PORT_CONTROL;
423 } else if (lilv_port_is_a(_impl->plugin, port, _world.lv2_AudioPort)) {
425 } else if (lilv_port_is_a(_impl->plugin, port, _world.ev_EventPort)) {
427 flags |= PORT_MIDI; // We assume old event API ports are for MIDI
428 } else if (lilv_port_is_a(_impl->plugin, port, _world.atom_AtomPort)) {
429 LilvNodes* buffer_types = lilv_port_get_value(
430 _impl->plugin, port, _world.atom_bufferType);
431 LilvNodes* atom_supports = lilv_port_get_value(
432 _impl->plugin, port, _world.atom_supports);
434 if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
435 flags |= PORT_SEQUENCE;
436 if (lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
439 if (lilv_nodes_contains(atom_supports, _world.time_Position)) {
440 flags |= PORT_POSITION;
443 lilv_nodes_free(buffer_types);
444 lilv_nodes_free(atom_supports);
446 error << string_compose(
447 "LV2: \"%1\" port %2 has no known data type",
448 lilv_node_as_string(_impl->name), i) << endmsg;
449 throw failed_constructor();
452 _port_flags.push_back(flags);
455 _control_data = new float[num_ports];
456 _shadow_data = new float[num_ports];
457 _defaults = new float[num_ports];
458 _ev_buffers = new LV2_Evbuf*[num_ports];
459 memset(_ev_buffers, 0, sizeof(LV2_Evbuf*) * num_ports);
461 const bool latent = lilv_plugin_has_latency(plugin);
462 const uint32_t latency_index = (latent)
463 ? lilv_plugin_get_latency_port_index(plugin)
466 // Build an array of pointers to special parameter buffers
467 void*** params = new void**[num_ports];
468 for (uint32_t i = 0; i < num_ports; ++i) {
471 _impl->designated_input (LV2_TIME__beatsPerMinute, params, (void**)&_bpm_control_port);
472 _impl->designated_input (LV2_CORE__freeWheeling, params, (void**)&_freewheel_control_port);
474 for (uint32_t i = 0; i < num_ports; ++i) {
475 const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
476 const LilvNode* sym = lilv_port_get_symbol(plugin, port);
478 // Store index in map so we can look up index by symbol
479 _port_indices.insert(std::make_pair(lilv_node_as_string(sym), i));
481 // Get range and default value if applicable
482 if (parameter_is_control(i)) {
484 lilv_port_get_range(plugin, port, &def, NULL, NULL);
485 _defaults[i] = def ? lilv_node_as_float(def) : 0.0f;
486 if (lilv_port_has_property (plugin, port, _world.lv2_sampleRate)) {
487 _defaults[i] *= _session.frame_rate ();
491 lilv_instance_connect_port(_impl->instance, i, &_control_data[i]);
493 if (latent && i == latency_index) {
494 _latency_control_port = &_control_data[i];
495 *_latency_control_port = 0;
498 if (parameter_is_input(i)) {
499 _shadow_data[i] = default_value(i);
501 *params[i] = (void*)&_shadow_data[i];
511 LilvUIs* uis = lilv_plugin_get_uis(plugin);
512 if (lilv_uis_size(uis) > 0) {
514 // Look for embeddable UI
515 LILV_FOREACH(uis, u, uis) {
516 const LilvUI* this_ui = lilv_uis_get(uis, u);
517 const LilvNode* this_ui_type = NULL;
518 if (lilv_ui_is_supported(this_ui,
522 // TODO: Multiple UI support
524 _impl->ui_type = this_ui_type;
529 // Look for Gtk native UI
530 LILV_FOREACH(uis, i, uis) {
531 const LilvUI* ui = lilv_uis_get(uis, i);
532 if (lilv_ui_is_a(ui, _world.ui_GtkUI)) {
534 _impl->ui_type = _world.ui_GtkUI;
540 // If Gtk UI is not available, try to find external UI
542 LILV_FOREACH(uis, i, uis) {
543 const LilvUI* ui = lilv_uis_get(uis, i);
544 if (lilv_ui_is_a(ui, _world.ui_external)) {
546 _impl->ui_type = _world.ui_external;
553 allocate_atom_event_buffers();
554 latency_compute_run();
557 LV2Plugin::~LV2Plugin ()
559 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 destroy\n", name()));
564 lilv_instance_free(_impl->instance);
565 lilv_node_free(_impl->name);
566 lilv_node_free(_impl->author);
569 free(_make_path_feature.data);
570 free(_work_schedule_feature.data);
576 if (_atom_ev_buffers) {
577 LV2_Evbuf** b = _atom_ev_buffers;
582 free(_atom_ev_buffers);
585 delete [] _control_data;
586 delete [] _shadow_data;
587 delete [] _ev_buffers;
591 LV2Plugin::is_external_ui() const
596 return lilv_ui_is_a(_impl->ui, _world.ui_external);
600 LV2Plugin::ui_is_resizable () const
602 const LilvNode* s = lilv_ui_get_uri(_impl->ui);
603 LilvNode* p = lilv_new_uri(_world.world, LV2_CORE__optionalFeature);
604 LilvNode* fs = lilv_new_uri(_world.world, LV2_UI__fixedSize);
605 LilvNode* nrs = lilv_new_uri(_world.world, LV2_UI__noUserResize);
607 LilvNodes* fs_matches = lilv_world_find_nodes(_world.world, s, p, fs);
608 LilvNodes* nrs_matches = lilv_world_find_nodes(_world.world, s, p, nrs);
610 lilv_nodes_free(nrs_matches);
611 lilv_nodes_free(fs_matches);
616 return !fs_matches && !nrs_matches;
620 LV2Plugin::unique_id() const
622 return lilv_node_as_uri(lilv_plugin_get_uri(_impl->plugin));
626 LV2Plugin::uri() const
628 return lilv_node_as_uri(lilv_plugin_get_uri(_impl->plugin));
632 LV2Plugin::label() const
634 return lilv_node_as_string(_impl->name);
638 LV2Plugin::name() const
640 return lilv_node_as_string(_impl->name);
644 LV2Plugin::maker() const
646 return _impl->author ? lilv_node_as_string (_impl->author) : "Unknown";
650 LV2Plugin::num_ports() const
652 return lilv_plugin_get_num_ports(_impl->plugin);
656 LV2Plugin::parameter_count() const
658 return lilv_plugin_get_num_ports(_impl->plugin);
662 LV2Plugin::default_value(uint32_t port)
664 return _defaults[port];
668 LV2Plugin::port_symbol(uint32_t index) const
670 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, index);
672 error << name() << ": Invalid port index " << index << endmsg;
675 const LilvNode* sym = lilv_port_get_symbol(_impl->plugin, port);
676 return lilv_node_as_string(sym);
680 LV2Plugin::port_index (const char* symbol) const
682 const map<string, uint32_t>::const_iterator i = _port_indices.find(symbol);
683 if (i != _port_indices.end()) {
686 warning << string_compose(_("LV2: Unknown port %1"), symbol) << endmsg;
692 LV2Plugin::set_parameter(uint32_t which, float val)
694 DEBUG_TRACE(DEBUG::LV2, string_compose(
695 "%1 set parameter %2 to %3\n", name(), which, val));
697 if (which < lilv_plugin_get_num_ports(_impl->plugin)) {
698 if (get_parameter (which) == val) {
702 _shadow_data[which] = val;
704 warning << string_compose(
705 _("Illegal parameter number used with plugin \"%1\". "
706 "This is a bug in either %2 or the LV2 plugin <%3>"),
707 name(), PROGRAM_NAME, unique_id()) << endmsg;
710 Plugin::set_parameter(which, val);
714 LV2Plugin::get_parameter(uint32_t which) const
716 if (parameter_is_input(which)) {
717 return (float)_shadow_data[which];
719 return (float)_control_data[which];
725 LV2Plugin::get_docs() const
727 LilvNodes* comments = lilv_plugin_get_value(_impl->plugin, _world.rdfs_comment);
729 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
730 lilv_nodes_free(comments);
738 LV2Plugin::get_parameter_docs(uint32_t which) const
740 LilvNodes* comments = lilv_port_get_value(
742 lilv_plugin_get_port_by_index(_impl->plugin, which),
743 _world.rdfs_comment);
746 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
747 lilv_nodes_free(comments);
755 LV2Plugin::nth_parameter(uint32_t n, bool& ok) const
758 for (uint32_t c = 0, x = 0; x < lilv_plugin_get_num_ports(_impl->plugin); ++x) {
759 if (parameter_is_control(x)) {
771 LV2Plugin::extension_data(const char* uri) const
773 return lilv_instance_get_extension_data(_impl->instance, uri);
777 LV2Plugin::c_plugin()
779 return _impl->plugin;
785 return (const void*)_impl->ui;
789 LV2Plugin::c_ui_type()
791 return (const void*)_impl->ui_type;
794 /** Directory for all plugin state. */
796 LV2Plugin::plugin_dir() const
798 return Glib::build_filename(_session.plugins_dir(), _insert_id.to_s());
801 /** Directory for files created by the plugin (except during save). */
803 LV2Plugin::scratch_dir() const
805 return Glib::build_filename(plugin_dir(), "scratch");
808 /** Directory for snapshots of files in the scratch directory. */
810 LV2Plugin::file_dir() const
812 return Glib::build_filename(plugin_dir(), "files");
815 /** Directory to save state snapshot version @c num into. */
817 LV2Plugin::state_dir(unsigned num) const
819 return Glib::build_filename(plugin_dir(), string_compose("state%1", num));
822 /** Implementation of state:makePath for files created at instantiation time.
823 * Note this is not used for files created at save time (Lilv deals with that).
826 LV2Plugin::lv2_state_make_path(LV2_State_Make_Path_Handle handle,
829 LV2Plugin* me = (LV2Plugin*)handle;
830 if (me->_insert_id == PBD::ID("0")) {
831 warning << string_compose(
832 "File path \"%1\" requested but LV2 %2 has no insert ID",
833 path, me->name()) << endmsg;
834 return g_strdup(path);
837 const std::string abs_path = Glib::build_filename(me->scratch_dir(), path);
838 const std::string dirname = Glib::path_get_dirname(abs_path);
839 g_mkdir_with_parents(dirname.c_str(), 0744);
841 DEBUG_TRACE(DEBUG::LV2, string_compose("new file path %1 => %2\n",
844 return g_strndup(abs_path.c_str(), abs_path.length());
848 remove_directory(const std::string& path)
850 if (!Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) {
851 warning << string_compose("\"%1\" is not a directory", path) << endmsg;
855 Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path(path);
856 Glib::RefPtr<Gio::FileEnumerator> e = dir->enumerate_children();
857 Glib::RefPtr<Gio::FileInfo> fi;
858 while ((fi = e->next_file())) {
859 if (fi->get_type() == Gio::FILE_TYPE_DIRECTORY) {
860 remove_directory(fi->get_name());
862 dir->get_child(fi->get_name())->remove();
869 LV2Plugin::add_state(XMLNode* root) const
871 assert(_insert_id != PBD::ID("0"));
875 LocaleGuard lg(X_("POSIX"));
877 for (uint32_t i = 0; i < parameter_count(); ++i) {
878 if (parameter_is_input(i) && parameter_is_control(i)) {
879 child = new XMLNode("Port");
880 child->add_property("symbol", port_symbol(i));
881 snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
882 child->add_property("value", string(buf));
883 root->add_child_nocopy(*child);
887 if (_has_state_interface) {
888 // Provisionally increment state version and create directory
889 const std::string new_dir = state_dir(++_state_version);
890 g_mkdir_with_parents(new_dir.c_str(), 0744);
892 LilvState* state = lilv_state_new_from_instance(
896 scratch_dir().c_str(),
898 _session.externals_dir().c_str(),
901 const_cast<LV2Plugin*>(this),
905 if (!_impl->state || !lilv_state_equals(state, _impl->state)) {
906 lilv_state_save(_world.world,
908 _uri_map.urid_unmap(),
914 lilv_state_free(_impl->state);
915 _impl->state = state;
917 // State is identical, decrement version and nuke directory
918 lilv_state_free(state);
919 remove_directory(new_dir);
923 root->add_property("state-dir", string_compose("state%1", _state_version));
927 static inline const LilvNode*
928 get_value(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate)
930 LilvNodes* vs = lilv_world_find_nodes(world, subject, predicate, NULL);
931 return vs ? lilv_nodes_get_first(vs) : NULL;
935 LV2Plugin::find_presets()
937 LilvNode* lv2_appliesTo = lilv_new_uri(_world.world, LV2_CORE__appliesTo);
938 LilvNode* pset_Preset = lilv_new_uri(_world.world, LV2_PRESETS__Preset);
939 LilvNode* rdfs_label = lilv_new_uri(_world.world, LILV_NS_RDFS "label");
941 LilvNodes* presets = lilv_plugin_get_related(_impl->plugin, pset_Preset);
942 LILV_FOREACH(nodes, i, presets) {
943 const LilvNode* preset = lilv_nodes_get(presets, i);
944 lilv_world_load_resource(_world.world, preset);
945 const LilvNode* name = get_value(_world.world, preset, rdfs_label);
947 _presets.insert(std::make_pair(lilv_node_as_string(preset),
948 Plugin::PresetRecord(
949 lilv_node_as_string(preset),
950 lilv_node_as_string(name))));
952 warning << string_compose(
953 _("Plugin \"%1\% preset \"%2%\" is missing a label\n"),
954 lilv_node_as_string(lilv_plugin_get_uri(_impl->plugin)),
955 lilv_node_as_string(preset)) << endmsg;
958 lilv_nodes_free(presets);
960 lilv_node_free(rdfs_label);
961 lilv_node_free(pset_Preset);
962 lilv_node_free(lv2_appliesTo);
966 set_port_value(const char* port_symbol,
972 LV2Plugin* self = (LV2Plugin*)user_data;
973 if (type != 0 && type != self->_uri_map.uri_to_id(LV2_ATOM__Float)) {
974 return; // TODO: Support non-float ports
977 const uint32_t port_index = self->port_index(port_symbol);
978 if (port_index != (uint32_t)-1) {
979 self->set_parameter(port_index, *(const float*)value);
984 LV2Plugin::load_preset(PresetRecord r)
986 LilvWorld* world = _world.world;
987 LilvNode* pset = lilv_new_uri(world, r.uri.c_str());
988 LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset);
991 lilv_state_restore(state, _impl->instance, set_port_value, this, 0, NULL);
992 lilv_state_free(state);
995 lilv_node_free(pset);
1000 ARDOUR::lv2plugin_get_port_value(const char* port_symbol,
1005 LV2Plugin *plugin = (LV2Plugin *) user_data;
1007 uint32_t index = plugin->port_index(port_symbol);
1008 if (index != (uint32_t) -1) {
1009 if (plugin->parameter_is_input(index) && plugin->parameter_is_control(index)) {
1011 *size = sizeof(float);
1012 *type = plugin->_uri_map.uri_to_id(LV2_ATOM__Float);
1013 value = &plugin->_shadow_data[index];
1025 LV2Plugin::do_save_preset(string name)
1027 const string base_name = legalize_for_uri(name);
1028 const string file_name = base_name + ".ttl";
1029 const string bundle = Glib::build_filename(
1030 Glib::get_home_dir(),
1031 Glib::build_filename(".lv2", base_name + ".lv2"));
1033 LilvState* state = lilv_state_new_from_instance(
1036 _uri_map.urid_map(),
1037 scratch_dir().c_str(), // file_dir
1038 bundle.c_str(), // copy_dir
1039 bundle.c_str(), // link_dir
1040 bundle.c_str(), // save_dir
1041 lv2plugin_get_port_value, // get_value
1042 (void*)this, // user_data
1043 LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
1044 _features // features
1047 lilv_state_set_label(state, name.c_str());
1049 _world.world, // world
1050 _uri_map.urid_map(), // map
1051 _uri_map.urid_unmap(), // unmap
1053 NULL, // uri (NULL = use file URI)
1054 bundle.c_str(), // dir
1055 file_name.c_str() // filename
1058 lilv_state_free(state);
1060 return Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
1064 LV2Plugin::do_remove_preset(string name)
1066 string preset_file = Glib::build_filename(
1067 Glib::get_home_dir(),
1068 Glib::build_filename(
1069 Glib::build_filename(".lv2", "presets"),
1073 unlink(preset_file.c_str());
1077 LV2Plugin::has_editor() const
1079 return _impl->ui != NULL;
1083 LV2Plugin::has_message_output() const
1085 for (uint32_t i = 0; i < num_ports(); ++i) {
1086 if ((_port_flags[i] & PORT_SEQUENCE) &&
1087 (_port_flags[i] & PORT_OUTPUT)) {
1095 LV2Plugin::write_to(RingBuffer<uint8_t>* dest,
1099 const uint8_t* body)
1101 const uint32_t buf_size = sizeof(UIMessage) + size;
1102 uint8_t buf[buf_size];
1104 UIMessage* msg = (UIMessage*)buf;
1106 msg->protocol = protocol;
1108 memcpy(msg + 1, body, size);
1110 return (dest->write(buf, buf_size) == buf_size);
1114 LV2Plugin::write_from_ui(uint32_t index,
1117 const uint8_t* body)
1120 _from_ui = new RingBuffer<uint8_t>(
1121 _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS);
1124 if (!write_to(_from_ui, index, protocol, size, body)) {
1125 error << "Error writing from UI to plugin" << endmsg;
1132 LV2Plugin::write_to_ui(uint32_t index,
1135 const uint8_t* body)
1137 if (!write_to(_to_ui, index, protocol, size, body)) {
1138 error << "Error writing from plugin to UI" << endmsg;
1145 LV2Plugin::enable_ui_emmission()
1148 _to_ui = new RingBuffer<uint8_t>(
1149 _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS);
1154 LV2Plugin::emit_to_ui(void* controller, UIMessageSink sink)
1160 uint32_t read_space = _to_ui->read_space();
1161 while (read_space > sizeof(UIMessage)) {
1163 if (_to_ui->read((uint8_t*)&msg, sizeof(msg)) != sizeof(msg)) {
1164 error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
1167 uint8_t body[msg.size];
1168 if (_to_ui->read(body, msg.size) != msg.size) {
1169 error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
1173 sink(controller, msg.index, msg.size, msg.protocol, body);
1175 read_space -= sizeof(msg) + msg.size;
1180 LV2Plugin::work(uint32_t size, const void* data)
1182 return _impl->work_iface->work(
1183 _impl->instance->lv2_handle, work_respond, this, size, data);
1187 LV2Plugin::work_response(uint32_t size, const void* data)
1189 return _impl->work_iface->work_response(
1190 _impl->instance->lv2_handle, size, data);
1194 LV2Plugin::set_insert_info(const PluginInsert* insert)
1196 _insert_id = insert->id();
1200 LV2Plugin::set_state(const XMLNode& node, int version)
1203 const XMLProperty* prop;
1204 XMLNodeConstIterator iter;
1209 LocaleGuard lg(X_("POSIX"));
1211 if (node.name() != state_node_name()) {
1212 error << _("Bad node sent to LV2Plugin::set_state") << endmsg;
1216 if (version < 3000) {
1217 nodes = node.children("port");
1219 nodes = node.children("Port");
1222 for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
1226 if ((prop = child->property("symbol")) != 0) {
1227 sym = prop->value().c_str();
1229 warning << _("LV2: port has no symbol, ignored") << endmsg;
1233 map<string, uint32_t>::iterator i = _port_indices.find(sym);
1235 if (i != _port_indices.end()) {
1236 port_id = i->second;
1238 warning << _("LV2: port has unknown index, ignored") << endmsg;
1242 if ((prop = child->property("value")) != 0) {
1243 value = prop->value().c_str();
1245 warning << _("LV2: port has no value, ignored") << endmsg;
1249 set_parameter(port_id, atof(value));
1253 if ((prop = node.property("state-dir")) != 0) {
1254 if (sscanf(prop->value().c_str(), "state%u", &_state_version) != 1) {
1255 error << string_compose(
1256 "LV2: failed to parse state version from \"%1\"",
1257 prop->value()) << endmsg;
1260 std::string state_file = Glib::build_filename(
1262 Glib::build_filename(prop->value(), "state.ttl"));
1264 LilvState* state = lilv_state_new_from_file(
1265 _world.world, _uri_map.urid_map(), NULL, state_file.c_str());
1267 lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
1270 latency_compute_run();
1272 return Plugin::set_state(node, version);
1276 LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) const
1278 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, which);
1280 LilvNode *def, *min, *max;
1281 lilv_port_get_range(_impl->plugin, port, &def, &min, &max);
1283 desc.integer_step = lilv_port_has_property(_impl->plugin, port, _world.lv2_integer);
1284 desc.toggled = lilv_port_has_property(_impl->plugin, port, _world.lv2_toggled);
1285 desc.logarithmic = lilv_port_has_property(_impl->plugin, port, _world.ext_logarithmic);
1286 desc.sr_dependent = lilv_port_has_property(_impl->plugin, port, _world.lv2_sampleRate);
1287 desc.label = lilv_node_as_string(lilv_port_get_name(_impl->plugin, port));
1288 desc.lower = min ? lilv_node_as_float(min) : 0.0f;
1289 desc.upper = max ? lilv_node_as_float(max) : 1.0f;
1290 if (desc.sr_dependent) {
1291 desc.lower *= _session.frame_rate ();
1292 desc.upper *= _session.frame_rate ();
1295 desc.min_unbound = false; // TODO: LV2 extension required
1296 desc.max_unbound = false; // TODO: LV2 extension required
1298 if (desc.integer_step) {
1300 desc.smallstep = 0.1;
1301 desc.largestep = 10.0;
1303 const float delta = desc.upper - desc.lower;
1304 desc.step = delta / 1000.0f;
1305 desc.smallstep = delta / 10000.0f;
1306 desc.largestep = delta / 10.0f;
1309 desc.enumeration = lilv_port_has_property(_impl->plugin, port, _world.lv2_enumeration);
1311 lilv_node_free(def);
1312 lilv_node_free(min);
1313 lilv_node_free(max);
1319 LV2Plugin::describe_parameter(Evoral::Parameter which)
1321 if (( which.type() == PluginAutomation) && ( which.id() < parameter_count()) ) {
1322 LilvNode* name = lilv_port_get_name(_impl->plugin,
1323 lilv_plugin_get_port_by_index(_impl->plugin, which.id()));
1324 string ret(lilv_node_as_string(name));
1325 lilv_node_free(name);
1333 LV2Plugin::signal_latency() const
1335 if (_latency_control_port) {
1336 return (framecnt_t)floor(*_latency_control_port);
1342 set<Evoral::Parameter>
1343 LV2Plugin::automatable() const
1345 set<Evoral::Parameter> ret;
1347 for (uint32_t i = 0; i < parameter_count(); ++i) {
1348 if (parameter_is_input(i) && parameter_is_control(i)) {
1349 ret.insert(ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
1357 LV2Plugin::activate()
1359 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 activate\n", name()));
1361 if (!_was_activated) {
1362 lilv_instance_activate(_impl->instance);
1363 _was_activated = true;
1368 LV2Plugin::deactivate()
1370 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 deactivate\n", name()));
1372 if (_was_activated) {
1373 lilv_instance_deactivate(_impl->instance);
1374 _was_activated = false;
1379 LV2Plugin::cleanup()
1381 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 cleanup\n", name()));
1385 lilv_instance_free(_impl->instance);
1386 _impl->instance = NULL;
1390 LV2Plugin::allocate_atom_event_buffers()
1392 /* reserve local scratch buffers for ATOM event-queues */
1393 const LilvPlugin* p = _impl->plugin;
1395 /* count non-MIDI atom event-ports
1396 * TODO: nicely ask drobilla to make a lilv_ call for that
1398 int count_atom_out = 0;
1399 int count_atom_in = 0;
1400 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
1401 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
1402 if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
1403 LilvNodes* buffer_types = lilv_port_get_value(
1404 p, port, _world.atom_bufferType);
1405 LilvNodes* atom_supports = lilv_port_get_value(
1406 p, port, _world.atom_supports);
1408 if (!lilv_nodes_contains(buffer_types, _world.atom_Sequence)
1409 || !lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
1410 if (lilv_port_is_a(p, port, _world.lv2_InputPort)) {
1413 if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
1417 lilv_nodes_free(buffer_types);
1418 lilv_nodes_free(atom_supports);
1422 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 need buffers for %2 atom-in and %3 atom-out event-ports\n",
1423 name(), count_atom_in, count_atom_out));
1425 const int total_atom_buffers = (count_atom_in + count_atom_out);
1426 if (_atom_ev_buffers || total_atom_buffers == 0) {
1430 DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers\n", total_atom_buffers));
1431 _atom_ev_buffers = (LV2_Evbuf**) malloc((total_atom_buffers + 1) * sizeof(LV2_Evbuf*));
1432 for (int i = 0; i < total_atom_buffers; ++i ) {
1433 _atom_ev_buffers[i] = lv2_evbuf_new(32768, LV2_EVBUF_ATOM,
1434 LV2Plugin::urids.atom_Chunk, LV2Plugin::urids.atom_Sequence);
1436 _atom_ev_buffers[total_atom_buffers] = 0;
1440 /** Write an ardour position/time/tempo/meter as an LV2 event.
1441 * @return true on success.
1444 write_position(LV2_Atom_Forge* forge,
1446 const TempoMetric& t,
1447 Timecode::BBT_Time& bbt,
1449 framepos_t position,
1452 uint8_t pos_buf[256];
1453 lv2_atom_forge_set_buffer(forge, pos_buf, sizeof(pos_buf));
1454 LV2_Atom_Forge_Frame frame;
1455 lv2_atom_forge_blank(forge, &frame, 1, LV2Plugin::urids.time_Position);
1456 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_frame, 0);
1457 lv2_atom_forge_long(forge, position);
1458 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_speed, 0);
1459 lv2_atom_forge_float(forge, speed);
1460 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_barBeat, 0);
1461 lv2_atom_forge_float(forge, bbt.beats - 1 +
1462 (bbt.ticks / Timecode::BBT_Time::ticks_per_beat));
1463 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_bar, 0);
1464 lv2_atom_forge_long(forge, bbt.bars - 1);
1465 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_beatUnit, 0);
1466 lv2_atom_forge_int(forge, t.meter().note_divisor());
1467 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_beatsPerBar, 0);
1468 lv2_atom_forge_float(forge, t.meter().divisions_per_bar());
1469 lv2_atom_forge_property_head(forge, LV2Plugin::urids.time_beatsPerMinute, 0);
1470 lv2_atom_forge_float(forge, t.tempo().beats_per_minute());
1472 LV2_Evbuf_Iterator end = lv2_evbuf_end(buf);
1473 const LV2_Atom* const atom = (const LV2_Atom*)pos_buf;
1474 return lv2_evbuf_write(&end, offset, 0, atom->type, atom->size,
1475 (const uint8_t*)(atom + 1));
1479 LV2Plugin::connect_and_run(BufferSet& bufs,
1480 ChanMapping in_map, ChanMapping out_map,
1481 pframes_t nframes, framecnt_t offset)
1483 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 run %2 offset %3\n", name(), nframes, offset));
1484 Plugin::connect_and_run(bufs, in_map, out_map, nframes, offset);
1486 cycles_t then = get_cycles();
1488 TempoMap& tmap = _session.tempo_map();
1489 Metrics::const_iterator metric_i = tmap.metrics_end();
1490 TempoMetric tmetric = tmap.metric_at(_session.transport_frame(), &metric_i);
1492 if (_freewheel_control_port) {
1493 *_freewheel_control_port = _session.engine().freewheeling();
1496 if (_bpm_control_port) {
1497 *_bpm_control_port = tmetric.tempo().beats_per_minute();
1500 ChanCount bufs_count;
1501 bufs_count.set(DataType::AUDIO, 1);
1502 bufs_count.set(DataType::MIDI, 1);
1503 BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
1504 BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
1505 uint32_t const num_ports = parameter_count();
1506 uint32_t const nil_index = std::numeric_limits<uint32_t>::max();
1508 uint32_t audio_in_index = 0;
1509 uint32_t audio_out_index = 0;
1510 uint32_t midi_in_index = 0;
1511 uint32_t midi_out_index = 0;
1512 uint32_t atom_port_index = 0;
1513 for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
1515 uint32_t index = nil_index;
1516 PortFlags flags = _port_flags[port_index];
1518 if (flags & PORT_AUDIO) {
1519 if (flags & PORT_INPUT) {
1520 index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
1522 ? bufs.get_audio(index).data(offset)
1523 : silent_bufs.get_audio(0).data(offset);
1525 index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
1527 ? bufs.get_audio(index).data(offset)
1528 : scratch_bufs.get_audio(0).data(offset);
1530 } else if (flags & (PORT_EVENT|PORT_SEQUENCE)) {
1531 /* FIXME: The checks here for bufs.count().n_midi() > index shouldn't
1532 be necessary, but the mapping is illegal in some cases. Ideally
1533 that should be fixed, but this is easier...
1535 if (flags & PORT_MIDI) {
1536 if (flags & PORT_INPUT) {
1537 index = in_map.get(DataType::MIDI, midi_in_index++, &valid);
1539 index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
1541 if (valid && bufs.count().n_midi() > index) {
1542 _ev_buffers[port_index] = bufs.get_lv2_midi(
1543 (flags & PORT_INPUT), index, (flags & PORT_EVENT));
1545 } else if ((flags & PORT_POSITION) && (flags & PORT_INPUT)) {
1546 lv2_evbuf_reset(_atom_ev_buffers[atom_port_index], true);
1547 _ev_buffers[port_index] = _atom_ev_buffers[atom_port_index++];
1551 if (valid && (flags & PORT_INPUT)) {
1552 Timecode::BBT_Time bbt;
1553 if ((flags & PORT_POSITION)) {
1554 if (_session.transport_frame() != _next_cycle_start ||
1555 _session.transport_speed() != _next_cycle_speed) {
1556 // Transport has changed, write position at cycle start
1557 tmap.bbt_time(_session.transport_frame(), bbt);
1558 write_position(&_impl->forge, _ev_buffers[port_index],
1559 tmetric, bbt, _session.transport_speed(),
1560 _session.transport_frame(), 0);
1564 // Get MIDI iterator range (empty range if no MIDI)
1565 MidiBuffer::iterator m = (index != nil_index)
1566 ? bufs.get_midi(index).begin()
1567 : silent_bufs.get_midi(0).end();
1568 MidiBuffer::iterator m_end = (index != nil_index)
1569 ? bufs.get_midi(index).end()
1572 // Now merge MIDI and any transport events into the buffer
1573 const uint32_t type = LV2Plugin::urids.midi_MidiEvent;
1574 const framepos_t tend = _session.transport_frame() + nframes;
1576 while (m != m_end || (metric_i != tmap.metrics_end() &&
1577 (*metric_i)->frame() < tend)) {
1578 MetricSection* metric = (metric_i != tmap.metrics_end())
1580 if (m != m_end && (!metric || metric->frame() > (*m).time())) {
1581 const Evoral::MIDIEvent<framepos_t> ev(*m, false);
1582 LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
1583 lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
1586 tmetric.set_metric(metric);
1587 bbt = metric->start();
1588 write_position(&_impl->forge, _ev_buffers[port_index],
1589 tmetric, bbt, _session.transport_speed(),
1591 metric->frame() - _session.transport_frame());
1595 } else if (!valid) {
1596 // Nothing we understand or care about, connect to scratch
1597 _ev_buffers[port_index] = silent_bufs.get_lv2_midi(
1598 (flags & PORT_INPUT), 0, (flags & PORT_EVENT));
1600 buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
1602 continue; // Control port, leave buffer alone
1604 lilv_instance_connect_port(_impl->instance, port_index, buf);
1607 // Read messages from UI and push into appropriate buffers
1609 uint32_t read_space = _from_ui->read_space();
1610 while (read_space > sizeof(UIMessage)) {
1612 if (_from_ui->read((uint8_t*)&msg, sizeof(msg)) != sizeof(msg)) {
1613 error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
1616 uint8_t body[msg.size];
1617 if (_from_ui->read(body, msg.size) != msg.size) {
1618 error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
1621 if (msg.protocol == urids.atom_eventTransfer) {
1622 LV2_Evbuf* buf = _ev_buffers[msg.index];
1623 LV2_Evbuf_Iterator i = lv2_evbuf_end(buf);
1624 const LV2_Atom* const atom = (const LV2_Atom*)body;
1625 if (!lv2_evbuf_write(&i, nframes, 0, atom->type, atom->size,
1626 (const uint8_t*)(atom + 1))) {
1627 error << "Failed to write data to LV2 event buffer\n";
1630 error << "Received unknown message type from UI" << endmsg;
1632 read_space -= sizeof(UIMessage) + msg.size;
1639 for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
1640 PortFlags flags = _port_flags[port_index];
1643 // Flush MIDI (write back to Ardour MIDI buffers)
1644 if ((flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
1645 const uint32_t buf_index = out_map.get(
1646 DataType::MIDI, midi_out_index++, &valid);
1648 bufs.flush_lv2_midi(true, buf_index);
1652 // Write messages to UI
1653 if (_to_ui && (flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
1654 LV2_Evbuf* buf = _ev_buffers[port_index];
1655 for (LV2_Evbuf_Iterator i = lv2_evbuf_begin(buf);
1656 lv2_evbuf_is_valid(i);
1657 i = lv2_evbuf_next(i)) {
1658 uint32_t frames, subframes, type, size;
1660 lv2_evbuf_get(i, &frames, &subframes, &type, &size, &data);
1661 write_to_ui(port_index, urids.atom_eventTransfer,
1662 size + sizeof(LV2_Atom),
1663 data - sizeof(LV2_Atom));
1668 cycles_t now = get_cycles();
1669 set_cycles((uint32_t)(now - then));
1671 // Update expected transport information for next cycle so we can detect changes
1672 _next_cycle_speed = _session.transport_speed();
1673 _next_cycle_start = _session.transport_frame() + (nframes * _next_cycle_speed);
1679 LV2Plugin::parameter_is_control(uint32_t param) const
1681 assert(param < _port_flags.size());
1682 return _port_flags[param] & PORT_CONTROL;
1686 LV2Plugin::parameter_is_audio(uint32_t param) const
1688 assert(param < _port_flags.size());
1689 return _port_flags[param] & PORT_AUDIO;
1693 LV2Plugin::parameter_is_event(uint32_t param) const
1695 assert(param < _port_flags.size());
1696 return _port_flags[param] & PORT_EVENT;
1700 LV2Plugin::parameter_is_output(uint32_t param) const
1702 assert(param < _port_flags.size());
1703 return _port_flags[param] & PORT_OUTPUT;
1707 LV2Plugin::parameter_is_input(uint32_t param) const
1709 assert(param < _port_flags.size());
1710 return _port_flags[param] & PORT_INPUT;
1714 LV2Plugin::print_parameter(uint32_t param, char* buf, uint32_t len) const
1717 if (param < parameter_count()) {
1718 snprintf(buf, len, "%.3f", get_parameter(param));
1725 boost::shared_ptr<Plugin::ScalePoints>
1726 LV2Plugin::get_scale_points(uint32_t port_index) const
1728 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, port_index);
1729 LilvScalePoints* points = lilv_port_get_scale_points(_impl->plugin, port);
1731 boost::shared_ptr<Plugin::ScalePoints> ret;
1736 ret = boost::shared_ptr<Plugin::ScalePoints>(new ScalePoints());
1738 LILV_FOREACH(scale_points, i, points) {
1739 const LilvScalePoint* p = lilv_scale_points_get(points, i);
1740 const LilvNode* label = lilv_scale_point_get_label(p);
1741 const LilvNode* value = lilv_scale_point_get_value(p);
1742 if (label && (lilv_node_is_float(value) || lilv_node_is_int(value))) {
1743 ret->insert(make_pair(lilv_node_as_string(label),
1744 lilv_node_as_float(value)));
1748 lilv_scale_points_free(points);
1753 LV2Plugin::run(pframes_t nframes)
1755 uint32_t const N = parameter_count();
1756 for (uint32_t i = 0; i < N; ++i) {
1757 if (parameter_is_control(i) && parameter_is_input(i)) {
1758 _control_data[i] = _shadow_data[i];
1762 lilv_instance_run(_impl->instance, nframes);
1764 if (_impl->work_iface) {
1765 _worker->emit_responses();
1766 if (_impl->work_iface->end_run) {
1767 _impl->work_iface->end_run(_impl->instance->lv2_handle);
1773 LV2Plugin::latency_compute_run()
1775 if (!_latency_control_port) {
1779 // Run the plugin so that it can set its latency parameter
1783 uint32_t port_index = 0;
1784 uint32_t in_index = 0;
1785 uint32_t out_index = 0;
1787 const framecnt_t bufsize = 1024;
1788 float buffer[bufsize];
1790 memset(buffer, 0, sizeof(float) * bufsize);
1792 // FIXME: Ensure plugins can handle in-place processing
1796 while (port_index < parameter_count()) {
1797 if (parameter_is_audio(port_index)) {
1798 if (parameter_is_input(port_index)) {
1799 lilv_instance_connect_port(_impl->instance, port_index, buffer);
1801 } else if (parameter_is_output(port_index)) {
1802 lilv_instance_connect_port(_impl->instance, port_index, buffer);
1814 LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** bufptr)
1816 const LilvPort* port = NULL;
1817 LilvNode* designation = lilv_new_uri(_world.world, uri);
1818 port = lilv_plugin_get_port_by_designation(
1819 plugin, _world.lv2_InputPort, designation);
1820 lilv_node_free(designation);
1822 bufptrs[lilv_port_get_index(plugin, port)] = bufptr;
1827 LV2World::LV2World()
1828 : world(lilv_world_new())
1830 lilv_world_load_all(world);
1831 atom_AtomPort = lilv_new_uri(world, LV2_ATOM__AtomPort);
1832 atom_Chunk = lilv_new_uri(world, LV2_ATOM__Chunk);
1833 atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence);
1834 atom_bufferType = lilv_new_uri(world, LV2_ATOM__bufferType);
1835 atom_supports = lilv_new_uri(world, LV2_ATOM__supports);
1836 atom_eventTransfer = lilv_new_uri(world, LV2_ATOM__eventTransfer);
1837 ev_EventPort = lilv_new_uri(world, LILV_URI_EVENT_PORT);
1838 ext_logarithmic = lilv_new_uri(world, LV2_PORT_PROPS__logarithmic);
1839 lv2_AudioPort = lilv_new_uri(world, LILV_URI_AUDIO_PORT);
1840 lv2_ControlPort = lilv_new_uri(world, LILV_URI_CONTROL_PORT);
1841 lv2_InputPort = lilv_new_uri(world, LILV_URI_INPUT_PORT);
1842 lv2_OutputPort = lilv_new_uri(world, LILV_URI_OUTPUT_PORT);
1843 lv2_inPlaceBroken = lilv_new_uri(world, LV2_CORE__inPlaceBroken);
1844 lv2_integer = lilv_new_uri(world, LV2_CORE__integer);
1845 lv2_sampleRate = lilv_new_uri(world, LV2_CORE__sampleRate);
1846 lv2_toggled = lilv_new_uri(world, LV2_CORE__toggled);
1847 lv2_enumeration = lilv_new_uri(world, LV2_CORE__enumeration);
1848 midi_MidiEvent = lilv_new_uri(world, LILV_URI_MIDI_EVENT);
1849 rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
1850 time_Position = lilv_new_uri(world, LV2_TIME__Position);
1851 ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI);
1852 ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
1855 LV2World::~LV2World()
1857 lilv_node_free(ui_external);
1858 lilv_node_free(ui_GtkUI);
1859 lilv_node_free(midi_MidiEvent);
1860 lilv_node_free(lv2_toggled);
1861 lilv_node_free(lv2_sampleRate);
1862 lilv_node_free(lv2_integer);
1863 lilv_node_free(lv2_inPlaceBroken);
1864 lilv_node_free(lv2_OutputPort);
1865 lilv_node_free(lv2_InputPort);
1866 lilv_node_free(lv2_ControlPort);
1867 lilv_node_free(lv2_AudioPort);
1868 lilv_node_free(ext_logarithmic);
1869 lilv_node_free(ev_EventPort);
1870 lilv_node_free(atom_eventTransfer);
1871 lilv_node_free(atom_bufferType);
1872 lilv_node_free(atom_Sequence);
1873 lilv_node_free(atom_Chunk);
1874 lilv_node_free(atom_AtomPort);
1877 LV2PluginInfo::LV2PluginInfo (const void* c_plugin)
1878 : _c_plugin(c_plugin)
1883 LV2PluginInfo::~LV2PluginInfo()
1887 LV2PluginInfo::load(Session& session)
1892 plugin.reset(new LV2Plugin(session.engine(), session,
1893 (const LilvPlugin*)_c_plugin,
1894 session.frame_rate()));
1896 plugin->set_info(PluginInfoPtr(new LV2PluginInfo(*this)));
1898 } catch (failed_constructor& err) {
1899 return PluginPtr((Plugin*)0);
1906 LV2PluginInfo::discover()
1908 PluginInfoList* plugs = new PluginInfoList;
1909 const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world);
1911 info << "LV2: Discovering " << lilv_plugins_size(plugins) << " plugins" << endmsg;
1913 LILV_FOREACH(plugins, i, plugins) {
1914 const LilvPlugin* p = lilv_plugins_get(plugins, i);
1915 LV2PluginInfoPtr info(new LV2PluginInfo((const void*)p));
1917 LilvNode* name = lilv_plugin_get_name(p);
1918 if (!name || !lilv_plugin_get_port_by_index(p, 0)) {
1919 warning << "Ignoring invalid LV2 plugin "
1920 << lilv_node_as_string(lilv_plugin_get_uri(p))
1927 info->name = string(lilv_node_as_string(name));
1928 lilv_node_free(name);
1930 const LilvPluginClass* pclass = lilv_plugin_get_class(p);
1931 const LilvNode* label = lilv_plugin_class_get_label(pclass);
1932 info->category = lilv_node_as_string(label);
1934 LilvNode* author_name = lilv_plugin_get_author_name(p);
1935 info->creator = author_name ? string(lilv_node_as_string(author_name)) : "Unknown";
1936 lilv_node_free(author_name);
1938 info->path = "/NOPATH"; // Meaningless for LV2
1940 /* count atom-event-ports that feature
1941 * atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent>
1943 * TODO: nicely ask drobilla to make a lilv_ call for that
1945 int count_midi_out = 0;
1946 int count_midi_in = 0;
1947 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
1948 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
1949 if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
1950 LilvNodes* buffer_types = lilv_port_get_value(
1951 p, port, _world.atom_bufferType);
1952 LilvNodes* atom_supports = lilv_port_get_value(
1953 p, port, _world.atom_supports);
1955 if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)
1956 && lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
1957 if (lilv_port_is_a(p, port, _world.lv2_InputPort)) {
1960 if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
1964 lilv_nodes_free(buffer_types);
1965 lilv_nodes_free(atom_supports);
1969 info->n_inputs.set_audio(
1970 lilv_plugin_get_num_ports_of_class(
1971 p, _world.lv2_InputPort, _world.lv2_AudioPort, NULL));
1972 info->n_inputs.set_midi(
1973 lilv_plugin_get_num_ports_of_class(
1974 p, _world.lv2_InputPort, _world.ev_EventPort, NULL)
1977 info->n_outputs.set_audio(
1978 lilv_plugin_get_num_ports_of_class(
1979 p, _world.lv2_OutputPort, _world.lv2_AudioPort, NULL));
1980 info->n_outputs.set_midi(
1981 lilv_plugin_get_num_ports_of_class(
1982 p, _world.lv2_OutputPort, _world.ev_EventPort, NULL)
1985 info->unique_id = lilv_node_as_uri(lilv_plugin_get_uri(p));
1986 info->index = 0; // Meaningless for LV2
1988 plugs->push_back(info);