1 /*
2   Copyright 2007-2017 David Robillard <http://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 
22 namespace Lilv {
23 
24 #if defined(__clang__)
25 #    pragma clang diagnostic push
26 #    pragma clang diagnostic ignored "-Wdeprecated-declarations"
27 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
28 #    pragma GCC diagnostic push
29 #    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
30 #endif
31 
32 LILV_DEPRECATED
33 static inline const char*
uri_to_path(const char * uri)34 uri_to_path(const char* uri) {
35 	return lilv_uri_to_path(uri);
36 }
37 
38 #if defined(__clang__)
39 #    pragma clang diagnostic pop
40 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
41 #    pragma GCC diagnostic pop
42 #endif
43 
44 #define LILV_WRAP0(RT, prefix, name) \
45 	inline RT name() { return lilv_ ## prefix ## _ ## name (me); }
46 
47 #define LILV_WRAP0_VOID(prefix, name) \
48 	inline void name() { lilv_ ## prefix ## _ ## name(me); }
49 
50 #define LILV_WRAP1(RT, prefix, name, T1, a1) \
51 	inline RT name(T1 a1) { return lilv_ ## prefix ## _ ## name (me, a1); }
52 
53 #define LILV_WRAP1_VOID(prefix, name, T1, a1) \
54 	inline void name(T1 a1) { lilv_ ## prefix ## _ ## name(me, a1); }
55 
56 #define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \
57 	inline RT name(T1 a1, T2 a2) { \
58 		return lilv_ ## prefix ## _ ## name(me, a1, a2); \
59 	}
60 
61 #define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \
62 	inline RT name(T1 a1, T2 a2, T3 a3) { \
63 		return lilv_ ## prefix ## _ ## name(me, a1, a2, a3); \
64 	}
65 
66 #define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \
67 	inline void name(T1 a1, T2 a2) { lilv_ ## prefix ## _ ## name(me, a1, a2); }
68 
69 #ifndef SWIG
70 #define LILV_WRAP_CONVERSION(CT) \
71 	inline operator CT*() const { return me; }
72 #else
73 #define LILV_WRAP_CONVERSION(CT)
74 #endif
75 
76 struct Node {
NodeLilv::Node77 	inline Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {}
NodeLilv::Node78 	inline Node(const Node& copy)     : me(lilv_node_duplicate(copy.me)) {}
79 
~NodeLilv::Node80 	inline ~Node() { lilv_node_free(me); }
81 
equalsLilv::Node82 	inline bool equals(const Node& other) const {
83 		return lilv_node_equals(me, other.me);
84 	}
85 
operator ==Lilv::Node86 	inline bool operator==(const Node& other) const { return equals(other); }
87 
88 	LILV_WRAP_CONVERSION(LilvNode);
89 
90 	LILV_WRAP0(char*,       node, get_turtle_token);
91 	LILV_WRAP0(bool,        node, is_uri);
92 	LILV_WRAP0(const char*, node, as_uri);
93 	LILV_WRAP0(bool,        node, is_blank);
94 	LILV_WRAP0(const char*, node, as_blank);
95 	LILV_WRAP0(bool,        node, is_literal);
96 	LILV_WRAP0(bool,        node, is_string);
97 	LILV_WRAP0(const char*, node, as_string);
98 	LILV_WRAP0(bool,        node, is_float);
99 	LILV_WRAP0(float,       node, as_float);
100 	LILV_WRAP0(bool,        node, is_int);
101 	LILV_WRAP0(int,         node, as_int);
102 	LILV_WRAP0(bool,        node, is_bool);
103 	LILV_WRAP0(bool,        node, as_bool);
104 
105 	LilvNode* me;
106 };
107 
108 struct ScalePoint {
ScalePointLilv::ScalePoint109 	inline ScalePoint(const LilvScalePoint* c_obj) : me(c_obj) {}
110 	LILV_WRAP_CONVERSION(const LilvScalePoint);
111 
112 	LILV_WRAP0(const LilvNode*, scale_point, get_label);
113 	LILV_WRAP0(const LilvNode*, scale_point, get_value);
114 
115 	const LilvScalePoint* me;
116 };
117 
118 struct PluginClass {
PluginClassLilv::PluginClass119 	inline PluginClass(const LilvPluginClass* c_obj) : me(c_obj) {}
120 	LILV_WRAP_CONVERSION(const LilvPluginClass);
121 
122 	LILV_WRAP0(Node, plugin_class, get_parent_uri);
123 	LILV_WRAP0(Node, plugin_class, get_uri);
124 	LILV_WRAP0(Node, plugin_class, get_label);
125 	LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children);
126 
127 	const LilvPluginClass* me;
128 };
129 
130 #define LILV_WRAP_COLL(CT, ET, prefix) \
131 	inline CT(const Lilv ## CT* c_obj) : me(c_obj) {} \
132 	LILV_WRAP_CONVERSION(const Lilv ## CT); \
133 	LILV_WRAP0(unsigned, prefix, size); \
134 	LILV_WRAP1(const ET, prefix, get, LilvIter*, i); \
135 	LILV_WRAP0(LilvIter*, prefix, begin); \
136 	LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \
137 	LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \
138 	const Lilv ## CT* me; \
139 
140 struct PluginClasses {
141 	LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes);
142 	LILV_WRAP1(const PluginClass, plugin_classes,
143 	           get_by_uri, const LilvNode*, uri);
144 };
145 
146 struct ScalePoints {
147 	LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points);
148 };
149 
150 struct Nodes {
151 	LILV_WRAP_COLL(Nodes, Node, nodes);
152 	LILV_WRAP1(bool, nodes, contains, const Node, node);
153 	LILV_WRAP0(Node, nodes, get_first);
154 };
155 
156 struct UI {
UILilv::UI157 	inline UI(const LilvUI* c_obj) : me(c_obj) {}
158 	LILV_WRAP_CONVERSION(const LilvUI);
159 
160 	LILV_WRAP0(const LilvNode*, ui, get_uri);
161 	LILV_WRAP0(const LilvNode*, ui, get_bundle_uri);
162 	LILV_WRAP0(const LilvNode*, ui, get_binary_uri);
163 	LILV_WRAP0(const LilvNodes*, ui, get_classes);
164 	/*LILV_WRAP3(bool, ui, is_supported,
165 	           LilvUISupportedFunc, supported_func,
166 	           const LilvNode*,     container_type,
167 	           const LilvNode**,    ui_type);*/
168 	LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri);
169 
170 	const LilvUI* me;
171 };
172 
173 struct UIs {
174 	LILV_WRAP_COLL(UIs, UI, uis);
175 };
176 
177 struct Port {
PortLilv::Port178 	inline Port(const LilvPlugin* p, const LilvPort* c_obj)
179 		: parent(p), me(c_obj)
180 	{}
181 
182 	LILV_WRAP_CONVERSION(const LilvPort);
183 
184 #define LILV_PORT_WRAP0(RT, name) \
185 	inline RT name () { return lilv_port_ ## name (parent, me); }
186 
187 #define LILV_PORT_WRAP1(RT, name, T1, a1) \
188 	inline RT name (T1 a1) { return lilv_port_ ## name (parent, me, a1); }
189 
190 	LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate);
191 	LILV_PORT_WRAP0(LilvNodes*, get_properties)
192 	LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri);
193 	LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri);
194 	LILV_PORT_WRAP0(const LilvNode*,  get_symbol);
195 	LILV_PORT_WRAP0(LilvNode*,  get_name);
196 	LILV_PORT_WRAP0(const LilvNodes*, get_classes);
197 	LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class);
198 	LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points);
199 
200 	// TODO: get_range (output parameters)
201 
202 	const LilvPlugin* parent;
203 	const LilvPort*   me;
204 };
205 
206 struct Plugin {
PluginLilv::Plugin207 	inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {}
208 	LILV_WRAP_CONVERSION(const LilvPlugin);
209 
210 	LILV_WRAP0(bool,        plugin, verify);
211 	LILV_WRAP0(Node,        plugin, get_uri);
212 	LILV_WRAP0(Node,        plugin, get_bundle_uri);
213 	LILV_WRAP0(Nodes,       plugin, get_data_uris);
214 	LILV_WRAP0(Node,        plugin, get_library_uri);
215 	LILV_WRAP0(Node,        plugin, get_name);
216 	LILV_WRAP0(PluginClass, plugin, get_class);
217 	LILV_WRAP1(Nodes,       plugin, get_value, Node, pred);
218 	LILV_WRAP1(bool,        plugin, has_feature, Node, feature_uri);
219 	LILV_WRAP0(Nodes,       plugin, get_supported_features);
220 	LILV_WRAP0(Nodes,       plugin, get_required_features);
221 	LILV_WRAP0(Nodes,       plugin, get_optional_features);
222 	LILV_WRAP0(unsigned,    plugin, get_num_ports);
223 	LILV_WRAP0(bool,        plugin, has_latency);
224 	LILV_WRAP0(unsigned,    plugin, get_latency_port_index);
225 	LILV_WRAP0(Node,        plugin, get_author_name);
226 	LILV_WRAP0(Node,        plugin, get_author_email);
227 	LILV_WRAP0(Node,        plugin, get_author_homepage);
228 	LILV_WRAP0(bool,        plugin, is_replaced);
229 	LILV_WRAP0(Nodes,       plugin, get_extension_data);
230 	LILV_WRAP0(UIs,         plugin, get_uis);
231 	LILV_WRAP1(Nodes,       plugin, get_related, Node, type);
232 
get_port_by_indexLilv::Plugin233 	inline Port get_port_by_index(unsigned index) {
234 		return Port(me, lilv_plugin_get_port_by_index(me, index));
235 	}
236 
get_port_by_symbolLilv::Plugin237 	inline Port get_port_by_symbol(LilvNode* symbol) {
238 		return Port(me, lilv_plugin_get_port_by_symbol(me, symbol));
239 	}
240 
get_port_ranges_floatLilv::Plugin241 	inline void get_port_ranges_float(float* min_values,
242 	                                  float* max_values,
243 	                                  float* def_values) {
244 		return lilv_plugin_get_port_ranges_float(
245 			me, min_values, max_values, def_values);
246 	}
247 
get_num_ports_of_classLilv::Plugin248 	inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) {
249 		va_list args;
250 		va_start(args, class_1);
251 
252 		const uint32_t count = lilv_plugin_get_num_ports_of_class_va(
253 			me, class_1, args);
254 
255 		va_end(args);
256 		return count;
257 	}
258 
259 	const LilvPlugin* me;
260 };
261 
262 struct Plugins {
263 	LILV_WRAP_COLL(Plugins, Plugin, plugins);
264 	LILV_WRAP1(const Plugin, plugins, get_by_uri, const LilvNode*, uri);
265 };
266 
267 struct Instance {
InstanceLilv::Instance268 	inline Instance(LilvInstance* instance) : me(instance) {}
269 
270 	LILV_DEPRECATED
InstanceLilv::Instance271 	inline Instance(Plugin plugin, double sample_rate) {
272 		me = lilv_plugin_instantiate(plugin, sample_rate, NULL);
273 	}
274 
InstanceLilv::Instance275 	LILV_DEPRECATED inline Instance(Plugin              plugin,
276 	                                double              sample_rate,
277 	                                LV2_Feature* const* features) {
278 		me = lilv_plugin_instantiate(plugin, sample_rate, features);
279 	}
280 
createLilv::Instance281 	static inline Instance* create(Plugin              plugin,
282 	                               double              sample_rate,
283 	                               LV2_Feature* const* features) {
284 		LilvInstance* me = lilv_plugin_instantiate(
285 			plugin, sample_rate, features);
286 
287 		return me ? new Instance(me) : NULL;
288 	}
289 
290 	LILV_WRAP_CONVERSION(LilvInstance);
291 
292 	LILV_WRAP2_VOID(instance, connect_port,
293 	                unsigned, port_index,
294 	                void*,    data_location);
295 
296 	LILV_WRAP0_VOID(instance, activate);
297 	LILV_WRAP1_VOID(instance, run, unsigned, sample_count);
298 	LILV_WRAP0_VOID(instance, deactivate);
299 
get_extension_dataLilv::Instance300 	inline const void* get_extension_data(const char* uri) {
301 		return lilv_instance_get_extension_data(me, uri);
302 	}
303 
get_descriptorLilv::Instance304 	inline const LV2_Descriptor* get_descriptor() {
305 		return lilv_instance_get_descriptor(me);
306 	}
307 
get_handleLilv::Instance308 	inline LV2_Handle get_handle() {
309 		return lilv_instance_get_handle(me);
310 	}
311 
312 	LilvInstance* me;
313 };
314 
315 struct World {
WorldLilv::World316 	inline World() : me(lilv_world_new()) {}
~WorldLilv::World317 	inline ~World() { lilv_world_free(me); }
318 
new_uriLilv::World319 	inline LilvNode* new_uri(const char* uri) {
320 		return lilv_new_uri(me, uri);
321 	}
new_stringLilv::World322 	inline LilvNode* new_string(const char* str) {
323 		return lilv_new_string(me, str);
324 	}
new_intLilv::World325 	inline LilvNode* new_int(int val) {
326 		return lilv_new_int(me, val);
327 	}
new_floatLilv::World328 	inline LilvNode* new_float(float val) {
329 		return lilv_new_float(me, val);
330 	}
new_boolLilv::World331 	inline LilvNode* new_bool(bool val) {
332 		return lilv_new_bool(me, val);
333 	}
find_nodesLilv::World334 	inline Nodes find_nodes(const LilvNode* subject,
335 	                        const LilvNode* predicate,
336 	                        const LilvNode* object) {
337 		return lilv_world_find_nodes(me, subject, predicate, object);
338 	}
339 
340 	LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value);
341 	LILV_WRAP0_VOID(world, load_all);
342 	LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri);
343 	LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class);
344 	LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes);
345 	LILV_WRAP0(const Plugins, world, get_all_plugins);
346 	LILV_WRAP1(int, world, load_resource, const LilvNode*, resource);
347 
348 	LilvWorld* me;
349 };
350 
351 } /* namespace Lilv */
352 
353 #endif /* LILV_LILVMM_HPP */
354