28 #include <glib/gstdio.h>
29 #include <glib/gprintf.h>
32 #include <boost/utility.hpp>
40 #include "libardour-config.h"
44 #include "ardour/debug.h"
49 #include "ardour/utils.h"
56 #include <lilv/lilv.h>
58 #include "lv2/lv2plug.in/ns/ext/atom/atom.h"
59 #include "lv2/lv2plug.in/ns/ext/atom/forge.h"
60 #include "lv2/lv2plug.in/ns/ext/log/log.h"
61 #include "lv2/lv2plug.in/ns/ext/midi/midi.h"
62 #include "lv2/lv2plug.in/ns/ext/port-props/port-props.h"
63 #include "lv2/lv2plug.in/ns/ext/presets/presets.h"
64 #include "lv2/lv2plug.in/ns/ext/state/state.h"
65 #include "lv2/lv2plug.in/ns/ext/time/time.h"
66 #include "lv2/lv2plug.in/ns/ext/worker/worker.h"
67 #include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h"
68 #include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
69 #include "lv2/lv2plug.in/ns/extensions/units/units.h"
70 #include "lv2/lv2plug.in/ns/ext/patch/patch.h"
72 #include "lv2/lv2plug.in/ns/ext/buf-size/buf-size.h"
73 #include "lv2/lv2plug.in/ns/ext/options/options.h"
79 #include <suil/suil.h>
83 #ifndef LV2_ATOM_CONTENTS_CONST
84 #define LV2_ATOM_CONTENTS_CONST(type, atom) \
85 ((const void*)((const uint8_t*)(atom) + sizeof(type)))
87 #ifndef LV2_ATOM_BODY_CONST
88 #define LV2_ATOM_BODY_CONST(atom) LV2_ATOM_CONTENTS_CONST(LV2_Atom, atom)
90 #ifndef LV2_PATCH__property
91 #define LV2_PATCH__property LV2_PATCH_PREFIX "property"
93 #ifndef LV2_PATCH__value
94 #define LV2_PATCH__value LV2_PATCH_PREFIX "value"
96 #ifndef LV2_PATCH__writable
97 #define LV2_PATCH__writable LV2_PATCH_PREFIX "writable"
115 void load_bundled_plugins(
bool verbose=
false);
168 static LV2_Worker_Status
176 return (LV2_Worker_Status)plugin->
work(size, data);
180 LV2_WORKER_SUCCESS : LV2_WORKER_ERR_UNKNOWN;
185 static LV2_Worker_Status
197 LV2_WORKER_SUCCESS : LV2_WORKER_ERR_UNKNOWN;
210 const int ret = g_vasprintf(&str, fmt, args);
211 if (type == URIMap::instance().urids.log_Error) {
213 }
else if (type == URIMap::instance().urids.log_Warning) {
215 }
else if (type == URIMap::instance().urids.log_Note) {
225 const char* fmt, ...)
229 const int ret =
log_vprintf(handle, type, fmt, args);
235 Impl() : plugin(0),
ui(0), ui_type(0),
name(0), author(0), instance(0)
243 const LilvPort* designated_input (
const char* uri,
void** bufptrs[],
void** bufptr);
259 const void* c_plugin,
261 :
Plugin (engine, session)
267 , _patch_port_in_index((uint32_t)-1)
268 , _patch_port_out_index((uint32_t)-1)
269 , _uri_map(
URIMap::instance())
271 init(c_plugin, rate);
280 , _insert_id(other._insert_id)
281 , _patch_port_in_index((uint32_t)-1)
282 , _patch_port_out_index((uint32_t)-1)
283 , _uri_map(
URIMap::instance())
329 LilvNode* state_iface_uri = lilv_new_uri(_world.
world, LV2_STATE__interface);
330 LilvNode* state_uri = lilv_new_uri(_world.
world, LV2_STATE_URI);
333 lilv_plugin_has_extension_data(plugin, state_iface_uri)
335 || lilv_plugin_has_feature(plugin, state_uri);
336 lilv_node_free(state_uri);
337 lilv_node_free(state_iface_uri);
339 _features = (LV2_Feature**)calloc(11,
sizeof(LV2_Feature*));
348 unsigned n_features = 7;
349 #ifdef HAVE_LV2_1_2_0
356 #ifdef HAVE_LV2_1_2_0
358 LV2_Options_Option options[] = {
365 { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL }
373 LV2_State_Make_Path* make_path = (LV2_State_Make_Path*)malloc(
374 sizeof(LV2_State_Make_Path));
375 make_path->handle =
this;
379 LV2_Log_Log* log = (LV2_Log_Log*)malloc(
sizeof(LV2_Log_Log));
385 LilvNode* worker_schedule = lilv_new_uri(_world.
world, LV2_WORKER__schedule);
386 if (lilv_plugin_has_feature(plugin, worker_schedule)) {
387 LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc(
388 sizeof(LV2_Worker_Schedule));
391 schedule->handle =
this;
396 lilv_node_free(worker_schedule);
399 _impl->
name = lilv_plugin_get_name(plugin);
400 _impl->
author = lilv_plugin_get_author_name(plugin);
411 LilvNode* worker_iface_uri = lilv_new_uri(_world.
world, LV2_WORKER__interface);
412 if (lilv_plugin_has_extension_data(plugin, worker_iface_uri)) {
414 LV2_WORKER__interface);
416 lilv_node_free(worker_iface_uri);
420 _(
"LV2: \"%1\" cannot be used, since it cannot do inplace processing"),
427 #ifdef HAVE_LILV_0_16_0
429 LilvState* state = lilv_state_new_from_world(
432 lilv_state_restore(state,
_impl->
instance, NULL, NULL, 0, NULL);
439 for (uint32_t i = 0; i <
num_ports; ++i) {
440 const LilvPort* port = lilv_plugin_get_port_by_index(
_impl->
plugin, i);
442 size_t minimumSize = 0;
450 "LV2: \"%1\" port %2 is neither input nor output",
463 LilvNodes* buffer_types = lilv_port_get_value(
465 LilvNodes* atom_supports = lilv_port_get_value(
468 if (lilv_nodes_contains(buffer_types, _world.
atom_Sequence)) {
473 if (lilv_nodes_contains(atom_supports, _world.
time_Position)) {
476 if (lilv_nodes_contains(atom_supports, _world.
patch_Message)) {
486 LilvNode* min_size = min_size_v ? lilv_nodes_get_first(min_size_v) : NULL;
487 if (min_size && lilv_node_is_int(min_size)) {
488 minimumSize = lilv_node_as_int(min_size);
490 lilv_nodes_free(min_size_v);
491 lilv_nodes_free(buffer_types);
492 lilv_nodes_free(atom_supports);
495 "LV2: \"%1\" port %2 has no known data type",
510 const bool latent = lilv_plugin_has_latency(plugin);
511 const uint32_t latency_index = (latent)
512 ? lilv_plugin_get_latency_port_index(plugin)
517 for (uint32_t i = 0; i <
num_ports; ++i) {
523 for (uint32_t i = 0; i <
num_ports; ++i) {
524 const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
525 const LilvNode* sym = lilv_port_get_symbol(plugin, port);
528 _port_indices.insert(std::make_pair(lilv_node_as_string(sym), i));
533 lilv_port_get_range(plugin, port, &def, NULL, NULL);
534 _defaults[i] = def ? lilv_node_as_float(def) : 0.0f;
535 if (lilv_port_has_property (plugin, port, _world.
lv2_sampleRate)) {
542 if (latent && i == latency_index) {
560 LilvUIs* uis = lilv_plugin_get_uis(plugin);
561 if (lilv_uis_size(uis) > 0) {
564 LILV_FOREACH(uis, u, uis) {
565 const LilvUI* this_ui = lilv_uis_get(uis, u);
566 const LilvNode* this_ui_type = NULL;
567 if (lilv_ui_is_supported(this_ui,
579 LILV_FOREACH(uis, i, uis) {
580 const LilvUI*
ui = lilv_uis_get(uis, i);
581 if (lilv_ui_is_a(ui, _world.
ui_GtkUI)) {
591 LILV_FOREACH(uis, i, uis) {
592 const LilvUI*
ui = lilv_uis_get(uis, i);
665 const LilvNode* s = lilv_ui_get_uri(
_impl->
ui);
666 LilvNode* p = lilv_new_uri(_world.
world, LV2_CORE__optionalFeature);
667 LilvNode* fs = lilv_new_uri(_world.
world, LV2_UI__fixedSize);
668 LilvNode* nrs = lilv_new_uri(_world.
world, LV2_UI__noUserResize);
670 LilvNodes* fs_matches = lilv_world_find_nodes(_world.
world, s, p, fs);
671 LilvNodes* nrs_matches = lilv_world_find_nodes(_world.
world, s, p, nrs);
673 lilv_nodes_free(nrs_matches);
674 lilv_nodes_free(fs_matches);
679 return !fs_matches && !nrs_matches;
685 return lilv_node_as_uri(lilv_plugin_get_uri(
_impl->
plugin));
691 return lilv_node_as_uri(lilv_plugin_get_uri(
_impl->
plugin));
733 const LilvPort* port = lilv_plugin_get_port_by_index(
_impl->
plugin, index);
738 const LilvNode* sym = lilv_port_get_symbol(
_impl->
plugin, port);
739 return lilv_node_as_string(sym);
745 const map<string, uint32_t>::const_iterator i =
_port_indices.find(symbol);
758 "%1 set parameter %2 to %3\n",
name(), which, val));
760 if (which < lilv_plugin_get_num_ports(
_impl->
plugin)) {
768 _(
"Illegal parameter number used with plugin \"%1\". "
769 "This is a bug in either %2 or the LV2 plugin <%3>"),
792 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
793 lilv_nodes_free(comments);
803 LilvNodes* comments = lilv_port_get_value(
805 lilv_plugin_get_port_by_index(
_impl->
plugin, which),
809 const std::string docs(lilv_node_as_string(lilv_nodes_get_first(comments)));
810 lilv_nodes_free(comments);
821 for (uint32_t c = 0, x = 0; x < lilv_plugin_get_num_ports(
_impl->
plugin); ++x) {
836 return lilv_instance_get_extension_data(
_impl->
instance, uri);
868 return Glib::build_filename(
plugin_dir(),
"scratch");
875 return Glib::build_filename(
plugin_dir(),
"files");
895 "File path \"%1\" requested but LV2 %2 has no insert ID",
897 return g_strdup(path);
900 const std::string abs_path = Glib::build_filename(me->
scratch_dir(), path);
901 const std::string dirname = Glib::path_get_dirname(abs_path);
902 g_mkdir_with_parents(dirname.c_str(), 0744);
907 return g_strndup(abs_path.c_str(), abs_path.length());
932 g_mkdir_with_parents(new_dir.c_str(), 0744);
934 LilvState* state = lilv_state_new_from_instance(
948 lilv_state_save(_world.
world,
960 lilv_state_free(state);
971 get_value(LilvWorld* world,
const LilvNode* subject,
const LilvNode* predicate)
973 LilvNodes* vs = lilv_world_find_nodes(world, subject, predicate, NULL);
975 LilvNode* node = lilv_node_duplicate(lilv_nodes_get_first(vs));
985 LilvNode* lv2_appliesTo = lilv_new_uri(_world.
world, LV2_CORE__appliesTo);
986 LilvNode* pset_Preset = lilv_new_uri(_world.
world, LV2_PRESETS__Preset);
987 LilvNode* rdfs_label = lilv_new_uri(_world.
world, LILV_NS_RDFS
"label");
989 LilvNodes* presets = lilv_plugin_get_related(
_impl->
plugin, pset_Preset);
990 LILV_FOREACH(nodes, i, presets) {
991 const LilvNode* preset = lilv_nodes_get(presets, i);
992 lilv_world_load_resource(_world.
world, preset);
995 _presets.insert(std::make_pair(lilv_node_as_string(preset),
997 lilv_node_as_string(preset),
998 lilv_node_as_string(name))));
999 lilv_node_free(name);
1002 _(
"Plugin \"%1\" preset \"%2\" is missing a label\n"),
1003 lilv_node_as_string(lilv_plugin_get_uri(
_impl->
plugin)),
1004 lilv_node_as_string(preset)) <<
endmsg;
1007 lilv_nodes_free(presets);
1009 lilv_node_free(rdfs_label);
1010 lilv_node_free(pset_Preset);
1011 lilv_node_free(lv2_appliesTo);
1026 const uint32_t
port_index =
self->port_index(port_symbol);
1027 if (port_index != (uint32_t)-1) {
1028 self->set_parameter(port_index, *(
const float*)value);
1035 LilvWorld* world = _world.
world;
1036 LilvNode* pset = lilv_new_uri(world, r.
uri.c_str());
1037 LilvState* state = lilv_state_new_from_world(world,
_uri_map.
urid_map(), pset);
1041 lilv_state_free(state);
1045 lilv_node_free(pset);
1057 uint32_t index = plugin->
port_index(port_symbol);
1058 if (index != (uint32_t) -1) {
1061 *size =
sizeof(float);
1077 LilvNode* plug_name = lilv_plugin_get_name(
_impl->
plugin);
1080 const string file_name = base_name +
".ttl";
1081 const string bundle = Glib::build_filename(
1082 Glib::get_home_dir(),
1083 Glib::build_filename(
".lv2", prefix +
"_" + base_name +
".lv2"));
1085 LilvState* state = lilv_state_new_from_instance(
1095 LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE,
1099 lilv_state_set_label(state, name.c_str());
1110 lilv_state_free(state);
1112 std::string
uri = Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
1113 LilvNode *node_bundle = lilv_new_uri(_world.
world, Glib::filename_to_uri(Glib::build_filename(bundle,
"/")).c_str());
1114 LilvNode *node_preset = lilv_new_uri(_world.
world, uri.c_str());
1115 #ifdef HAVE_LILV_0_21_3
1116 lilv_world_unload_resource(_world.
world, node_preset);
1117 lilv_world_unload_bundle(_world.
world, node_bundle);
1119 lilv_world_load_bundle(_world.
world, node_bundle);
1120 lilv_world_load_resource(_world.
world, node_preset);
1121 lilv_node_free(node_bundle);
1122 lilv_node_free(node_preset);
1123 lilv_node_free(plug_name);
1130 #ifdef HAVE_LILV_0_21_3
1138 LilvWorld* world = _world.
world;
1139 LilvNode* pset = lilv_new_uri(world, r->
uri.c_str());
1140 LilvState* state = lilv_state_new_from_world(world,
_uri_map.
urid_map(), pset);
1142 lilv_node_free(pset);
1149 lilv_state_delete(world, state);
1151 lilv_state_free(state);
1152 lilv_node_free(pset);
1169 for (uint32_t i = 0; i <
num_ports(); ++i) {
1183 const uint8_t* body)
1185 const uint32_t buf_size =
sizeof(
UIMessage) + size;
1186 vector<uint8_t> buf(buf_size);
1192 memcpy(msg + 1, body, size);
1194 return (dest->
write(&buf[0], buf_size) == buf_size);
1201 const uint8_t* body)
1216 uint32_t bufsiz = 32768;
1220 rbs = max((
size_t) bufsiz * 8, rbs);
1225 error <<
"Error writing from UI to plugin" <<
endmsg;
1235 const uint8_t* body)
1238 error <<
"Error writing from plugin to UI" <<
endmsg;
1247 switch (value.
type()) {
1255 lv2_atom_forge_bool(forge, value.
get_bool());
1258 lv2_atom_forge_double(forge, value.
get_double());
1261 lv2_atom_forge_float(forge, value.
get_float());
1264 lv2_atom_forge_int(forge, value.
get_int());
1267 lv2_atom_forge_long(forge, value.
get_long());
1270 lv2_atom_forge_path(
1274 lv2_atom_forge_string(
1288 if (uri == LV2_ATOM__Bool) {
1290 }
else if (uri == LV2_ATOM__Double) {
1292 }
else if (uri == LV2_ATOM__Float) {
1294 }
else if (uri == LV2_ATOM__Int) {
1296 }
else if (uri == LV2_ATOM__Long) {
1298 }
else if (uri == LV2_ATOM__Path) {
1300 }
else if (uri == LV2_ATOM__String) {
1302 }
else if (uri == LV2_ATOM__URI) {
1314 error <<
"LV2: set_property called with unset patch_port_in_index" <<
endmsg;
1317 error <<
"LV2: set_property called with void value" <<
endmsg;
1323 LV2_Atom_Forge_Frame frame;
1326 lv2_atom_forge_set_buffer(forge, buf,
sizeof(buf));
1329 #ifdef HAVE_LV2_1_10_0
1332 lv2_atom_forge_urid(forge, key);
1337 lv2_atom_forge_urid(forge, key);
1344 const LV2_Atom*
const atom = (
const LV2_Atom*)buf;
1347 lv2_atom_total_size(atom),
1348 (
const uint8_t*)atom);
1366 }
else if (lilv_nodes_contains(units, _world.
units_db)) {
1368 }
else if (lilv_nodes_contains(units, _world.
units_hz)) {
1371 if (lilv_nodes_size(units) > 0) {
1372 const LilvNode* unit = lilv_nodes_get_first(units);
1375 desc.
print_fmt = lilv_node_as_string(render);
1376 lilv_node_free(render);
1385 const LilvNode* subject)
1387 LilvWorld* lworld = _world.
world;
1392 LilvNodes* units = lilv_world_find_nodes(lworld, subject, _world.
units_unit, NULL);
1394 desc.
label = lilv_node_as_string(label);
1396 if (def && lilv_node_is_float(def)) {
1397 desc.
normal = lilv_node_as_float(def);
1399 if (minimum && lilv_node_is_float(minimum)) {
1400 desc.
lower = lilv_node_as_float(minimum);
1402 if (maximum && lilv_node_is_float(maximum)) {
1403 desc.
upper = lilv_node_as_float(maximum);
1411 lilv_nodes_free(units);
1412 lilv_node_free(label);
1413 lilv_node_free(def);
1414 lilv_node_free(minimum);
1415 lilv_node_free(maximum);
1421 LilvWorld* lworld = _world.
world;
1422 const LilvNode* subject = lilv_plugin_get_uri(
_impl->
plugin);
1423 LilvNodes*
properties = lilv_world_find_nodes(
1425 LILV_FOREACH(nodes, p, properties) {
1427 const LilvNode* prop = lilv_nodes_get(properties, p);
1431 lilv_node_as_uri(prop)) <<
endmsg;
1439 lilv_node_as_uri(prop), lilv_node_as_uri(range)) <<
endmsg;
1448 descs.insert(std::make_pair(desc.
key, desc));
1450 lilv_node_free(range);
1452 lilv_nodes_free(properties);
1464 LV2_Atom_Forge_Frame frame;
1467 lv2_atom_forge_set_buffer(forge, buf,
sizeof(buf));
1470 #ifdef HAVE_LV2_1_10_0
1477 const LV2_Atom*
const atom = (
const LV2_Atom*)buf;
1480 lv2_atom_total_size(atom),
1481 (
const uint8_t*)atom);
1489 uint32_t bufsiz = 32768;
1494 rbs = max((
size_t) bufsiz * 8, rbs);
1507 while (read_space >
sizeof(
UIMessage)) {
1509 if (
_to_ui->
read((uint8_t*)&msg,
sizeof(msg)) !=
sizeof(msg)) {
1510 error <<
"Error reading from Plugin=>UI RingBuffer" <<
endmsg;
1513 vector<uint8_t> body(msg.
size);
1515 error <<
"Error reading from Plugin=>UI RingBuffer" <<
endmsg;
1521 read_space -=
sizeof(msg) + msg.
size;
1558 error <<
_(
"Bad node sent to LV2Plugin::set_state") <<
endmsg;
1562 #ifndef NO_PLUGIN_STATE
1564 if (version < 3000) {
1570 for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
1574 if ((prop = child->
property(
"symbol")) != 0) {
1575 sym = prop->
value().c_str();
1581 map<string, uint32_t>::iterator i =
_port_indices.find(sym);
1584 port_id = i->second;
1590 if ((prop = child->
property(
"value")) != 0) {
1591 value = prop->
value().c_str();
1601 if ((prop = node.
property(
"state-dir")) != 0) {
1604 "LV2: failed to parse state version from \"%1\"",
1608 std::string state_file = Glib::build_filename(
1610 Glib::build_filename(prop->
value(),
"state.ttl"));
1612 LilvState* state = lilv_state_new_from_file(
1615 lilv_state_restore(state,
_impl->
instance, NULL, NULL, 0, NULL);
1627 const LilvPort* port = lilv_plugin_get_port_by_index(
_impl->
plugin, which);
1634 LilvNodes* portunits;
1635 LilvNode *def, *min, *max;
1636 lilv_port_get_range(
_impl->
plugin, port, &def, &min, &max);
1646 desc.
normal = def ? lilv_node_as_float(def) : 0.0f;
1647 desc.
lower = min ? lilv_node_as_float(min) : 0.0f;
1648 desc.
upper = max ? lilv_node_as_float(max) : 1.0f;
1664 lilv_node_free(def);
1665 lilv_node_free(min);
1666 lilv_node_free(max);
1667 lilv_nodes_free(portunits);
1679 return X_(
"hidden");
1684 return X_(
"hidden");
1689 return X_(
"latency");
1694 string ret(lilv_node_as_string(name));
1695 lilv_node_free(name);
1712 set<Evoral::Parameter>
1715 set<Evoral::Parameter> ret;
1773 int count_atom_out = 0;
1774 int count_atom_in = 0;
1775 int minimumSize = 32768;
1776 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
1777 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
1779 LilvNodes* buffer_types = lilv_port_get_value(
1781 LilvNodes* atom_supports = lilv_port_get_value(
1784 if (!lilv_nodes_contains(buffer_types, _world.
atom_Sequence)
1793 LilvNode* min_size = min_size_v ? lilv_nodes_get_first(min_size_v) : NULL;
1794 if (min_size && lilv_node_is_int(min_size)) {
1795 minimumSize = std::max(minimumSize, lilv_node_as_int(min_size));
1797 lilv_nodes_free(min_size_v);
1799 lilv_nodes_free(buffer_types);
1800 lilv_nodes_free(atom_supports);
1805 name(), count_atom_in, count_atom_out));
1807 const int total_atom_buffers = (count_atom_in + count_atom_out);
1814 for (
int i = 0; i < total_atom_buffers; ++i ) {
1829 Timecode::BBT_Time& bbt,
1836 uint8_t pos_buf[256];
1837 lv2_atom_forge_set_buffer(forge, pos_buf,
sizeof(pos_buf));
1838 LV2_Atom_Forge_Frame frame;
1839 #ifdef HAVE_LV2_1_10_0
1840 lv2_atom_forge_object(forge, &frame, 1, urids.
time_Position);
1842 lv2_atom_forge_long(forge, position);
1844 lv2_atom_forge_float(forge, speed);
1846 lv2_atom_forge_float(forge, bbt.beats - 1 +
1847 (bbt.ticks / Timecode::BBT_Time::ticks_per_beat));
1848 lv2_atom_forge_key(forge, urids.
time_bar);
1849 lv2_atom_forge_long(forge, bbt.bars - 1);
1857 lv2_atom_forge_blank(forge, &frame, 1, urids.
time_Position);
1858 lv2_atom_forge_property_head(forge, urids.
time_frame, 0);
1859 lv2_atom_forge_long(forge, position);
1860 lv2_atom_forge_property_head(forge, urids.
time_speed, 0);
1861 lv2_atom_forge_float(forge, speed);
1862 lv2_atom_forge_property_head(forge, urids.
time_barBeat, 0);
1863 lv2_atom_forge_float(forge, bbt.beats - 1 +
1864 (bbt.ticks / Timecode::BBT_Time::ticks_per_beat));
1865 lv2_atom_forge_property_head(forge, urids.
time_bar, 0);
1866 lv2_atom_forge_long(forge, bbt.bars - 1);
1867 lv2_atom_forge_property_head(forge, urids.
time_beatUnit, 0);
1876 const LV2_Atom*
const atom = (
const LV2_Atom*)pos_buf;
1878 (
const uint8_t*)(atom + 1));
1892 Metrics::const_iterator metric_i = tmap.
metrics_end();
1909 uint32_t
const nil_index = std::numeric_limits<uint32_t>::max();
1911 uint32_t audio_in_index = 0;
1912 uint32_t audio_out_index = 0;
1913 uint32_t midi_in_index = 0;
1914 uint32_t midi_out_index = 0;
1915 uint32_t atom_port_index = 0;
1918 uint32_t index = nil_index;
1952 (flags & PORT_INPUT), index, (flags &
PORT_EVENT));
1960 if (valid && (flags & PORT_INPUT)) {
1961 Timecode::BBT_Time bbt;
1962 if ((flags & PORT_POSITION)) {
1985 while (m != m_end || (metric_i != tmap.
metrics_end() &&
1986 (*metric_i)->frame() < tend)) {
1989 if (m != m_end && (!metric || metric->
frame() > (*m).time())) {
1996 bbt = metric->
start();
2004 }
else if (!valid) {
2007 scratch_bufs.ensure_lv2_bufsize((flags & PORT_INPUT),
2010 (flags & PORT_INPUT), 0, (flags &
PORT_EVENT));
2023 while (read_space >
sizeof(
UIMessage)) {
2025 if (
_from_ui->
read((uint8_t*)&msg,
sizeof(msg)) !=
sizeof(msg)) {
2026 error <<
"Error reading from UI=>Plugin RingBuffer" <<
endmsg;
2029 vector<uint8_t> body(msg.
size);
2031 error <<
"Error reading from UI=>Plugin RingBuffer" <<
endmsg;
2037 const LV2_Atom*
const atom = (
const LV2_Atom*)&body[0];
2039 (
const uint8_t*)(atom + 1))) {
2040 error <<
"Failed to write data to LV2 event buffer\n";
2043 error <<
"Received unknown message type from UI" <<
endmsg;
2070 const uint32_t buf_index = out_map.
get(
2078 const uint32_t buf_index = out_map.
get(
2081 bufs.flush_lv2_midi(
true, buf_index);
2093 uint32_t frames, subframes, type, size;
2099 LV2_Atom* atom = (LV2_Atom*)(data -
sizeof(LV2_Atom));
2102 LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
2104 const LV2_Atom*
property = NULL;
2105 const LV2_Atom* value = NULL;
2106 lv2_atom_object_get(obj,
2111 if (!property || !value ||
2114 std::cerr <<
"warning: patch:Set for unknown property" << std::endl;
2118 const uint32_t prop_id = ((
const LV2_Atom_URID*)property)->body;
2130 size +
sizeof(LV2_Atom),
2131 data -
sizeof(LV2_Atom));
2196 const LilvPort* port = lilv_plugin_get_port_by_index(
_impl->
plugin, port_index);
2197 LilvScalePoints* points = lilv_port_get_scale_points(
_impl->
plugin, port);
2206 LILV_FOREACH(scale_points, i, points) {
2207 const LilvScalePoint* p = lilv_scale_points_get(points, i);
2208 const LilvNode*
label = lilv_scale_point_get_label(p);
2209 const LilvNode* value = lilv_scale_point_get_value(p);
2210 if (label && (lilv_node_is_float(value) || lilv_node_is_int(value))) {
2211 ret->insert(make_pair(lilv_node_as_string(label),
2212 lilv_node_as_float(value)));
2216 lilv_scale_points_free(points);
2224 for (uint32_t i = 0; i <
N; ++i) {
2253 uint32_t in_index = 0;
2254 uint32_t out_index = 0;
2260 memset(buffer, 0,
sizeof(
float) * bufsize);
2269 lilv_instance_connect_port(
_impl->
instance, port_index, buffer);
2272 lilv_instance_connect_port(
_impl->
instance, port_index, buffer);
2281 if (was_activated) {
2290 const LilvPort* port = NULL;
2291 LilvNode* designation = lilv_new_uri(_world.
world, uri);
2292 port = lilv_plugin_get_port_by_designation(
2294 lilv_node_free(designation);
2296 bufptrs[lilv_port_get_index(plugin, port)] = bufptr;
2305 return str[0] !=
'.' && (str.length() > 3 && str.find (
".lv2") == (str.length() - 4));
2310 : world(lilv_world_new())
2311 , _bundle_checked(false)
2343 ui_external = lilv_new_uri(
world,
"http://lv2plug.in/ns/extensions/ui#external");
2344 ui_externalkx = lilv_new_uri(
world,
"http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget");
2392 lilv_world_free(
world);
2403 vector<string> plugin_objects;
2405 for ( vector<string>::iterator x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
2406 #ifdef PLATFORM_WINDOWS
2407 string uri =
"file:///" + *x +
"/";
2409 string uri =
"file://" + *x +
"/";
2411 LilvNode *node = lilv_new_uri(
world, uri.c_str());
2412 lilv_world_load_bundle(
world, node);
2413 lilv_node_free(node);
2416 lilv_world_load_all(
world);
2421 LV2PluginInfo::LV2PluginInfo (
const char* plugin_uri)
2438 const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.
world);
2441 const LilvPlugin* lp = lilv_plugins_get_by_uri(plugins, uri);
2444 lilv_node_free(uri);
2462 const LilvPlugins* plugins = lilv_world_get_all_plugins(world.
world);
2464 LILV_FOREACH(plugins, i, plugins) {
2465 const LilvPlugin* p = lilv_plugins_get(plugins, i);
2466 const LilvNode* pun = lilv_plugin_get_uri(p);
2470 LilvNode*
name = lilv_plugin_get_name(p);
2471 if (!name || !lilv_plugin_get_port_by_index(p, 0)) {
2472 warning <<
"Ignoring invalid LV2 plugin "
2473 << lilv_node_as_string(lilv_plugin_get_uri(p))
2480 info->name = string(lilv_node_as_string(name));
2481 lilv_node_free(name);
2484 const LilvPluginClass* pclass = lilv_plugin_get_class(p);
2485 const LilvNode* label = lilv_plugin_class_get_label(pclass);
2486 info->category = lilv_node_as_string(label);
2488 LilvNode* author_name = lilv_plugin_get_author_name(p);
2489 info->creator = author_name ? string(lilv_node_as_string(author_name)) :
"Unknown";
2490 lilv_node_free(author_name);
2492 info->path =
"/NOPATH";
2499 int count_midi_out = 0;
2500 int count_midi_in = 0;
2501 for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
2502 const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
2504 LilvNodes* buffer_types = lilv_port_get_value(
2506 LilvNodes* atom_supports = lilv_port_get_value(
2518 lilv_nodes_free(buffer_types);
2519 lilv_nodes_free(atom_supports);
2523 info->n_inputs.set_audio(
2524 lilv_plugin_get_num_ports_of_class(
2526 info->n_inputs.set_midi(
2527 lilv_plugin_get_num_ports_of_class(
2531 info->n_outputs.set_audio(
2532 lilv_plugin_get_num_ports_of_class(
2534 info->n_outputs.set_midi(
2535 lilv_plugin_get_num_ports_of_class(
2539 info->unique_id = lilv_node_as_uri(lilv_plugin_get_uri(p));
2542 plugs->push_back(info);
void find_paths_matching_filter(vector< string > &result, const Searchpath &paths, bool(*filter)(const string &, void *), void *arg, bool pass_fullpath, bool return_fullpath, bool recurse)
bool lv2_evbuf_is_valid(LV2_Evbuf_Iterator iter)
#define LV2_ATOM_BODY_CONST(atom)
bool respond(uint32_t size, const void *data)
LV2_Evbuf_Iterator lv2_evbuf_begin(LV2_Evbuf *evbuf)
Event port understands MIDI.
bool load_preset(PresetRecord)
bool parameter_is_output(uint32_t) const
uint32_t _patch_port_out_index
uint32_t time_beatsPerBar
uint32_t atom_eventTransfer
virtual int set_state(const XMLNode &, int version)
float lower
Minimum value (in Hz, for frequencies)
MidiBuffer & get_midi(size_t i)
float normal
Default value.
const char * name() const
static int log_printf(LV2_Log_Handle handle, LV2_URID type, const char *fmt,...)
bool is_external_ui() const
float default_value(uint32_t port)
framepos_t _next_cycle_start
Expected start frame of next run cycle.
void bbt_time(framepos_t when, Timecode::BBT_Time &)
void latency_compute_run()
const std::string & value() const
LV2Plugin(ARDOUR::AudioEngine &engine, ARDOUR::Session &session, const void *c_plugin, framecnt_t sample_rate)
LV2_Feature _options_feature
const Meter & meter() const
LIBARDOUR_API std::string legalize_for_uri(const std::string &str)
std::string get_docs() const
double transport_speed() const
static bool uri_to_variant_type(const std::string &uri, Variant::Type &type)
static bool lv2_filter(const string &str, void *)
virtual void set_parameter(uint32_t which, float val)
LV2_Evbuf_Iterator lv2_evbuf_end(LV2_Evbuf *evbuf)
LV2_Feature * urid_map_feature()
void run(pframes_t nsamples)
LV2_URID_Map * urid_map()
LilvNode * patch_writable
pframes_t samples_per_cycle() const
void set_insert_id(PBD::ID id)
uint32_t num_ports() const
void set_metric(const MetricSection *section)
void remove_directory(const std::string &dir)
const LilvPlugin * plugin
const std::string & name() const
LilvNode * rsz_minimumSize
static LV2_Worker_Status work_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void *data)
std::map< const std::string, const float > ScalePoints
static void load_parameter_descriptor_units(LilvWorld *lworld, ParameterDescriptor &desc, const LilvNodes *units)
Metrics::const_iterator metrics_end()
LV2_Feature _make_path_feature
framecnt_t signal_latency() const
LilvNode * atom_bufferType
ARDOUR::AudioEngine & _engine
static void load_parameter_descriptor(LV2World &world, ParameterDescriptor &desc, Variant::Type datatype, const LilvNode *subject)
bool write_to_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t *body)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
const XMLNodeList & children(const std::string &str=std::string()) const
void allocate_atom_event_buffers()
uint32_t key
for properties
std::ostream & endmsg(std::ostream &ostr)
static PluginInfoList * discover()
C float (32-bit IEEE-754)
static URIMap & instance()
float * _bpm_control_port
Special input set by ardour.
void * lv2_evbuf_get_buffer(LV2_Evbuf *evbuf)
framecnt_t frame_rate() const
guint read(T *dest, guint cnt)
AudioBuffer & get_audio(size_t i)
const std::string file_dir() const
uint32_t port_index(const char *symbol) const
const char * maker() const
static cycles_t get_cycles(void)
LV2_DataAccess _data_access_extension_data
LilvNode * atom_eventTransfer
const std::string plugin_dir() const
static char * lv2_state_make_path(void *host_data, const char *path)
LilvNode * ext_logarithmic
LilvNode * lv2_inPlaceBroken
virtual int connect_and_run(BufferSet &bufs, ChanMapping in, ChanMapping out, pframes_t nframes, framecnt_t offset)
std::vector< PortFlags > _port_flags
bool lv2_evbuf_get(LV2_Evbuf_Iterator iter, uint32_t *frames, uint32_t *subframes, uint32_t *type, uint32_t *size, uint8_t **data)
uint32_t parameter_count() const
std::list< XMLNode * > XMLNodeList
const Timecode::BBT_Time & start() const
LV2_Evbuf_Iterator lv2_evbuf_next(LV2_Evbuf_Iterator iter)
static void forge_variant(LV2_Atom_Forge *forge, const Variant &value)
uint32_t uri_to_id(const char *uri)
const PresetRecord * preset_by_label(const std::string &)
bool schedule(uint32_t size, const void *data)
bool parameter_is_input(uint32_t) const
const void * extension_data(const char *uri) const
void set_parameter(uint32_t port, float val)
LV2_URID_Unmap * urid_unmap()
const std::string & get_uri() const
bool lv2_evbuf_write(LV2_Evbuf_Iterator *iter, uint32_t frames, uint32_t subframes, uint32_t type, uint32_t size, const uint8_t *data)
Old event API event port.
boost::shared_ptr< Plugin > PluginPtr
LV2_Evbuf * lv2_evbuf_new(uint32_t capacity, LV2_Evbuf_Type type, uint32_t atom_Chunk, uint32_t atom_Sequence)
XMLProperty * property(const char *)
LV2_Feature _def_state_feature
float upper
Maximum value (in Hz, for frequencies)
float get_parameter(uint32_t port) const
const char * label() const
const LV2_Worker_Interface * work_iface
LilvNode * units_midiNote
virtual const ParameterDescriptor & get_property_descriptor(uint32_t id) const
std::map< uint32_t, ParameterDescriptor > PropertyDescriptors
const std::string scratch_dir() const
uint32_t lv2_evbuf_get_capacity(LV2_Evbuf *evbuf)
LV2_Feature _work_schedule_feature
bool ui_is_resizable() const
framepos_t transport_frame() const
#define LV2_PATCH__writable
std::string print_fmt
format string for pretty printing
std::string plugins_dir() const
Plugin state.
std::map< std::string, PresetRecord > _presets
LV2_Feature * uri_map_feature()
const PBD::ID & id() const
int work(uint32_t size, const void *data)
bool parameter_is_control(uint32_t) const
int work_response(uint32_t size, const void *data)
LilvNode * midi_MidiEvent
std::string describe_parameter(Evoral::Parameter)
bool parameter_is_event(uint32_t) const
Event port supports patch:Message.
void init(const void *c_plugin, framecnt_t rate)
#define DEBUG_TRACE(bits, str)
guint write(T const *src, guint cnt)
LilvNode * lv2_enumeration
boost::shared_ptr< ScalePoints > get_scale_points(uint32_t port_index) const
Event port understands position.
const ParameterDescriptor & get_property_descriptor(uint32_t id) const
Raw string (no semantics)
std::string state_node_name() const
double note_divisor() const
const OwnedPropertyList & properties() const
const Evoral::Beats & get_beats() const
Message send to/from UI via ports.
LilvNode * lv2_ControlPort
const std::string & get_path() const
LIBPBD_API Transmitter info
int connect_and_run(BufferSet &bufs, ChanMapping in, ChanMapping out, pframes_t nframes, framecnt_t offset)
std::string unique_id() const
RingBuffer< uint8_t > * _to_ui
void do_remove_preset(std::string)
double beats_per_minute() const
void enable_ui_emission()
LIBARDOUR_API uint64_t LV2
size_t raw_buffer_size(DataType t)
bool write_from_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t *body)
LV2_Feature _data_access_feature
void add_state(XMLNode *) const
const std::string state_dir(unsigned num) const
LilvNode * lv2_freewheeling
XMLProperty * add_property(const char *name, const std::string &value)
static void set_port_value(const char *port_symbol, void *user_data, const void *value, uint32_t, uint32_t type)
LV2PluginInfo(const char *plugin_uri)
RingBuffer< uint8_t > * _from_ui
PBD::Signal2< void, uint32_t, Variant > PropertyChanged
const void * lv2plugin_get_port_value(const char *port_symbol, void *user_data, uint32_t *size, uint32_t *type)
void add_child_nocopy(XMLNode &)
bool freewheeling() const
void announce_property_values()
void load_bundled_plugins(bool verbose=false)
bool toggled
True iff parameter is boolean.
bool parameter_is_audio(uint32_t) const
void print_parameter(uint32_t param, char *buf, uint32_t len) const
void load_supported_properties(PropertyDescriptors &descs)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
const ChanCount & count() const
void set(DataType t, uint32_t count)
LIBPBD_TEMPLATE_MEMBER_API const std::string to_string() const
ARDOUR::Session & _session
const Tempo & tempo() const
double divisions_per_bar() const
float * _latency_control_port
Special output set by ardour.
uint32_t nth_parameter(uint32_t port, bool &ok) const
std::set< Evoral::Parameter > automatable() const
boost::shared_ptr< ScalePoints > scale_points
std::map< std::string, uint32_t > _port_indices
TempoMetric metric_at(Timecode::BBT_Time bbt) const
C double (64-bit IEEE-754)
const std::string & get_string() const
bool is_external_kx() const
static int log_vprintf(LV2_Log_Handle, LV2_URID type, const char *fmt, va_list args)
static LV2_Worker_Status work_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void *data)
void emit_to_ui(void *controller, UIMessageSink sink)
LilvNode * lv2_sampleRate
static bool write_position(LV2_Atom_Forge *forge, LV2_Evbuf *buf, const TempoMetric &t, Timecode::BBT_Time &bbt, double speed, framepos_t position, framecnt_t offset)
LIBARDOUR_API PBD::Signal3< void, std::string, std::string, bool > PluginScanMessage
LV2_Feature _instance_access_feature
double get_double() const
const uint8_t * buffer() const
std::string get_parameter_docs(uint32_t which) const
uint32_t time_beatsPerMinute
uint32_t _patch_port_in_index
std::list< PluginInfoPtr > PluginInfoList
void set_cycles(uint32_t c)
const Sample * data(framecnt_t offset=0) const
int get_parameter_descriptor(uint32_t which, ParameterDescriptor &) const
boost::shared_ptr< PluginInfo > PluginInfoPtr
std::string externals_dir() const
Links to external files.
const LilvPort * designated_input(const char *uri, void **bufptrs[], void **bufptr)
PluginPtr load(Session &session)
static LilvNode * get_value(LilvWorld *world, const LilvNode *subject, const LilvNode *predicate)
PropertyDescriptors _property_descriptors
bool write_to(RingBuffer< uint8_t > *dest, uint32_t index, uint32_t protocol, uint32_t size, const uint8_t *body)
LilvNode * lv2_OutputPort
Variant::Type datatype
for properties
void lv2_evbuf_reset(LV2_Evbuf *evbuf, bool input)
double _next_cycle_speed
Expected start frame of next run cycle.
XMLNodeList::const_iterator XMLNodeConstIterator
BufferSet & get_silent_buffers(ChanCount count=ChanCount::ZERO)
bool _has_state_interface
LV2_Feature * urid_unmap_feature()
friend const void * lv2plugin_get_port_value(const char *port_symbol, void *user_data, uint32_t *size, uint32_t *type)
std::vector< size_t > _port_minimumSize
void set_property(uint32_t key, const Variant &value)
float * _freewheel_control_port
Special input set by ardour.
bool has_message_output() const
LilvNode * lv2_reportsLatency
ARDOUR::Session & session() const
virtual bool load_preset(PresetRecord)
BufferSet & get_scratch_buffers(ChanCount count=ChanCount::ZERO, bool silence=true)
uint32_t get(DataType t, uint32_t from, bool *valid)
LV2_Evbuf ** _atom_ev_buffers
LIBARDOUR_API PBD::Searchpath lv2_bundled_search_path()
std::string string_compose(const std::string &fmt, const T1 &o1)
std::string do_save_preset(std::string)
double atof(const string &s)
static const size_t NBUFS
const void *(* extension_data)(const char *uri)
void UIMessageSink(void *controller, uint32_t index, uint32_t size, uint32_t format, const void *buffer)
int set_state(const XMLNode &node, int version)
const char * port_symbol(uint32_t port) const