1 /*
2 Copyright 2007-2017 David Robillard <d@drobilla.net>
3
4 Permission to use, copy, modify, and/or distribute this software for any
5 purpose with or without fee is hereby granted, provided that the above
6 copyright notice and this permission notice appear in all copies.
7
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef LILV_LILVMM_HPP
18 #define LILV_LILVMM_HPP
19
20 #include "lilv/lilv.h"
21 #include "lv2/core/lv2.h"
22
23 #include <cstdarg>
24 #include <cstdint>
25
26 namespace Lilv {
27
28 #if defined(__clang__)
29 # pragma clang diagnostic push
30 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
31 #elif defined(__GNUC__) && __GNUC__ > 4
32 # pragma GCC diagnostic push
33 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
34 #endif
35
36 struct Instance;
37 struct Node;
38 struct Nodes;
39 struct Plugin;
40 struct PluginClass;
41 struct PluginClasses;
42 struct Plugins;
43 struct Port;
44 struct ScalePoint;
45 struct ScalePoints;
46 struct UI;
47 struct UIs;
48 struct World;
49
50 LILV_DEPRECATED
51 static inline const char*
uri_to_path(const char * uri)52 uri_to_path(const char* uri)
53 {
54 return lilv_uri_to_path(uri);
55 }
56
57 #if defined(__clang__)
58 # pragma clang diagnostic pop
59 #elif defined(__GNUC__) && __GNUC__ > 4
60 # pragma GCC diagnostic pop
61 #endif
62
63 #define LILV_WRAP0(RT, prefix, name) \
64 inline RT name() { return lilv_##prefix##_##name(me); }
65
66 #define LILV_WRAP0_VOID(prefix, name) \
67 inline void name() { lilv_##prefix##_##name(me); }
68
69 #define LILV_WRAP1(RT, prefix, name, T1, a1) \
70 inline RT name(T1 a1) { return lilv_##prefix##_##name(me, a1); }
71
72 #define LILV_WRAP1_VOID(prefix, name, T1, a1) \
73 inline void name(T1 a1) { lilv_##prefix##_##name(me, a1); }
74
75 #define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \
76 inline RT name(T1 a1, T2 a2) { return lilv_##prefix##_##name(me, a1, a2); }
77
78 #define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \
79 inline RT name(T1 a1, T2 a2, T3 a3) \
80 { \
81 return lilv_##prefix##_##name(me, a1, a2, a3); \
82 }
83
84 #define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \
85 inline void name(T1 a1, T2 a2) { lilv_##prefix##_##name(me, a1, a2); }
86
87 #ifndef SWIG
88 # define LILV_WRAP_CONVERSION(CT) \
89 inline operator CT*() const { return me; }
90 #else
91 # define LILV_WRAP_CONVERSION(CT)
92 #endif
93
94 struct Node {
NodeLilv::Node95 inline Node(const LilvNode* node)
96 : me(lilv_node_duplicate(node))
97 {}
98
NodeLilv::Node99 inline Node(const Node& copy)
100 : me(lilv_node_duplicate(copy.me))
101 {}
102
operator =Lilv::Node103 inline Node& operator=(const Node& rhs)
104 {
105 if (&rhs != this) {
106 lilv_node_free(me);
107 me = lilv_node_duplicate(rhs.me);
108 }
109 return *this;
110 }
111
NodeLilv::Node112 inline Node(Node&& other) noexcept
113 : me(other.me)
114 {
115 other.me = nullptr;
116 }
117
operator =Lilv::Node118 inline Node& operator=(Node&& rhs) noexcept
119 {
120 if (&rhs != this) {
121 me = rhs.me;
122 rhs.me = nullptr;
123 }
124 return *this;
125 }
126
~NodeLilv::Node127 inline ~Node() { lilv_node_free(me); }
128
equalsLilv::Node129 inline bool equals(const Node& other) const
130 {
131 return lilv_node_equals(me, other.me);
132 }
133
operator ==Lilv::Node134 inline bool operator==(const Node& other) const { return equals(other); }
135
136 LILV_WRAP_CONVERSION(LilvNode);
137
138 LILV_WRAP0(char*, node, get_turtle_token);
139 LILV_WRAP0(bool, node, is_uri);
140 LILV_WRAP0(const char*, node, as_uri);
141 LILV_WRAP0(bool, node, is_blank);
142 LILV_WRAP0(const char*, node, as_blank);
143 LILV_WRAP0(bool, node, is_literal);
144 LILV_WRAP0(bool, node, is_string);
145 LILV_WRAP0(const char*, node, as_string);
146 LILV_WRAP0(bool, node, is_float);
147 LILV_WRAP0(float, node, as_float);
148 LILV_WRAP0(bool, node, is_int);
149 LILV_WRAP0(int, node, as_int);
150 LILV_WRAP0(bool, node, is_bool);
151 LILV_WRAP0(bool, node, as_bool);
152
153 LilvNode* me;
154 };
155
156 struct ScalePoint {
ScalePointLilv::ScalePoint157 inline ScalePoint(const LilvScalePoint* c_obj)
158 : me(c_obj)
159 {}
160
161 LILV_WRAP_CONVERSION(const LilvScalePoint);
162
163 LILV_WRAP0(const LilvNode*, scale_point, get_label);
164 LILV_WRAP0(const LilvNode*, scale_point, get_value);
165
166 const LilvScalePoint* me;
167 };
168
169 struct PluginClass {
PluginClassLilv::PluginClass170 inline PluginClass(const LilvPluginClass* c_obj)
171 : me(c_obj)
172 {}
173
174 LILV_WRAP_CONVERSION(const LilvPluginClass);
175
176 LILV_WRAP0(Node, plugin_class, get_parent_uri);
177 LILV_WRAP0(Node, plugin_class, get_uri);
178 LILV_WRAP0(Node, plugin_class, get_label);
179 LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children);
180
181 const LilvPluginClass* me;
182 };
183
184 #define LILV_WRAP_COLL(CT, ET, prefix) \
185 inline CT(const Lilv##CT* c_obj) \
186 : me(c_obj) \
187 {} \
188 LILV_WRAP_CONVERSION(const Lilv##CT); \
189 LILV_WRAP0(unsigned, prefix, size); \
190 LILV_WRAP1(ET, prefix, get, LilvIter*, i); \
191 LILV_WRAP0(LilvIter*, prefix, begin); \
192 LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \
193 LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \
194 const Lilv##CT* me;
195
196 struct PluginClasses {
197 LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes);
198 LILV_WRAP1(PluginClass, plugin_classes, get_by_uri, const LilvNode*, uri);
199 };
200
201 struct ScalePoints {
202 LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points);
203 };
204
205 struct Nodes {
206 LILV_WRAP_COLL(Nodes, Node, nodes);
207 LILV_WRAP1(bool, nodes, contains, const Node&, node);
208 LILV_WRAP0(Node, nodes, get_first);
209 };
210
211 struct UI {
UILilv::UI212 inline UI(const LilvUI* c_obj)
213 : me(c_obj)
214 {}
215
216 LILV_WRAP_CONVERSION(const LilvUI);
217
218 LILV_WRAP0(const LilvNode*, ui, get_uri);
219 LILV_WRAP0(const LilvNode*, ui, get_bundle_uri);
220 LILV_WRAP0(const LilvNode*, ui, get_binary_uri);
221 LILV_WRAP0(const LilvNodes*, ui, get_classes);
222 /*LILV_WRAP3(bool, ui, is_supported,
223 LilvUISupportedFunc, supported_func,
224 const LilvNode*, container_type,
225 const LilvNode**, ui_type);*/
226 LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri);
227
228 const LilvUI* me;
229 };
230
231 struct UIs {
232 LILV_WRAP_COLL(UIs, UI, uis);
233 };
234
235 struct Port {
PortLilv::Port236 inline Port(const LilvPlugin* p, const LilvPort* c_obj)
237 : parent(p)
238 , me(c_obj)
239 {}
240
241 LILV_WRAP_CONVERSION(const LilvPort);
242
243 #define LILV_PORT_WRAP0(RT, name) \
244 inline RT name() { return lilv_port_##name(parent, me); }
245
246 #define LILV_PORT_WRAP1(RT, name, T1, a1) \
247 inline RT name(T1 a1) { return lilv_port_##name(parent, me, a1); }
248
249 LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate);
250 LILV_PORT_WRAP0(LilvNodes*, get_properties)
251 LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri);
252 LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri);
253 LILV_PORT_WRAP0(const LilvNode*, get_symbol);
254 LILV_PORT_WRAP0(LilvNode*, get_name);
255 LILV_PORT_WRAP0(const LilvNodes*, get_classes);
256 LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class);
257 LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points);
258
259 // TODO: get_range (output parameters)
260
261 const LilvPlugin* parent;
262 const LilvPort* me;
263 };
264
265 struct Plugin {
PluginLilv::Plugin266 inline Plugin(const LilvPlugin* c_obj)
267 : me(c_obj)
268 {}
269
270 LILV_WRAP_CONVERSION(const LilvPlugin);
271
272 LILV_WRAP0(bool, plugin, verify);
273 LILV_WRAP0(Node, plugin, get_uri);
274 LILV_WRAP0(Node, plugin, get_bundle_uri);
275 LILV_WRAP0(Nodes, plugin, get_data_uris);
276 LILV_WRAP0(Node, plugin, get_library_uri);
277 LILV_WRAP0(Node, plugin, get_name);
278 LILV_WRAP0(PluginClass, plugin, get_class);
279 LILV_WRAP1(Nodes, plugin, get_value, const Node&, pred);
280 LILV_WRAP1(bool, plugin, has_feature, const Node&, feature_uri);
281 LILV_WRAP0(Nodes, plugin, get_supported_features);
282 LILV_WRAP0(Nodes, plugin, get_required_features);
283 LILV_WRAP0(Nodes, plugin, get_optional_features);
284 LILV_WRAP0(unsigned, plugin, get_num_ports);
285 LILV_WRAP0(bool, plugin, has_latency);
286 LILV_WRAP0(unsigned, plugin, get_latency_port_index);
287 LILV_WRAP0(Node, plugin, get_author_name);
288 LILV_WRAP0(Node, plugin, get_author_email);
289 LILV_WRAP0(Node, plugin, get_author_homepage);
290 LILV_WRAP0(bool, plugin, is_replaced);
291 LILV_WRAP0(Nodes, plugin, get_extension_data);
292 LILV_WRAP0(UIs, plugin, get_uis);
293 LILV_WRAP1(Nodes, plugin, get_related, const Node&, type);
294
get_port_by_indexLilv::Plugin295 inline Port get_port_by_index(unsigned index) const
296 {
297 return Port(me, lilv_plugin_get_port_by_index(me, index));
298 }
299
get_port_by_symbolLilv::Plugin300 inline Port get_port_by_symbol(LilvNode* symbol) const
301 {
302 return Port(me, lilv_plugin_get_port_by_symbol(me, symbol));
303 }
304
get_port_ranges_floatLilv::Plugin305 inline void get_port_ranges_float(float* min_values,
306 float* max_values,
307 float* def_values) const
308 {
309 return lilv_plugin_get_port_ranges_float(
310 me, min_values, max_values, def_values);
311 }
312
get_num_ports_of_classLilv::Plugin313 inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) const
314 {
315 va_list args;
316 va_start(args, class_1);
317
318 const uint32_t count =
319 lilv_plugin_get_num_ports_of_class_va(me, class_1, args);
320
321 va_end(args);
322 return count;
323 }
324
325 const LilvPlugin* me;
326 };
327
328 struct Plugins {
329 LILV_WRAP_COLL(Plugins, Plugin, plugins);
330 LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri);
331 };
332
333 struct Instance {
InstanceLilv::Instance334 inline Instance(LilvInstance* instance)
335 : me(instance)
336 {}
337
338 LILV_DEPRECATED
InstanceLilv::Instance339 inline Instance(Plugin plugin, double sample_rate)
340 {
341 me = lilv_plugin_instantiate(plugin, sample_rate, nullptr);
342 }
343
InstanceLilv::Instance344 LILV_DEPRECATED inline Instance(Plugin plugin,
345 double sample_rate,
346 LV2_Feature* const* features)
347 {
348 me = lilv_plugin_instantiate(plugin, sample_rate, features);
349 }
350
createLilv::Instance351 static inline Instance* create(Plugin plugin,
352 double sample_rate,
353 LV2_Feature* const* features)
354 {
355 LilvInstance* me = lilv_plugin_instantiate(plugin, sample_rate, features);
356
357 return me ? new Instance(me) : nullptr;
358 }
359
360 LILV_WRAP_CONVERSION(LilvInstance);
361
362 LILV_WRAP2_VOID(instance,
363 connect_port,
364 unsigned,
365 port_index,
366 void*,
367 data_location);
368
369 LILV_WRAP0_VOID(instance, activate);
370 LILV_WRAP1_VOID(instance, run, unsigned, sample_count);
371 LILV_WRAP0_VOID(instance, deactivate);
372
get_extension_dataLilv::Instance373 inline const void* get_extension_data(const char* uri) const
374 {
375 return lilv_instance_get_extension_data(me, uri);
376 }
377
get_descriptorLilv::Instance378 inline const LV2_Descriptor* get_descriptor() const
379 {
380 return lilv_instance_get_descriptor(me);
381 }
382
get_handleLilv::Instance383 inline LV2_Handle get_handle() const { return lilv_instance_get_handle(me); }
384
385 LilvInstance* me;
386 };
387
388 struct World {
WorldLilv::World389 inline World()
390 : me(lilv_world_new())
391 {}
392
~WorldLilv::World393 inline ~World() { lilv_world_free(me); }
394
395 World(const World&) = delete;
396 World& operator=(const World&) = delete;
397
398 World(World&&) = delete;
399 World& operator=(World&&) = delete;
400
new_uriLilv::World401 inline LilvNode* new_uri(const char* uri) const
402 {
403 return lilv_new_uri(me, uri);
404 }
405
new_stringLilv::World406 inline LilvNode* new_string(const char* str) const
407 {
408 return lilv_new_string(me, str);
409 }
410
new_intLilv::World411 inline LilvNode* new_int(int val) const { return lilv_new_int(me, val); }
412
new_floatLilv::World413 inline LilvNode* new_float(float val) const
414 {
415 return lilv_new_float(me, val);
416 }
417
new_boolLilv::World418 inline LilvNode* new_bool(bool val) const { return lilv_new_bool(me, val); }
419
find_nodesLilv::World420 inline Nodes find_nodes(const LilvNode* subject,
421 const LilvNode* predicate,
422 const LilvNode* object) const
423 {
424 return lilv_world_find_nodes(me, subject, predicate, object);
425 }
426
427 LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value);
428 LILV_WRAP0_VOID(world, load_all);
429 LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri);
430 LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class);
431 LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes);
432 LILV_WRAP0(Plugins, world, get_all_plugins);
433 LILV_WRAP1(int, world, load_resource, const LilvNode*, resource);
434
435 LilvWorld* me;
436 };
437
438 } /* namespace Lilv */
439
440 #endif /* LILV_LILVMM_HPP */
441