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.
29 #include "pbd/gstdio_compat.h"
30 #include <glib/gprintf.h>
33 #include <boost/utility.hpp>
35 #include "pbd/file_utils.h"
36 #include "pbd/stl_delete.h"
37 #include "pbd/compose.h"
38 #include "pbd/error.h"
39 #include "pbd/locale_guard.h"
40 #include "pbd/replace_all.h"
41 #include "pbd/xml++.h"
43 #ifdef PLATFORM_WINDOWS
44 #include <shlobj.h> // CSIDL_*
45 #include "pbd/windows_special_dirs.h"
48 #include "libardour-config.h"
50 #include "ardour/audio_buffer.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/debug.h"
53 #include "ardour/lv2_plugin.h"
54 #include "ardour/midi_patch_manager.h"
55 #include "ardour/session.h"
56 #include "ardour/tempo.h"
57 #include "ardour/types.h"
58 #include "ardour/utils.h"
59 #include "ardour/worker.h"
60 #include "ardour/search_paths.h"
65 #include <lilv/lilv.h>
67 #include "lv2/lv2plug.in/ns/ext/atom/atom.h"
68 #include "lv2/lv2plug.in/ns/ext/atom/forge.h"
69 #include "lv2/lv2plug.in/ns/ext/log/log.h"
70 #include "lv2/lv2plug.in/ns/ext/midi/midi.h"
71 #include "lv2/lv2plug.in/ns/ext/port-props/port-props.h"
72 #include "lv2/lv2plug.in/ns/ext/presets/presets.h"
73 #include "lv2/lv2plug.in/ns/ext/state/state.h"
74 #include "lv2/lv2plug.in/ns/ext/time/time.h"
75 #include "lv2/lv2plug.in/ns/ext/worker/worker.h"
76 #include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h"
77 #include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
78 #include "lv2/lv2plug.in/ns/extensions/units/units.h"
79 #include "lv2/lv2plug.in/ns/ext/patch/patch.h"
80 #include "lv2/lv2plug.in/ns/ext/port-groups/port-groups.h"
82 #include "lv2/lv2plug.in/ns/ext/buf-size/buf-size.h"
83 #include "lv2/lv2plug.in/ns/ext/options/options.h"
86 #include "lv2_evbuf.h"
89 #include <suil/suil.h>
92 // Compatibility for old LV2
93 #ifndef LV2_ATOM_CONTENTS_CONST
94 #define LV2_ATOM_CONTENTS_CONST(type, atom) \
95 ((const void*)((const uint8_t*)(atom) + sizeof(type)))
97 #ifndef LV2_ATOM_BODY_CONST
98 #define LV2_ATOM_BODY_CONST(atom) LV2_ATOM_CONTENTS_CONST(LV2_Atom, atom)
100 #ifndef LV2_PATCH__property
101 #define LV2_PATCH__property LV2_PATCH_PREFIX "property"
103 #ifndef LV2_PATCH__value
104 #define LV2_PATCH__value LV2_PATCH_PREFIX "value"
106 #ifndef LV2_PATCH__writable
107 #define LV2_PATCH__writable LV2_PATCH_PREFIX "writable"
110 /** The number of MIDI buffers that will fit in a UI/worker comm buffer.
111 This needs to be roughly the number of cycles the UI will get around to
112 actually processing the traffic. Lower values are flakier but save memory.
114 static const size_t NBUFS = 4;
117 using namespace ARDOUR;
120 bool LV2Plugin::force_state_save = false;
122 class LV2World : boost::noncopyable {
127 void load_bundled_plugins(bool verbose=false);
131 LilvNode* atom_AtomPort;
132 LilvNode* atom_Chunk;
133 LilvNode* atom_Sequence;
134 LilvNode* atom_bufferType;
135 LilvNode* atom_eventTransfer;
136 LilvNode* atom_supports;
137 LilvNode* ev_EventPort;
138 LilvNode* ext_logarithmic;
139 LilvNode* ext_notOnGUI;
140 LilvNode* ext_expensive;
141 LilvNode* ext_causesArtifacts;
142 LilvNode* ext_notAutomatic;
143 LilvNode* ext_rangeSteps;
144 LilvNode* groups_group;
145 LilvNode* groups_element;
146 LilvNode* lv2_AudioPort;
147 LilvNode* lv2_ControlPort;
148 LilvNode* lv2_InputPort;
149 LilvNode* lv2_OutputPort;
150 LilvNode* lv2_designation;
151 LilvNode* lv2_enumeration;
152 LilvNode* lv2_freewheeling;
153 LilvNode* lv2_inPlaceBroken;
154 LilvNode* lv2_isSideChain;
156 LilvNode* lv2_integer;
157 LilvNode* lv2_default;
158 LilvNode* lv2_minimum;
159 LilvNode* lv2_maximum;
160 LilvNode* lv2_reportsLatency;
161 LilvNode* lv2_sampleRate;
162 LilvNode* lv2_toggled;
163 LilvNode* midi_MidiEvent;
164 LilvNode* rdfs_comment;
165 LilvNode* rdfs_label;
166 LilvNode* rdfs_range;
167 LilvNode* rsz_minimumSize;
168 LilvNode* time_Position;
170 LilvNode* ui_external;
171 LilvNode* ui_externalkx;
174 LilvNode* units_unit;
175 LilvNode* units_render;
176 LilvNode* units_midiNote;
177 LilvNode* patch_writable;
178 LilvNode* patch_Message;
179 #ifdef HAVE_LV2_1_2_0
180 LilvNode* bufz_powerOf2BlockLength;
181 LilvNode* bufz_fixedBlockLength;
182 LilvNode* bufz_nominalBlockLength;
183 LilvNode* bufz_coarseBlockLength;
186 #ifdef HAVE_LV2_1_10_0
188 LilvNode* atom_float;
189 LilvNode* atom_object; // new in 1.8
190 LilvNode* atom_vector;
193 LilvNode* lv2_noSampleAccurateCtrl;
194 LilvNode* auto_can_write_automatation; // lv2:optionalFeature
195 LilvNode* auto_automation_control; // atom:supports
196 LilvNode* auto_automation_controlled; // lv2:portProperty
197 LilvNode* auto_automation_controller; // lv2:portProperty
198 LilvNode* inline_display_in_gui; // lv2:optionalFeature
202 bool _bundle_checked;
205 static LV2World _world;
207 /* worker extension */
209 /** Called by the plugin to schedule non-RT work. */
210 static LV2_Worker_Status
211 work_schedule(LV2_Worker_Schedule_Handle handle,
215 return (((Worker*)handle)->schedule(size, data)
217 : LV2_WORKER_ERR_UNKNOWN);
220 /** Called by the plugin to respond to non-RT work. */
221 static LV2_Worker_Status
222 work_respond(LV2_Worker_Respond_Handle handle,
226 return (((Worker*)handle)->respond(size, data)
228 : LV2_WORKER_ERR_UNKNOWN);
232 /* inline display extension */
234 queue_draw (LV2_Inline_Display_Handle handle)
236 LV2Plugin* plugin = (LV2Plugin*)handle;
237 plugin->QueueDraw(); /* EMIT SIGNAL */
241 midnam_update (LV2_Midnam_Handle handle)
243 LV2Plugin* plugin = (LV2Plugin*)handle;
244 plugin->UpdateMidnam (); /* EMIT SIGNAL */
251 log_vprintf(LV2_Log_Handle /*handle*/,
257 const int ret = g_vasprintf(&str, fmt, args);
258 /* strip trailing whitespace */
259 while (strlen (str) > 0 && isspace (str[strlen (str) - 1])) {
260 str[strlen (str) - 1] = '\0';
262 if (strlen (str) == 0) {
266 if (type == URIMap::instance().urids.log_Error) {
267 error << str << endmsg;
268 } else if (type == URIMap::instance().urids.log_Warning) {
269 warning << str << endmsg;
270 } else if (type == URIMap::instance().urids.log_Note) {
271 info << str << endmsg;
272 } else if (type == URIMap::instance().urids.log_Trace) {
273 DEBUG_TRACE(DEBUG::LV2, str);
279 log_printf(LV2_Log_Handle handle,
281 const char* fmt, ...)
285 const int ret = log_vprintf(handle, type, fmt, args);
290 struct LV2Plugin::Impl {
291 Impl() : plugin(0), ui(0), ui_type(0), name(0), author(0), instance(0)
293 #ifdef HAVE_LV2_1_2_0
298 #ifdef HAVE_LV2_1_2_0
307 /** Find the LV2 input port with the given designation.
308 * If found, bufptrs[port_index] will be set to bufptr.
310 const LilvPort* designated_input (const char* uri, void** bufptrs[], void** bufptr);
312 const LilvPlugin* plugin;
314 const LilvNode* ui_type;
317 LilvInstance* instance;
318 const LV2_Worker_Interface* work_iface;
319 #ifdef HAVE_LV2_1_2_0
320 const LV2_Options_Interface* opts_iface;
323 LV2_Atom_Forge forge;
324 LV2_Atom_Forge ui_forge;
325 int32_t block_length;
326 #ifdef HAVE_LV2_1_2_0
327 LV2_Options_Option* options;
330 LV2_Inline_Display* queue_draw;
335 LV2Plugin::LV2Plugin (AudioEngine& engine,
337 const void* c_plugin,
339 : Plugin (engine, session)
344 , _state_worker(NULL)
346 , _patch_port_in_index((uint32_t)-1)
347 , _patch_port_out_index((uint32_t)-1)
348 , _uri_map(URIMap::instance())
349 , _no_sample_accurate_ctrl (false)
351 init(c_plugin, rate);
354 LV2Plugin::LV2Plugin (const LV2Plugin& other)
360 , _state_worker(NULL)
361 , _insert_id(other._insert_id)
362 , _patch_port_in_index((uint32_t)-1)
363 , _patch_port_out_index((uint32_t)-1)
364 , _uri_map(URIMap::instance())
365 , _no_sample_accurate_ctrl (false)
367 init(other._impl->plugin, other._sample_rate);
369 for (uint32_t i = 0; i < parameter_count(); ++i) {
370 _control_data[i] = other._shadow_data[i];
371 _shadow_data[i] = other._shadow_data[i];
376 LV2Plugin::init(const void* c_plugin, framecnt_t rate)
378 DEBUG_TRACE(DEBUG::LV2, "init\n");
380 _impl->plugin = (const LilvPlugin*)c_plugin;
382 _impl->ui_type = NULL;
387 _atom_ev_buffers = 0;
389 _bpm_control_port = 0;
390 _freewheel_control_port = 0;
391 _latency_control_port = 0;
392 _next_cycle_start = std::numeric_limits<framepos_t>::max();
393 _next_cycle_speed = 1.0;
394 _seq_size = _engine.raw_buffer_size(DataType::MIDI);
396 _was_activated = false;
397 _has_state_interface = false;
398 _can_write_automation = false;
399 _inline_display_in_gui = false;
401 _current_latency = 0;
402 _impl->block_length = _session.get_block_size();
404 _instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
405 _data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
406 _make_path_feature.URI = LV2_STATE__makePath;
407 _log_feature.URI = LV2_LOG__log;
408 _work_schedule_feature.URI = LV2_WORKER__schedule;
409 _work_schedule_feature.data = NULL;
410 _def_state_feature.URI = LV2_STATE_PREFIX "loadDefaultState"; // Post LV2-1.2.0
411 _def_state_feature.data = NULL;
413 const LilvPlugin* plugin = _impl->plugin;
415 LilvNode* state_iface_uri = lilv_new_uri(_world.world, LV2_STATE__interface);
416 LilvNode* state_uri = lilv_new_uri(_world.world, LV2_STATE_URI);
417 _has_state_interface =
418 // What plugins should have (lv2:extensionData state:Interface)
419 lilv_plugin_has_extension_data(plugin, state_iface_uri)
420 // What some outdated/incorrect ones have
421 || lilv_plugin_has_feature(plugin, state_uri);
422 lilv_node_free(state_uri);
423 lilv_node_free(state_iface_uri);
425 _features = (LV2_Feature**)calloc(13, sizeof(LV2_Feature*));
426 _features[0] = &_instance_access_feature;
427 _features[1] = &_data_access_feature;
428 _features[2] = &_make_path_feature;
429 _features[3] = _uri_map.uri_map_feature();
430 _features[4] = _uri_map.urid_map_feature();
431 _features[5] = _uri_map.urid_unmap_feature();
432 _features[6] = &_log_feature;
434 unsigned n_features = 7;
435 #ifdef HAVE_LV2_1_2_0
436 _features[n_features++] = &_def_state_feature;
439 lv2_atom_forge_init(&_impl->forge, _uri_map.urid_map());
440 lv2_atom_forge_init(&_impl->ui_forge, _uri_map.urid_map());
443 _impl->queue_draw = (LV2_Inline_Display*)
444 malloc (sizeof(LV2_Inline_Display));
445 _impl->queue_draw->handle = this;
446 _impl->queue_draw->queue_draw = queue_draw;
448 _queue_draw_feature.URI = LV2_INLINEDISPLAY__queue_draw;
449 _queue_draw_feature.data = _impl->queue_draw;
450 _features[n_features++] = &_queue_draw_feature;
452 _impl->midnam = (LV2_Midnam*)
453 malloc (sizeof(LV2_Midnam));
454 _impl->midnam->handle = this;
455 _impl->midnam->update = midnam_update;
457 _midnam_feature.URI = LV2_MIDNAM__update;
458 _midnam_feature.data = _impl->midnam;
459 _features[n_features++] = &_midnam_feature;
462 #ifdef HAVE_LV2_1_2_0
463 LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int);
464 static const int32_t _min_block_length = 1; // may happen during split-cycles
465 static const int32_t _max_block_length = 8192; // max possible (with all engines and during export)
466 /* Consider updating max-block-size whenever the buffersize changes.
467 * It requires re-instantiating the plugin (which is a non-realtime operation),
468 * so it should be done lightly and only for plugins that require it.
470 * given that the block-size can change at any time (split-cycles) ardour currently
471 * does not support plugins that require bufz_fixedBlockLength.
473 LV2_Options_Option options[] = {
474 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__minBlockLength),
475 sizeof(int32_t), atom_Int, &_min_block_length },
476 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__maxBlockLength),
477 sizeof(int32_t), atom_Int, &_max_block_length },
478 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__sequenceSize),
479 sizeof(int32_t), atom_Int, &_seq_size },
480 { LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id("http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"),
481 sizeof(int32_t), atom_Int, &_impl->block_length },
482 { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL }
485 _impl->options = (LV2_Options_Option*) malloc (sizeof (options));
486 memcpy ((void*) _impl->options, (void*) options, sizeof (options));
488 _options_feature.URI = LV2_OPTIONS__options;
489 _options_feature.data = _impl->options;
490 _features[n_features++] = &_options_feature;
493 LV2_State_Make_Path* make_path = (LV2_State_Make_Path*)malloc(
494 sizeof(LV2_State_Make_Path));
495 make_path->handle = this;
496 make_path->path = &lv2_state_make_path;
497 _make_path_feature.data = make_path;
499 LV2_Log_Log* log = (LV2_Log_Log*)malloc(sizeof(LV2_Log_Log));
501 log->printf = &log_printf;
502 log->vprintf = &log_vprintf;
503 _log_feature.data = log;
505 const size_t ring_size = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS;
506 LilvNode* worker_schedule = lilv_new_uri(_world.world, LV2_WORKER__schedule);
507 if (lilv_plugin_has_feature(plugin, worker_schedule)) {
508 LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc(
509 sizeof(LV2_Worker_Schedule));
510 _worker = new Worker(this, ring_size);
511 schedule->handle = _worker;
512 schedule->schedule_work = work_schedule;
513 _work_schedule_feature.data = schedule;
514 _features[n_features++] = &_work_schedule_feature;
516 lilv_node_free(worker_schedule);
518 if (_has_state_interface) {
519 // Create a non-threaded worker for use by state restore
520 _state_worker = new Worker(this, ring_size, false);
523 _impl->instance = lilv_plugin_instantiate(plugin, rate, _features);
524 _impl->name = lilv_plugin_get_name(plugin);
525 _impl->author = lilv_plugin_get_author_name(plugin);
527 if (_impl->instance == 0) {
528 error << _("LV2: Failed to instantiate plugin ") << uri() << endmsg;
529 throw failed_constructor();
532 _instance_access_feature.data = (void*)_impl->instance->lv2_handle;
533 _data_access_extension_data.extension_data = _impl->instance->lv2_descriptor->extension_data;
534 _data_access_feature.data = &_data_access_extension_data;
536 LilvNode* worker_iface_uri = lilv_new_uri(_world.world, LV2_WORKER__interface);
537 if (lilv_plugin_has_extension_data(plugin, worker_iface_uri)) {
538 _impl->work_iface = (const LV2_Worker_Interface*)extension_data(
539 LV2_WORKER__interface);
541 lilv_node_free(worker_iface_uri);
544 #ifdef HAVE_LV2_1_2_0
545 LilvNode* options_iface_uri = lilv_new_uri(_world.world, LV2_OPTIONS__interface);
546 if (lilv_plugin_has_extension_data(plugin, options_iface_uri)) {
547 _impl->opts_iface = (const LV2_Options_Interface*)extension_data(
548 LV2_OPTIONS__interface);
550 lilv_node_free(options_iface_uri);
554 _display_interface = (const LV2_Inline_Display_Interface*)
555 extension_data (LV2_INLINEDISPLAY__interface);
557 _midname_interface = (const LV2_Midnam_Interface*)
558 extension_data (LV2_MIDNAM__interface);
559 if (_midname_interface) {
564 if (lilv_plugin_has_feature(plugin, _world.lv2_inPlaceBroken)) {
565 error << string_compose(
566 _("LV2: \"%1\" cannot be used, since it cannot do inplace processing."),
567 lilv_node_as_string(_impl->name)) << endmsg;
568 lilv_node_free(_impl->name);
569 lilv_node_free(_impl->author);
570 throw failed_constructor();
573 #ifdef HAVE_LV2_1_2_0
574 LilvNodes *required_features = lilv_plugin_get_required_features (plugin);
575 if (lilv_nodes_contains (required_features, _world.bufz_powerOf2BlockLength) ||
576 lilv_nodes_contains (required_features, _world.bufz_fixedBlockLength)
578 error << string_compose(
579 _("LV2: \"%1\" buffer-size requirements cannot be satisfied."),
580 lilv_node_as_string(_impl->name)) << endmsg;
581 lilv_node_free(_impl->name);
582 lilv_node_free(_impl->author);
583 lilv_nodes_free(required_features);
584 throw failed_constructor();
586 lilv_nodes_free(required_features);
589 LilvNodes* optional_features = lilv_plugin_get_optional_features (plugin);
590 #ifdef HAVE_LV2_1_2_0
591 if (lilv_nodes_contains (optional_features, _world.bufz_coarseBlockLength)) {
592 _no_sample_accurate_ctrl = true;
596 if (lilv_nodes_contains (optional_features, _world.lv2_noSampleAccurateCtrl)) {
597 /* deprecated 2016-Sep-18 in favor of bufz_coarseBlockLength */
598 _no_sample_accurate_ctrl = true;
600 if (lilv_nodes_contains (optional_features, _world.auto_can_write_automatation)) {
601 _can_write_automation = true;
603 if (lilv_nodes_contains (optional_features, _world.inline_display_in_gui)) {
604 _inline_display_in_gui = true;
606 lilv_nodes_free(optional_features);
609 #ifdef HAVE_LILV_0_16_0
610 // Load default state
612 /* immediately schedule any work,
613 * so that state restore later will not find a busy
614 * worker. latency_compute_run() flushes any replies
616 _worker->set_synchronous(true);
618 LilvState* state = lilv_state_new_from_world(
619 _world.world, _uri_map.urid_map(), lilv_plugin_get_uri(_impl->plugin));
620 if (state && _has_state_interface) {
621 lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
623 lilv_state_free(state);
628 const uint32_t num_ports = this->num_ports();
629 for (uint32_t i = 0; i < num_ports; ++i) {
630 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, i);
632 size_t minimumSize = 0;
634 if (lilv_port_is_a(_impl->plugin, port, _world.lv2_OutputPort)) {
635 flags |= PORT_OUTPUT;
636 } else if (lilv_port_is_a(_impl->plugin, port, _world.lv2_InputPort)) {
639 error << string_compose(
640 "LV2: \"%1\" port %2 is neither input nor output",
641 lilv_node_as_string(_impl->name), i) << endmsg;
642 throw failed_constructor();
645 if (lilv_port_is_a(_impl->plugin, port, _world.lv2_ControlPort)) {
646 flags |= PORT_CONTROL;
647 } else if (lilv_port_is_a(_impl->plugin, port, _world.lv2_AudioPort)) {
649 } else if (lilv_port_is_a(_impl->plugin, port, _world.ev_EventPort)) {
651 flags |= PORT_MIDI; // We assume old event API ports are for MIDI
652 } else if (lilv_port_is_a(_impl->plugin, port, _world.atom_AtomPort)) {
653 LilvNodes* buffer_types = lilv_port_get_value(
654 _impl->plugin, port, _world.atom_bufferType);
655 LilvNodes* atom_supports = lilv_port_get_value(
656 _impl->plugin, port, _world.atom_supports);
658 if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
659 flags |= PORT_SEQUENCE;
660 if (lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
663 if (lilv_nodes_contains(atom_supports, _world.time_Position)) {
664 flags |= PORT_POSITION;
667 if (lilv_nodes_contains(atom_supports, _world.auto_automation_control)) {
668 flags |= PORT_AUTOCTRL;
671 if (lilv_nodes_contains(atom_supports, _world.patch_Message)) {
672 flags |= PORT_PATCHMSG;
673 if (flags & PORT_INPUT) {
674 _patch_port_in_index = i;
676 _patch_port_out_index = i;
680 LilvNodes* min_size_v = lilv_port_get_value(_impl->plugin, port, _world.rsz_minimumSize);
681 LilvNode* min_size = min_size_v ? lilv_nodes_get_first(min_size_v) : NULL;
682 if (min_size && lilv_node_is_int(min_size)) {
683 minimumSize = lilv_node_as_int(min_size);
685 lilv_nodes_free(min_size_v);
686 lilv_nodes_free(buffer_types);
687 lilv_nodes_free(atom_supports);
689 error << string_compose(
690 "LV2: \"%1\" port %2 has no known data type",
691 lilv_node_as_string(_impl->name), i) << endmsg;
692 throw failed_constructor();
695 if ((flags & PORT_INPUT) && (flags & PORT_CONTROL)) {
696 if (lilv_port_has_property(_impl->plugin, port, _world.ext_causesArtifacts)) {
697 flags |= PORT_NOAUTO;
699 if (lilv_port_has_property(_impl->plugin, port, _world.ext_notAutomatic)) {
700 flags |= PORT_NOAUTO;
702 if (lilv_port_has_property(_impl->plugin, port, _world.ext_expensive)) {
703 flags |= PORT_NOAUTO;
707 if (lilv_port_has_property(_impl->plugin, port, _world.auto_automation_controlled)) {
708 if ((flags & PORT_INPUT) && (flags & PORT_CONTROL)) {
709 flags |= PORT_CTRLED;
712 if (lilv_port_has_property(_impl->plugin, port, _world.auto_automation_controller)) {
713 if ((flags & PORT_INPUT) && (flags & PORT_CONTROL)) {
714 flags |= PORT_CTRLER;
719 _port_flags.push_back(flags);
720 _port_minimumSize.push_back(minimumSize);
721 DEBUG_TRACE(DEBUG::LV2, string_compose("port %1 buffer %2 bytes\n", i, minimumSize));
724 _control_data = new float[num_ports];
725 _shadow_data = new float[num_ports];
726 _defaults = new float[num_ports];
727 _ev_buffers = new LV2_Evbuf*[num_ports];
728 memset(_ev_buffers, 0, sizeof(LV2_Evbuf*) * num_ports);
730 const bool latent = lilv_plugin_has_latency(plugin);
731 const uint32_t latency_index = (latent)
732 ? lilv_plugin_get_latency_port_index(plugin)
735 // Build an array of pointers to special parameter buffers
736 void*** params = new void**[num_ports];
737 for (uint32_t i = 0; i < num_ports; ++i) {
740 _impl->designated_input (LV2_TIME__beatsPerMinute, params, (void**)&_bpm_control_port);
741 _impl->designated_input (LV2_CORE__freeWheeling, params, (void**)&_freewheel_control_port);
743 for (uint32_t i = 0; i < num_ports; ++i) {
744 const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
745 const LilvNode* sym = lilv_port_get_symbol(plugin, port);
747 // Store index in map so we can look up index by symbol
748 _port_indices.insert(std::make_pair(lilv_node_as_string(sym), i));
750 // Get range and default value if applicable
751 if (parameter_is_control(i)) {
753 lilv_port_get_range(plugin, port, &def, NULL, NULL);
754 _defaults[i] = def ? lilv_node_as_float(def) : 0.0f;
755 if (lilv_port_has_property (plugin, port, _world.lv2_sampleRate)) {
756 _defaults[i] *= _session.frame_rate ();
760 lilv_instance_connect_port(_impl->instance, i, &_control_data[i]);
762 if (latent && i == latency_index) {
764 lilv_port_get_range(_impl->plugin, port, NULL, NULL, &max);
765 _max_latency = max ? lilv_node_as_float(max) : .02 * _sample_rate;
766 _latency_control_port = &_control_data[i];
767 *_latency_control_port = 0;
770 if (parameter_is_input(i)) {
771 _shadow_data[i] = default_value(i);
773 *params[i] = (void*)&_shadow_data[i];
783 LilvUIs* uis = lilv_plugin_get_uis(plugin);
784 if (lilv_uis_size(uis) > 0) {
786 // Look for embeddable UI
787 LILV_FOREACH(uis, u, uis) {
788 const LilvUI* this_ui = lilv_uis_get(uis, u);
789 const LilvNode* this_ui_type = NULL;
790 if (lilv_ui_is_supported(this_ui,
794 // TODO: Multiple UI support
796 _impl->ui_type = this_ui_type;
801 // Look for Gtk native UI
802 LILV_FOREACH(uis, i, uis) {
803 const LilvUI* ui = lilv_uis_get(uis, i);
804 if (lilv_ui_is_a(ui, _world.ui_GtkUI)) {
806 _impl->ui_type = _world.ui_GtkUI;
812 // If Gtk UI is not available, try to find external UI
814 LILV_FOREACH(uis, i, uis) {
815 const LilvUI* ui = lilv_uis_get(uis, i);
816 if (lilv_ui_is_a(ui, _world.ui_externalkx)) {
818 _impl->ui_type = _world.ui_external;
821 if (lilv_ui_is_a(ui, _world.ui_external)) {
823 _impl->ui_type = _world.ui_external;
829 load_supported_properties(_property_descriptors);
830 allocate_atom_event_buffers();
831 latency_compute_run();
835 LV2Plugin::set_block_size (pframes_t nframes)
837 #ifdef HAVE_LV2_1_2_0
838 if (_impl->opts_iface) {
839 LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int);
840 _impl->block_length = nframes;
841 LV2_Options_Option block_size_option = {
842 LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id ("http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"),
843 sizeof(int32_t), atom_Int, (void*)&_impl->block_length
845 _impl->opts_iface->set (_impl->instance->lv2_handle, &block_size_option);
852 LV2Plugin::requires_fixed_sized_buffers () const
854 /* This controls if Ardour will split the plugin's run()
855 * on automation events in order to pass sample-accurate automation
856 * via standard control-ports.
858 * When returning true Ardour will *not* sub-divide the process-cycle.
859 * Automation events that happen between cycle-start and cycle-end will be
860 * ignored (ctrl values are interpolated to cycle-start).
861 * NB. Atom Sequences are still sample accurate.
863 * Note: This does not guarantee a fixed block-size.
864 * e.g The process cycle may be split when looping, also
865 * the period-size may change any time: see set_block_size()
867 if (get_info()->n_inputs.n_midi() > 0) {
868 /* we don't yet implement midi buffer offsets (for split cycles).
869 * Also connect_and_run() also uses _session.transport_frame() directly
870 * (for BBT) which is not offset for plugin cycle split.
874 return _no_sample_accurate_ctrl;
877 LV2Plugin::~LV2Plugin ()
879 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 destroy\n", name()));
886 std::stringstream ss;
889 MIDI::Name::MidiPatchManager::instance().remove_custom_midnam (ss.str());
893 lilv_instance_free(_impl->instance);
894 lilv_state_free(_impl->state);
895 lilv_node_free(_impl->name);
896 lilv_node_free(_impl->author);
897 #ifdef HAVE_LV2_1_2_0
898 free(_impl->options);
901 free(_impl->queue_draw);
906 free(_log_feature.data);
907 free(_make_path_feature.data);
908 free(_work_schedule_feature.data);
913 delete _state_worker;
915 if (_atom_ev_buffers) {
916 LV2_Evbuf** b = _atom_ev_buffers;
921 free(_atom_ev_buffers);
924 delete [] _control_data;
925 delete [] _shadow_data;
927 delete [] _ev_buffers;
932 LV2Plugin::is_external_ui() const
937 return lilv_ui_is_a(_impl->ui, _world.ui_external) || lilv_ui_is_a(_impl->ui, _world.ui_externalkx);
941 LV2Plugin::is_external_kx() const
946 return lilv_ui_is_a(_impl->ui, _world.ui_externalkx);
950 LV2Plugin::ui_is_resizable () const
952 const LilvNode* s = lilv_ui_get_uri(_impl->ui);
953 LilvNode* p = lilv_new_uri(_world.world, LV2_CORE__optionalFeature);
954 LilvNode* fs = lilv_new_uri(_world.world, LV2_UI__fixedSize);
955 LilvNode* nrs = lilv_new_uri(_world.world, LV2_UI__noUserResize);
957 LilvNodes* fs_matches = lilv_world_find_nodes(_world.world, s, p, fs);
958 LilvNodes* nrs_matches = lilv_world_find_nodes(_world.world, s, p, nrs);
960 lilv_nodes_free(nrs_matches);
961 lilv_nodes_free(fs_matches);
966 return !fs_matches && !nrs_matches;
971 LV2Plugin::has_inline_display () {
972 return _display_interface ? true : false;
976 LV2Plugin::inline_display_in_gui () {
977 return _inline_display_in_gui;
980 Plugin::Display_Image_Surface*
981 LV2Plugin::render_inline_display (uint32_t w, uint32_t h) {
982 if (_display_interface) {
983 /* Plugin::Display_Image_Surface is identical to
984 * LV2_Inline_Display_Image_Surface */
985 return (Plugin::Display_Image_Surface*) _display_interface->render ((void*)_impl->instance->lv2_handle, w, h);
991 LV2Plugin::has_midnam () {
992 return _midname_interface ? true : false;
996 LV2Plugin::read_midnam () {
998 if (!_midname_interface) {
1001 char* midnam = _midname_interface->midnam ((void*)_impl->instance->lv2_handle);
1003 std::stringstream ss;
1006 rv = MIDI::Name::MidiPatchManager::instance().update_custom_midnam (ss.str(), midnam);
1010 info << string_compose(_("LV2: update midnam for plugin '%1'"), name ()) << endmsg;
1012 warning << string_compose(_("LV2: Failed to parse midnam of plugin '%1'"), name ()) << endmsg;
1015 _midname_interface->free (midnam);
1020 LV2Plugin::midnam_model () {
1022 if (!_midname_interface) {
1025 char* model = _midname_interface->model ((void*)_impl->instance->lv2_handle);
1029 _midname_interface->free (model);
1035 LV2Plugin::unique_id() const
1037 return lilv_node_as_uri(lilv_plugin_get_uri(_impl->plugin));
1041 LV2Plugin::uri() const
1043 return lilv_node_as_uri(lilv_plugin_get_uri(_impl->plugin));
1047 LV2Plugin::label() const
1049 return lilv_node_as_string(_impl->name);
1053 LV2Plugin::name() const
1055 return lilv_node_as_string(_impl->name);
1059 LV2Plugin::maker() const
1061 return _impl->author ? lilv_node_as_string (_impl->author) : "Unknown";
1065 LV2Plugin::num_ports() const
1067 return lilv_plugin_get_num_ports(_impl->plugin);
1071 LV2Plugin::parameter_count() const
1073 return lilv_plugin_get_num_ports(_impl->plugin);
1077 LV2Plugin::default_value(uint32_t port)
1079 return _defaults[port];
1083 LV2Plugin::port_symbol(uint32_t index) const
1085 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, index);
1087 error << name() << ": Invalid port index " << index << endmsg;
1090 const LilvNode* sym = lilv_port_get_symbol(_impl->plugin, port);
1091 return lilv_node_as_string(sym);
1095 LV2Plugin::port_index (const char* symbol) const
1097 const map<string, uint32_t>::const_iterator i = _port_indices.find(symbol);
1098 if (i != _port_indices.end()) {
1101 warning << string_compose(_("LV2: Unknown port %1"), symbol) << endmsg;
1102 return (uint32_t)-1;
1107 LV2Plugin::set_parameter(uint32_t which, float val)
1109 DEBUG_TRACE(DEBUG::LV2, string_compose(
1110 "%1 set parameter %2 to %3\n", name(), which, val));
1112 if (which < lilv_plugin_get_num_ports(_impl->plugin)) {
1113 if (get_parameter (which) == val) {
1117 _shadow_data[which] = val;
1119 warning << string_compose(
1120 _("Illegal parameter number used with plugin \"%1\". "
1121 "This is a bug in either %2 or the LV2 plugin <%3>"),
1122 name(), PROGRAM_NAME, unique_id()) << endmsg;
1125 Plugin::set_parameter(which, val);
1129 LV2Plugin::get_parameter(uint32_t which) const
1131 if (parameter_is_input(which)) {
1132 return (float)_shadow_data[which];
1134 return (float)_control_data[which];
1140 LV2Plugin::get_docs() const
1142 LilvNodes* comments = lilv_plugin_get_value(_impl->plugin, _world.rdfs_comment);
1144 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
1145 lilv_nodes_free(comments);
1153 LV2Plugin::get_parameter_docs(uint32_t which) const
1155 LilvNodes* comments = lilv_port_get_value(
1157 lilv_plugin_get_port_by_index(_impl->plugin, which),
1158 _world.rdfs_comment);
1161 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
1162 lilv_nodes_free(comments);
1170 LV2Plugin::get_layout (uint32_t which, UILayoutHint& h) const
1172 /// TODO lookup port-properties
1173 if (unique_id () != "urn:ardour:a-eq") {
1178 case 0: h.x0 = 0; h.x1 = 1; h.y0 = 2; h.y1 = 3; break; // Frequency L
1179 case 1: h.x0 = 0; h.x1 = 1; h.y0 = 0; h.y1 = 1; break; // Gain L
1180 case 17: h.x0 = 0; h.x1 = 1; h.y0 = 5; h.y1 = 6; break; // enable L
1182 case 2: h.x0 = 1; h.x1 = 3; h.y0 = 2; h.y1 = 3; break; // Frequency 1
1183 case 3: h.x0 = 1; h.x1 = 3; h.y0 = 0; h.y1 = 1; break; // Gain 1
1184 case 4: h.x0 = 1; h.x1 = 3; h.y0 = 1; h.y1 = 2; break; // Bandwidth 1
1185 case 18: h.x0 = 1; h.x1 = 4; h.y0 = 5; h.y1 = 6; break; // enable 1
1187 case 5: h.x0 = 4; h.x1 = 6; h.y0 = 2; h.y1 = 3; break; // Frequency 2
1188 case 6: h.x0 = 4; h.x1 = 6; h.y0 = 0; h.y1 = 1; break; // Gain 2
1189 case 7: h.x0 = 4; h.x1 = 6; h.y0 = 1; h.y1 = 2; break; // Bandwidth 2
1190 case 19: h.x0 = 4; h.x1 = 7; h.y0 = 5; h.y1 = 6; break; // enable 2
1192 case 8: h.x0 = 7; h.x1 = 9; h.y0 = 2; h.y1 = 3; break; // Frequency 3
1193 case 9: h.x0 = 7; h.x1 = 9; h.y0 = 0; h.y1 = 1; break; // Gain 3
1194 case 10: h.x0 = 7; h.x1 = 9; h.y0 = 1; h.y1 = 2; break; // Bandwidth 3
1195 case 20: h.x0 = 7; h.x1 = 10; h.y0 = 5; h.y1 = 6; break; // enable 3
1197 case 11: h.x0 = 10; h.x1 = 12; h.y0 = 2; h.y1 = 3; break; // Frequency 4
1198 case 12: h.x0 = 10; h.x1 = 12; h.y0 = 0; h.y1 = 1; break; // Gain 4
1199 case 13: h.x0 = 10; h.x1 = 12; h.y0 = 1; h.y1 = 2; break; // Bandwidth 4
1200 case 21: h.x0 = 10; h.x1 = 13; h.y0 = 5; h.y1 = 6; break; // enable 4
1202 case 14: h.x0 = 13; h.x1 = 14; h.y0 = 2; h.y1 = 3; break; // Frequency H
1203 case 15: h.x0 = 13; h.x1 = 14; h.y0 = 0; h.y1 = 1; break; // Gain H
1204 case 22: h.x0 = 13; h.x1 = 14; h.y0 = 5; h.y1 = 6; break; // enable H
1206 case 16: h.x0 = 14; h.x1 = 15; h.y0 = 1; h.y1 = 3; break; // Master Gain
1207 case 23: h.x0 = 14; h.x1 = 15; h.y0 = 5; h.y1 = 6; break; // Master Enable
1215 LV2Plugin::nth_parameter(uint32_t n, bool& ok) const
1218 for (uint32_t c = 0, x = 0; x < lilv_plugin_get_num_ports(_impl->plugin); ++x) {
1219 if (parameter_is_control(x)) {
1231 LV2Plugin::extension_data(const char* uri) const
1233 return lilv_instance_get_extension_data(_impl->instance, uri);
1237 LV2Plugin::c_plugin()
1239 return _impl->plugin;
1245 return (const void*)_impl->ui;
1249 LV2Plugin::c_ui_type()
1251 return (const void*)_impl->ui_type;
1254 /** Directory for all plugin state. */
1256 LV2Plugin::plugin_dir() const
1258 if (!_plugin_state_dir.empty ()){
1259 return Glib::build_filename(_plugin_state_dir, _insert_id.to_s());
1261 return Glib::build_filename(_session.plugins_dir(), _insert_id.to_s());
1265 /** Directory for files created by the plugin (except during save). */
1267 LV2Plugin::scratch_dir() const
1269 return Glib::build_filename(plugin_dir(), "scratch");
1272 /** Directory for snapshots of files in the scratch directory. */
1274 LV2Plugin::file_dir() const
1276 return Glib::build_filename(plugin_dir(), "files");
1279 /** Directory to save state snapshot version @c num into. */
1281 LV2Plugin::state_dir(unsigned num) const
1283 return Glib::build_filename(plugin_dir(), string("state") + PBD::to_string (num));
1286 /** Implementation of state:makePath for files created at instantiation time.
1287 * Note this is not used for files created at save time (Lilv deals with that).
1290 LV2Plugin::lv2_state_make_path(LV2_State_Make_Path_Handle handle,
1293 LV2Plugin* me = (LV2Plugin*)handle;
1294 if (me->_insert_id == PBD::ID("0")) {
1295 warning << string_compose(
1296 "File path \"%1\" requested but LV2 %2 has no insert ID",
1297 path, me->name()) << endmsg;
1298 return g_strdup(path);
1301 const std::string abs_path = Glib::build_filename(me->scratch_dir(), path);
1302 const std::string dirname = Glib::path_get_dirname(abs_path);
1303 g_mkdir_with_parents(dirname.c_str(), 0744);
1305 DEBUG_TRACE(DEBUG::LV2, string_compose("new file path %1 => %2\n",
1308 return g_strndup(abs_path.c_str(), abs_path.length());
1312 LV2Plugin::add_state(XMLNode* root) const
1314 assert(_insert_id != PBD::ID("0"));
1319 for (uint32_t i = 0; i < parameter_count(); ++i) {
1320 if (parameter_is_input(i) && parameter_is_control(i)) {
1321 child = new XMLNode("Port");
1322 child->set_property("symbol", port_symbol(i));
1323 child->set_property("value", _shadow_data[i]);
1324 root->add_child_nocopy(*child);
1328 if (!_plugin_state_dir.empty()) {
1329 root->set_property("template-dir", _plugin_state_dir);
1332 if (_has_state_interface) {
1333 // Provisionally increment state version and create directory
1334 const std::string new_dir = state_dir(++_state_version);
1335 // and keep track of it (for templates & archive)
1336 unsigned int saved_state = _state_version;;
1337 g_mkdir_with_parents(new_dir.c_str(), 0744);
1339 LilvState* state = lilv_state_new_from_instance(
1342 _uri_map.urid_map(),
1343 scratch_dir().c_str(),
1345 _session.externals_dir().c_str(),
1348 const_cast<LV2Plugin*>(this),
1352 if (!_plugin_state_dir.empty() || force_state_save
1354 || !lilv_state_equals(state, _impl->state)) {
1355 lilv_state_save(_world.world,
1356 _uri_map.urid_map(),
1357 _uri_map.urid_unmap(),
1363 if (force_state_save) {
1364 // archive or save-as
1365 lilv_state_free(state);
1368 else if (_plugin_state_dir.empty()) {
1369 // normal session save
1370 lilv_state_free(_impl->state);
1371 _impl->state = state;
1373 // template save (dedicated state-dir)
1374 lilv_state_free(state);
1378 // State is identical, decrement version and nuke directory
1379 lilv_state_free(state);
1380 PBD::remove_directory(new_dir);
1382 saved_state = _state_version;
1385 root->set_property("state-dir", string("state") + PBD::to_string (saved_state));
1389 // TODO: Once we can rely on lilv 0.16.0, lilv_world_get can replace this
1391 get_value(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate)
1393 LilvNodes* vs = lilv_world_find_nodes(world, subject, predicate, NULL);
1395 LilvNode* node = lilv_node_duplicate(lilv_nodes_get_first(vs));
1396 lilv_nodes_free(vs);
1403 LV2Plugin::find_presets()
1405 LilvNode* lv2_appliesTo = lilv_new_uri(_world.world, LV2_CORE__appliesTo);
1406 LilvNode* pset_Preset = lilv_new_uri(_world.world, LV2_PRESETS__Preset);
1407 LilvNode* rdfs_label = lilv_new_uri(_world.world, LILV_NS_RDFS "label");
1409 LilvNodes* presets = lilv_plugin_get_related(_impl->plugin, pset_Preset);
1410 LILV_FOREACH(nodes, i, presets) {
1411 const LilvNode* preset = lilv_nodes_get(presets, i);
1412 lilv_world_load_resource(_world.world, preset);
1413 LilvNode* name = get_value(_world.world, preset, rdfs_label);
1414 bool userpreset = true; // TODO
1416 _presets.insert(std::make_pair(lilv_node_as_string(preset),
1417 Plugin::PresetRecord(
1418 lilv_node_as_string(preset),
1419 lilv_node_as_string(name),
1421 lilv_node_free(name);
1423 warning << string_compose(
1424 _("Plugin \"%1\" preset \"%2\" is missing a label\n"),
1425 lilv_node_as_string(lilv_plugin_get_uri(_impl->plugin)),
1426 lilv_node_as_string(preset)) << endmsg;
1429 lilv_nodes_free(presets);
1431 lilv_node_free(rdfs_label);
1432 lilv_node_free(pset_Preset);
1433 lilv_node_free(lv2_appliesTo);
1437 set_port_value(const char* port_symbol,
1443 LV2Plugin* self = (LV2Plugin*)user_data;
1444 if (type != 0 && type != URIMap::instance().urids.atom_Float) {
1445 return; // TODO: Support non-float ports
1448 const uint32_t port_index = self->port_index(port_symbol);
1449 if (port_index != (uint32_t)-1) {
1450 self->set_parameter(port_index, *(const float*)value);
1451 self->PresetPortSetValue (port_index, *(const float*)value); /* EMIT SIGNAL */
1456 LV2Plugin::load_preset(PresetRecord r)
1458 LilvWorld* world = _world.world;
1459 LilvNode* pset = lilv_new_uri(world, r.uri.c_str());
1460 LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset);
1462 const LV2_Feature* state_features[2] = { NULL, NULL };
1463 LV2_Worker_Schedule schedule = { _state_worker, work_schedule };
1464 const LV2_Feature state_sched_feature = { LV2_WORKER__schedule, &schedule };
1465 if (_state_worker) {
1466 state_features[0] = &state_sched_feature;
1470 lilv_state_restore(state, _impl->instance, set_port_value, this, 0, state_features);
1471 lilv_state_free(state);
1472 Plugin::load_preset(r);
1475 lilv_node_free(pset);
1480 ARDOUR::lv2plugin_get_port_value(const char* port_symbol,
1485 LV2Plugin *plugin = (LV2Plugin *) user_data;
1487 uint32_t index = plugin->port_index(port_symbol);
1488 if (index != (uint32_t) -1) {
1489 if (plugin->parameter_is_input(index) && plugin->parameter_is_control(index)) {
1491 *size = sizeof(float);
1492 *type = plugin->_uri_map.uri_to_id(LV2_ATOM__Float);
1493 value = &plugin->_shadow_data[index];
1505 LV2Plugin::do_save_preset(string name)
1507 LilvNode* plug_name = lilv_plugin_get_name(_impl->plugin);
1508 const string prefix = legalize_for_uri(lilv_node_as_string(plug_name));
1509 const string base_name = legalize_for_uri(name);
1510 const string file_name = base_name + ".ttl";
1511 #ifdef PLATFORM_WINDOWS
1512 /* http://lv2plug.in/pages/filesystem-hierarchy-standard.html */
1513 std::string appdata = PBD::get_win_special_folder_path (CSIDL_APPDATA);
1514 if (appdata.empty ()) {
1515 // TODO consider a fallback location
1518 const string bundle = Glib::build_filename (
1520 Glib::build_filename(prefix + "_" + base_name + ".lv2"));
1522 /* while macOS/OSX user-specific path is
1524 * $HOME/Library/Audio/Plug-Ins/LV2/
1526 * liblilv's LV2 search path on all unices does include ~/.lv2/
1527 * Ardour has been saving lv2 presets to ~/.lv2 for along time,
1528 * so just keep them there.
1530 const string bundle = Glib::build_filename(
1531 Glib::get_home_dir(),
1532 Glib::build_filename(".lv2", prefix + "_" + base_name + ".lv2"));
1535 #ifdef HAVE_LILV_0_21_3
1536 /* delete reference to old preset (if any) */
1537 const PresetRecord* r = preset_by_label(name);
1539 LilvNode* pset = lilv_new_uri (_world.world, r->uri.c_str());
1541 lilv_world_unload_resource (_world.world, pset);
1542 lilv_node_free(pset);
1547 LilvState* state = lilv_state_new_from_instance(
1550 _uri_map.urid_map(),
1551 scratch_dir().c_str(), // file_dir
1552 bundle.c_str(), // copy_dir
1553 bundle.c_str(), // link_dir
1554 bundle.c_str(), // save_dir
1555 lv2plugin_get_port_value, // get_value
1556 (void*)this, // user_data
1557 LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
1558 _features // features
1561 lilv_state_set_label(state, name.c_str());
1563 _world.world, // world
1564 _uri_map.urid_map(), // map
1565 _uri_map.urid_unmap(), // unmap
1567 NULL, // uri (NULL = use file URI)
1568 bundle.c_str(), // dir
1569 file_name.c_str() // filename
1572 lilv_state_free(state);
1574 std::string uri = Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
1575 LilvNode *node_bundle = lilv_new_uri(_world.world, Glib::filename_to_uri(Glib::build_filename(bundle, "/")).c_str());
1576 LilvNode *node_preset = lilv_new_uri(_world.world, uri.c_str());
1577 #ifdef HAVE_LILV_0_21_3
1578 lilv_world_unload_resource(_world.world, node_preset);
1579 lilv_world_unload_bundle(_world.world, node_bundle);
1581 lilv_world_load_bundle(_world.world, node_bundle);
1582 lilv_world_load_resource(_world.world, node_preset);
1583 lilv_node_free(node_bundle);
1584 lilv_node_free(node_preset);
1585 lilv_node_free(plug_name);
1590 LV2Plugin::do_remove_preset(string name)
1592 #ifdef HAVE_LILV_0_21_3
1593 /* Look up preset record by label (FIXME: ick, label as ID) */
1594 const PresetRecord* r = preset_by_label(name);
1599 /* Load a LilvState for the preset. */
1600 LilvWorld* world = _world.world;
1601 LilvNode* pset = lilv_new_uri(world, r->uri.c_str());
1602 LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset);
1604 lilv_node_free(pset);
1608 /* Unload preset from world. */
1609 lilv_world_unload_resource(world, pset);
1611 /* Delete it from the file system. This will remove the preset file and the entry
1612 from the manifest. If this results in an empty manifest (i.e. the
1613 preset is the only thing in the bundle), then the bundle is removed. */
1614 lilv_state_delete(world, state);
1616 lilv_state_free(state);
1617 lilv_node_free(pset);
1619 /* Without lilv_state_delete(), we could delete the preset file, but this
1620 would leave a broken bundle/manifest around, so the preset would still
1621 be visible, but broken. Naively deleting a bundle is too dangerous, so
1622 we simply do not support preset deletion with older Lilv */
1626 LV2Plugin::has_editor() const
1628 return _impl->ui != NULL;
1632 LV2Plugin::has_message_output() const
1634 for (uint32_t i = 0; i < num_ports(); ++i) {
1635 if ((_port_flags[i] & PORT_SEQUENCE) &&
1636 (_port_flags[i] & PORT_OUTPUT)) {
1644 LV2Plugin::write_to(RingBuffer<uint8_t>* dest,
1648 const uint8_t* body)
1650 const uint32_t buf_size = sizeof(UIMessage) + size;
1651 vector<uint8_t> buf(buf_size);
1653 UIMessage* msg = (UIMessage*)&buf[0];
1655 msg->protocol = protocol;
1657 memcpy(msg + 1, body, size);
1659 return (dest->write(&buf[0], buf_size) == buf_size);
1663 LV2Plugin::write_from_ui(uint32_t index,
1666 const uint8_t* body)
1669 size_t rbs = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS;
1670 /* buffer data communication from plugin UI to plugin instance.
1671 * this buffer needs to potentially hold
1672 * (port's minimumSize) * (audio-periods) / (UI-periods)
1675 * e.g 48kSPS / 128fpp -> audio-periods = 375 Hz
1676 * ui-periods = 25 Hz (SuperRapidScreenUpdate)
1677 * default minimumSize = 32K (see LV2Plugin::allocate_atom_event_buffers()
1679 * it is NOT safe to overflow (msg.size will be misinterpreted)
1681 uint32_t bufsiz = 32768;
1682 if (_atom_ev_buffers && _atom_ev_buffers[0]) {
1683 bufsiz = lv2_evbuf_get_capacity(_atom_ev_buffers[0]);
1685 int fact = ceilf(_session.frame_rate () / 3000.f);
1686 rbs = max((size_t) bufsiz * std::max (8, fact), rbs);
1687 _from_ui = new RingBuffer<uint8_t>(rbs);
1690 if (!write_to(_from_ui, index, protocol, size, body)) {
1691 error << "Error writing from UI to plugin" << endmsg;
1698 LV2Plugin::write_to_ui(uint32_t index,
1701 const uint8_t* body)
1703 if (!write_to(_to_ui, index, protocol, size, body)) {
1704 error << "Error writing from plugin to UI" << endmsg;
1711 forge_variant(LV2_Atom_Forge* forge, const Variant& value)
1713 switch (value.type()) {
1714 case Variant::NOTHING:
1716 case Variant::BEATS:
1717 // No atom type for this, just forge a double
1718 lv2_atom_forge_double(forge, value.get_beats().to_double());
1721 lv2_atom_forge_bool(forge, value.get_bool());
1723 case Variant::DOUBLE:
1724 lv2_atom_forge_double(forge, value.get_double());
1726 case Variant::FLOAT:
1727 lv2_atom_forge_float(forge, value.get_float());
1730 lv2_atom_forge_int(forge, value.get_int());
1733 lv2_atom_forge_long(forge, value.get_long());
1736 lv2_atom_forge_path(
1737 forge, value.get_path().c_str(), value.get_path().size());
1739 case Variant::STRING:
1740 lv2_atom_forge_string(
1741 forge, value.get_string().c_str(), value.get_string().size());
1745 forge, value.get_uri().c_str(), value.get_uri().size());
1750 /** Get a variant type from a URI, return false iff no match found. */
1752 uri_to_variant_type(const std::string& uri, Variant::Type& type)
1754 if (uri == LV2_ATOM__Bool) {
1755 type = Variant::BOOL;
1756 } else if (uri == LV2_ATOM__Double) {
1757 type = Variant::DOUBLE;
1758 } else if (uri == LV2_ATOM__Float) {
1759 type = Variant::FLOAT;
1760 } else if (uri == LV2_ATOM__Int) {
1761 type = Variant::INT;
1762 } else if (uri == LV2_ATOM__Long) {
1763 type = Variant::LONG;
1764 } else if (uri == LV2_ATOM__Path) {
1765 type = Variant::PATH;
1766 } else if (uri == LV2_ATOM__String) {
1767 type = Variant::STRING;
1768 } else if (uri == LV2_ATOM__URI) {
1769 type = Variant::URI;
1777 LV2Plugin::set_property(uint32_t key, const Variant& value)
1779 if (_patch_port_in_index == (uint32_t)-1) {
1780 error << "LV2: set_property called with unset patch_port_in_index" << endmsg;
1782 } else if (value.type() == Variant::NOTHING) {
1783 error << "LV2: set_property called with void value" << endmsg;
1787 // Set up forge to write to temporary buffer on the stack
1788 LV2_Atom_Forge* forge = &_impl->ui_forge;
1789 LV2_Atom_Forge_Frame frame;
1790 uint8_t buf[PATH_MAX]; // Ought to be enough for anyone...
1792 lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
1794 // Serialize patch:Set message to set property
1795 #ifdef HAVE_LV2_1_10_0
1796 lv2_atom_forge_object(forge, &frame, 0, _uri_map.urids.patch_Set);
1797 lv2_atom_forge_key(forge, _uri_map.urids.patch_property);
1798 lv2_atom_forge_urid(forge, key);
1799 lv2_atom_forge_key(forge, _uri_map.urids.patch_value);
1801 lv2_atom_forge_blank(forge, &frame, 0, _uri_map.urids.patch_Set);
1802 lv2_atom_forge_property_head(forge, _uri_map.urids.patch_property, 0);
1803 lv2_atom_forge_urid(forge, key);
1804 lv2_atom_forge_property_head(forge, _uri_map.urids.patch_value, 0);
1807 forge_variant(forge, value);
1809 // Write message to UI=>Plugin ring
1810 const LV2_Atom* const atom = (const LV2_Atom*)buf;
1811 write_from_ui(_patch_port_in_index,
1812 _uri_map.urids.atom_eventTransfer,
1813 lv2_atom_total_size(atom),
1814 (const uint8_t*)atom);
1817 const ParameterDescriptor&
1818 LV2Plugin::get_property_descriptor(uint32_t id) const
1820 PropertyDescriptors::const_iterator p = _property_descriptors.find(id);
1821 if (p != _property_descriptors.end()) {
1824 return Plugin::get_property_descriptor(id);
1828 load_parameter_descriptor_units(LilvWorld* lworld, ParameterDescriptor& desc, const LilvNodes* units)
1830 if (lilv_nodes_contains(units, _world.units_midiNote)) {
1831 desc.unit = ParameterDescriptor::MIDI_NOTE;
1832 } else if (lilv_nodes_contains(units, _world.units_db)) {
1833 desc.unit = ParameterDescriptor::DB;
1834 } else if (lilv_nodes_contains(units, _world.units_hz)) {
1835 desc.unit = ParameterDescriptor::HZ;
1837 if (lilv_nodes_size(units) > 0) {
1838 const LilvNode* unit = lilv_nodes_get_first(units);
1839 LilvNode* render = get_value(lworld, unit, _world.units_render);
1841 desc.print_fmt = lilv_node_as_string(render);
1842 /* override lilv's default "%f" format */
1843 if (desc.integer_step) {
1844 replace_all (desc.print_fmt, "%f", "%.0f");
1845 } else if (desc.upper - desc.lower >= 1000) {
1846 replace_all (desc.print_fmt, "%f", "%.1f");
1847 } else if (desc.upper - desc.lower >= 100) {
1848 replace_all (desc.print_fmt, "%f", "%.2f");
1850 replace_all (desc.print_fmt, "%f", "%.3f");
1852 lilv_node_free(render);
1858 load_parameter_descriptor(LV2World& world,
1859 ParameterDescriptor& desc,
1860 Variant::Type datatype,
1861 const LilvNode* subject)
1863 LilvWorld* lworld = _world.world;
1864 LilvNode* label = get_value(lworld, subject, _world.rdfs_label);
1865 LilvNode* def = get_value(lworld, subject, _world.lv2_default);
1866 LilvNode* minimum = get_value(lworld, subject, _world.lv2_minimum);
1867 LilvNode* maximum = get_value(lworld, subject, _world.lv2_maximum);
1868 LilvNodes* units = lilv_world_find_nodes(lworld, subject, _world.units_unit, NULL);
1870 desc.label = lilv_node_as_string(label);
1873 if (lilv_node_is_float(def)) {
1874 desc.normal = lilv_node_as_float(def);
1875 } else if (lilv_node_is_int(def)) {
1876 desc.normal = lilv_node_as_int(def);
1880 if (lilv_node_is_float(minimum)) {
1881 desc.lower = lilv_node_as_float(minimum);
1882 } else if (lilv_node_is_int(minimum)) {
1883 desc.lower = lilv_node_as_int(minimum);
1887 if (lilv_node_is_float(maximum)) {
1888 desc.upper = lilv_node_as_float(maximum);
1889 } else if (lilv_node_is_int(maximum)) {
1890 desc.upper = lilv_node_as_int(maximum);
1893 load_parameter_descriptor_units(lworld, desc, units);
1894 desc.datatype = datatype;
1895 desc.toggled |= datatype == Variant::BOOL;
1896 desc.integer_step |= datatype == Variant::INT || datatype == Variant::LONG;
1897 desc.update_steps();
1899 lilv_nodes_free(units);
1900 lilv_node_free(label);
1901 lilv_node_free(def);
1902 lilv_node_free(minimum);
1903 lilv_node_free(maximum);
1907 LV2Plugin::load_supported_properties(PropertyDescriptors& descs)
1909 LilvWorld* lworld = _world.world;
1910 const LilvNode* subject = lilv_plugin_get_uri(_impl->plugin);
1911 LilvNodes* properties = lilv_world_find_nodes(
1912 lworld, subject, _world.patch_writable, NULL);
1913 LILV_FOREACH(nodes, p, properties) {
1914 // Get label and range
1915 const LilvNode* prop = lilv_nodes_get(properties, p);
1916 LilvNode* range = get_value(lworld, prop, _world.rdfs_range);
1918 warning << string_compose(_("LV2: property <%1> has no range datatype, ignoring"),
1919 lilv_node_as_uri(prop)) << endmsg;
1923 // Convert range to variant type (TODO: support for multiple range types)
1924 Variant::Type datatype;
1925 if (!uri_to_variant_type(lilv_node_as_uri(range), datatype)) {
1926 error << string_compose(_("LV2: property <%1> has unsupported datatype <%1>"),
1927 lilv_node_as_uri(prop), lilv_node_as_uri(range)) << endmsg;
1931 // Add description to result
1932 ParameterDescriptor desc;
1933 desc.key = _uri_map.uri_to_id(lilv_node_as_uri(prop));
1934 desc.datatype = datatype;
1935 load_parameter_descriptor(_world, desc, datatype, prop);
1936 descs.insert(std::make_pair(desc.key, desc));
1938 lilv_node_free(range);
1940 lilv_nodes_free(properties);
1944 LV2Plugin::announce_property_values()
1946 if (_patch_port_in_index == (uint32_t)-1) {
1950 // Set up forge to write to temporary buffer on the stack
1951 LV2_Atom_Forge* forge = &_impl->ui_forge;
1952 LV2_Atom_Forge_Frame frame;
1953 uint8_t buf[PATH_MAX]; // Ought to be enough for anyone...
1955 lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
1957 // Serialize patch:Get message with no subject (implicitly plugin instance)
1958 #ifdef HAVE_LV2_1_10_0
1959 lv2_atom_forge_object(forge, &frame, 0, _uri_map.urids.patch_Get);
1961 lv2_atom_forge_blank(forge, &frame, 0, _uri_map.urids.patch_Get);
1964 // Write message to UI=>Plugin ring
1965 const LV2_Atom* const atom = (const LV2_Atom*)buf;
1966 write_from_ui(_patch_port_in_index,
1967 _uri_map.urids.atom_eventTransfer,
1968 lv2_atom_total_size(atom),
1969 (const uint8_t*)atom);
1973 LV2Plugin::enable_ui_emission()
1976 /* see note in LV2Plugin::write_from_ui() */
1977 uint32_t bufsiz = 32768;
1978 if (_atom_ev_buffers && _atom_ev_buffers[0]) {
1979 bufsiz = lv2_evbuf_get_capacity(_atom_ev_buffers[0]);
1981 size_t rbs = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS;
1982 rbs = max((size_t) bufsiz * 8, rbs);
1983 _to_ui = new RingBuffer<uint8_t>(rbs);
1988 LV2Plugin::emit_to_ui(void* controller, UIMessageSink sink)
1994 uint32_t read_space = _to_ui->read_space();
1995 while (read_space > sizeof(UIMessage)) {
1997 if (_to_ui->read((uint8_t*)&msg, sizeof(msg)) != sizeof(msg)) {
1998 error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
2001 vector<uint8_t> body(msg.size);
2002 if (_to_ui->read(&body[0], msg.size) != msg.size) {
2003 error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
2007 sink(controller, msg.index, msg.size, msg.protocol, &body[0]);
2009 read_space -= sizeof(msg) + msg.size;
2014 LV2Plugin::work(Worker& worker, uint32_t size, const void* data)
2016 Glib::Threads::Mutex::Lock lm(_work_mutex);
2017 return _impl->work_iface->work(
2018 _impl->instance->lv2_handle, work_respond, &worker, size, data);
2022 LV2Plugin::work_response(uint32_t size, const void* data)
2024 return _impl->work_iface->work_response(
2025 _impl->instance->lv2_handle, size, data);
2029 LV2Plugin::set_insert_id(PBD::ID id)
2031 if (_insert_id == "0") {
2033 } else if (_insert_id != id) {
2034 lilv_state_free(_impl->state);
2035 _impl->state = NULL;
2041 LV2Plugin::set_state_dir (const std::string& d)
2043 _plugin_state_dir = d;
2047 LV2Plugin::set_state(const XMLNode& node, int version)
2050 XMLNodeConstIterator iter;
2054 if (node.name() != state_node_name()) {
2055 error << _("Bad node sent to LV2Plugin::set_state") << endmsg;
2059 #ifndef NO_PLUGIN_STATE
2061 if (version < 3000) {
2062 nodes = node.children("port");
2064 nodes = node.children("Port");
2067 for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
2072 if (!child->get_property("symbol", sym)) {
2073 warning << _("LV2: port has no symbol, ignored") << endmsg;
2077 map<string, uint32_t>::iterator i = _port_indices.find(sym);
2081 if (i != _port_indices.end()) {
2082 port_id = i->second;
2084 warning << _("LV2: port has unknown index, ignored") << endmsg;
2089 if (!child->get_property("value", val)) {
2090 warning << _("LV2: port has no value, ignored") << endmsg;
2094 set_parameter(port_id, val);
2097 std::string template_dir;
2098 if (node.get_property("template-dir", template_dir)) {
2099 set_state_dir (template_dir);
2103 std::string state_dir;
2104 if (node.get_property("state-dir", state_dir) != 0) {
2105 if (sscanf(state_dir.c_str(), "state%u", &_state_version) != 1) {
2106 error << string_compose(
2107 "LV2: failed to parse state version from \"%1\"",
2108 state_dir) << endmsg;
2111 std::string state_file = Glib::build_filename(
2113 Glib::build_filename(state_dir, "state.ttl"));
2115 LilvState* state = lilv_state_new_from_file(
2116 _world.world, _uri_map.urid_map(), NULL, state_file.c_str());
2118 lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
2119 lilv_state_free(_impl->state);
2120 _impl->state = state;
2123 if (!_plugin_state_dir.empty ()) {
2124 // force save with session, next time (increment counter)
2125 lilv_state_free (_impl->state);
2126 _impl->state = NULL;
2130 latency_compute_run();
2133 return Plugin::set_state(node, version);
2137 LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) const
2139 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, which);
2141 error << string_compose("LV2: get descriptor of non-existent port %1", which)
2146 LilvNodes* portunits;
2147 LilvNode *def, *min, *max;
2148 lilv_port_get_range(_impl->plugin, port, &def, &min, &max);
2149 portunits = lilv_port_get_value(_impl->plugin, port, _world.units_unit);
2151 LilvNode* steps = lilv_port_get(_impl->plugin, port, _world.ext_rangeSteps);
2153 // TODO: Once we can rely on lilv 0.18.0 being present,
2154 // load_parameter_descriptor() can be used for ports as well
2155 desc.integer_step = lilv_port_has_property(_impl->plugin, port, _world.lv2_integer);
2156 desc.toggled = lilv_port_has_property(_impl->plugin, port, _world.lv2_toggled);
2157 desc.logarithmic = lilv_port_has_property(_impl->plugin, port, _world.ext_logarithmic);
2158 desc.sr_dependent = lilv_port_has_property(_impl->plugin, port, _world.lv2_sampleRate);
2159 desc.label = lilv_node_as_string(lilv_port_get_name(_impl->plugin, port));
2160 desc.normal = def ? lilv_node_as_float(def) : 0.0f;
2161 desc.lower = min ? lilv_node_as_float(min) : 0.0f;
2162 desc.upper = max ? lilv_node_as_float(max) : 1.0f;
2163 load_parameter_descriptor_units(_world.world, desc, portunits);
2165 if (desc.sr_dependent) {
2166 desc.lower *= _session.frame_rate ();
2167 desc.upper *= _session.frame_rate ();
2170 desc.enumeration = lilv_port_has_property(_impl->plugin, port, _world.lv2_enumeration);
2171 desc.scale_points = get_scale_points(which);
2174 desc.rangesteps = lilv_node_as_float (steps);
2177 desc.update_steps();
2179 lilv_node_free(def);
2180 lilv_node_free(min);
2181 lilv_node_free(max);
2182 lilv_node_free(steps);
2183 lilv_nodes_free(portunits);
2188 Plugin::IOPortDescription
2189 LV2Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const
2191 PortFlags match = 0;
2193 case DataType::AUDIO:
2196 case DataType::MIDI:
2197 match = PORT_SEQUENCE | PORT_MIDI; // ignore old PORT_EVENT
2200 return Plugin::IOPortDescription ("?");
2204 match |= PORT_INPUT;
2206 match |= PORT_OUTPUT;
2210 uint32_t idx = UINT32_MAX;
2212 uint32_t const num_ports = parameter_count();
2213 for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
2214 PortFlags flags = _port_flags[port_index];
2215 if ((flags & match) == match) {
2222 if (idx == UINT32_MAX) {
2223 return Plugin::IOPortDescription ("?");
2226 const LilvPort* pport = lilv_plugin_get_port_by_index (_impl->plugin, idx);
2228 LilvNode* name = lilv_port_get_name(_impl->plugin, pport);
2229 Plugin::IOPortDescription iod (lilv_node_as_string (name));
2230 lilv_node_free(name);
2232 /* get the port's pg:group */
2233 LilvNodes* groups = lilv_port_get_value (_impl->plugin, pport, _world.groups_group);
2234 if (lilv_nodes_size (groups) > 0) {
2235 const LilvNode* group = lilv_nodes_get_first (groups);
2236 LilvNodes* grouplabel = lilv_world_find_nodes (_world.world, group, _world.rdfs_label, NULL);
2238 /* get the name of the port-group */
2239 if (lilv_nodes_size (grouplabel) > 0) {
2240 const LilvNode* grpname = lilv_nodes_get_first (grouplabel);
2241 iod.group_name = lilv_node_as_string (grpname);
2243 lilv_nodes_free (grouplabel);
2245 /* get all port designations.
2246 * we're interested in e.g. lv2:designation pg:right */
2247 LilvNodes* designations = lilv_port_get_value (_impl->plugin, pport, _world.lv2_designation);
2248 if (lilv_nodes_size (designations) > 0) {
2249 /* get all pg:elements of the pg:group */
2250 LilvNodes* group_childs = lilv_world_find_nodes (_world.world, group, _world.groups_element, NULL);
2251 if (lilv_nodes_size (group_childs) > 0) {
2252 /* iterate over all port designations .. */
2253 LILV_FOREACH (nodes, i, designations) {
2254 const LilvNode* designation = lilv_nodes_get (designations, i);
2255 /* match the lv2:designation's element against the port-group's element */
2256 LILV_FOREACH (nodes, j, group_childs) {
2257 const LilvNode* group_element = lilv_nodes_get (group_childs, j);
2258 LilvNodes* elem = lilv_world_find_nodes (_world.world, group_element, _world.lv2_designation, designation);
2259 /* found it. Now look up the index (channel-number) of the pg:Element */
2260 if (lilv_nodes_size (elem) > 0) {
2261 LilvNodes* idx = lilv_world_find_nodes (_world.world, lilv_nodes_get_first (elem), _world.lv2_index, NULL);
2262 if (lilv_node_is_int (lilv_nodes_get_first (idx))) {
2263 iod.group_channel = lilv_node_as_int(lilv_nodes_get_first (idx));
2270 lilv_nodes_free (groups);
2271 lilv_nodes_free (designations);
2274 if (lilv_port_has_property(_impl->plugin, pport, _world.lv2_isSideChain)) {
2275 iod.is_sidechain = true;
2281 LV2Plugin::describe_parameter(Evoral::Parameter which)
2283 if (( which.type() == PluginAutomation) && ( which.id() < parameter_count()) ) {
2285 if (lilv_port_has_property(_impl->plugin,
2286 lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.ext_notOnGUI)) {
2287 return X_("hidden");
2290 if (lilv_port_has_property(_impl->plugin,
2291 lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_freewheeling)) {
2292 return X_("hidden");
2295 if (lilv_port_has_property(_impl->plugin,
2296 lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_reportsLatency)) {
2297 return X_("latency");
2300 LilvNode* name = lilv_port_get_name(_impl->plugin,
2301 lilv_plugin_get_port_by_index(_impl->plugin, which.id()));
2302 string ret(lilv_node_as_string(name));
2303 lilv_node_free(name);
2311 LV2Plugin::max_latency () const
2313 return _max_latency;
2317 LV2Plugin::signal_latency() const
2319 if (_latency_control_port) {
2320 return (framecnt_t)floor(*_latency_control_port);
2326 set<Evoral::Parameter>
2327 LV2Plugin::automatable() const
2329 set<Evoral::Parameter> ret;
2331 for (uint32_t i = 0; i < parameter_count(); ++i) {
2332 if (parameter_is_input(i) && parameter_is_control(i) && !(_port_flags[i] & PORT_NOAUTO)) {
2333 ret.insert(ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
2337 for (PropertyDescriptors::const_iterator p = _property_descriptors.begin();
2338 p != _property_descriptors.end();
2340 ret.insert(ret.end(), Evoral::Parameter(PluginPropertyAutomation, 0, p->first));
2346 LV2Plugin::set_automation_control (uint32_t i, boost::shared_ptr<AutomationControl> c)
2348 if ((_port_flags[i] & (PORT_CTRLED | PORT_CTRLER))) {
2349 DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("Ctrl Port %1\n", i));
2350 _ctrl_map [i] = AutomationCtrlPtr (new AutomationCtrl(c));
2354 LV2Plugin::AutomationCtrlPtr
2355 LV2Plugin::get_automation_control (uint32_t i)
2357 if (_ctrl_map.find (i) == _ctrl_map.end()) {
2358 return AutomationCtrlPtr ();
2360 return _ctrl_map[i];
2364 LV2Plugin::activate()
2366 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 activate\n", name()));
2368 if (!_was_activated) {
2369 lilv_instance_activate(_impl->instance);
2370 _was_activated = true;
2375 LV2Plugin::deactivate()
2377 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 deactivate\n", name()));
2379 if (_was_activated) {
2380 lilv_instance_deactivate(_impl->instance);
2381 _was_activated = false;
2386 LV2Plugin::cleanup()
2388 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 cleanup\n", name()));
2391 lilv_instance_free(_impl->instance);
2392 _impl->instance = NULL;
2396 LV2Plugin::allocate_atom_event_buffers()
2398 /* reserve local scratch buffers for ATOM event-queues */
2399 const LilvPlugin* p = _impl->plugin;
2401 /* count non-MIDI atom event-ports
2402 * TODO: nicely ask drobilla to make a lilv_ call for that
2404 int count_atom_out = 0;
2405 int count_atom_in = 0;
2406 int minimumSize = 32768; // TODO use a per-port minimum-size
2407 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
2408 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
2409 if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
2410 LilvNodes* buffer_types = lilv_port_get_value(
2411 p, port, _world.atom_bufferType);
2412 LilvNodes* atom_supports = lilv_port_get_value(
2413 p, port, _world.atom_supports);
2415 if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
2416 if (lilv_port_is_a(p, port, _world.lv2_InputPort)) {
2419 if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
2422 LilvNodes* min_size_v = lilv_port_get_value(_impl->plugin, port, _world.rsz_minimumSize);
2423 LilvNode* min_size = min_size_v ? lilv_nodes_get_first(min_size_v) : NULL;
2424 if (min_size && lilv_node_is_int(min_size)) {
2425 minimumSize = std::max(minimumSize, lilv_node_as_int(min_size));
2427 lilv_nodes_free(min_size_v);
2429 lilv_nodes_free(buffer_types);
2430 lilv_nodes_free(atom_supports);
2434 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 need buffers for %2 atom-in and %3 atom-out event-ports\n",
2435 name(), count_atom_in, count_atom_out));
2437 const int total_atom_buffers = (count_atom_in + count_atom_out);
2438 if (_atom_ev_buffers || total_atom_buffers == 0) {
2442 DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers of %2 bytes\n", total_atom_buffers, minimumSize));
2443 _atom_ev_buffers = (LV2_Evbuf**) malloc((total_atom_buffers + 1) * sizeof(LV2_Evbuf*));
2444 for (int i = 0; i < total_atom_buffers; ++i ) {
2445 _atom_ev_buffers[i] = lv2_evbuf_new(minimumSize, LV2_EVBUF_ATOM,
2446 _uri_map.urids.atom_Chunk, _uri_map.urids.atom_Sequence);
2448 _atom_ev_buffers[total_atom_buffers] = 0;
2452 /** Write an ardour position/time/tempo/meter as an LV2 event.
2453 * @return true on success.
2456 write_position(LV2_Atom_Forge* forge,
2458 const TempoMetric& t,
2459 Timecode::BBT_Time& bbt,
2462 framepos_t position,
2465 const URIMap::URIDs& urids = URIMap::instance().urids;
2467 uint8_t pos_buf[256];
2468 lv2_atom_forge_set_buffer(forge, pos_buf, sizeof(pos_buf));
2469 LV2_Atom_Forge_Frame frame;
2470 #ifdef HAVE_LV2_1_10_0
2471 lv2_atom_forge_object(forge, &frame, 0, urids.time_Position);
2472 lv2_atom_forge_key(forge, urids.time_frame);
2473 lv2_atom_forge_long(forge, position);
2474 lv2_atom_forge_key(forge, urids.time_speed);
2475 lv2_atom_forge_float(forge, speed);
2476 lv2_atom_forge_key(forge, urids.time_barBeat);
2477 lv2_atom_forge_float(forge, bbt.beats - 1 +
2478 (bbt.ticks / Timecode::BBT_Time::ticks_per_beat));
2479 lv2_atom_forge_key(forge, urids.time_bar);
2480 lv2_atom_forge_long(forge, bbt.bars - 1);
2481 lv2_atom_forge_key(forge, urids.time_beatUnit);
2482 lv2_atom_forge_int(forge, t.meter().note_divisor());
2483 lv2_atom_forge_key(forge, urids.time_beatsPerBar);
2484 lv2_atom_forge_float(forge, t.meter().divisions_per_bar());
2485 lv2_atom_forge_key(forge, urids.time_beatsPerMinute);
2486 lv2_atom_forge_float(forge, bpm);
2488 lv2_atom_forge_blank(forge, &frame, 1, urids.time_Position);
2489 lv2_atom_forge_property_head(forge, urids.time_frame, 0);
2490 lv2_atom_forge_long(forge, position);
2491 lv2_atom_forge_property_head(forge, urids.time_speed, 0);
2492 lv2_atom_forge_float(forge, speed);
2493 lv2_atom_forge_property_head(forge, urids.time_barBeat, 0);
2494 lv2_atom_forge_float(forge, bbt.beats - 1 +
2495 (bbt.ticks / Timecode::BBT_Time::ticks_per_beat));
2496 lv2_atom_forge_property_head(forge, urids.time_bar, 0);
2497 lv2_atom_forge_long(forge, bbt.bars - 1);
2498 lv2_atom_forge_property_head(forge, urids.time_beatUnit, 0);
2499 lv2_atom_forge_int(forge, t.meter().note_divisor());
2500 lv2_atom_forge_property_head(forge, urids.time_beatsPerBar, 0);
2501 lv2_atom_forge_float(forge, t.meter().divisions_per_bar());
2502 lv2_atom_forge_property_head(forge, urids.time_beatsPerMinute, 0);
2503 lv2_atom_forge_float(forge, bpm);
2506 LV2_Evbuf_Iterator end = lv2_evbuf_end(buf);
2507 const LV2_Atom* const atom = (const LV2_Atom*)pos_buf;
2508 return lv2_evbuf_write(&end, offset, 0, atom->type, atom->size,
2509 (const uint8_t*)(atom + 1));
2513 LV2Plugin::connect_and_run(BufferSet& bufs,
2514 framepos_t start, framepos_t end, double speed,
2515 ChanMapping in_map, ChanMapping out_map,
2516 pframes_t nframes, framecnt_t offset)
2518 DEBUG_TRACE(DEBUG::LV2, string_compose("%1 run %2 offset %3\n", name(), nframes, offset));
2519 Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
2521 cycles_t then = get_cycles();
2523 TempoMap& tmap = _session.tempo_map();
2524 Metrics::const_iterator metric_i = tmap.metrics_end();
2525 TempoMetric tmetric = tmap.metric_at(start, &metric_i);
2527 if (_freewheel_control_port) {
2528 *_freewheel_control_port = _session.engine().freewheeling() ? 1.f : 0.f;
2531 if (_bpm_control_port) {
2532 *_bpm_control_port = tmap.tempo_at_frame (start).note_types_per_minute();
2536 if (_can_write_automation && start != _next_cycle_start) {
2537 // add guard-points after locating
2538 for (AutomationCtrlMap::iterator i = _ctrl_map.begin(); i != _ctrl_map.end(); ++i) {
2539 i->second->guard = true;
2544 ChanCount bufs_count;
2545 bufs_count.set(DataType::AUDIO, 1);
2546 bufs_count.set(DataType::MIDI, 1);
2547 BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
2548 BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
2549 uint32_t const num_ports = parameter_count();
2550 uint32_t const nil_index = std::numeric_limits<uint32_t>::max();
2552 uint32_t audio_in_index = 0;
2553 uint32_t audio_out_index = 0;
2554 uint32_t midi_in_index = 0;
2555 uint32_t midi_out_index = 0;
2556 uint32_t atom_port_index = 0;
2557 for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
2559 uint32_t index = nil_index;
2560 PortFlags flags = _port_flags[port_index];
2562 if (flags & PORT_AUDIO) {
2563 if (flags & PORT_INPUT) {
2564 index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
2566 ? bufs.get_audio(index).data(offset)
2567 : silent_bufs.get_audio(0).data(offset);
2569 index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
2571 ? bufs.get_audio(index).data(offset)
2572 : scratch_bufs.get_audio(0).data(offset);
2574 } else if (flags & (PORT_EVENT|PORT_SEQUENCE)) {
2575 /* FIXME: The checks here for bufs.count().n_midi() > index shouldn't
2576 be necessary, but the mapping is illegal in some cases. Ideally
2577 that should be fixed, but this is easier...
2579 if (flags & PORT_MIDI) {
2580 if (flags & PORT_INPUT) {
2581 index = in_map.get(DataType::MIDI, midi_in_index++, &valid);
2583 index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
2585 if (valid && bufs.count().n_midi() > index) {
2586 /* Note, ensure_lv2_bufsize() is not RT safe!
2587 * However free()/alloc() is only called if a
2588 * plugin requires a rsz:minimumSize buffersize
2589 * and the existing buffer if smaller.
2591 bufs.ensure_lv2_bufsize((flags & PORT_INPUT), index, _port_minimumSize[port_index]);
2592 _ev_buffers[port_index] = bufs.get_lv2_midi(
2593 (flags & PORT_INPUT), index, (flags & PORT_EVENT));
2595 } else if ((flags & PORT_POSITION) && (flags & PORT_INPUT)) {
2596 lv2_evbuf_reset(_atom_ev_buffers[atom_port_index], true);
2597 _ev_buffers[port_index] = _atom_ev_buffers[atom_port_index++];
2601 if (valid && (flags & PORT_INPUT)) {
2602 if ((flags & PORT_POSITION)) {
2603 Timecode::BBT_Time bbt (tmap.bbt_at_frame (start));
2604 double bpm = tmap.tempo_at_frame (start).note_types_per_minute();
2605 double beatpos = (bbt.bars - 1) * tmetric.meter().divisions_per_bar()
2607 + (bbt.ticks / Timecode::BBT_Time::ticks_per_beat);
2608 beatpos *= tmetric.meter().note_divisor() / 4.0;
2609 if (start != _next_cycle_start ||
2610 speed != _next_cycle_speed ||
2611 rint (1000 * beatpos) != rint(1000 * _next_cycle_beat) ||
2612 bpm != _current_bpm) {
2613 // Transport or Tempo has changed, write position at cycle start
2614 write_position(&_impl->forge, _ev_buffers[port_index],
2615 tmetric, bbt, speed, bpm, start, 0);
2619 // Get MIDI iterator range (empty range if no MIDI)
2620 MidiBuffer::iterator m = (index != nil_index)
2621 ? bufs.get_midi(index).begin()
2622 : silent_bufs.get_midi(0).end();
2623 MidiBuffer::iterator m_end = (index != nil_index)
2624 ? bufs.get_midi(index).end()
2627 // Now merge MIDI and any transport events into the buffer
2628 const uint32_t type = _uri_map.urids.midi_MidiEvent;
2629 const framepos_t tend = end;
2631 while (m != m_end || (metric_i != tmap.metrics_end() &&
2632 (*metric_i)->frame() < tend)) {
2633 MetricSection* metric = (metric_i != tmap.metrics_end())
2635 if (m != m_end && (!metric || metric->frame() > (*m).time())) {
2636 const Evoral::Event<framepos_t> ev(*m, false);
2637 if (ev.time() < nframes) {
2638 LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
2639 lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
2643 tmetric.set_metric(metric);
2644 Timecode::BBT_Time bbt;
2645 bbt = tmap.bbt_at_frame (metric->frame());
2646 double bpm = tmap.tempo_at_frame (start/*XXX*/).note_types_per_minute();
2647 write_position(&_impl->forge, _ev_buffers[port_index],
2648 tmetric, bbt, speed, bpm,
2650 metric->frame() - start);
2654 } else if (!valid) {
2655 // Nothing we understand or care about, connect to scratch
2656 // see note for midi-buffer size above
2657 scratch_bufs.ensure_lv2_bufsize((flags & PORT_INPUT),
2658 0, _port_minimumSize[port_index]);
2659 _ev_buffers[port_index] = scratch_bufs.get_lv2_midi(
2660 (flags & PORT_INPUT), 0, (flags & PORT_EVENT));
2663 buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
2665 continue; // Control port, leave buffer alone
2667 lilv_instance_connect_port(_impl->instance, port_index, buf);
2670 // Read messages from UI and push into appropriate buffers
2672 uint32_t read_space = _from_ui->read_space();
2673 while (read_space > sizeof(UIMessage)) {
2675 if (_from_ui->read((uint8_t*)&msg, sizeof(msg)) != sizeof(msg)) {
2676 error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
2679 vector<uint8_t> body(msg.size);
2680 if (_from_ui->read(&body[0], msg.size) != msg.size) {
2681 error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
2684 if (msg.protocol == URIMap::instance().urids.atom_eventTransfer) {
2685 LV2_Evbuf* buf = _ev_buffers[msg.index];
2686 LV2_Evbuf_Iterator i = lv2_evbuf_end(buf);
2687 const LV2_Atom* const atom = (const LV2_Atom*)&body[0];
2688 if (!lv2_evbuf_write(&i, nframes - 1, 0, atom->type, atom->size,
2689 (const uint8_t*)(atom + 1))) {
2690 error << "Failed to write data to LV2 event buffer\n";
2693 error << "Received unknown message type from UI" << endmsg;
2695 read_space -= sizeof(UIMessage) + msg.size;
2702 for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
2703 PortFlags flags = _port_flags[port_index];
2706 /* TODO ask drobilla about comment
2707 * "Make Ardour event buffers generic so plugins can communicate"
2708 * in libs/ardour/buffer_set.cc:310
2710 * ideally the user could choose which of the following two modes
2711 * to use (e.g. instrument/effect chains MIDI OUT vs MIDI TRHU).
2713 * This implementation follows the discussion on IRC Mar 16 2013 16:47 UTC
2714 * 16:51 < drobilla> rgareus: [..] i.e always replace with MIDI output [of LV2 plugin] if it's there
2715 * 16:52 < drobilla> rgareus: That would probably be good enough [..] to make users not complain
2716 * for quite a while at least ;)
2718 // copy output of LV2 plugin's MIDI port to Ardour MIDI buffers -- MIDI OUT
2719 if ((flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE|PORT_MIDI))) {
2720 const uint32_t buf_index = out_map.get(
2721 DataType::MIDI, midi_out_index++, &valid);
2723 bufs.forward_lv2_midi(_ev_buffers[port_index], buf_index);
2726 // Flush MIDI (write back to Ardour MIDI buffers) -- MIDI THRU
2727 else if ((flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
2728 const uint32_t buf_index = out_map.get(
2729 DataType::MIDI, midi_out_index++, &valid);
2731 bufs.flush_lv2_midi(true, buf_index);
2735 // Write messages to UI
2736 if ((_to_ui || _can_write_automation || _patch_port_out_index != (uint32_t)-1) &&
2737 (flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
2738 LV2_Evbuf* buf = _ev_buffers[port_index];
2739 for (LV2_Evbuf_Iterator i = lv2_evbuf_begin(buf);
2740 lv2_evbuf_is_valid(i);
2741 i = lv2_evbuf_next(i)) {
2742 uint32_t frames, subframes, type, size;
2744 lv2_evbuf_get(i, &frames, &subframes, &type, &size, &data);
2747 // Intercept Automation Write Events
2748 if ((flags & PORT_AUTOCTRL)) {
2749 LV2_Atom* atom = (LV2_Atom*)(data - sizeof(LV2_Atom));
2750 if (atom->type == _uri_map.urids.atom_Blank ||
2751 atom->type == _uri_map.urids.atom_Object) {
2752 LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
2753 if (obj->body.otype == _uri_map.urids.auto_event) {
2754 // only if transport_rolling ??
2755 const LV2_Atom* parameter = NULL;
2756 const LV2_Atom* value = NULL;
2757 lv2_atom_object_get(obj,
2758 _uri_map.urids.auto_parameter, ¶meter,
2759 _uri_map.urids.auto_value, &value,
2761 if (parameter && value) {
2762 const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
2763 const float v = ((const LV2_Atom_Float*)value)->body;
2764 // -> add automation event..
2765 DEBUG_TRACE(DEBUG::LV2Automate,
2766 string_compose ("Event p: %1 t: %2 v: %3\n", p, frames, v));
2767 AutomationCtrlPtr c = get_automation_control (p);
2769 (c->ac->automation_state() == Touch || c->ac->automation_state() == Write)
2771 framepos_t when = std::max ((framepos_t) 0, start + frames - _current_latency);
2772 assert (start + frames - _current_latency >= 0);
2775 c->ac->list()->add (when, v, true, true);
2777 c->ac->set_double (v, when, true);
2782 else if (obj->body.otype == _uri_map.urids.auto_setup) {
2783 // TODO optional arguments, for now we assume the plugin
2784 // writes automation for its own inputs
2785 // -> put them in "touch" mode (preferably "exclusive plugin touch(TM)"
2786 for (AutomationCtrlMap::iterator i = _ctrl_map.begin(); i != _ctrl_map.end(); ++i) {
2787 if (_port_flags[i->first] & PORT_CTRLED) {
2788 DEBUG_TRACE(DEBUG::LV2Automate,
2789 string_compose ("Setup p: %1\n", i->first));
2790 i->second->ac->set_automation_state (Touch);
2794 else if (obj->body.otype == _uri_map.urids.auto_finalize) {
2795 // set [touched] parameters to "play" ??
2796 // allow plugin to change its mode (from analyze to apply)
2797 const LV2_Atom* parameter = NULL;
2798 const LV2_Atom* value = NULL;
2799 lv2_atom_object_get(obj,
2800 _uri_map.urids.auto_parameter, ¶meter,
2801 _uri_map.urids.auto_value, &value,
2803 if (parameter && value) {
2804 const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
2805 const float v = ((const LV2_Atom_Float*)value)->body;
2806 AutomationCtrlPtr c = get_automation_control (p);
2807 DEBUG_TRACE(DEBUG::LV2Automate,
2808 string_compose ("Finalize p: %1 v: %2\n", p, v));
2809 if (c && _port_flags[p] & PORT_CTRLER) {
2810 c->ac->set_value(v, Controllable::NoGroup);
2813 DEBUG_TRACE(DEBUG::LV2Automate, "Finalize\n");
2815 for (AutomationCtrlMap::iterator i = _ctrl_map.begin(); i != _ctrl_map.end(); ++i) {
2816 // guard will be false if an event was written
2817 if ((_port_flags[i->first] & PORT_CTRLED) && !i->second->guard) {
2818 DEBUG_TRACE(DEBUG::LV2Automate,
2819 string_compose ("Thin p: %1\n", i->first));
2820 i->second->ac->alist ()->thin (20);
2824 else if (obj->body.otype == _uri_map.urids.auto_start) {
2825 const LV2_Atom* parameter = NULL;
2826 lv2_atom_object_get(obj,
2827 _uri_map.urids.auto_parameter, ¶meter,
2830 const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
2831 AutomationCtrlPtr c = get_automation_control (p);
2832 DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("Start Touch p: %1\n", p));
2834 c->ac->start_touch (std::max ((framepos_t)0, start - _current_latency));
2839 else if (obj->body.otype == _uri_map.urids.auto_end) {
2840 const LV2_Atom* parameter = NULL;
2841 lv2_atom_object_get(obj,
2842 _uri_map.urids.auto_parameter, ¶meter,
2845 const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
2846 AutomationCtrlPtr c = get_automation_control (p);
2847 DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("End Touch p: %1\n", p));
2849 c->ac->stop_touch (std::max ((framepos_t)0, start - _current_latency));
2856 // Intercept state dirty message
2857 if (_has_state_interface /* && (flags & PORT_DIRTYMSG)*/) {
2858 LV2_Atom* atom = (LV2_Atom*)(data - sizeof(LV2_Atom));
2859 if (atom->type == _uri_map.urids.atom_Blank ||
2860 atom->type == _uri_map.urids.atom_Object) {
2861 LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
2862 if (obj->body.otype == _uri_map.urids.state_StateChanged) {
2863 _session.set_dirty ();
2868 // Intercept patch change messages to emit PropertyChanged signal
2869 if ((flags & PORT_PATCHMSG)) {
2870 LV2_Atom* atom = (LV2_Atom*)(data - sizeof(LV2_Atom));
2871 if (atom->type == _uri_map.urids.atom_Blank ||
2872 atom->type == _uri_map.urids.atom_Object) {
2873 LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
2874 if (obj->body.otype == _uri_map.urids.patch_Set) {
2875 const LV2_Atom* property = NULL;
2876 const LV2_Atom* value = NULL;
2877 lv2_atom_object_get(obj,
2878 _uri_map.urids.patch_property, &property,
2879 _uri_map.urids.patch_value, &value,
2882 if (property && value &&
2883 property->type == _uri_map.urids.atom_URID &&
2884 value->type == _uri_map.urids.atom_Path) {
2885 const uint32_t prop_id = ((const LV2_Atom_URID*)property)->body;
2886 const char* path = (const char*)LV2_ATOM_BODY_CONST(value);
2888 // Emit PropertyChanged signal for UI
2889 // TODO: This should emit the control's Changed signal
2890 PropertyChanged(prop_id, Variant(Variant::PATH, path));
2892 std::cerr << "warning: patch:Set for unknown property" << std::endl;
2898 if (!_to_ui) continue;
2899 write_to_ui(port_index, URIMap::instance().urids.atom_eventTransfer,
2900 size + sizeof(LV2_Atom),
2901 data - sizeof(LV2_Atom));
2906 cycles_t now = get_cycles();
2907 set_cycles((uint32_t)(now - then));
2909 // Update expected transport information for next cycle so we can detect changes
2910 _next_cycle_speed = speed;
2911 _next_cycle_start = end;
2914 /* keep track of lv2:timePosition like plugins can do.
2915 * Note: for no-midi plugins, we only ever send information at cycle-start,
2916 * so it needs to be realative to that.
2918 TempoMetric t = tmap.metric_at(start);
2919 _current_bpm = tmap.tempo_at_frame (start).note_types_per_minute();
2920 Timecode::BBT_Time bbt (tmap.bbt_at_frame (start));
2921 double beatpos = (bbt.bars - 1) * t.meter().divisions_per_bar()
2923 + (bbt.ticks / Timecode::BBT_Time::ticks_per_beat);
2924 beatpos *= tmetric.meter().note_divisor() / 4.0;
2925 _next_cycle_beat = beatpos + nframes * speed * _current_bpm / (60.f * _session.frame_rate());
2928 if (_latency_control_port) {
2929 framecnt_t new_latency = signal_latency ();
2930 _current_latency = new_latency;
2936 LV2Plugin::parameter_is_control(uint32_t param) const
2938 assert(param < _port_flags.size());
2939 return _port_flags[param] & PORT_CONTROL;
2943 LV2Plugin::parameter_is_audio(uint32_t param) const
2945 assert(param < _port_flags.size());
2946 return _port_flags[param] & PORT_AUDIO;
2950 LV2Plugin::parameter_is_event(uint32_t param) const
2952 assert(param < _port_flags.size());
2953 return _port_flags[param] & PORT_EVENT;
2957 LV2Plugin::parameter_is_output(uint32_t param) const
2959 assert(param < _port_flags.size());
2960 return _port_flags[param] & PORT_OUTPUT;
2964 LV2Plugin::parameter_is_input(uint32_t param) const
2966 assert(param < _port_flags.size());
2967 return _port_flags[param] & PORT_INPUT;
2971 LV2Plugin::designated_bypass_port ()
2973 const LilvPort* port = NULL;
2974 LilvNode* designation = lilv_new_uri (_world.world, LV2_CORE_PREFIX "enabled");
2975 port = lilv_plugin_get_port_by_designation (
2976 _impl->plugin, _world.lv2_InputPort, designation);
2977 lilv_node_free(designation);
2979 return lilv_port_get_index (_impl->plugin, port);
2982 /* deprecated on 2016-Sep-18 in favor of lv2:enabled */
2983 designation = lilv_new_uri (_world.world, LV2_PROCESSING_URI__enable);
2984 port = lilv_plugin_get_port_by_designation (
2985 _impl->plugin, _world.lv2_InputPort, designation);
2986 lilv_node_free(designation);
2988 return lilv_port_get_index (_impl->plugin, port);
2995 LV2Plugin::print_parameter(uint32_t param, char* buf, uint32_t len) const
2998 if (param < parameter_count()) {
2999 snprintf(buf, len, "%.3f", get_parameter(param));
3006 boost::shared_ptr<ScalePoints>
3007 LV2Plugin::get_scale_points(uint32_t port_index) const
3009 const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, port_index);
3010 LilvScalePoints* points = lilv_port_get_scale_points(_impl->plugin, port);
3012 boost::shared_ptr<ScalePoints> ret;
3017 ret = boost::shared_ptr<ScalePoints>(new ScalePoints());
3019 LILV_FOREACH(scale_points, i, points) {
3020 const LilvScalePoint* p = lilv_scale_points_get(points, i);
3021 const LilvNode* label = lilv_scale_point_get_label(p);
3022 const LilvNode* value = lilv_scale_point_get_value(p);
3023 if (label && (lilv_node_is_float(value) || lilv_node_is_int(value))) {
3024 ret->insert(make_pair(lilv_node_as_string(label),
3025 lilv_node_as_float(value)));
3029 lilv_scale_points_free(points);
3034 LV2Plugin::run(pframes_t nframes, bool sync_work)
3036 uint32_t const N = parameter_count();
3037 for (uint32_t i = 0; i < N; ++i) {
3038 if (parameter_is_control(i) && parameter_is_input(i)) {
3039 _control_data[i] = _shadow_data[i];
3044 // Execute work synchronously if we're freewheeling (export)
3045 _worker->set_synchronous(sync_work || session().engine().freewheeling());
3048 // Run the plugin for this cycle
3049 lilv_instance_run(_impl->instance, nframes);
3051 // Emit any queued worker responses (calls a plugin callback)
3052 if (_state_worker) {
3053 _state_worker->emit_responses();
3056 _worker->emit_responses();
3059 // Notify the plugin that a work run cycle is complete
3060 if (_impl->work_iface) {
3061 if (_impl->work_iface->end_run) {
3062 _impl->work_iface->end_run(_impl->instance->lv2_handle);
3068 LV2Plugin::latency_compute_run()
3070 if (!_latency_control_port) {
3074 // Run the plugin so that it can set its latency parameter
3076 bool was_activated = _was_activated;
3079 uint32_t port_index = 0;
3080 uint32_t in_index = 0;
3081 uint32_t out_index = 0;
3083 // this is done in the main thread. non realtime.
3084 const framecnt_t bufsize = _engine.samples_per_cycle();
3085 float *buffer = (float*) malloc(_engine.samples_per_cycle() * sizeof(float));
3087 memset(buffer, 0, sizeof(float) * bufsize);
3089 // FIXME: Ensure plugins can handle in-place processing
3093 while (port_index < parameter_count()) {
3094 if (parameter_is_audio(port_index)) {
3095 if (parameter_is_input(port_index)) {
3096 lilv_instance_connect_port(_impl->instance, port_index, buffer);
3098 } else if (parameter_is_output(port_index)) {
3099 lilv_instance_connect_port(_impl->instance, port_index, buffer);
3108 if (was_activated) {
3115 LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** bufptr)
3117 const LilvPort* port = NULL;
3118 LilvNode* designation = lilv_new_uri(_world.world, uri);
3119 port = lilv_plugin_get_port_by_designation(
3120 plugin, _world.lv2_InputPort, designation);
3121 lilv_node_free(designation);
3123 bufptrs[lilv_port_get_index(plugin, port)] = bufptr;
3128 static bool lv2_filter (const string& str, void* /*arg*/)
3130 /* Not a dotfile, has a prefix before a period, suffix is "lv2" */
3132 return str[0] != '.' && (str.length() > 3 && str.find (".lv2") == (str.length() - 4));
3136 LV2World::LV2World()
3137 : world(lilv_world_new())
3138 , _bundle_checked(false)
3140 atom_AtomPort = lilv_new_uri(world, LV2_ATOM__AtomPort);
3141 atom_Chunk = lilv_new_uri(world, LV2_ATOM__Chunk);
3142 atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence);
3143 atom_bufferType = lilv_new_uri(world, LV2_ATOM__bufferType);
3144 atom_supports = lilv_new_uri(world, LV2_ATOM__supports);
3145 atom_eventTransfer = lilv_new_uri(world, LV2_ATOM__eventTransfer);
3146 ev_EventPort = lilv_new_uri(world, LILV_URI_EVENT_PORT);
3147 ext_logarithmic = lilv_new_uri(world, LV2_PORT_PROPS__logarithmic);
3148 ext_notOnGUI = lilv_new_uri(world, LV2_PORT_PROPS__notOnGUI);
3149 ext_expensive = lilv_new_uri(world, LV2_PORT_PROPS__expensive);
3150 ext_causesArtifacts= lilv_new_uri(world, LV2_PORT_PROPS__causesArtifacts);
3151 ext_notAutomatic = lilv_new_uri(world, LV2_PORT_PROPS__notAutomatic);
3152 ext_rangeSteps = lilv_new_uri(world, LV2_PORT_PROPS__rangeSteps);
3153 groups_group = lilv_new_uri(world, LV2_PORT_GROUPS__group);
3154 groups_element = lilv_new_uri(world, LV2_PORT_GROUPS__element);
3155 lv2_AudioPort = lilv_new_uri(world, LILV_URI_AUDIO_PORT);
3156 lv2_ControlPort = lilv_new_uri(world, LILV_URI_CONTROL_PORT);
3157 lv2_InputPort = lilv_new_uri(world, LILV_URI_INPUT_PORT);
3158 lv2_OutputPort = lilv_new_uri(world, LILV_URI_OUTPUT_PORT);
3159 lv2_inPlaceBroken = lilv_new_uri(world, LV2_CORE__inPlaceBroken);
3160 lv2_isSideChain = lilv_new_uri(world, LV2_CORE_PREFIX "isSideChain");
3161 lv2_index = lilv_new_uri(world, LV2_CORE__index);
3162 lv2_integer = lilv_new_uri(world, LV2_CORE__integer);
3163 lv2_default = lilv_new_uri(world, LV2_CORE__default);
3164 lv2_minimum = lilv_new_uri(world, LV2_CORE__minimum);
3165 lv2_maximum = lilv_new_uri(world, LV2_CORE__maximum);
3166 lv2_reportsLatency = lilv_new_uri(world, LV2_CORE__reportsLatency);
3167 lv2_sampleRate = lilv_new_uri(world, LV2_CORE__sampleRate);
3168 lv2_toggled = lilv_new_uri(world, LV2_CORE__toggled);
3169 lv2_designation = lilv_new_uri(world, LV2_CORE__designation);
3170 lv2_enumeration = lilv_new_uri(world, LV2_CORE__enumeration);
3171 lv2_freewheeling = lilv_new_uri(world, LV2_CORE__freeWheeling);
3172 midi_MidiEvent = lilv_new_uri(world, LILV_URI_MIDI_EVENT);
3173 rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
3174 rdfs_label = lilv_new_uri(world, LILV_NS_RDFS "label");
3175 rdfs_range = lilv_new_uri(world, LILV_NS_RDFS "range");
3176 rsz_minimumSize = lilv_new_uri(world, LV2_RESIZE_PORT__minimumSize);
3177 time_Position = lilv_new_uri(world, LV2_TIME__Position);
3178 ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI);
3179 ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
3180 ui_externalkx = lilv_new_uri(world, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget");
3181 units_unit = lilv_new_uri(world, LV2_UNITS__unit);
3182 units_render = lilv_new_uri(world, LV2_UNITS__render);
3183 units_hz = lilv_new_uri(world, LV2_UNITS__hz);
3184 units_midiNote = lilv_new_uri(world, LV2_UNITS__midiNote);
3185 units_db = lilv_new_uri(world, LV2_UNITS__db);
3186 patch_writable = lilv_new_uri(world, LV2_PATCH__writable);
3187 patch_Message = lilv_new_uri(world, LV2_PATCH__Message);
3189 lv2_noSampleAccurateCtrl = lilv_new_uri(world, "http://ardour.org/lv2/ext#noSampleAccurateControls"); // deprecated 2016-09-18
3190 auto_can_write_automatation = lilv_new_uri(world, LV2_AUTOMATE_URI__can_write);
3191 auto_automation_control = lilv_new_uri(world, LV2_AUTOMATE_URI__control);
3192 auto_automation_controlled = lilv_new_uri(world, LV2_AUTOMATE_URI__controlled);
3193 auto_automation_controller = lilv_new_uri(world, LV2_AUTOMATE_URI__controller);
3194 inline_display_in_gui = lilv_new_uri(world, LV2_INLINEDISPLAY__in_gui);
3196 #ifdef HAVE_LV2_1_2_0
3197 bufz_powerOf2BlockLength = lilv_new_uri(world, LV2_BUF_SIZE__powerOf2BlockLength);
3198 bufz_fixedBlockLength = lilv_new_uri(world, LV2_BUF_SIZE__fixedBlockLength);
3199 bufz_nominalBlockLength = lilv_new_uri(world, "http://lv2plug.in/ns/ext/buf-size#nominalBlockLength");
3200 bufz_coarseBlockLength = lilv_new_uri(world, "http://lv2plug.in/ns/ext/buf-size#coarseBlockLength");
3205 LV2World::~LV2World()
3210 #ifdef HAVE_LV2_1_2_0
3211 lilv_node_free(bufz_coarseBlockLength);
3212 lilv_node_free(bufz_nominalBlockLength);
3213 lilv_node_free(bufz_fixedBlockLength);
3214 lilv_node_free(bufz_powerOf2BlockLength);
3217 lilv_node_free(lv2_noSampleAccurateCtrl);
3218 lilv_node_free(auto_can_write_automatation);
3219 lilv_node_free(auto_automation_control);
3220 lilv_node_free(auto_automation_controlled);
3221 lilv_node_free(auto_automation_controller);
3223 lilv_node_free(patch_Message);
3224 lilv_node_free(patch_writable);
3225 lilv_node_free(units_hz);
3226 lilv_node_free(units_midiNote);
3227 lilv_node_free(units_db);
3228 lilv_node_free(units_unit);
3229 lilv_node_free(units_render);
3230 lilv_node_free(ui_externalkx);
3231 lilv_node_free(ui_external);
3232 lilv_node_free(ui_GtkUI);
3233 lilv_node_free(time_Position);
3234 lilv_node_free(rsz_minimumSize);
3235 lilv_node_free(rdfs_comment);
3236 lilv_node_free(rdfs_label);
3237 lilv_node_free(rdfs_range);
3238 lilv_node_free(midi_MidiEvent);
3239 lilv_node_free(lv2_designation);
3240 lilv_node_free(lv2_enumeration);
3241 lilv_node_free(lv2_freewheeling);
3242 lilv_node_free(lv2_toggled);
3243 lilv_node_free(lv2_sampleRate);
3244 lilv_node_free(lv2_reportsLatency);
3245 lilv_node_free(lv2_index);
3246 lilv_node_free(lv2_integer);
3247 lilv_node_free(lv2_isSideChain);
3248 lilv_node_free(lv2_inPlaceBroken);
3249 lilv_node_free(lv2_OutputPort);
3250 lilv_node_free(lv2_InputPort);
3251 lilv_node_free(lv2_ControlPort);
3252 lilv_node_free(lv2_AudioPort);
3253 lilv_node_free(groups_group);
3254 lilv_node_free(groups_element);
3255 lilv_node_free(ext_rangeSteps);
3256 lilv_node_free(ext_notAutomatic);
3257 lilv_node_free(ext_causesArtifacts);
3258 lilv_node_free(ext_expensive);
3259 lilv_node_free(ext_notOnGUI);
3260 lilv_node_free(ext_logarithmic);
3261 lilv_node_free(ev_EventPort);
3262 lilv_node_free(atom_supports);
3263 lilv_node_free(atom_eventTransfer);
3264 lilv_node_free(atom_bufferType);
3265 lilv_node_free(atom_Sequence);
3266 lilv_node_free(atom_Chunk);
3267 lilv_node_free(atom_AtomPort);
3268 lilv_world_free(world);
3273 LV2World::load_bundled_plugins(bool verbose)
3275 if (!_bundle_checked) {
3277 cout << "Scanning folders for bundled LV2s: " << ARDOUR::lv2_bundled_search_path().to_string() << endl;
3280 vector<string> plugin_objects;
3281 find_paths_matching_filter (plugin_objects, ARDOUR::lv2_bundled_search_path(), lv2_filter, 0, true, true, true);
3282 for ( vector<string>::iterator x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
3283 #ifdef PLATFORM_WINDOWS
3284 string uri = "file:///" + *x + "/";
3286 string uri = "file://" + *x + "/";
3288 LilvNode *node = lilv_new_uri(world, uri.c_str());
3289 lilv_world_load_bundle(world, node);
3290 lilv_node_free(node);
3293 lilv_world_load_all(world);
3294 _bundle_checked = true;
3298 LV2PluginInfo::LV2PluginInfo (const char* plugin_uri)
3301 _plugin_uri = strdup(plugin_uri);
3304 LV2PluginInfo::~LV2PluginInfo()
3311 LV2PluginInfo::load(Session& session)
3315 const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world);
3316 LilvNode* uri = lilv_new_uri(_world.world, _plugin_uri);
3317 if (!uri) { throw failed_constructor(); }
3318 const LilvPlugin* lp = lilv_plugins_get_by_uri(plugins, uri);
3319 if (!lp) { throw failed_constructor(); }
3320 plugin.reset(new LV2Plugin(session.engine(), session, lp, session.frame_rate()));
3321 lilv_node_free(uri);
3322 plugin->set_info(PluginInfoPtr(shared_from_this ()));
3324 } catch (failed_constructor& err) {
3325 return PluginPtr((Plugin*)0);
3331 std::vector<Plugin::PresetRecord>
3332 LV2PluginInfo::get_presets (bool /*user_only*/) const
3334 std::vector<Plugin::PresetRecord> p;
3335 #ifndef NO_PLUGIN_STATE
3336 const LilvPlugin* lp = NULL;
3339 const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world);
3340 LilvNode* uri = lilv_new_uri(_world.world, _plugin_uri);
3341 if (!uri) { throw failed_constructor(); }
3342 lp = lilv_plugins_get_by_uri(plugins, uri);
3343 if (!lp) { throw failed_constructor(); }
3344 lilv_node_free(uri);
3345 } catch (failed_constructor& err) {
3349 // see LV2Plugin::find_presets
3350 LilvNode* lv2_appliesTo = lilv_new_uri(_world.world, LV2_CORE__appliesTo);
3351 LilvNode* pset_Preset = lilv_new_uri(_world.world, LV2_PRESETS__Preset);
3352 LilvNode* rdfs_label = lilv_new_uri(_world.world, LILV_NS_RDFS "label");
3354 LilvNodes* presets = lilv_plugin_get_related(lp, pset_Preset);
3355 LILV_FOREACH(nodes, i, presets) {
3356 const LilvNode* preset = lilv_nodes_get(presets, i);
3357 lilv_world_load_resource(_world.world, preset);
3358 LilvNode* name = get_value(_world.world, preset, rdfs_label);
3359 bool userpreset = true; // TODO
3361 p.push_back (Plugin::PresetRecord (lilv_node_as_string(preset), lilv_node_as_string(name), userpreset));
3362 lilv_node_free(name);
3365 lilv_nodes_free(presets);
3366 lilv_node_free(rdfs_label);
3367 lilv_node_free(pset_Preset);
3368 lilv_node_free(lv2_appliesTo);
3374 LV2PluginInfo::in_category (const std::string &c) const
3376 // TODO use untranslated lilv_plugin_get_class()
3377 // match gtk2_ardour/plugin_selector.cc
3378 return category == c;
3382 LV2PluginInfo::is_instrument () const
3384 if (category == "Instrument") {
3388 /* until we make sure that category remains untranslated in the lv2.ttl spec
3389 * and until most instruments also classify themselves as such, there's a 2nd check:
3391 if (n_inputs.n_midi() > 0 && n_inputs.n_audio() == 0 && n_outputs.n_audio() > 0) {
3399 LV2PluginInfo::discover()
3402 world.load_bundled_plugins();
3403 _world.load_bundled_plugins(true);
3405 PluginInfoList* plugs = new PluginInfoList;
3406 const LilvPlugins* plugins = lilv_world_get_all_plugins(world.world);
3408 LILV_FOREACH(plugins, i, plugins) {
3409 const LilvPlugin* p = lilv_plugins_get(plugins, i);
3410 const LilvNode* pun = lilv_plugin_get_uri(p);
3412 LV2PluginInfoPtr info(new LV2PluginInfo(lilv_node_as_string(pun)));
3414 LilvNode* name = lilv_plugin_get_name(p);
3415 if (!name || !lilv_plugin_get_port_by_index(p, 0)) {
3416 warning << "Ignoring invalid LV2 plugin "
3417 << lilv_node_as_string(lilv_plugin_get_uri(p))
3422 if (lilv_plugin_has_feature(p, world.lv2_inPlaceBroken)) {
3423 warning << string_compose(
3424 _("Ignoring LV2 plugin \"%1\" since it cannot do inplace processing."),
3425 lilv_node_as_string(name)) << endmsg;
3426 lilv_node_free(name);
3430 #ifdef HAVE_LV2_1_2_0
3431 LilvNodes *required_features = lilv_plugin_get_required_features (p);
3432 if (lilv_nodes_contains (required_features, world.bufz_powerOf2BlockLength) ||
3433 lilv_nodes_contains (required_features, world.bufz_fixedBlockLength)
3435 warning << string_compose(
3436 _("Ignoring LV2 plugin \"%1\" because its buffer-size requirements cannot be satisfied."),
3437 lilv_node_as_string(name)) << endmsg;
3438 lilv_nodes_free(required_features);
3439 lilv_node_free(name);
3442 lilv_nodes_free(required_features);
3447 info->name = string(lilv_node_as_string(name));
3448 lilv_node_free(name);
3449 ARDOUR::PluginScanMessage(_("LV2"), info->name, false);
3451 const LilvPluginClass* pclass = lilv_plugin_get_class(p);
3452 const LilvNode* label = lilv_plugin_class_get_label(pclass);
3453 info->category = lilv_node_as_string(label);
3455 LilvNode* author_name = lilv_plugin_get_author_name(p);
3456 info->creator = author_name ? string(lilv_node_as_string(author_name)) : "Unknown";
3457 lilv_node_free(author_name);
3459 info->path = "/NOPATH"; // Meaningless for LV2
3461 /* count atom-event-ports that feature
3462 * atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent>
3464 * TODO: nicely ask drobilla to make a lilv_ call for that
3466 int count_midi_out = 0;
3467 int count_midi_in = 0;
3468 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
3469 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
3470 if (lilv_port_is_a(p, port, world.atom_AtomPort)) {
3471 LilvNodes* buffer_types = lilv_port_get_value(
3472 p, port, world.atom_bufferType);
3473 LilvNodes* atom_supports = lilv_port_get_value(
3474 p, port, world.atom_supports);
3476 if (lilv_nodes_contains(buffer_types, world.atom_Sequence)
3477 && lilv_nodes_contains(atom_supports, world.midi_MidiEvent)) {
3478 if (lilv_port_is_a(p, port, world.lv2_InputPort)) {
3481 if (lilv_port_is_a(p, port, world.lv2_OutputPort)) {
3485 lilv_nodes_free(buffer_types);
3486 lilv_nodes_free(atom_supports);
3490 info->n_inputs.set_audio(
3491 lilv_plugin_get_num_ports_of_class(
3492 p, world.lv2_InputPort, world.lv2_AudioPort, NULL));
3493 info->n_inputs.set_midi(
3494 lilv_plugin_get_num_ports_of_class(
3495 p, world.lv2_InputPort, world.ev_EventPort, NULL)
3498 info->n_outputs.set_audio(
3499 lilv_plugin_get_num_ports_of_class(
3500 p, world.lv2_OutputPort, world.lv2_AudioPort, NULL));
3501 info->n_outputs.set_midi(
3502 lilv_plugin_get_num_ports_of_class(
3503 p, world.lv2_OutputPort, world.ev_EventPort, NULL)
3506 info->unique_id = lilv_node_as_uri(lilv_plugin_get_uri(p));
3507 info->index = 0; // Meaningless for LV2
3509 plugs->push_back(info);