// Copyright 2007-2017 David Robillard // SPDX-License-Identifier: ISC #ifndef LILV_LILVMM_HPP #define LILV_LILVMM_HPP #include "lilv/lilv.h" #include "lv2/core/lv2.h" #include #include namespace Lilv { #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdeprecated-declarations" #elif defined(__GNUC__) && __GNUC__ > 4 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif struct Instance; struct Node; struct Nodes; struct Plugin; struct PluginClass; struct PluginClasses; struct Plugins; struct Port; struct ScalePoint; struct ScalePoints; struct UI; struct UIs; struct World; LILV_DEPRECATED static inline const char* uri_to_path(const char* uri) { return lilv_uri_to_path(uri); } #if defined(__clang__) # pragma clang diagnostic pop #elif defined(__GNUC__) && __GNUC__ > 4 # pragma GCC diagnostic pop #endif #define LILV_WRAP0(RT, prefix, name) \ inline RT name() \ { \ return lilv_##prefix##_##name(me); \ } #define LILV_WRAP0_VOID(prefix, name) \ inline void name() \ { \ lilv_##prefix##_##name(me); \ } #define LILV_WRAP1(RT, prefix, name, T1, a1) \ inline RT name(T1 a1) \ { \ return lilv_##prefix##_##name(me, a1); \ } #define LILV_WRAP1_VOID(prefix, name, T1, a1) \ inline void name(T1 a1) \ { \ lilv_##prefix##_##name(me, a1); \ } #define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \ inline RT name(T1 a1, T2 a2) \ { \ return lilv_##prefix##_##name(me, a1, a2); \ } #define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \ inline RT name(T1 a1, T2 a2, T3 a3) \ { \ return lilv_##prefix##_##name(me, a1, a2, a3); \ } #define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \ inline void name(T1 a1, T2 a2) \ { \ lilv_##prefix##_##name(me, a1, a2); \ } #ifndef SWIG # define LILV_WRAP_CONVERSION(CT) \ inline operator CT*() const \ { \ return me; \ } #else # define LILV_WRAP_CONVERSION(CT) #endif struct Node { Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {} Node(const Node& copy) : me(lilv_node_duplicate(copy.me)) {} Node& operator=(const Node& rhs) { if (&rhs != this) { lilv_node_free(me); me = lilv_node_duplicate(rhs.me); } return *this; } Node(Node&& other) noexcept : me(other.me) { other.me = nullptr; } Node& operator=(Node&& rhs) noexcept { if (&rhs != this) { me = rhs.me; rhs.me = nullptr; } return *this; } ~Node() { lilv_node_free(me); } bool equals(const Node& other) const { return lilv_node_equals(me, other.me); } bool operator==(const Node& other) const { return equals(other); } LILV_WRAP_CONVERSION(LilvNode) LILV_WRAP0(char*, node, get_turtle_token) LILV_WRAP0(bool, node, is_uri) LILV_WRAP0(const char*, node, as_uri) LILV_WRAP0(bool, node, is_blank) LILV_WRAP0(const char*, node, as_blank) LILV_WRAP0(bool, node, is_literal) LILV_WRAP0(bool, node, is_string) LILV_WRAP0(const char*, node, as_string) LILV_WRAP0(bool, node, is_float) LILV_WRAP0(float, node, as_float) LILV_WRAP0(bool, node, is_int) LILV_WRAP0(int, node, as_int) LILV_WRAP0(bool, node, is_bool) LILV_WRAP0(bool, node, as_bool) LilvNode* me; }; struct ScalePoint { ScalePoint(const LilvScalePoint* c_obj) : me(c_obj) {} LILV_WRAP_CONVERSION(const LilvScalePoint) LILV_WRAP0(const LilvNode*, scale_point, get_label) LILV_WRAP0(const LilvNode*, scale_point, get_value) const LilvScalePoint* me; }; struct PluginClass { PluginClass(const LilvPluginClass* c_obj) : me(c_obj) {} LILV_WRAP_CONVERSION(const LilvPluginClass) LILV_WRAP0(Node, plugin_class, get_parent_uri) LILV_WRAP0(Node, plugin_class, get_uri) LILV_WRAP0(Node, plugin_class, get_label) LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children) const LilvPluginClass* me; }; #define LILV_WRAP_COLL(CT, ET, prefix) \ inline CT(const Lilv##CT* c_obj) \ : me(c_obj) \ {} \ LILV_WRAP_CONVERSION(const Lilv##CT) \ LILV_WRAP0(unsigned, prefix, size) \ LILV_WRAP1(ET, prefix, get, const LilvIter*, i) \ LILV_WRAP0(LilvIter*, prefix, begin) \ LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i) \ LILV_WRAP1(bool, prefix, is_end, const LilvIter*, i) \ const Lilv##CT* me; struct PluginClasses { LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes) LILV_WRAP1(PluginClass, plugin_classes, get_by_uri, const LilvNode*, uri) }; struct ScalePoints { LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points) }; struct Nodes { LILV_WRAP_COLL(Nodes, Node, nodes) LILV_WRAP1(bool, nodes, contains, const Node&, node) LILV_WRAP0(Node, nodes, get_first) }; struct UI { UI(const LilvUI* c_obj) : me(c_obj) {} LILV_WRAP_CONVERSION(const LilvUI) LILV_WRAP0(const LilvNode*, ui, get_uri) LILV_WRAP0(const LilvNode*, ui, get_bundle_uri) LILV_WRAP0(const LilvNode*, ui, get_binary_uri) LILV_WRAP0(const LilvNodes*, ui, get_classes) /*LILV_WRAP3(bool, ui, is_supported, LilvUISupportedFunc, supported_func, const LilvNode*, container_type, const LilvNode**, ui_type);*/ LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri) const LilvUI* me; }; struct UIs { LILV_WRAP_COLL(UIs, UI, uis) }; struct Port { Port(const LilvPlugin* p, const LilvPort* c_obj) : parent(p) , me(c_obj) {} LILV_WRAP_CONVERSION(const LilvPort) #define LILV_PORT_WRAP0(RT, name) \ inline RT name() { return lilv_port_##name(parent, me); } #define LILV_PORT_WRAP1(RT, name, T1, a1) \ inline RT name(T1 a1) { return lilv_port_##name(parent, me, a1); } LILV_PORT_WRAP1(LilvNodes*, get_value, const LilvNode*, predicate) LILV_PORT_WRAP0(LilvNodes*, get_properties) LILV_PORT_WRAP1(bool, has_property, const LilvNode*, property_uri) LILV_PORT_WRAP1(bool, supports_event, const LilvNode*, event_uri) LILV_PORT_WRAP0(const LilvNode*, get_symbol) LILV_PORT_WRAP0(LilvNode*, get_name) LILV_PORT_WRAP0(const LilvNodes*, get_classes) LILV_PORT_WRAP1(bool, is_a, const LilvNode*, port_class) LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points) // TODO: get_range (output parameters) const LilvPlugin* parent; const LilvPort* me; }; struct Plugin { Plugin(const LilvPlugin* c_obj) : me(c_obj) {} LILV_WRAP_CONVERSION(const LilvPlugin) LILV_WRAP0(bool, plugin, verify) LILV_WRAP0(Node, plugin, get_uri) LILV_WRAP0(Node, plugin, get_bundle_uri) LILV_WRAP0(Nodes, plugin, get_data_uris) LILV_WRAP0(Node, plugin, get_library_uri) LILV_WRAP0(Node, plugin, get_name) LILV_WRAP0(PluginClass, plugin, get_class) LILV_WRAP1(Nodes, plugin, get_value, const Node&, pred) LILV_WRAP1(bool, plugin, has_feature, const Node&, feature_uri) LILV_WRAP0(Nodes, plugin, get_supported_features) LILV_WRAP0(Nodes, plugin, get_required_features) LILV_WRAP0(Nodes, plugin, get_optional_features) LILV_WRAP0(unsigned, plugin, get_num_ports) LILV_WRAP0(bool, plugin, has_latency) LILV_WRAP0(unsigned, plugin, get_latency_port_index) LILV_WRAP0(Node, plugin, get_author_name) LILV_WRAP0(Node, plugin, get_author_email) LILV_WRAP0(Node, plugin, get_author_homepage) LILV_WRAP0(bool, plugin, is_replaced) LILV_WRAP0(Nodes, plugin, get_extension_data) LILV_WRAP0(UIs, plugin, get_uis) LILV_WRAP1(Nodes, plugin, get_related, const Node&, type) Port get_port_by_index(unsigned index) const { return Port(me, lilv_plugin_get_port_by_index(me, index)); } Port get_port_by_symbol(const LilvNode* symbol) const { return Port(me, lilv_plugin_get_port_by_symbol(me, symbol)); } void get_port_ranges_float(float* min_values, float* max_values, float* def_values) const { lilv_plugin_get_port_ranges_float(me, min_values, max_values, def_values); } unsigned get_num_ports_of_class(LilvNode* class_1, ...) const { va_list args; // NOLINT(cppcoreguidelines-init-variables) va_start(args, class_1); const uint32_t count = lilv_plugin_get_num_ports_of_class_va(me, class_1, args); va_end(args); return count; } const LilvPlugin* me; }; struct Plugins { LILV_WRAP_COLL(Plugins, Plugin, plugins) LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri) }; struct Instance { Instance(LilvInstance* instance) : me(instance) {} LILV_DEPRECATED Instance(Plugin plugin, double sample_rate) : me(lilv_plugin_instantiate(plugin, sample_rate, nullptr)) {} LILV_DEPRECATED Instance(Plugin plugin, double sample_rate, LV2_Feature* const* features) : me(lilv_plugin_instantiate(plugin, sample_rate, features)) {} static Instance* create(Plugin plugin, double sample_rate, LV2_Feature* const* features) { LilvInstance* me = lilv_plugin_instantiate(plugin, sample_rate, features); return me ? new Instance(me) : nullptr; } LILV_WRAP_CONVERSION(LilvInstance) LILV_WRAP2_VOID(instance, connect_port, unsigned, port_index, void*, data_location) LILV_WRAP0_VOID(instance, activate) LILV_WRAP1_VOID(instance, run, unsigned, sample_count) LILV_WRAP0_VOID(instance, deactivate) const void* get_extension_data(const char* uri) const { return lilv_instance_get_extension_data(me, uri); } const LV2_Descriptor* get_descriptor() const { return lilv_instance_get_descriptor(me); } LV2_Handle get_handle() const { return lilv_instance_get_handle(me); } LilvInstance* me; }; struct World { World() : me(lilv_world_new()) {} ~World() { lilv_world_free(me); } World(const World&) = delete; World& operator=(const World&) = delete; World(World&&) = delete; World& operator=(World&&) = delete; LilvNode* new_uri(const char* uri) const { return lilv_new_uri(me, uri); } LilvNode* new_string(const char* str) const { return lilv_new_string(me, str); } LilvNode* new_int(int val) const { return lilv_new_int(me, val); } LilvNode* new_float(float val) const { return lilv_new_float(me, val); } LilvNode* new_bool(bool val) const { return lilv_new_bool(me, val); } Nodes find_nodes(const LilvNode* subject, const LilvNode* predicate, const LilvNode* object) const { return lilv_world_find_nodes(me, subject, predicate, object); } LILV_WRAP2_VOID(world, set_option, const char*, uri, const LilvNode*, value) LILV_WRAP0_VOID(world, load_all) LILV_WRAP1_VOID(world, load_bundle, const LilvNode*, bundle_uri) LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class) LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes) LILV_WRAP0(Plugins, world, get_all_plugins) LILV_WRAP1(int, world, load_resource, const LilvNode*, resource) LilvWorld* me; }; } /* namespace Lilv */ #endif /* LILV_LILVMM_HPP */