1"""Lilv Python interface"""
2
3__author__     = "David Robillard"
4__copyright__  = "Copyright 2016 David Robillard"
5__license__    = "ISC"
6__version__    = "0.22.1"
7__maintainer__ = "David Robillard"
8__email__      = "d@drobilla.net"
9__status__     = "Production"
10
11import ctypes
12import os
13import sys
14
15from ctypes import Structure, CDLL, POINTER, CFUNCTYPE
16from ctypes import c_bool, c_double, c_float, c_int, c_size_t, c_uint, c_uint32
17from ctypes import c_char, c_char_p, c_void_p
18from ctypes import byref
19
20# Load lilv library
21
22_lib = CDLL("liblilv-0.so")
23
24# Set namespaced aliases for all lilv functions
25
26class String(str):
27    # Wrapper for string parameters to pass as raw C UTF-8 strings
28    def from_param(cls, obj):
29        return obj.encode('utf-8')
30
31    from_param = classmethod(from_param)
32
33def _as_uri(obj):
34    if type(obj) in [Plugin, PluginClass, UI]:
35        return obj.get_uri()
36    else:
37        return obj
38
39free                             = _lib.lilv_free
40# uri_to_path                      = _lib.lilv_uri_to_path
41file_uri_parse                   = _lib.lilv_file_uri_parse
42new_uri                          = _lib.lilv_new_uri
43new_file_uri                     = _lib.lilv_new_file_uri
44new_string                       = _lib.lilv_new_string
45new_int                          = _lib.lilv_new_int
46new_float                        = _lib.lilv_new_float
47new_bool                         = _lib.lilv_new_bool
48node_free                        = _lib.lilv_node_free
49node_duplicate                   = _lib.lilv_node_duplicate
50node_equals                      = _lib.lilv_node_equals
51node_get_turtle_token            = _lib.lilv_node_get_turtle_token
52node_is_uri                      = _lib.lilv_node_is_uri
53node_as_uri                      = _lib.lilv_node_as_uri
54node_is_blank                    = _lib.lilv_node_is_blank
55node_as_blank                    = _lib.lilv_node_as_blank
56node_is_literal                  = _lib.lilv_node_is_literal
57node_is_string                   = _lib.lilv_node_is_string
58node_as_string                   = _lib.lilv_node_as_string
59node_get_path                    = _lib.lilv_node_get_path
60node_is_float                    = _lib.lilv_node_is_float
61node_as_float                    = _lib.lilv_node_as_float
62node_is_int                      = _lib.lilv_node_is_int
63node_as_int                      = _lib.lilv_node_as_int
64node_is_bool                     = _lib.lilv_node_is_bool
65node_as_bool                     = _lib.lilv_node_as_bool
66plugin_classes_free              = _lib.lilv_plugin_classes_free
67plugin_classes_size              = _lib.lilv_plugin_classes_size
68plugin_classes_begin             = _lib.lilv_plugin_classes_begin
69plugin_classes_get               = _lib.lilv_plugin_classes_get
70plugin_classes_next              = _lib.lilv_plugin_classes_next
71plugin_classes_is_end            = _lib.lilv_plugin_classes_is_end
72plugin_classes_get_by_uri        = _lib.lilv_plugin_classes_get_by_uri
73scale_points_free                = _lib.lilv_scale_points_free
74scale_points_size                = _lib.lilv_scale_points_size
75scale_points_begin               = _lib.lilv_scale_points_begin
76scale_points_get                 = _lib.lilv_scale_points_get
77scale_points_next                = _lib.lilv_scale_points_next
78scale_points_is_end              = _lib.lilv_scale_points_is_end
79uis_free                         = _lib.lilv_uis_free
80uis_size                         = _lib.lilv_uis_size
81uis_begin                        = _lib.lilv_uis_begin
82uis_get                          = _lib.lilv_uis_get
83uis_next                         = _lib.lilv_uis_next
84uis_is_end                       = _lib.lilv_uis_is_end
85uis_get_by_uri                   = _lib.lilv_uis_get_by_uri
86nodes_free                       = _lib.lilv_nodes_free
87nodes_size                       = _lib.lilv_nodes_size
88nodes_begin                      = _lib.lilv_nodes_begin
89nodes_get                        = _lib.lilv_nodes_get
90nodes_next                       = _lib.lilv_nodes_next
91nodes_is_end                     = _lib.lilv_nodes_is_end
92nodes_get_first                  = _lib.lilv_nodes_get_first
93nodes_contains                   = _lib.lilv_nodes_contains
94nodes_merge                      = _lib.lilv_nodes_merge
95plugins_size                     = _lib.lilv_plugins_size
96plugins_begin                    = _lib.lilv_plugins_begin
97plugins_get                      = _lib.lilv_plugins_get
98plugins_next                     = _lib.lilv_plugins_next
99plugins_is_end                   = _lib.lilv_plugins_is_end
100plugins_get_by_uri               = _lib.lilv_plugins_get_by_uri
101world_new                        = _lib.lilv_world_new
102world_set_option                 = _lib.lilv_world_set_option
103world_free                       = _lib.lilv_world_free
104world_load_all                   = _lib.lilv_world_load_all
105world_load_bundle                = _lib.lilv_world_load_bundle
106world_load_specifications        = _lib.lilv_world_load_specifications
107world_load_plugin_classes        = _lib.lilv_world_load_plugin_classes
108world_unload_bundle              = _lib.lilv_world_unload_bundle
109world_load_resource              = _lib.lilv_world_load_resource
110world_unload_resource            = _lib.lilv_world_unload_resource
111world_get_plugin_class           = _lib.lilv_world_get_plugin_class
112world_get_plugin_classes         = _lib.lilv_world_get_plugin_classes
113world_get_all_plugins            = _lib.lilv_world_get_all_plugins
114world_find_nodes                 = _lib.lilv_world_find_nodes
115world_get                        = _lib.lilv_world_get
116world_ask                        = _lib.lilv_world_ask
117plugin_verify                    = _lib.lilv_plugin_verify
118plugin_get_uri                   = _lib.lilv_plugin_get_uri
119plugin_get_bundle_uri            = _lib.lilv_plugin_get_bundle_uri
120plugin_get_data_uris             = _lib.lilv_plugin_get_data_uris
121plugin_get_library_uri           = _lib.lilv_plugin_get_library_uri
122plugin_get_name                  = _lib.lilv_plugin_get_name
123plugin_get_class                 = _lib.lilv_plugin_get_class
124plugin_get_value                 = _lib.lilv_plugin_get_value
125plugin_has_feature               = _lib.lilv_plugin_has_feature
126plugin_get_supported_features    = _lib.lilv_plugin_get_supported_features
127plugin_get_required_features     = _lib.lilv_plugin_get_required_features
128plugin_get_optional_features     = _lib.lilv_plugin_get_optional_features
129plugin_has_extension_data        = _lib.lilv_plugin_has_extension_data
130plugin_get_extension_data        = _lib.lilv_plugin_get_extension_data
131plugin_get_num_ports             = _lib.lilv_plugin_get_num_ports
132plugin_get_port_ranges_float     = _lib.lilv_plugin_get_port_ranges_float
133plugin_has_latency               = _lib.lilv_plugin_has_latency
134plugin_get_latency_port_index    = _lib.lilv_plugin_get_latency_port_index
135plugin_get_port_by_index         = _lib.lilv_plugin_get_port_by_index
136plugin_get_port_by_symbol        = _lib.lilv_plugin_get_port_by_symbol
137plugin_get_port_by_designation   = _lib.lilv_plugin_get_port_by_designation
138plugin_get_project               = _lib.lilv_plugin_get_project
139plugin_get_author_name           = _lib.lilv_plugin_get_author_name
140plugin_get_author_email          = _lib.lilv_plugin_get_author_email
141plugin_get_author_homepage       = _lib.lilv_plugin_get_author_homepage
142plugin_is_replaced               = _lib.lilv_plugin_is_replaced
143plugin_get_related               = _lib.lilv_plugin_get_related
144port_get_node                    = _lib.lilv_port_get_node
145port_get_value                   = _lib.lilv_port_get_value
146port_get                         = _lib.lilv_port_get
147port_get_properties              = _lib.lilv_port_get_properties
148port_has_property                = _lib.lilv_port_has_property
149port_supports_event              = _lib.lilv_port_supports_event
150port_get_index                   = _lib.lilv_port_get_index
151port_get_symbol                  = _lib.lilv_port_get_symbol
152port_get_name                    = _lib.lilv_port_get_name
153port_get_classes                 = _lib.lilv_port_get_classes
154port_is_a                        = _lib.lilv_port_is_a
155port_get_range                   = _lib.lilv_port_get_range
156port_get_scale_points            = _lib.lilv_port_get_scale_points
157state_new_from_world             = _lib.lilv_state_new_from_world
158state_new_from_file              = _lib.lilv_state_new_from_file
159state_new_from_string            = _lib.lilv_state_new_from_string
160state_new_from_instance          = _lib.lilv_state_new_from_instance
161state_free                       = _lib.lilv_state_free
162state_equals                     = _lib.lilv_state_equals
163state_get_num_properties         = _lib.lilv_state_get_num_properties
164state_get_plugin_uri             = _lib.lilv_state_get_plugin_uri
165state_get_uri                    = _lib.lilv_state_get_uri
166state_get_label                  = _lib.lilv_state_get_label
167state_set_label                  = _lib.lilv_state_set_label
168state_set_metadata               = _lib.lilv_state_set_metadata
169state_emit_port_values           = _lib.lilv_state_emit_port_values
170state_restore                    = _lib.lilv_state_restore
171state_save                       = _lib.lilv_state_save
172state_to_string                  = _lib.lilv_state_to_string
173state_delete                     = _lib.lilv_state_delete
174scale_point_get_label            = _lib.lilv_scale_point_get_label
175scale_point_get_value            = _lib.lilv_scale_point_get_value
176plugin_class_get_parent_uri      = _lib.lilv_plugin_class_get_parent_uri
177plugin_class_get_uri             = _lib.lilv_plugin_class_get_uri
178plugin_class_get_label           = _lib.lilv_plugin_class_get_label
179plugin_class_get_children        = _lib.lilv_plugin_class_get_children
180plugin_instantiate               = _lib.lilv_plugin_instantiate
181instance_free                    = _lib.lilv_instance_free
182plugin_get_uis                   = _lib.lilv_plugin_get_uis
183ui_get_uri                       = _lib.lilv_ui_get_uri
184ui_get_classes                   = _lib.lilv_ui_get_classes
185ui_is_a                          = _lib.lilv_ui_is_a
186ui_is_supported                  = _lib.lilv_ui_is_supported
187ui_get_bundle_uri                = _lib.lilv_ui_get_bundle_uri
188ui_get_binary_uri                = _lib.lilv_ui_get_binary_uri
189
190## LV2 types
191
192LV2_Handle            = POINTER(None)
193LV2_URID_Map_Handle   = POINTER(None)
194LV2_URID_Unmap_Handle = POINTER(None)
195LV2_URID              = c_uint32
196
197class LV2_Feature(Structure):
198    __slots__ = [ 'URI', 'data' ]
199    _fields_  = [('URI', c_char_p),
200                 ('data', POINTER(None))]
201
202class LV2_Descriptor(Structure):
203    __slots__ = [ 'URI',
204                  'instantiate',
205                  'connect_port',
206                  'activate',
207                  'run',
208                  'deactivate',
209                  'cleanup',
210                  'extension_data' ]
211
212LV2_Descriptor._fields_ = [
213    ('URI', c_char_p),
214    ('instantiate', CFUNCTYPE(LV2_Handle, POINTER(LV2_Descriptor),
215                              c_double, c_char_p, POINTER(POINTER(LV2_Feature)))),
216    ('connect_port', CFUNCTYPE(None, LV2_Handle, c_uint32, POINTER(None))),
217    ('activate', CFUNCTYPE(None, LV2_Handle)),
218    ('run', CFUNCTYPE(None, LV2_Handle, c_uint32)),
219    ('deactivate', CFUNCTYPE(None, LV2_Handle)),
220    ('cleanup', CFUNCTYPE(None, LV2_Handle)),
221    ('extension_data', CFUNCTYPE(c_void_p, c_char_p)),
222]
223
224class LV2_URID_Map(Structure):
225    __slots__ = [ 'handle', 'map' ]
226    _fields_  = [
227        ('handle', LV2_URID_Map_Handle),
228        ('map', CFUNCTYPE(LV2_URID, LV2_URID_Map_Handle, c_char_p)),
229    ]
230
231class LV2_URID_Unmap(Structure):
232    __slots__ = [ 'handle', 'unmap' ]
233    _fields_  = [
234        ('handle', LV2_URID_Unmap_Handle),
235        ('unmap', CFUNCTYPE(c_char_p, LV2_URID_Unmap_Handle, LV2_URID)),
236    ]
237
238# Lilv types
239
240class Plugin(Structure):
241    """LV2 Plugin."""
242    def __init__(self, world, plugin):
243        self.world  = world
244        self.plugin = plugin
245
246    def __eq__(self, other):
247        return self.get_uri() == other.get_uri()
248
249    def verify(self):
250        """Check if `plugin` is valid.
251
252        This is not a rigorous validator, but can be used to reject some malformed
253        plugins that could cause bugs (e.g. plugins with missing required fields).
254
255        Note that normal hosts do NOT need to use this - lilv does not
256        load invalid plugins into plugin lists.  This is included for plugin
257        testing utilities, etc.
258        """
259        return plugin_verify(self.plugin)
260
261    def get_uri(self):
262        """Get the URI of `plugin`.
263
264        Any serialization that refers to plugins should refer to them by this.
265        Hosts SHOULD NOT save any filesystem paths, plugin indexes, etc. in saved
266        files pass save only the URI.
267
268        The URI is a globally unique identifier for one specific plugin.  Two
269        plugins with the same URI are compatible in port signature, and should
270        be guaranteed to work in a compatible and consistent way.  If a plugin
271        is upgraded in an incompatible way (eg if it has different ports), it
272        MUST have a different URI than it's predecessor.
273        """
274        return Node.wrap(node_duplicate(plugin_get_uri(self.plugin)))
275
276    def get_bundle_uri(self):
277        """Get the (resolvable) URI of the plugin's "main" bundle.
278
279        This returns the URI of the bundle where the plugin itself was found.  Note
280        that the data for a plugin may be spread over many bundles, that is,
281        get_data_uris() may return URIs which are not within this bundle.
282
283        Typical hosts should not need to use this function.
284        Note this always returns a fully qualified URI.  If you want a local
285        filesystem path, use lilv.file_uri_parse().
286        """
287        return Node.wrap(node_duplicate(plugin_get_bundle_uri(self.plugin)))
288
289    def get_data_uris(self):
290        """Get the (resolvable) URIs of the RDF data files that define a plugin.
291
292        Typical hosts should not need to use this function.
293        Note this always returns fully qualified URIs.  If you want local
294        filesystem paths, use lilv.file_uri_parse().
295        """
296        return Nodes(plugin_get_data_uris(self.plugin))
297
298    def get_library_uri(self):
299        """Get the (resolvable) URI of the shared library for `plugin`.
300
301        Note this always returns a fully qualified URI.  If you want a local
302        filesystem path, use lilv.file_uri_parse().
303        """
304        return Node.wrap(node_duplicate(plugin_get_library_uri(self.plugin)))
305
306    def get_name(self):
307        """Get the name of `plugin`.
308
309        This returns the name (doap:name) of the plugin.  The name may be
310        translated according to the current locale, this value MUST NOT be used
311        as a plugin identifier (use the URI for that).
312        """
313        return Node.wrap(plugin_get_name(self.plugin))
314
315    def get_class(self):
316        """Get the class this plugin belongs to (e.g. Filters)."""
317        return PluginClass(plugin_get_class(self.plugin))
318
319    def get_value(self, predicate):
320        """Get a value associated with the plugin in a plugin's data files.
321
322        `predicate` must be either a URI or a QName.
323
324        Returns the ?object of all triples found of the form:
325
326        plugin-uri predicate ?object
327
328        May return None if the property was not found, or if object(s) is not
329        sensibly represented as a LilvNodes (e.g. blank nodes).
330        """
331        return Nodes(plugin_get_value(self.plugin, predicate.node))
332
333    def has_feature(self, feature_uri):
334        """Return whether a feature is supported by a plugin.
335
336        This will return true if the feature is an optional or required feature
337        of the plugin.
338        """
339        return plugin_has_feature(self.plugin, feature_uri.node)
340
341    def get_supported_features(self):
342        """Get the LV2 Features supported (required or optionally) by a plugin.
343
344        A feature is "supported" by a plugin if it is required OR optional.
345
346        Since required features have special rules the host must obey, this function
347        probably shouldn't be used by normal hosts.  Using get_optional_features()
348        and get_required_features() separately is best in most cases.
349        """
350        return Nodes(plugin_get_supported_features(self.plugin))
351
352    def get_required_features(self):
353        """Get the LV2 Features required by a plugin.
354
355        If a feature is required by a plugin, hosts MUST NOT use the plugin if they do not
356        understand (or are unable to support) that feature.
357
358        All values returned here MUST be return plugin_(self.plugin)ed to the plugin's instantiate method
359        (along with data, if necessary, as defined by the feature specification)
360        or plugin instantiation will fail.
361        """
362        return Nodes(plugin_get_required_features(self.plugin))
363
364    def get_optional_features(self):
365        """Get the LV2 Features optionally supported by a plugin.
366
367        Hosts MAY ignore optional plugin features for whatever reasons.  Plugins
368        MUST operate (at least somewhat) if they are instantiated without being
369        passed optional features.
370        """
371        return Nodes(plugin_get_optional_features(self.plugin))
372
373    def has_extension_data(self, uri):
374        """Return whether or not a plugin provides a specific extension data."""
375        return plugin_has_extension_data(self.plugin, uri.node)
376
377    def get_extension_data(self):
378        """Get a sequence of all extension data provided by a plugin.
379
380        This can be used to find which URIs get_extension_data()
381        will return a value for without instantiating the plugin.
382        """
383        return Nodes(plugin_get_extension_data(self.plugin))
384
385    def get_num_ports(self):
386        """Get the number of ports on this plugin."""
387        return plugin_get_num_ports(self.plugin)
388
389    # def get_port_ranges_float(self, min_values, max_values, def_values):
390    #     """Get the port ranges (minimum, maximum and default values) for all ports.
391
392    #     `min_values`, `max_values` and `def_values` must either point to an array
393    #     of N floats, where N is the value returned by get_num_ports()
394    #     for this plugin, or None.  The elements of the array will be set to the
395    #     the minimum, maximum and default values of the ports on this plugin,
396    #     with array index corresponding to port index.  If a port doesn't have a
397    #     minimum, maximum or default value, or the port's type is not float, the
398    #     corresponding array element will be set to NAN.
399
400    #     This is a convenience method for the common case of getting the range of
401    #     all float ports on a plugin, and may be significantly faster than
402    #     repeated calls to Port.get_range().
403    #     """
404    #     plugin_get_port_ranges_float(self.plugin, min_values, max_values, def_values)
405
406    def get_num_ports_of_class(self, *args):
407        """Get the number of ports on this plugin that are members of some class(es)."""
408        args = list(map(lambda x: x.node, args))
409        args += (None,)
410        return plugin_get_num_ports_of_class(self.plugin, *args)
411
412    def has_latency(self):
413        """Return whether or not the plugin introduces (and reports) latency.
414
415        The index of the latency port can be found with
416        get_latency_port() ONLY if this function returns true.
417        """
418        return plugin_has_latency(self.plugin)
419
420    def get_latency_port_index(self):
421        """Return the index of the plugin's latency port.
422
423        Returns None if the plugin has no latency port.
424
425        Any plugin that introduces unwanted latency that should be compensated for
426        (by hosts with the ability/need) MUST provide this port, which is a control
427        rate output port that reports the latency for each cycle in frames.
428        """
429        return plugin_get_latency_port_index(self.plugin) if self.has_latency() else None
430
431    def get_port(self, key):
432        """Get a port on `plugin` by index or symbol."""
433        if type(key) == int:
434            return self.get_port_by_index(key)
435        else:
436            return self.get_port_by_symbol(key)
437
438    def get_port_by_index(self, index):
439        """Get a port on `plugin` by `index`."""
440        return Port.wrap(self, plugin_get_port_by_index(self.plugin, index))
441
442    def get_port_by_symbol(self, symbol):
443        """Get a port on `plugin` by `symbol`.
444
445        Note this function is slower than get_port_by_index(),
446        especially on plugins with a very large number of ports.
447        """
448        if type(symbol) == str:
449            symbol = self.world.new_string(symbol)
450        return Port.wrap(self, plugin_get_port_by_symbol(self.plugin, symbol.node))
451
452    def get_port_by_designation(self, port_class, designation):
453        """Get a port on `plugin` by its lv2:designation.
454
455        The designation of a port describes the meaning, assignment, allocation or
456        role of the port, e.g. "left channel" or "gain".  If found, the port with
457        matching `port_class` and `designation` is be returned, otherwise None is
458        returned.  The `port_class` can be used to distinguish the input and output
459        ports for a particular designation.  If `port_class` is None, any port with
460        the given designation will be returned.
461        """
462        return Port.wrap(self,
463                         plugin_get_port_by_designation(self.plugin,
464                                                        port_class.node,
465                                                        designation.node))
466
467    def get_project(self):
468        """Get the project the plugin is a part of.
469
470        More information about the project can be read via find_nodes(),
471        typically using properties from DOAP (e.g. doap:name).
472        """
473        return Node.wrap(plugin_get_project(self.plugin))
474
475    def get_author_name(self):
476        """Get the full name of the plugin's author.
477
478        Returns None if author name is not present.
479        """
480        return Node.wrap(plugin_get_author_name(self.plugin))
481
482    def get_author_email(self):
483        """Get the email address of the plugin's author.
484
485        Returns None if author email address is not present.
486        """
487        return Node.wrap(plugin_get_author_email(self.plugin))
488
489    def get_author_homepage(self):
490        """Get the address of the plugin author's home page.
491
492        Returns None if author homepage is not present.
493        """
494        return Node.wrap(plugin_get_author_homepage(self.plugin))
495
496    def is_replaced(self):
497        """Return true iff `plugin` has been replaced by another plugin.
498
499        The plugin will still be usable, but hosts should hide them from their
500        user interfaces to prevent users from using deprecated plugins.
501        """
502        return plugin_is_replaced(self.plugin)
503
504    def get_related(self, resource_type):
505        """Get the resources related to `plugin` with lv2:appliesTo.
506
507        Some plugin-related resources are not linked directly to the plugin with
508        rdfs:seeAlso and thus will not be automatically loaded along with the plugin
509        data (usually for performance reasons).  All such resources of the given @c
510        type related to `plugin` can be accessed with this function.
511
512        If `resource_type` is None, all such resources will be returned, regardless of type.
513
514        To actually load the data for each returned resource, use world.load_resource().
515        """
516        return Nodes(plugin_get_related(self.plugin, resource_type))
517
518    def get_uis(self):
519        """Get all UIs for `plugin`."""
520        return UIs(plugin_get_uis(self.plugin))
521
522class PluginClass(Structure):
523    """Plugin Class (type/category)."""
524    def __init__(self, plugin_class):
525        self.plugin_class = plugin_class
526
527    def __str__(self):
528        return self.get_uri().__str__()
529
530    def get_parent_uri(self):
531        """Get the URI of this class' superclass.
532
533           May return None if class has no parent.
534        """
535        return Node.wrap(node_duplicate(plugin_class_get_parent_uri(self.plugin_class)))
536
537    def get_uri(self):
538        """Get the URI of this plugin class."""
539        return Node.wrap(node_duplicate(plugin_class_get_uri(self.plugin_class)))
540
541    def get_label(self):
542        """Get the label of this plugin class, ie "Oscillators"."""
543        return Node.wrap(node_duplicate(plugin_class_get_label(self.plugin_class)))
544
545    def get_children(self):
546        """Get the subclasses of this plugin class."""
547        return PluginClasses(plugin_class_get_children(self.plugin_class))
548
549class Port(Structure):
550    """Port on a Plugin."""
551    @classmethod
552    def wrap(cls, plugin, port):
553        return Port(plugin, port) if plugin and port else None
554
555    def __init__(self, plugin, port):
556        self.plugin = plugin
557        self.port   = port
558
559    def get_node(self):
560        """Get the RDF node of `port`.
561
562        Ports nodes may be may be URIs or blank nodes.
563        """
564        return Node.wrap(node_duplicate(port_get_node(self.plugin, self.port)))
565
566    def get_value(self, predicate):
567        """Port analog of Plugin.get_value()."""
568        return Nodes(port_get_value(self.plugin.plugin, self.port, predicate.node))
569
570    def get(self, predicate):
571        """Get a single property value of a port.
572
573        This is equivalent to lilv_nodes_get_first(lilv_port_get_value(...)) but is
574        simpler to use in the common case of only caring about one value.  The
575        caller is responsible for freeing the returned node.
576        """
577        return Node.wrap(port_get(self.plugin.plugin, self.port, predicate.node))
578
579    def get_properties(self):
580        """Return the LV2 port properties of a port."""
581        return Nodes(port_get_properties(self.plugin.plugin, self.port))
582
583    def has_property(self, property_uri):
584        """Return whether a port has a certain property."""
585        return port_has_property(self.plugin.plugin, self.port, property_uri.node)
586
587    def supports_event(self, event_type):
588        """Return whether a port supports a certain event type.
589
590        More precisely, this returns true iff the port has an atom:supports or an
591        ev:supportsEvent property with `event_type` as the value.
592        """
593        return port_supports_event(self.plugin.plugin, self.port, event_type.node)
594
595    def get_index(self):
596        """Get the index of a port.
597
598        The index is only valid for the life of the plugin and may change between
599        versions.  For a stable identifier, use the symbol.
600        """
601        return port_get_index(self.plugin.plugin, self.port)
602
603    def get_symbol(self):
604        """Get the symbol of a port.
605
606        The 'symbol' is a short string, a valid C identifier.
607        """
608        return Node.wrap(node_duplicate(port_get_symbol(self.plugin.plugin, self.port)))
609
610    def get_name(self):
611        """Get the name of a port.
612
613        This is guaranteed to return the untranslated name (the doap:name in the
614        data file without a language tag).
615        """
616        return Node.wrap(port_get_name(self.plugin.plugin, self.port))
617
618    def get_classes(self):
619        """Get all the classes of a port.
620
621        This can be used to determine if a port is an input, output, audio,
622        control, midi, etc, etc, though it's simpler to use is_a().
623        The returned list does not include lv2:Port, which is implied.
624        Returned value is shared and must not be destroyed by caller.
625        """
626        return Nodes(port_get_classes(self.plugin.plugin, self.port))
627
628    def is_a(self, port_class):
629        """Determine if a port is of a given class (input, output, audio, etc).
630
631        For convenience/performance/extensibility reasons, hosts are expected to
632        create a LilvNode for each port class they "care about".  Well-known type
633        URI strings are defined (e.g. LILV_URI_INPUT_PORT) for convenience, but
634        this function is designed so that Lilv is usable with any port types
635        without requiring explicit support in Lilv.
636        """
637        return port_is_a(self.plugin.plugin, self.port, port_class.node)
638
639    def get_range(self):
640        """Return the default, minimum, and maximum values of a port as a tuple."""
641        pdef = POINTER(Node)()
642        pmin = POINTER(Node)()
643        pmax = POINTER(Node)()
644        port_get_range(self.plugin.plugin, self.port, byref(pdef), byref(pmin), byref(pmax))
645        return (Node(pdef.contents) if pdef else None,
646                Node(pmin.contents) if pmin else None,
647                Node(pmax.contents) if pmax else None)
648
649    def get_scale_points(self):
650        """Get the scale points (enumeration values) of a port.
651
652        This returns a collection of 'interesting' named values of a port
653        (e.g. appropriate entries for a UI selector associated with this port).
654        Returned value may be None if `port` has no scale points.
655        """
656        return ScalePoints(port_get_scale_points(self.plugin.plugin, self.port))
657
658class ScalePoint(Structure):
659    """Scale point (detent)."""
660    def __init__(self, point):
661        self.point = point
662
663    def get_label(self):
664        """Get the label of this scale point (enumeration value)."""
665        return Node.wrap(scale_point_get_label(self.point))
666
667    def get_value(self):
668        """Get the value of this scale point (enumeration value)."""
669        return Node.wrap(scale_point_get_value(self.point))
670
671class UI(Structure):
672    """Plugin UI."""
673    def __init__(self, ui):
674        self.ui = ui
675
676    def __str__(self):
677        return str(self.get_uri())
678
679    def __eq__(self, other):
680        return self.get_uri() == _as_uri(other)
681
682    def get_uri(self):
683        """Get the URI of a Plugin UI."""
684        return Node.wrap(node_duplicate(ui_get_uri(self.ui)))
685
686    def get_classes(self):
687        """Get the types (URIs of RDF classes) of a Plugin UI.
688
689        Note that in most cases is_supported() should be used, which avoids
690           the need to use this function (and type specific logic).
691        """
692        return Nodes(ui_get_classes(self.ui))
693
694    def is_a(self, class_uri):
695        """Check whether a plugin UI has a given type."""
696        return ui_is_a(self.ui, class_uri.node)
697
698    def get_bundle_uri(self):
699        """Get the URI of the UI's bundle."""
700        return Node.wrap(node_duplicate(ui_get_bundle_uri(self.ui)))
701
702    def get_binary_uri(self):
703        """Get the URI for the UI's shared library."""
704        return Node.wrap(node_duplicate(ui_get_binary_uri(self.ui)))
705
706class Node(Structure):
707    """Data node (URI, string, integer, etc.).
708
709    A Node can be converted to the corresponding Python datatype, and all nodes
710    can be converted to strings, for example::
711
712       >>> world = lilv.World()
713       >>> i = world.new_int(42)
714       >>> print(i)
715       42
716       >>> int(i) * 2
717       84
718    """
719    @classmethod
720    def wrap(cls, node):
721        return Node(node) if node else None
722
723    def __init__(self, node):
724        self.node = node
725
726    def __del__(self):
727        if hasattr(self, 'node'):
728            node_free(self.node)
729
730    def __eq__(self, other):
731        otype = type(other)
732        if otype in [str, int, float]:
733            return otype(self) == other
734        return node_equals(self.node, other.node)
735
736    def __ne__(self, other):
737        return not node_equals(self.node, other.node)
738
739    def __str__(self):
740        return node_as_string(self.node).decode('utf-8')
741
742    def __int__(self):
743        if not self.is_int():
744            raise ValueError('node %s is not an integer' % str(self))
745        return node_as_int(self.node)
746
747    def __float__(self):
748        if not self.is_float():
749            raise ValueError('node %s is not a float' % str(self))
750        return node_as_float(self.node)
751
752    def __bool__(self):
753        if not self.is_bool():
754            raise ValueError('node %s is not a bool' % str(self))
755        return node_as_bool(self.node)
756    __nonzero__ = __bool__
757
758    def get_turtle_token(self):
759        """Return this value as a Turtle/SPARQL token."""
760        return node_get_turtle_token(self.node).decode('utf-8')
761
762    def is_uri(self):
763        """Return whether the value is a URI (resource)."""
764        return node_is_uri(self.node)
765
766    def is_blank(self):
767        """Return whether the value is a blank node (resource with no URI)."""
768        return node_is_blank(self.node)
769
770    def is_literal(self):
771        """Return whether this value is a literal (i.e. not a URI)."""
772        return node_is_literal(self.node)
773
774    def is_string(self):
775        """Return whether this value is a string literal.
776
777        Returns true if value is a string value (and not numeric).
778        """
779        return node_is_string(self.node)
780
781    def get_path(self, hostname=None):
782        """Return the path of a file URI node.
783
784        Returns None if value is not a file URI."""
785        return node_get_path(self.node, hostname).decode('utf-8')
786
787    def is_float(self):
788        """Return whether this value is a decimal literal."""
789        return node_is_float(self.node)
790
791    def is_int(self):
792        """Return whether this value is an integer literal."""
793        return node_is_int(self.node)
794
795    def is_bool(self):
796        """Return whether this value is a boolean."""
797        return node_is_bool(self.node)
798
799class Iter(Structure):
800    """Collection iterator."""
801    def __init__(self, collection, iterator, constructor, iter_get, iter_next, iter_is_end):
802        self.collection = collection
803        self.iterator = iterator
804        self.constructor = constructor
805        self.iter_get = iter_get
806        self.iter_next = iter_next
807        self.iter_is_end = iter_is_end
808
809    def get(self):
810        """Get the current item."""
811        return self.constructor(self.iter_get(self.collection, self.iterator))
812
813    def next(self):
814        """Move to and return the next item."""
815        if self.is_end():
816            raise StopIteration
817        elem = self.get()
818        self.iterator = self.iter_next(self.collection, self.iterator)
819        return elem
820
821    def is_end(self):
822        """Return true if the end of the collection has been reached."""
823        return self.iter_is_end(self.collection, self.iterator)
824
825    __next__ = next
826
827class Collection(Structure):
828    # Base class for all lilv collection wrappers.
829    def __init__(self, collection, iter_begin, constructor, iter_get, iter_next, is_end):
830        self.collection = collection
831        self.constructor = constructor
832        self.iter_begin = iter_begin
833        self.iter_get = iter_get
834        self.iter_next = iter_next
835        self.is_end = is_end
836
837    def __iter__(self):
838        return Iter(self.collection, self.iter_begin(self.collection), self.constructor,
839                    self.iter_get, self.iter_next, self.is_end)
840
841    def __getitem__(self, index):
842        if index >= len(self):
843            raise IndexError
844        pos = 0
845        for i in self:
846            if pos == index:
847                return i
848            pos += 1
849
850    def begin(self):
851        return self.__iter__()
852
853    def get(self, iterator):
854        return iterator.get()
855
856class Plugins(Collection):
857    """Collection of plugins."""
858    def __init__(self, world, collection):
859        def constructor(plugin):
860            return Plugin(world, plugin)
861
862        super(Plugins, self).__init__(collection, plugins_begin, constructor, plugins_get, plugins_next, plugins_is_end)
863        self.world = world
864
865    def __contains__(self, key):
866        return bool(self.get_by_uri(_as_uri(key)))
867
868    def __len__(self):
869        return plugins_size(self.collection)
870
871    def __getitem__(self, key):
872        if type(key) == int:
873            return super(Plugins, self).__getitem__(key)
874        return self.get_by_uri(key)
875
876    def get_by_uri(self, uri):
877        plugin = plugins_get_by_uri(self.collection, uri.node)
878        return Plugin(self.world, plugin) if plugin else None
879
880class PluginClasses(Collection):
881    """Collection of plugin classes."""
882    def __init__(self, collection):
883        super(PluginClasses, self).__init__(
884            collection, plugin_classes_begin, PluginClass,
885            plugin_classes_get, plugin_classes_next, plugin_classes_is_end)
886
887    def __contains__(self, key):
888        return bool(self.get_by_uri(_as_uri(key)))
889
890    def __len__(self):
891        return plugin_classes_size(self.collection)
892
893    def __getitem__(self, key):
894        if type(key) == int:
895            return super(PluginClasses, self).__getitem__(key)
896        return self.get_by_uri(key)
897
898    def get_by_uri(self, uri):
899        plugin_class = plugin_classes_get_by_uri(self.collection, uri.node)
900        return PluginClass(plugin_class) if plugin_class else None
901
902class ScalePoints(Collection):
903    """Collection of scale points."""
904    def __init__(self, collection):
905        super(ScalePoints, self).__init__(
906            collection, scale_points_begin, ScalePoint,
907            scale_points_get, scale_points_next, scale_points_is_end)
908
909    def __len__(self):
910        return scale_points_size(self.collection)
911
912class UIs(Collection):
913    """Collection of plugin UIs."""
914    def __init__(self, collection):
915        super(UIs, self).__init__(collection, uis_begin, UI,
916                                  uis_get, uis_next, uis_is_end)
917
918    def __contains__(self, uri):
919        return bool(self.get_by_uri(_as_uri(uri)))
920
921    def __len__(self):
922        return uis_size(self.collection)
923
924    def __getitem__(self, key):
925        if type(key) == int:
926            return super(UIs, self).__getitem__(key)
927        return self.get_by_uri(key)
928
929    def get_by_uri(self, uri):
930        ui = uis_get_by_uri(self.collection, uri.node)
931        return UI(ui) if ui else None
932
933class Nodes(Collection):
934    """Collection of data nodes."""
935    @classmethod
936    def constructor(ignore, node):
937        return Node(node_duplicate(node))
938
939    def __init__(self, collection):
940        super(Nodes, self).__init__(collection, nodes_begin, Nodes.constructor,
941                                    nodes_get, nodes_next, nodes_is_end)
942
943    def __contains__(self, value):
944        return nodes_contains(self.collection, value.node)
945
946    def __len__(self):
947        return nodes_size(self.collection)
948
949    def merge(self, b):
950        return Nodes(nodes_merge(self.collection, b.collection))
951
952class Namespace():
953    """Namespace prefix.
954
955    Use attribute syntax to easily create URIs within this namespace, for
956    example::
957
958       >>> world = lilv.World()
959       >>> ns = Namespace(world, "http://example.org/")
960       >>> print(ns.foo)
961       http://example.org/foo
962    """
963    def __init__(self, world, prefix):
964        self.world  = world
965        self.prefix = prefix
966
967    def __eq__(self, other):
968        return str(self) == str(other)
969
970    def __str__(self):
971        return self.prefix
972
973    def __getattr__(self, suffix):
974        return self.world.new_uri(self.prefix + suffix)
975
976class World(Structure):
977    """Library context.
978
979    Includes a set of namespaces as the instance variable `ns`, so URIs can be constructed like::
980
981        uri = world.ns.lv2.Plugin
982
983    :ivar ns: Common LV2 namespace prefixes: atom, doap, foaf, lilv, lv2, midi, owl, rdf, rdfs, ui, xsd.
984    """
985    def __init__(self):
986        world = self
987
988        # Define Namespaces class locally so available prefixes are documented
989        class Namespaces():
990            """Set of namespaces.
991
992            Use to easily construct uris, like: ns.lv2.InputPort"""
993
994            atom = Namespace(world, 'http://lv2plug.in/ns/ext/atom#')
995            doap = Namespace(world, 'http://usefulinc.com/ns/doap#')
996            foaf = Namespace(world, 'http://xmlns.com/foaf/0.1/')
997            lilv = Namespace(world, 'http://drobilla.net/ns/lilv#')
998            lv2  = Namespace(world, 'http://lv2plug.in/ns/lv2core#')
999            midi = Namespace(world, 'http://lv2plug.in/ns/ext/midi#')
1000            owl  = Namespace(world, 'http://www.w3.org/2002/07/owl#')
1001            rdf  = Namespace(world, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
1002            rdfs = Namespace(world, 'http://www.w3.org/2000/01/rdf-schema#')
1003            ui   = Namespace(world, 'http://lv2plug.in/ns/extensions/ui#')
1004            xsd  = Namespace(world, 'http://www.w3.org/2001/XMLSchema#')
1005
1006        self.world = _lib.lilv_world_new()
1007        self.ns    = Namespaces()
1008
1009    def __del__(self):
1010        world_free(self.world)
1011
1012    def set_option(self, uri, value):
1013        """Set a world option.
1014
1015        Currently recognized options:
1016        lilv.OPTION_FILTER_LANG
1017        lilv.OPTION_DYN_MANIFEST
1018        """
1019        return world_set_option(self, uri, value.node)
1020
1021    def load_all(self):
1022        """Load all installed LV2 bundles on the system.
1023
1024        This is the recommended way for hosts to load LV2 data.  It implements the
1025        established/standard best practice for discovering all LV2 data on the
1026        system.  The environment variable LV2_PATH may be used to control where
1027        this function will look for bundles.
1028
1029        Hosts should use this function rather than explicitly load bundles, except
1030        in special circumstances (e.g. development utilities, or hosts that ship
1031        with special plugin bundles which are installed to a known location).
1032        """
1033        world_load_all(self.world)
1034
1035    def load_bundle(self, bundle_uri):
1036        """Load a specific bundle.
1037
1038        `bundle_uri` must be a fully qualified URI to the bundle directory,
1039        with the trailing slash, eg. file:///usr/lib/lv2/foo.lv2/
1040
1041        Normal hosts should not need this function (use load_all()).
1042
1043        Hosts MUST NOT attach any long-term significance to bundle paths
1044        (e.g. in save files), since there are no guarantees they will remain
1045        unchanged between (or even during) program invocations. Plugins (among
1046        other things) MUST be identified by URIs (not paths) in save files.
1047        """
1048        world_load_bundle(self.world, bundle_uri.node)
1049
1050    def load_specifications(self):
1051        """Load all specifications from currently loaded bundles.
1052
1053        This is for hosts that explicitly load specific bundles, its use is not
1054        necessary when using load_all().  This function parses the
1055        specifications and adds them to the model.
1056        """
1057        world_load_specifications(self.world)
1058
1059    def load_plugin_classes(self):
1060        """Load all plugin classes from currently loaded specifications.
1061
1062        Must be called after load_specifications().  This is for hosts
1063        that explicitly load specific bundles, its use is not necessary when using
1064        load_all().
1065        """
1066        world_load_plugin_classes(self.world)
1067
1068    def unload_bundle(self, bundle_uri):
1069        """Unload a specific bundle.
1070
1071        This unloads statements loaded by load_bundle().  Note that this
1072        is not necessarily all information loaded from the bundle.  If any resources
1073        have been separately loaded with load_resource(), they must be
1074        separately unloaded with unload_resource().
1075        """
1076        return world_unload_bundle(self.world, bundle_uri.node)
1077
1078    def load_resource(self, resource):
1079        """Load all the data associated with the given `resource`.
1080
1081        The resource must be a subject (i.e. a URI or a blank node).
1082        Returns the number of files parsed, or -1 on error.
1083
1084        All accessible data files linked to `resource` with rdfs:seeAlso will be
1085        loaded into the world model.
1086        """
1087        return world_load_resource(self.world, _as_uri(resource).node)
1088
1089    def unload_resource(self, resource):
1090        """Unload all the data associated with the given `resource`.
1091
1092        The resource must be a subject (i.e. a URI or a blank node).
1093
1094        This unloads all data loaded by a previous call to
1095        load_resource() with the given `resource`.
1096        """
1097        return world_unload_resource(self.world, _as_uri(resource).node)
1098
1099    def get_plugin_class(self):
1100        """Get the parent of all other plugin classes, lv2:Plugin."""
1101        return PluginClass(world_get_plugin_class(self.world))
1102
1103    def get_plugin_classes(self):
1104        """Return a list of all found plugin classes."""
1105        return PluginClasses(world_get_plugin_classes(self.world))
1106
1107    def get_all_plugins(self):
1108        """Return a list of all found plugins.
1109
1110        The returned list contains just enough references to query
1111        or instantiate plugins.  The data for a particular plugin will not be
1112        loaded into memory until a call to an lilv_plugin_* function results in
1113        a query (at which time the data is cached with the LilvPlugin so future
1114        queries are very fast).
1115
1116        The returned list and the plugins it contains are owned by `world`
1117        and must not be freed by caller.
1118        """
1119        return Plugins(self, _lib.lilv_world_get_all_plugins(self.world))
1120
1121    def find_nodes(self, subject, predicate, obj):
1122        """Find nodes matching a triple pattern.
1123
1124        Either `subject` or `object` may be None (i.e. a wildcard), but not both.
1125        Returns all matches for the wildcard field, or None.
1126        """
1127        return Nodes(world_find_nodes(self.world,
1128                                      subject.node if subject is not None else None,
1129                                      predicate.node if predicate is not None else None,
1130                                      obj.node if obj is not None else None))
1131
1132    def get(self, subject, predicate, obj):
1133        """Find a single node that matches a pattern.
1134
1135        Exactly one of `subject`, `predicate`, `object` must be None.
1136
1137        Returns the first matching node, or None if no matches are found.
1138        """
1139        return Node.wrap(world_get(self.world,
1140                                   subject.node if subject is not None else None,
1141                                   predicate.node if predicate is not None else None,
1142                                   obj.node if obj is not None else None))
1143
1144    def ask(self, subject, predicate, obj):
1145        """Return true iff a statement matching a certain pattern exists.
1146
1147        This is useful for checking if particular statement exists without having to
1148        bother with collections and memory management.
1149        """
1150        return world_ask(self.world,
1151                         subject.node if subject is not None else None,
1152                         predicate.node if predicate is not None else None,
1153                         obj.node if obj is not None else None)
1154
1155    def new_uri(self, uri):
1156        """Create a new URI node."""
1157        return Node.wrap(_lib.lilv_new_uri(self.world, uri))
1158
1159    def new_file_uri(self, host, path):
1160        """Create a new file URI node.  The host may be None."""
1161        return Node.wrap(_lib.lilv_new_file_uri(self.world, host, path))
1162
1163    def new_string(self, string):
1164        """Create a new string node."""
1165        return Node.wrap(_lib.lilv_new_string(self.world, string))
1166
1167    def new_int(self, val):
1168        """Create a new int node."""
1169        return Node.wrap(_lib.lilv_new_int(self.world, val))
1170
1171    def new_float(self, val):
1172        """Create a new float node."""
1173        return Node.wrap(_lib.lilv_new_float(self.world, val))
1174
1175    def new_bool(self, val):
1176        """Create a new bool node."""
1177        return Node.wrap(_lib.lilv_new_bool(self.world, val))
1178
1179class Instance(Structure):
1180    """Plugin instance."""
1181    __slots__ = [ 'lv2_descriptor', 'lv2_handle', 'pimpl', 'plugin', 'rate', 'instance' ]
1182    _fields_  = [
1183        ('lv2_descriptor', POINTER(LV2_Descriptor)),
1184        ('lv2_handle', LV2_Handle),
1185        ('pimpl', POINTER(None)),
1186    ]
1187
1188    def __init__(self, plugin, rate, features=None):
1189        self.plugin   = plugin
1190        self.rate     = rate
1191        self.instance = plugin_instantiate(plugin.plugin, rate, features)
1192
1193    def get_uri(self):
1194        """Get the URI of the plugin which `instance` is an instance of.
1195
1196           Returned string is shared and must not be modified or deleted.
1197        """
1198        return self.get_descriptor().URI
1199
1200    def connect_port(self, port_index, data):
1201        """Connect a port to a data location.
1202
1203           This may be called regardless of whether the plugin is activated,
1204           activation and deactivation does not destroy port connections.
1205        """
1206        import numpy
1207        if data is None:
1208            self.get_descriptor().connect_port(
1209                self.get_handle(),
1210                port_index,
1211                data)
1212        elif type(data) == numpy.ndarray:
1213            self.get_descriptor().connect_port(
1214                self.get_handle(),
1215                port_index,
1216                data.ctypes.data_as(POINTER(c_float)))
1217        else:
1218            raise Exception("Unsupported data type")
1219
1220    def activate(self):
1221        """Activate a plugin instance.
1222
1223           This resets all state information in the plugin, except for port data
1224           locations (as set by connect_port()).  This MUST be called
1225           before calling run().
1226        """
1227        if self.get_descriptor().activate:
1228            self.get_descriptor().activate(self.get_handle())
1229
1230    def run(self, sample_count):
1231        """Run `instance` for `sample_count` frames.
1232
1233           If the hint lv2:hardRTCapable is set for this plugin, this function is
1234           guaranteed not to block.
1235        """
1236        self.get_descriptor().run(self.get_handle(), sample_count)
1237
1238    def deactivate(self):
1239        """Deactivate a plugin instance.
1240
1241           Note that to run the plugin after this you must activate it, which will
1242           reset all state information (except port connections).
1243        """
1244        if self.get_descriptor().deactivate:
1245            self.get_descriptor().deactivate(self.get_handle())
1246
1247    def get_extension_data(self, uri):
1248        """Get extension data from the plugin instance.
1249
1250           The type and semantics of the data returned is specific to the particular
1251           extension, though in all cases it is shared and must not be deleted.
1252        """
1253        if self.get_descriptor().extension_data:
1254            return self.get_descriptor().extension_data(str(uri))
1255
1256    def get_descriptor(self):
1257        """Get the LV2_Descriptor of the plugin instance.
1258
1259           Normally hosts should not need to access the LV2_Descriptor directly,
1260           use the lilv_instance_* functions.
1261        """
1262        return self.instance[0].lv2_descriptor[0]
1263
1264    def get_handle(self):
1265        """Get the LV2_Handle of the plugin instance.
1266
1267           Normally hosts should not need to access the LV2_Handle directly,
1268           use the lilv_instance_* functions.
1269        """
1270        return self.instance[0].lv2_handle
1271
1272class State(Structure):
1273    """Plugin state (TODO)."""
1274    pass
1275
1276class VariadicFunction(object):
1277    # Wrapper for calling C variadic functions
1278    def __init__(self, function, restype, argtypes):
1279        self.function         = function
1280        self.function.restype = restype
1281        self.argtypes         = argtypes
1282
1283    def __call__(self, *args):
1284        fixed_args = []
1285        i          = 0
1286        for argtype in self.argtypes:
1287            fixed_args.append(argtype.from_param(args[i]))
1288            i += 1
1289        return self.function(*fixed_args + list(args[i:]))
1290
1291# Set return and argument types for lilv C functions
1292
1293free.argtypes = [POINTER(None)]
1294free.restype  = None
1295
1296# uri_to_path.argtypes = [String]
1297# uri_to_path.restype  = c_char_p
1298
1299file_uri_parse.argtypes = [String, POINTER(POINTER(c_char))]
1300file_uri_parse.restype  = c_char_p
1301
1302new_uri.argtypes = [POINTER(World), String]
1303new_uri.restype  = POINTER(Node)
1304
1305new_file_uri.argtypes = [POINTER(World), c_char_p, String]
1306new_file_uri.restype  = POINTER(Node)
1307
1308new_string.argtypes = [POINTER(World), String]
1309new_string.restype  = POINTER(Node)
1310
1311new_int.argtypes = [POINTER(World), c_int]
1312new_int.restype  = POINTER(Node)
1313
1314new_float.argtypes = [POINTER(World), c_float]
1315new_float.restype  = POINTER(Node)
1316
1317new_bool.argtypes = [POINTER(World), c_bool]
1318new_bool.restype  = POINTER(Node)
1319
1320node_free.argtypes = [POINTER(Node)]
1321node_free.restype  = None
1322
1323node_duplicate.argtypes = [POINTER(Node)]
1324node_duplicate.restype  = POINTER(Node)
1325
1326node_equals.argtypes = [POINTER(Node), POINTER(Node)]
1327node_equals.restype  = c_bool
1328
1329node_get_turtle_token.argtypes = [POINTER(Node)]
1330node_get_turtle_token.restype  = c_char_p
1331
1332node_is_uri.argtypes = [POINTER(Node)]
1333node_is_uri.restype  = c_bool
1334
1335node_as_uri.argtypes = [POINTER(Node)]
1336node_as_uri.restype  = c_char_p
1337
1338node_is_blank.argtypes = [POINTER(Node)]
1339node_is_blank.restype  = c_bool
1340
1341node_as_blank.argtypes = [POINTER(Node)]
1342node_as_blank.restype  = c_char_p
1343
1344node_is_literal.argtypes = [POINTER(Node)]
1345node_is_literal.restype  = c_bool
1346
1347node_is_string.argtypes = [POINTER(Node)]
1348node_is_string.restype  = c_bool
1349
1350node_as_string.argtypes = [POINTER(Node)]
1351node_as_string.restype  = c_char_p
1352
1353node_get_path.argtypes = [POINTER(Node), POINTER(POINTER(c_char))]
1354node_get_path.restype  = c_char_p
1355
1356node_is_float.argtypes = [POINTER(Node)]
1357node_is_float.restype  = c_bool
1358
1359node_as_float.argtypes = [POINTER(Node)]
1360node_as_float.restype  = c_float
1361
1362node_is_int.argtypes = [POINTER(Node)]
1363node_is_int.restype  = c_bool
1364
1365node_as_int.argtypes = [POINTER(Node)]
1366node_as_int.restype  = c_int
1367
1368node_is_bool.argtypes = [POINTER(Node)]
1369node_is_bool.restype  = c_bool
1370
1371node_as_bool.argtypes = [POINTER(Node)]
1372node_as_bool.restype  = c_bool
1373
1374plugin_classes_free.argtypes = [POINTER(PluginClasses)]
1375plugin_classes_free.restype  = None
1376
1377plugin_classes_size.argtypes = [POINTER(PluginClasses)]
1378plugin_classes_size.restype  = c_uint
1379
1380plugin_classes_begin.argtypes = [POINTER(PluginClasses)]
1381plugin_classes_begin.restype  = POINTER(Iter)
1382
1383plugin_classes_get.argtypes = [POINTER(PluginClasses), POINTER(Iter)]
1384plugin_classes_get.restype  = POINTER(PluginClass)
1385
1386plugin_classes_next.argtypes = [POINTER(PluginClasses), POINTER(Iter)]
1387plugin_classes_next.restype  = POINTER(Iter)
1388
1389plugin_classes_is_end.argtypes = [POINTER(PluginClasses), POINTER(Iter)]
1390plugin_classes_is_end.restype  = c_bool
1391
1392plugin_classes_get_by_uri.argtypes = [POINTER(PluginClasses), POINTER(Node)]
1393plugin_classes_get_by_uri.restype  = POINTER(PluginClass)
1394
1395scale_points_free.argtypes = [POINTER(ScalePoints)]
1396scale_points_free.restype  = None
1397
1398scale_points_size.argtypes = [POINTER(ScalePoints)]
1399scale_points_size.restype  = c_uint
1400
1401scale_points_begin.argtypes = [POINTER(ScalePoints)]
1402scale_points_begin.restype  = POINTER(Iter)
1403
1404scale_points_get.argtypes = [POINTER(ScalePoints), POINTER(Iter)]
1405scale_points_get.restype  = POINTER(ScalePoint)
1406
1407scale_points_next.argtypes = [POINTER(ScalePoints), POINTER(Iter)]
1408scale_points_next.restype  = POINTER(Iter)
1409
1410scale_points_is_end.argtypes = [POINTER(ScalePoints), POINTER(Iter)]
1411scale_points_is_end.restype  = c_bool
1412
1413uis_free.argtypes = [POINTER(UIs)]
1414uis_free.restype  = None
1415
1416uis_size.argtypes = [POINTER(UIs)]
1417uis_size.restype  = c_uint
1418
1419uis_begin.argtypes = [POINTER(UIs)]
1420uis_begin.restype  = POINTER(Iter)
1421
1422uis_get.argtypes = [POINTER(UIs), POINTER(Iter)]
1423uis_get.restype  = POINTER(UI)
1424
1425uis_next.argtypes = [POINTER(UIs), POINTER(Iter)]
1426uis_next.restype  = POINTER(Iter)
1427
1428uis_is_end.argtypes = [POINTER(UIs), POINTER(Iter)]
1429uis_is_end.restype  = c_bool
1430
1431uis_get_by_uri.argtypes = [POINTER(UIs), POINTER(Node)]
1432uis_get_by_uri.restype  = POINTER(UI)
1433
1434nodes_free.argtypes = [POINTER(Nodes)]
1435nodes_free.restype  = None
1436
1437nodes_size.argtypes = [POINTER(Nodes)]
1438nodes_size.restype  = c_uint
1439
1440nodes_begin.argtypes = [POINTER(Nodes)]
1441nodes_begin.restype  = POINTER(Iter)
1442
1443nodes_get.argtypes = [POINTER(Nodes), POINTER(Iter)]
1444nodes_get.restype  = POINTER(Node)
1445
1446nodes_next.argtypes = [POINTER(Nodes), POINTER(Iter)]
1447nodes_next.restype  = POINTER(Iter)
1448
1449nodes_is_end.argtypes = [POINTER(Nodes), POINTER(Iter)]
1450nodes_is_end.restype  = c_bool
1451
1452nodes_get_first.argtypes = [POINTER(Nodes)]
1453nodes_get_first.restype  = POINTER(Node)
1454
1455nodes_contains.argtypes = [POINTER(Nodes), POINTER(Node)]
1456nodes_contains.restype  = c_bool
1457
1458nodes_merge.argtypes = [POINTER(Nodes), POINTER(Nodes)]
1459nodes_merge.restype  = POINTER(Nodes)
1460
1461plugins_size.argtypes = [POINTER(Plugins)]
1462plugins_size.restype  = c_uint
1463
1464plugins_begin.argtypes = [POINTER(Plugins)]
1465plugins_begin.restype  = POINTER(Iter)
1466
1467plugins_get.argtypes = [POINTER(Plugins), POINTER(Iter)]
1468plugins_get.restype  = POINTER(Plugin)
1469
1470plugins_next.argtypes = [POINTER(Plugins), POINTER(Iter)]
1471plugins_next.restype  = POINTER(Iter)
1472
1473plugins_is_end.argtypes = [POINTER(Plugins), POINTER(Iter)]
1474plugins_is_end.restype  = c_bool
1475
1476plugins_get_by_uri.argtypes = [POINTER(Plugins), POINTER(Node)]
1477plugins_get_by_uri.restype  = POINTER(Plugin)
1478
1479world_new.argtypes = []
1480world_new.restype  = POINTER(World)
1481
1482world_set_option.argtypes = [POINTER(World), String, POINTER(Node)]
1483world_set_option.restype  = None
1484
1485world_free.argtypes = [POINTER(World)]
1486world_free.restype  = None
1487
1488world_load_all.argtypes = [POINTER(World)]
1489world_load_all.restype  = None
1490
1491world_load_bundle.argtypes = [POINTER(World), POINTER(Node)]
1492world_load_bundle.restype  = None
1493
1494world_load_specifications.argtypes = [POINTER(World)]
1495world_load_specifications.restype  = None
1496
1497world_load_plugin_classes.argtypes = [POINTER(World)]
1498world_load_plugin_classes.restype  = None
1499
1500world_unload_bundle.argtypes = [POINTER(World), POINTER(Node)]
1501world_unload_bundle.restype  = c_int
1502
1503world_load_resource.argtypes = [POINTER(World), POINTER(Node)]
1504world_load_resource.restype  = c_int
1505
1506world_unload_resource.argtypes = [POINTER(World), POINTER(Node)]
1507world_unload_resource.restype  = c_int
1508
1509world_get_plugin_class.argtypes = [POINTER(World)]
1510world_get_plugin_class.restype  = POINTER(PluginClass)
1511
1512world_get_plugin_classes.argtypes = [POINTER(World)]
1513world_get_plugin_classes.restype  = POINTER(PluginClasses)
1514
1515world_get_all_plugins.argtypes = [POINTER(World)]
1516world_get_all_plugins.restype  = POINTER(Plugins)
1517
1518world_find_nodes.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)]
1519world_find_nodes.restype  = POINTER(Nodes)
1520
1521world_get.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)]
1522world_get.restype  = POINTER(Node)
1523
1524world_ask.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)]
1525world_ask.restype  = c_bool
1526
1527plugin_verify.argtypes = [POINTER(Plugin)]
1528plugin_verify.restype  = c_bool
1529
1530plugin_get_uri.argtypes = [POINTER(Plugin)]
1531plugin_get_uri.restype  = POINTER(Node)
1532
1533plugin_get_bundle_uri.argtypes = [POINTER(Plugin)]
1534plugin_get_bundle_uri.restype  = POINTER(Node)
1535
1536plugin_get_data_uris.argtypes = [POINTER(Plugin)]
1537plugin_get_data_uris.restype  = POINTER(Nodes)
1538
1539plugin_get_library_uri.argtypes = [POINTER(Plugin)]
1540plugin_get_library_uri.restype  = POINTER(Node)
1541
1542plugin_get_name.argtypes = [POINTER(Plugin)]
1543plugin_get_name.restype  = POINTER(Node)
1544
1545plugin_get_class.argtypes = [POINTER(Plugin)]
1546plugin_get_class.restype  = POINTER(PluginClass)
1547
1548plugin_get_value.argtypes = [POINTER(Plugin), POINTER(Node)]
1549plugin_get_value.restype  = POINTER(Nodes)
1550
1551plugin_has_feature.argtypes = [POINTER(Plugin), POINTER(Node)]
1552plugin_has_feature.restype  = c_bool
1553
1554plugin_get_supported_features.argtypes = [POINTER(Plugin)]
1555plugin_get_supported_features.restype  = POINTER(Nodes)
1556
1557plugin_get_required_features.argtypes = [POINTER(Plugin)]
1558plugin_get_required_features.restype  = POINTER(Nodes)
1559
1560plugin_get_optional_features.argtypes = [POINTER(Plugin)]
1561plugin_get_optional_features.restype  = POINTER(Nodes)
1562
1563plugin_has_extension_data.argtypes = [POINTER(Plugin), POINTER(Node)]
1564plugin_has_extension_data.restype  = c_bool
1565
1566plugin_get_extension_data.argtypes = [POINTER(Plugin)]
1567plugin_get_extension_data.restype  = POINTER(Nodes)
1568
1569plugin_get_num_ports.argtypes = [POINTER(Plugin)]
1570plugin_get_num_ports.restype  = c_uint32
1571
1572plugin_get_port_ranges_float.argtypes = [POINTER(Plugin), POINTER(c_float), POINTER(c_float), POINTER(c_float)]
1573plugin_get_port_ranges_float.restype  = None
1574
1575plugin_get_num_ports_of_class = VariadicFunction(_lib.lilv_plugin_get_num_ports_of_class,
1576                                                 c_uint32,
1577                                                 [POINTER(Plugin), POINTER(Node)])
1578
1579plugin_has_latency.argtypes = [POINTER(Plugin)]
1580plugin_has_latency.restype  = c_bool
1581
1582plugin_get_latency_port_index.argtypes = [POINTER(Plugin)]
1583plugin_get_latency_port_index.restype  = c_uint32
1584
1585plugin_get_port_by_index.argtypes = [POINTER(Plugin), c_uint32]
1586plugin_get_port_by_index.restype  = POINTER(Port)
1587
1588plugin_get_port_by_symbol.argtypes = [POINTER(Plugin), POINTER(Node)]
1589plugin_get_port_by_symbol.restype  = POINTER(Port)
1590
1591plugin_get_port_by_designation.argtypes = [POINTER(Plugin), POINTER(Node), POINTER(Node)]
1592plugin_get_port_by_designation.restype  = POINTER(Port)
1593
1594plugin_get_project.argtypes = [POINTER(Plugin)]
1595plugin_get_project.restype  = POINTER(Node)
1596
1597plugin_get_author_name.argtypes = [POINTER(Plugin)]
1598plugin_get_author_name.restype  = POINTER(Node)
1599
1600plugin_get_author_email.argtypes = [POINTER(Plugin)]
1601plugin_get_author_email.restype  = POINTER(Node)
1602
1603plugin_get_author_homepage.argtypes = [POINTER(Plugin)]
1604plugin_get_author_homepage.restype  = POINTER(Node)
1605
1606plugin_is_replaced.argtypes = [POINTER(Plugin)]
1607plugin_is_replaced.restype  = c_bool
1608
1609plugin_get_related.argtypes = [POINTER(Plugin), POINTER(Node)]
1610plugin_get_related.restype  = POINTER(Nodes)
1611
1612port_get_node.argtypes = [POINTER(Plugin), POINTER(Port)]
1613port_get_node.restype  = POINTER(Node)
1614
1615port_get_value.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)]
1616port_get_value.restype  = POINTER(Nodes)
1617
1618port_get.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)]
1619port_get.restype  = POINTER(Node)
1620
1621port_get_properties.argtypes = [POINTER(Plugin), POINTER(Port)]
1622port_get_properties.restype  = POINTER(Nodes)
1623
1624port_has_property.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)]
1625port_has_property.restype  = c_bool
1626
1627port_supports_event.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)]
1628port_supports_event.restype  = c_bool
1629
1630port_get_index.argtypes = [POINTER(Plugin), POINTER(Port)]
1631port_get_index.restype  = c_uint32
1632
1633port_get_symbol.argtypes = [POINTER(Plugin), POINTER(Port)]
1634port_get_symbol.restype  = POINTER(Node)
1635
1636port_get_name.argtypes = [POINTER(Plugin), POINTER(Port)]
1637port_get_name.restype  = POINTER(Node)
1638
1639port_get_classes.argtypes = [POINTER(Plugin), POINTER(Port)]
1640port_get_classes.restype  = POINTER(Nodes)
1641
1642port_is_a.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)]
1643port_is_a.restype  = c_bool
1644
1645port_get_range.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(POINTER(Node)), POINTER(POINTER(Node)), POINTER(POINTER(Node))]
1646port_get_range.restype  = None
1647
1648port_get_scale_points.argtypes = [POINTER(Plugin), POINTER(Port)]
1649port_get_scale_points.restype  = POINTER(ScalePoints)
1650
1651state_new_from_world.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(Node)]
1652state_new_from_world.restype  = POINTER(State)
1653
1654state_new_from_file.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(Node), String]
1655state_new_from_file.restype  = POINTER(State)
1656
1657state_new_from_string.argtypes = [POINTER(World), POINTER(LV2_URID_Map), String]
1658state_new_from_string.restype  = POINTER(State)
1659
1660LilvGetPortValueFunc = CFUNCTYPE(c_void_p, c_char_p, POINTER(None), POINTER(c_uint32), POINTER(c_uint32))
1661
1662state_new_from_instance.argtypes = [POINTER(Plugin), POINTER(Instance), POINTER(LV2_URID_Map), c_char_p, c_char_p, c_char_p, String, LilvGetPortValueFunc, POINTER(None), c_uint32, POINTER(POINTER(LV2_Feature))]
1663state_new_from_instance.restype  = POINTER(State)
1664
1665state_free.argtypes = [POINTER(State)]
1666state_free.restype  = None
1667
1668state_equals.argtypes = [POINTER(State), POINTER(State)]
1669state_equals.restype  = c_bool
1670
1671state_get_num_properties.argtypes = [POINTER(State)]
1672state_get_num_properties.restype  = c_uint
1673
1674state_get_plugin_uri.argtypes = [POINTER(State)]
1675state_get_plugin_uri.restype  = POINTER(Node)
1676
1677state_get_uri.argtypes = [POINTER(State)]
1678state_get_uri.restype  = POINTER(Node)
1679
1680state_get_label.argtypes = [POINTER(State)]
1681state_get_label.restype  = c_char_p
1682
1683state_set_label.argtypes = [POINTER(State), String]
1684state_set_label.restype  = None
1685
1686state_set_metadata.argtypes = [POINTER(State), c_uint32, POINTER(None), c_size_t, c_uint32, c_uint32]
1687state_set_metadata.restype  = c_int
1688
1689LilvSetPortValueFunc            = CFUNCTYPE(None, c_char_p, POINTER(None), POINTER(None), c_uint32, c_uint32)
1690state_emit_port_values.argtypes = [POINTER(State), LilvSetPortValueFunc, POINTER(None)]
1691state_emit_port_values.restype  = None
1692
1693state_restore.argtypes = [POINTER(State), POINTER(Instance), LilvSetPortValueFunc, POINTER(None), c_uint32, POINTER(POINTER(LV2_Feature))]
1694state_restore.restype  = None
1695
1696state_save.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(LV2_URID_Unmap), POINTER(State), c_char_p, c_char_p, String]
1697state_save.restype  = c_int
1698
1699state_to_string.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(LV2_URID_Unmap), POINTER(State), c_char_p, String]
1700state_to_string.restype  = c_char_p
1701
1702state_delete.argtypes = [POINTER(World), POINTER(State)]
1703state_delete.restype  = c_int
1704
1705scale_point_get_label.argtypes = [POINTER(ScalePoint)]
1706scale_point_get_label.restype  = POINTER(Node)
1707
1708scale_point_get_value.argtypes = [POINTER(ScalePoint)]
1709scale_point_get_value.restype  = POINTER(Node)
1710
1711plugin_class_get_parent_uri.argtypes = [POINTER(PluginClass)]
1712plugin_class_get_parent_uri.restype  = POINTER(Node)
1713
1714plugin_class_get_uri.argtypes = [POINTER(PluginClass)]
1715plugin_class_get_uri.restype  = POINTER(Node)
1716
1717plugin_class_get_label.argtypes = [POINTER(PluginClass)]
1718plugin_class_get_label.restype  = POINTER(Node)
1719
1720plugin_class_get_children.argtypes = [POINTER(PluginClass)]
1721plugin_class_get_children.restype  = POINTER(PluginClasses)
1722
1723plugin_instantiate.argtypes = [POINTER(Plugin), c_double, POINTER(POINTER(LV2_Feature))]
1724plugin_instantiate.restype = POINTER(Instance)
1725
1726instance_free.argtypes = [POINTER(Instance)]
1727instance_free.restype = None
1728
1729plugin_get_uis.argtypes = [POINTER(Plugin)]
1730plugin_get_uis.restype = POINTER(UIs)
1731
1732ui_get_uri.argtypes = [POINTER(UI)]
1733ui_get_uri.restype = POINTER(Node)
1734
1735ui_get_classes.argtypes = [POINTER(UI)]
1736ui_get_classes.restype = POINTER(Nodes)
1737
1738ui_is_a.argtypes = [POINTER(UI), POINTER(Node)]
1739ui_is_a.restype = c_bool
1740
1741LilvUISupportedFunc = CFUNCTYPE(c_uint, c_char_p, c_char_p)
1742
1743ui_is_supported.argtypes = [POINTER(UI), LilvUISupportedFunc, POINTER(Node), POINTER(POINTER(Node))]
1744ui_is_supported.restype = c_uint
1745
1746ui_get_bundle_uri.argtypes = [POINTER(UI)]
1747ui_get_bundle_uri.restype = POINTER(Node)
1748
1749ui_get_binary_uri.argtypes = [POINTER(UI)]
1750ui_get_binary_uri.restype = POINTER(Node)
1751
1752OPTION_FILTER_LANG  = 'http://drobilla.net/ns/lilv#filter-lang'
1753OPTION_DYN_MANIFEST = 'http://drobilla.net/ns/lilv#dyn-manifest'
1754
1755# Define URI constants for compatibility with old Python bindings
1756
1757LILV_NS_DOAP             = 'http://usefulinc.com/ns/doap#'
1758LILV_NS_FOAF             = 'http://xmlns.com/foaf/0.1/'
1759LILV_NS_LILV             = 'http://drobilla.net/ns/lilv#'
1760LILV_NS_LV2              = 'http://lv2plug.in/ns/lv2core#'
1761LILV_NS_OWL              = 'http://www.w3.org/2002/07/owl#'
1762LILV_NS_RDF              = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
1763LILV_NS_RDFS             = 'http://www.w3.org/2000/01/rdf-schema#'
1764LILV_NS_XSD              = 'http://www.w3.org/2001/XMLSchema#'
1765LILV_URI_ATOM_PORT       = 'http://lv2plug.in/ns/ext/atom#AtomPort'
1766LILV_URI_AUDIO_PORT      = 'http://lv2plug.in/ns/lv2core#AudioPort'
1767LILV_URI_CONTROL_PORT    = 'http://lv2plug.in/ns/lv2core#ControlPort'
1768LILV_URI_CV_PORT         = 'http://lv2plug.in/ns/lv2core#CVPort'
1769LILV_URI_EVENT_PORT      = 'http://lv2plug.in/ns/ext/event#EventPort'
1770LILV_URI_INPUT_PORT      = 'http://lv2plug.in/ns/lv2core#InputPort'
1771LILV_URI_MIDI_EVENT      = 'http://lv2plug.in/ns/ext/midi#MidiEvent'
1772LILV_URI_OUTPUT_PORT     = 'http://lv2plug.in/ns/lv2core#OutputPort'
1773LILV_URI_PORT            = 'http://lv2plug.in/ns/lv2core#Port'
1774LILV_OPTION_FILTER_LANG  = 'http://drobilla.net/ns/lilv#filter-lang'
1775LILV_OPTION_DYN_MANIFEST = 'http://drobilla.net/ns/lilv#dyn-manifest'
1776