1 /*
2   Copyright 2007-2014 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 "CarlaDefines.h"
21 
22 #include "lilv/lilv.h"
23 
24 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
25 #    define LILV_DEPRECATED __attribute__((__deprecated__))
26 #else
27 #    define LILV_DEPRECATED
28 #endif
29 
30 namespace Lilv {
31 
32 #define LILV_WRAP0(RT, prefix, name) \
33 	inline RT name() { return lilv_ ## prefix ## _ ## name (me); }
34 
35 #define LILV_WRAP0_CONST(RT, prefix, name) \
36 	inline RT name() const { return lilv_ ## prefix ## _ ## name (me); }
37 
38 #define LILV_WRAP0_VOID(prefix, name) \
39 	inline void name() { lilv_ ## prefix ## _ ## name(me); }
40 
41 #define LILV_WRAP1(RT, prefix, name, T1, a1) \
42 	inline RT name(T1 a1) { return lilv_ ## prefix ## _ ## name (me, a1); }
43 
44 #define LILV_WRAP1_VOID(prefix, name, T1, a1) \
45 	inline void name(T1 a1) { lilv_ ## prefix ## _ ## name(me, a1); }
46 
47 #define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \
48 	inline RT name(T1 a1, T2 a2) { \
49 		return lilv_ ## prefix ## _ ## name(me, a1, a2); \
50 	}
51 
52 #define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \
53 	inline RT name(T1 a1, T2 a2, T3 a3) { \
54 		return lilv_ ## prefix ## _ ## name(me, a1, a2, a3); \
55 	}
56 
57 #define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \
58 	inline void name(T1 a1, T2 a2) { lilv_ ## prefix ## _ ## name(me, a1, a2); }
59 
60 #ifndef SWIG
61 #define LILV_WRAP_CONVERSION(CT) \
62 	inline operator CT*() const { return me; }
63 #else
64 #define LILV_WRAP_CONVERSION(CT)
65 #endif
66 
67 struct Node {
NodeLilv::Node68 	inline Node(LilvNode* node)       : me(node) {}
NodeLilv::Node69 	inline Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {}
NodeLilv::Node70 	inline Node(const Node& copy)     : me(lilv_node_duplicate(copy.me)) {}
71 
~NodeLilv::Node72 	inline ~Node() { lilv_node_free(me); }
73 
equalsLilv::Node74 	inline bool equals(const Node& other) const {
75 		return lilv_node_equals(me, other.me);
76 	}
77 
operator ==Lilv::Node78 	inline bool operator==(const Node& other) const { return equals(other); }
79 
80 	LILV_WRAP_CONVERSION(LilvNode);
81 
82 	LILV_WRAP0_CONST(char*,       node, get_turtle_token);
83 	LILV_WRAP0_CONST(bool,        node, is_uri);
84 	LILV_WRAP0_CONST(const char*, node, as_uri);
85 	LILV_WRAP0_CONST(bool,        node, is_blank);
86 	LILV_WRAP0_CONST(const char*, node, as_blank);
87 	LILV_WRAP0_CONST(bool,        node, is_literal);
88 	LILV_WRAP0_CONST(bool,        node, is_string);
89 	LILV_WRAP0_CONST(const char*, node, as_string);
90 	LILV_WRAP0_CONST(bool,        node, is_float);
91 	LILV_WRAP0_CONST(float,       node, as_float);
92 	LILV_WRAP0_CONST(bool,        node, is_int);
93 	LILV_WRAP0_CONST(int,         node, as_int);
94 	LILV_WRAP0_CONST(bool,        node, is_bool);
95 	LILV_WRAP0_CONST(bool,        node, as_bool);
96 
operator =Lilv::Node97 	Node& operator=(const Node& copy) {
98 		lilv_node_free(me);
99 		me = lilv_node_duplicate(copy.me);
100 		return *this;
101 	}
102 
103 	LilvNode* me;
104 };
105 
106 struct ScalePoint {
ScalePointLilv::ScalePoint107 	inline ScalePoint(const LilvScalePoint* c_obj) : me(c_obj) {}
108 	LILV_WRAP_CONVERSION(const LilvScalePoint);
109 
110 	LILV_WRAP0(const LilvNode*, scale_point, get_label);
111 	LILV_WRAP0(const LilvNode*, scale_point, get_value);
112 
113 	const LilvScalePoint* me;
114 };
115 
116 struct PluginClass {
PluginClassLilv::PluginClass117 	inline PluginClass(const LilvPluginClass* c_obj) : me(c_obj) {}
118 	LILV_WRAP_CONVERSION(const LilvPluginClass);
119 
120 	LILV_WRAP0(Node, plugin_class, get_parent_uri);
121 	LILV_WRAP0(Node, plugin_class, get_uri);
122 	LILV_WRAP0(Node, plugin_class, get_label);
123 	LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children);
124 
125 	const LilvPluginClass* me;
126 };
127 
128 #define LILV_WRAP_COLL(CT, ET, prefix) \
129 	inline CT(const Lilv ## CT* c_obj) : me(c_obj) {} \
130 	LILV_WRAP_CONVERSION(const Lilv ## CT); \
131 	LILV_WRAP0(unsigned, prefix, size); \
132 	LILV_WRAP1(const ET, prefix, get, LilvIter*, i); \
133 	LILV_WRAP0(LilvIter*, prefix, begin); \
134 	LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \
135 	LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \
136 	const Lilv ## CT* me
137 
138 struct PluginClasses {
139 	LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes);
140 	LILV_WRAP1(const PluginClass, plugin_classes,
141 	           get_by_uri, const LilvNode*, uri);
142 };
143 
144 struct ScalePoints {
145 	LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points);
146 };
147 
148 struct Nodes {
149 	LILV_WRAP_COLL(Nodes, Node, nodes);
150 	LILV_WRAP1(bool, nodes, contains, const Node, node);
151 
get_firstLilv::Nodes152 	inline Node get_first() const {
153 		return Node((const LilvNode*)lilv_nodes_get_first(me));
154 	}
155 };
156 
157 struct UI {
UILilv::UI158 	inline UI(const LilvUI* c_obj) : me(c_obj) {}
159 	LILV_WRAP_CONVERSION(const LilvUI);
160 
161 	LILV_WRAP0(Node,  ui, get_uri);
162 	LILV_WRAP1(bool,  ui, is_a, LilvNode*, ui_class);
163 	LILV_WRAP0(Node,  ui, get_bundle_uri);
164 	LILV_WRAP0(Node,  ui, get_binary_uri);
165 	LILV_WRAP0(Nodes, ui, get_supported_features);
166 	LILV_WRAP0(Nodes, ui, get_required_features);
167 	LILV_WRAP0(Nodes, ui, get_optional_features);
168 	LILV_WRAP0(Nodes, ui, get_extension_data);
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(LilvNode*, get, LilvNode*, predicate);
191 	LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate);
192 	LILV_PORT_WRAP0(LilvNodes*, get_properties)
193 	LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri);
194 	LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri);
195 	LILV_PORT_WRAP0(const LilvNode*,  get_symbol);
196 	LILV_PORT_WRAP0(LilvNode*,  get_name);
197 	LILV_PORT_WRAP0(const LilvNodes*, get_classes);
198 	LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class);
199 	LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points);
200 
201 	// TODO: get_range (output parameters)
202 
203 	const LilvPlugin* parent;
204 	const LilvPort*   me;
205 };
206 
207 struct Plugin {
PluginLilv::Plugin208 	inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {}
209 	LILV_WRAP_CONVERSION(const LilvPlugin);
210 
211 	LILV_WRAP0(bool,        plugin, verify);
212 	LILV_WRAP0(Node,        plugin, get_uri);
213 	LILV_WRAP0(Node,        plugin, get_bundle_uri);
214 	LILV_WRAP0(Nodes,       plugin, get_data_uris);
215 	LILV_WRAP0(Node,        plugin, get_library_uri);
216 	LILV_WRAP0(Node,        plugin, get_name);
217 	LILV_WRAP0(PluginClass, plugin, get_class);
218 	LILV_WRAP1(Nodes,       plugin, get_value, Node, pred);
219 	LILV_WRAP1(bool,        plugin, has_feature, Node, feature_uri);
220 	LILV_WRAP0(Nodes,       plugin, get_supported_features);
221 	LILV_WRAP0(Nodes,       plugin, get_required_features);
222 	LILV_WRAP0(Nodes,       plugin, get_optional_features);
223 	LILV_WRAP0(unsigned,    plugin, get_num_ports);
224 	LILV_WRAP0(bool,        plugin, has_latency);
225 	LILV_WRAP0(unsigned,    plugin, get_latency_port_index);
226 	LILV_WRAP0(Node,        plugin, get_author_name);
227 	LILV_WRAP0(Node,        plugin, get_author_email);
228 	LILV_WRAP0(Node,        plugin, get_author_homepage);
229 	LILV_WRAP0(bool,        plugin, is_replaced);
230 	LILV_WRAP0(Nodes,       plugin, get_extension_data);
231 	LILV_WRAP0(UIs,         plugin, get_uis);
232 	LILV_WRAP1(Nodes,       plugin, get_related, Node, type);
233 	LILV_WRAP0(Node,        plugin, get_modgui_resources_directory);
234 	LILV_WRAP0(Node,        plugin, get_modgui_stylesheet);
235 	LILV_WRAP0(Node,        plugin, get_modgui_icon_template);
236 	LILV_WRAP0(Node,        plugin, get_modgui_settings_template);
237 	LILV_WRAP0(Node,        plugin, get_modgui_template_data);
238 	LILV_WRAP0(Node,        plugin, get_modgui_screenshot);
239 	LILV_WRAP0(Node,        plugin, get_modgui_thumbnail);
240 
get_port_by_indexLilv::Plugin241 	inline Port get_port_by_index(unsigned index) {
242 		return Port(me, lilv_plugin_get_port_by_index(me, index));
243 	}
244 
get_port_by_symbolLilv::Plugin245 	inline Port get_port_by_symbol(LilvNode* symbol) {
246 		return Port(me, lilv_plugin_get_port_by_symbol(me, symbol));
247 	}
248 
get_port_ranges_floatLilv::Plugin249 	inline void get_port_ranges_float(float* min_values,
250 	                                  float* max_values,
251 	                                  float* def_values) {
252 		return lilv_plugin_get_port_ranges_float(
253 			me, min_values, max_values, def_values);
254 	}
255 
get_num_ports_of_classLilv::Plugin256 	inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) {
257 		va_list args;
258 		va_start(args, class_1);
259 
260 		const uint32_t count = lilv_plugin_get_num_ports_of_class_va(
261 			me, class_1, args);
262 
263 		va_end(args);
264 		return count;
265 	}
266 
267 	const LilvPlugin* me;
268 };
269 
270 struct Plugins {
271 	LILV_WRAP_COLL(Plugins, Plugin, plugins);
272 	LILV_WRAP1(const Plugin, plugins, get_by_uri, const LilvNode*, uri);
273 };
274 
275 struct Instance {
InstanceLilv::Instance276 	inline Instance(LilvInstance* instance) : me(instance) {}
277 
278 	LILV_DEPRECATED
InstanceLilv::Instance279 	inline Instance(Plugin plugin, double sample_rate)
280 		: me(lilv_plugin_instantiate(plugin, sample_rate, NULL)) {}
281 
InstanceLilv::Instance282 	LILV_DEPRECATED inline Instance(Plugin              plugin,
283 	                                double              sample_rate,
284 	                                LV2_Feature* const* features)
285 		: me(lilv_plugin_instantiate(plugin, sample_rate, features)) {}
286 
createLilv::Instance287 	static inline Instance* create(Plugin              plugin,
288 	                               double              sample_rate,
289 	                               LV2_Feature* const* features) {
290 		LilvInstance* me = lilv_plugin_instantiate(
291 			plugin, sample_rate, features);
292 
293 		return me ? new Instance(me) : NULL;
294 	}
295 
296 	LILV_WRAP_CONVERSION(LilvInstance);
297 
298 	LILV_WRAP2_VOID(instance, connect_port,
299 	                unsigned, port_index,
300 	                void*,    data_location);
301 
302 	LILV_WRAP0_VOID(instance, activate);
303 	LILV_WRAP1_VOID(instance, run, unsigned, sample_count);
304 	LILV_WRAP0_VOID(instance, deactivate);
305 
get_extension_dataLilv::Instance306 	inline const void* get_extension_data(const char* uri) {
307 		return lilv_instance_get_extension_data(me, uri);
308 	}
309 
get_descriptorLilv::Instance310 	inline const LV2_Descriptor* get_descriptor() {
311 		return lilv_instance_get_descriptor(me);
312 	}
313 
get_handleLilv::Instance314 	inline LV2_Handle get_handle() {
315 		return lilv_instance_get_handle(me);
316 	}
317 
318 	LilvInstance* me;
319 };
320 
321 struct World {
WorldLilv::World322 	inline          World() : me(lilv_world_new()) {}
~WorldLilv::World323 	inline virtual ~World() { lilv_world_free(me); }
324 
new_uriLilv::World325 	inline LilvNode* new_uri(const char* uri) const {
326 		return lilv_new_uri(me, uri);
327 	}
new_file_uriLilv::World328 	inline LilvNode* new_file_uri(const char* host, const char* path) const {
329 		return lilv_new_file_uri(me, host, path);
330 	}
new_stringLilv::World331 	inline LilvNode* new_string(const char* str) const {
332 		return lilv_new_string(me, str);
333 	}
new_intLilv::World334 	inline LilvNode* new_int(int val) const {
335 		return lilv_new_int(me, val);
336 	}
new_floatLilv::World337 	inline LilvNode* new_float(float val) const {
338 		return lilv_new_float(me, val);
339 	}
new_boolLilv::World340 	inline LilvNode* new_bool(bool val) const {
341 		return lilv_new_bool(me, val);
342 	}
find_nodesLilv::World343 	inline Nodes find_nodes(const LilvNode* subject,
344 	                        const LilvNode* predicate,
345 	                        const LilvNode* object) {
346 		return lilv_world_find_nodes(me, subject, predicate, object);
347 	}
348 
349 	LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value);
350 	LILV_WRAP1_VOID(world, load_all, const char*, lv2_path);
351 	LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri);
352 	LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class);
353 	LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes);
354 	LILV_WRAP0(const Plugins, world, get_all_plugins);
355 	LILV_WRAP1(int, world, load_resource, const LilvNode*, resource);
356 
357 	LilvWorld* me;
358 
359 	CARLA_DECLARE_NON_COPY_STRUCT(World)
360 };
361 
362 } /* namespace Lilv */
363 
364 #endif /* LILV_LILVMM_HPP */
365