From 06e30c3fc93a2cc59e8d0642e257f73b59c38974 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 21 Oct 2019 21:26:49 +0200 Subject: Clean up Python bindings --- bindings/python/lilv.py | 1861 ++++++++++++++++++++++------------------------- 1 file changed, 884 insertions(+), 977 deletions(-) (limited to 'bindings/python/lilv.py') diff --git a/bindings/python/lilv.py b/bindings/python/lilv.py index e8162d6..6fdd790 100644 --- a/bindings/python/lilv.py +++ b/bindings/python/lilv.py @@ -1,241 +1,110 @@ """Lilv Python interface""" -__author__ = "David Robillard" -__copyright__ = "Copyright 2016-2019 David Robillard" -__license__ = "ISC" -__version__ = "0.22.1" +__author__ = "David Robillard" +__copyright__ = "Copyright 2016-2019 David Robillard" +__license__ = "ISC" +__version__ = "0.24.5" __maintainer__ = "David Robillard" -__email__ = "d@drobilla.net" -__status__ = "Production" +__email__ = "d@drobilla.net" +__status__ = "Production" from ctypes import Structure, CDLL, POINTER, CFUNCTYPE from ctypes import c_bool, c_double, c_float, c_int, c_size_t, c_uint, c_uint32 from ctypes import c_char, c_char_p, c_void_p from ctypes import byref, cast -# Load lilv library +# Option constants +OPTION_FILTER_LANG = "http://drobilla.net/ns/lilv#filter-lang" +OPTION_DYN_MANIFEST = "http://drobilla.net/ns/lilv#dyn-manifest" -_lib = CDLL("liblilv-0.so") -# Set namespaced aliases for all lilv functions +class _LilvLib: + """Object that represents the liblilv C library""" -class String(str): - # Wrapper for string parameters to pass as raw C UTF-8 strings - def from_param(cls, obj): - assert isinstance(obj, str) - return obj.encode('utf-8') + def __init__(self): + self.lib = CDLL("liblilv-0.so") + + +# Load lilv C library and define library global (which is populated below) +c = _LilvLib() - from_param = classmethod(from_param) def _as_uri(obj): + """Utility function for converting some object into a URI node""" if type(obj) in [Plugin, PluginClass, UI]: return obj.get_uri() else: assert type(obj) == Node assert obj.node - return Node(obj.world, node_duplicate(obj.node)) - -free = _lib.lilv_free -# uri_to_path = _lib.lilv_uri_to_path -file_uri_parse = _lib.lilv_file_uri_parse -new_uri = _lib.lilv_new_uri -new_file_uri = _lib.lilv_new_file_uri -new_string = _lib.lilv_new_string -new_int = _lib.lilv_new_int -new_float = _lib.lilv_new_float -new_bool = _lib.lilv_new_bool -node_free = _lib.lilv_node_free -node_duplicate = _lib.lilv_node_duplicate -node_equals = _lib.lilv_node_equals -node_get_turtle_token = _lib.lilv_node_get_turtle_token -node_is_uri = _lib.lilv_node_is_uri -node_as_uri = _lib.lilv_node_as_uri -node_is_blank = _lib.lilv_node_is_blank -node_as_blank = _lib.lilv_node_as_blank -node_is_literal = _lib.lilv_node_is_literal -node_is_string = _lib.lilv_node_is_string -node_as_string = _lib.lilv_node_as_string -node_get_path = _lib.lilv_node_get_path -node_is_float = _lib.lilv_node_is_float -node_as_float = _lib.lilv_node_as_float -node_is_int = _lib.lilv_node_is_int -node_as_int = _lib.lilv_node_as_int -node_is_bool = _lib.lilv_node_is_bool -node_as_bool = _lib.lilv_node_as_bool -plugin_classes_free = _lib.lilv_plugin_classes_free -plugin_classes_size = _lib.lilv_plugin_classes_size -plugin_classes_begin = _lib.lilv_plugin_classes_begin -plugin_classes_get = _lib.lilv_plugin_classes_get -plugin_classes_next = _lib.lilv_plugin_classes_next -plugin_classes_is_end = _lib.lilv_plugin_classes_is_end -plugin_classes_get_by_uri = _lib.lilv_plugin_classes_get_by_uri -scale_points_free = _lib.lilv_scale_points_free -scale_points_size = _lib.lilv_scale_points_size -scale_points_begin = _lib.lilv_scale_points_begin -scale_points_get = _lib.lilv_scale_points_get -scale_points_next = _lib.lilv_scale_points_next -scale_points_is_end = _lib.lilv_scale_points_is_end -uis_free = _lib.lilv_uis_free -uis_size = _lib.lilv_uis_size -uis_begin = _lib.lilv_uis_begin -uis_get = _lib.lilv_uis_get -uis_next = _lib.lilv_uis_next -uis_is_end = _lib.lilv_uis_is_end -uis_get_by_uri = _lib.lilv_uis_get_by_uri -nodes_free = _lib.lilv_nodes_free -nodes_size = _lib.lilv_nodes_size -nodes_begin = _lib.lilv_nodes_begin -nodes_get = _lib.lilv_nodes_get -nodes_next = _lib.lilv_nodes_next -nodes_is_end = _lib.lilv_nodes_is_end -nodes_get_first = _lib.lilv_nodes_get_first -nodes_contains = _lib.lilv_nodes_contains -nodes_merge = _lib.lilv_nodes_merge -plugins_size = _lib.lilv_plugins_size -plugins_begin = _lib.lilv_plugins_begin -plugins_get = _lib.lilv_plugins_get -plugins_next = _lib.lilv_plugins_next -plugins_is_end = _lib.lilv_plugins_is_end -plugins_get_by_uri = _lib.lilv_plugins_get_by_uri -world_new = _lib.lilv_world_new -world_set_option = _lib.lilv_world_set_option -world_free = _lib.lilv_world_free -world_load_all = _lib.lilv_world_load_all -world_load_bundle = _lib.lilv_world_load_bundle -world_load_specifications = _lib.lilv_world_load_specifications -world_load_plugin_classes = _lib.lilv_world_load_plugin_classes -world_unload_bundle = _lib.lilv_world_unload_bundle -world_load_resource = _lib.lilv_world_load_resource -world_unload_resource = _lib.lilv_world_unload_resource -world_get_plugin_class = _lib.lilv_world_get_plugin_class -world_get_plugin_classes = _lib.lilv_world_get_plugin_classes -world_get_all_plugins = _lib.lilv_world_get_all_plugins -world_find_nodes = _lib.lilv_world_find_nodes -world_get = _lib.lilv_world_get -world_ask = _lib.lilv_world_ask -plugin_verify = _lib.lilv_plugin_verify -plugin_get_uri = _lib.lilv_plugin_get_uri -plugin_get_bundle_uri = _lib.lilv_plugin_get_bundle_uri -plugin_get_data_uris = _lib.lilv_plugin_get_data_uris -plugin_get_library_uri = _lib.lilv_plugin_get_library_uri -plugin_get_name = _lib.lilv_plugin_get_name -plugin_get_class = _lib.lilv_plugin_get_class -plugin_get_value = _lib.lilv_plugin_get_value -plugin_has_feature = _lib.lilv_plugin_has_feature -plugin_get_supported_features = _lib.lilv_plugin_get_supported_features -plugin_get_required_features = _lib.lilv_plugin_get_required_features -plugin_get_optional_features = _lib.lilv_plugin_get_optional_features -plugin_has_extension_data = _lib.lilv_plugin_has_extension_data -plugin_get_extension_data = _lib.lilv_plugin_get_extension_data -plugin_get_num_ports = _lib.lilv_plugin_get_num_ports -plugin_get_port_ranges_float = _lib.lilv_plugin_get_port_ranges_float -plugin_has_latency = _lib.lilv_plugin_has_latency -plugin_get_latency_port_index = _lib.lilv_plugin_get_latency_port_index -plugin_get_port_by_index = _lib.lilv_plugin_get_port_by_index -plugin_get_port_by_symbol = _lib.lilv_plugin_get_port_by_symbol -plugin_get_port_by_designation = _lib.lilv_plugin_get_port_by_designation -plugin_get_project = _lib.lilv_plugin_get_project -plugin_get_author_name = _lib.lilv_plugin_get_author_name -plugin_get_author_email = _lib.lilv_plugin_get_author_email -plugin_get_author_homepage = _lib.lilv_plugin_get_author_homepage -plugin_is_replaced = _lib.lilv_plugin_is_replaced -plugin_get_related = _lib.lilv_plugin_get_related -port_get_node = _lib.lilv_port_get_node -port_get_value = _lib.lilv_port_get_value -port_get = _lib.lilv_port_get -port_get_properties = _lib.lilv_port_get_properties -port_has_property = _lib.lilv_port_has_property -port_supports_event = _lib.lilv_port_supports_event -port_get_index = _lib.lilv_port_get_index -port_get_symbol = _lib.lilv_port_get_symbol -port_get_name = _lib.lilv_port_get_name -port_get_classes = _lib.lilv_port_get_classes -port_is_a = _lib.lilv_port_is_a -port_get_range = _lib.lilv_port_get_range -port_get_scale_points = _lib.lilv_port_get_scale_points -state_new_from_world = _lib.lilv_state_new_from_world -state_new_from_file = _lib.lilv_state_new_from_file -state_new_from_string = _lib.lilv_state_new_from_string -state_new_from_instance = _lib.lilv_state_new_from_instance -state_free = _lib.lilv_state_free -state_equals = _lib.lilv_state_equals -state_get_num_properties = _lib.lilv_state_get_num_properties -state_get_plugin_uri = _lib.lilv_state_get_plugin_uri -state_get_uri = _lib.lilv_state_get_uri -state_get_label = _lib.lilv_state_get_label -state_set_label = _lib.lilv_state_set_label -state_set_metadata = _lib.lilv_state_set_metadata -state_emit_port_values = _lib.lilv_state_emit_port_values -state_restore = _lib.lilv_state_restore -state_save = _lib.lilv_state_save -state_to_string = _lib.lilv_state_to_string -state_delete = _lib.lilv_state_delete -scale_point_get_label = _lib.lilv_scale_point_get_label -scale_point_get_value = _lib.lilv_scale_point_get_value -plugin_class_get_parent_uri = _lib.lilv_plugin_class_get_parent_uri -plugin_class_get_uri = _lib.lilv_plugin_class_get_uri -plugin_class_get_label = _lib.lilv_plugin_class_get_label -plugin_class_get_children = _lib.lilv_plugin_class_get_children -plugin_instantiate = _lib.lilv_plugin_instantiate -instance_free = _lib.lilv_instance_free -plugin_get_uis = _lib.lilv_plugin_get_uis -ui_get_uri = _lib.lilv_ui_get_uri -ui_get_classes = _lib.lilv_ui_get_classes -ui_is_a = _lib.lilv_ui_is_a -ui_is_supported = _lib.lilv_ui_is_supported -ui_get_bundle_uri = _lib.lilv_ui_get_bundle_uri -ui_get_binary_uri = _lib.lilv_ui_get_binary_uri - -## LV2 types - -LV2_Handle = POINTER(None) -LV2_URID_Map_Handle = POINTER(None) + return Node(obj.world, c.node_duplicate(obj.node)) + + +# LV2 types + +LV2_Handle = POINTER(None) +LV2_URID_Map_Handle = POINTER(None) LV2_URID_Unmap_Handle = POINTER(None) -LV2_URID = c_uint32 +LV2_URID = c_uint32 + class LV2_Feature(Structure): - __slots__ = [ 'URI', 'data' ] - _fields_ = [('URI', c_char_p), - ('data', POINTER(None))] + __slots__ = ["URI", "data"] + _fields_ = [("URI", c_char_p), ("data", POINTER(None))] + class LV2_Descriptor(Structure): - __slots__ = [ 'URI', - 'instantiate', - 'connect_port', - 'activate', - 'run', - 'deactivate', - 'cleanup', - 'extension_data' ] + __slots__ = [ + "URI", + "instantiate", + "connect_port", + "activate", + "run", + "deactivate", + "cleanup", + "extension_data", + ] + LV2_Descriptor._fields_ = [ - ('URI', c_char_p), - ('instantiate', CFUNCTYPE(LV2_Handle, POINTER(LV2_Descriptor), - c_double, c_char_p, POINTER(POINTER(LV2_Feature)))), - ('connect_port', CFUNCTYPE(None, LV2_Handle, c_uint32, POINTER(None))), - ('activate', CFUNCTYPE(None, LV2_Handle)), - ('run', CFUNCTYPE(None, LV2_Handle, c_uint32)), - ('deactivate', CFUNCTYPE(None, LV2_Handle)), - ('cleanup', CFUNCTYPE(None, LV2_Handle)), - ('extension_data', CFUNCTYPE(c_void_p, c_char_p)), + ("URI", c_char_p), + ( + "instantiate", + CFUNCTYPE( + LV2_Handle, + POINTER(LV2_Descriptor), + c_double, + c_char_p, + POINTER(POINTER(LV2_Feature)), + ), + ), + ("connect_port", CFUNCTYPE(None, LV2_Handle, c_uint32, POINTER(None))), + ("activate", CFUNCTYPE(None, LV2_Handle)), + ("run", CFUNCTYPE(None, LV2_Handle, c_uint32)), + ("deactivate", CFUNCTYPE(None, LV2_Handle)), + ("cleanup", CFUNCTYPE(None, LV2_Handle)), + ("extension_data", CFUNCTYPE(c_void_p, c_char_p)), ] + class LV2_URID_Map(Structure): - __slots__ = [ 'handle', 'map' ] - _fields_ = [ - ('handle', LV2_URID_Map_Handle), - ('map', CFUNCTYPE(LV2_URID, LV2_URID_Map_Handle, c_char_p)), + __slots__ = ["handle", "map"] + _fields_ = [ + ("handle", LV2_URID_Map_Handle), + ("map", CFUNCTYPE(LV2_URID, LV2_URID_Map_Handle, c_char_p)), ] + class LV2_URID_Unmap(Structure): - __slots__ = [ 'handle', 'unmap' ] - _fields_ = [ - ('handle', LV2_URID_Unmap_Handle), - ('unmap', CFUNCTYPE(c_char_p, LV2_URID_Unmap_Handle, LV2_URID)), + __slots__ = ["handle", "unmap"] + _fields_ = [ + ("handle", LV2_URID_Unmap_Handle), + ("unmap", CFUNCTYPE(c_char_p, LV2_URID_Unmap_Handle, LV2_URID)), ] + # Lilv types + class Plugin(Structure): """LV2 Plugin.""" @@ -248,7 +117,7 @@ class Plugin(Structure): assert type(plugin) == POINTER(Plugin) assert plugin - self.world = world + self.world = world self.plugin = plugin def __eq__(self, other): @@ -257,21 +126,22 @@ class Plugin(Structure): def verify(self): """Check if `plugin` is valid. - This is not a rigorous validator, but can be used to reject some malformed - plugins that could cause bugs (e.g. plugins with missing required fields). + This is not a rigorous validator, but can be used to reject some + malformed plugins that could cause bugs (e.g. plugins with missing + required fields). - Note that normal hosts do NOT need to use this - lilv does not - load invalid plugins into plugin lists. This is included for plugin - testing utilities, etc. + Note that normal hosts do NOT need to use this - lilv does not load + invalid plugins into plugin lists. This is included for plugin testing + utilities, etc. """ - return plugin_verify(self.plugin) + return c.plugin_verify(self.plugin) def get_uri(self): """Get the URI of `plugin`. Any serialization that refers to plugins should refer to them by this. - Hosts SHOULD NOT save any filesystem paths, plugin indexes, etc. in saved - files pass save only the URI. + Hosts SHOULD NOT save any filesystem paths, plugin indexes, etc. in + saved files pass save only the URI. The URI is a globally unique identifier for one specific plugin. Two plugins with the same URI are compatible in port signature, and should @@ -279,29 +149,33 @@ class Plugin(Structure): is upgraded in an incompatible way (eg if it has different ports), it MUST have a different URI than it's predecessor. """ - return Node.wrap(self.world, node_duplicate(plugin_get_uri(self.plugin))) + return Node.wrap( + self.world, c.node_duplicate(c.plugin_get_uri(self.plugin)) + ) def get_bundle_uri(self): """Get the (resolvable) URI of the plugin's "main" bundle. - This returns the URI of the bundle where the plugin itself was found. Note - that the data for a plugin may be spread over many bundles, that is, - get_data_uris() may return URIs which are not within this bundle. + This returns the URI of the bundle where the plugin itself was found. + Note that the data for a plugin may be spread over many bundles, that + is, get_data_uris() may return URIs which are not within this bundle. - Typical hosts should not need to use this function. - Note this always returns a fully qualified URI. If you want a local - filesystem path, use lilv.file_uri_parse(). + Typical hosts should not need to use this function. Note this always + returns a fully qualified URI. If you want a local filesystem path, + use lilv.file_uri_parse(). """ - return Node.wrap(self.world, node_duplicate(plugin_get_bundle_uri(self.plugin))) + return Node.wrap( + self.world, c.node_duplicate(c.plugin_get_bundle_uri(self.plugin)) + ) def get_data_uris(self): """Get the (resolvable) URIs of the RDF data files that define a plugin. - Typical hosts should not need to use this function. - Note this always returns fully qualified URIs. If you want local - filesystem paths, use lilv.file_uri_parse(). + Typical hosts should not need to use this function. Note this always + returns fully qualified URIs. If you want local filesystem paths, use + lilv.file_uri_parse(). """ - return Nodes(self.world, plugin_get_data_uris(self.plugin), False) + return Nodes(self.world, c.plugin_get_data_uris(self.plugin), False) def get_library_uri(self): """Get the (resolvable) URI of the shared library for `plugin`. @@ -309,7 +183,9 @@ class Plugin(Structure): Note this always returns a fully qualified URI. If you want a local filesystem path, use lilv.file_uri_parse(). """ - return Node.wrap(self.world, node_duplicate(plugin_get_library_uri(self.plugin))) + return Node.wrap( + self.world, c.node_duplicate(c.plugin_get_library_uri(self.plugin)) + ) def get_name(self): """Get the name of `plugin`. @@ -318,11 +194,11 @@ class Plugin(Structure): translated according to the current locale, this value MUST NOT be used as a plugin identifier (use the URI for that). """ - return Node.wrap(self.world, plugin_get_name(self.plugin)) + return Node.wrap(self.world, c.plugin_get_name(self.plugin)) def get_class(self): """Get the class this plugin belongs to (e.g. Filters).""" - return PluginClass(self.world, plugin_get_class(self.plugin)) + return PluginClass(self.world, c.plugin_get_class(self.plugin)) def get_value(self, predicate): """Get a value associated with the plugin in a plugin's data files. @@ -336,7 +212,9 @@ class Plugin(Structure): May return None if the property was not found, or if object(s) is not sensibly represented as a LilvNodes (e.g. blank nodes). """ - return Nodes(self.world, plugin_get_value(self.plugin, predicate.node), True) + return Nodes( + self.world, c.plugin_get_value(self.plugin, predicate.node), True + ) def has_feature(self, feature_uri): """Return whether a feature is supported by a plugin. @@ -344,43 +222,50 @@ class Plugin(Structure): This will return true if the feature is an optional or required feature of the plugin. """ - return plugin_has_feature(self.plugin, feature_uri.node) + return c.plugin_has_feature(self.plugin, feature_uri.node) def get_supported_features(self): """Get the LV2 Features supported (required or optionally) by a plugin. A feature is "supported" by a plugin if it is required OR optional. - Since required features have special rules the host must obey, this function - probably shouldn't be used by normal hosts. Using get_optional_features() - and get_required_features() separately is best in most cases. + Since required features have special rules the host must obey, this + function probably shouldn't be used by normal hosts. Using + get_optional_features() and get_required_features() separately is best + in most cases. """ - return Nodes(self.world, plugin_get_supported_features(self.plugin), True) + return Nodes( + self.world, c.plugin_get_supported_features(self.plugin), True + ) def get_required_features(self): """Get the LV2 Features required by a plugin. - If a feature is required by a plugin, hosts MUST NOT use the plugin if they do not - understand (or are unable to support) that feature. + If a feature is required by a plugin, hosts MUST NOT use the plugin if + they do not understand (or are unable to support) that feature. - All values returned here MUST be return plugin_(self.plugin)ed to the plugin's instantiate method - (along with data, if necessary, as defined by the feature specification) - or plugin instantiation will fail. + All values returned here MUST be return plugin_(self.plugin)ed to the + plugin's instantiate method (along with data, if necessary, as defined + by the feature specification) or plugin instantiation will fail. """ - return Nodes(self.world, plugin_get_required_features(self.plugin), True) + return Nodes( + self.world, c.plugin_get_required_features(self.plugin), True + ) def get_optional_features(self): """Get the LV2 Features optionally supported by a plugin. - Hosts MAY ignore optional plugin features for whatever reasons. Plugins - MUST operate (at least somewhat) if they are instantiated without being - passed optional features. + Hosts MAY ignore optional plugin features for whatever reasons. + Plugins MUST operate (at least somewhat) if they are instantiated + without being passed optional features. """ - return Nodes(self.world, plugin_get_optional_features(self.plugin), True) + return Nodes( + self.world, c.plugin_get_optional_features(self.plugin), True + ) def has_extension_data(self, uri): - """Return whether or not a plugin provides a specific extension data.""" - return plugin_has_extension_data(self.plugin, uri.node) + """Return whether or not a plugin provides specific extension data.""" + return c.plugin_has_extension_data(self.plugin, uri.node) def get_extension_data(self): """Get a sequence of all extension data provided by a plugin. @@ -388,34 +273,19 @@ class Plugin(Structure): This can be used to find which URIs get_extension_data() will return a value for without instantiating the plugin. """ - return Nodes(self.world, plugin_get_extension_data(self.plugin), True) + return Nodes( + self.world, c.plugin_get_extension_data(self.plugin), True + ) def get_num_ports(self): """Get the number of ports on this plugin.""" - return plugin_get_num_ports(self.plugin) - - # def get_port_ranges_float(self, min_values, max_values, def_values): - # """Get the port ranges (minimum, maximum and default values) for all ports. - - # `min_values`, `max_values` and `def_values` must either point to an array - # of N floats, where N is the value returned by get_num_ports() - # for this plugin, or None. The elements of the array will be set to the - # the minimum, maximum and default values of the ports on this plugin, - # with array index corresponding to port index. If a port doesn't have a - # minimum, maximum or default value, or the port's type is not float, the - # corresponding array element will be set to NAN. - - # This is a convenience method for the common case of getting the range of - # all float ports on a plugin, and may be significantly faster than - # repeated calls to Port.get_range(). - # """ - # plugin_get_port_ranges_float(self.plugin, min_values, max_values, def_values) + return c.plugin_get_num_ports(self.plugin) def get_num_ports_of_class(self, *args): - """Get the number of ports on this plugin that are members of some class(es).""" - return plugin_get_num_ports_of_class( - self.plugin, - *(list(map(lambda n: n.node, args)) + [None])) + """Get the number of ports of some class(es) on this plugin.""" + return c.plugin_get_num_ports_of_class( + self.plugin, *(list(map(lambda n: n.node, args)) + [None]) + ) def has_latency(self): """Return whether or not the plugin introduces (and reports) latency. @@ -423,18 +293,23 @@ class Plugin(Structure): The index of the latency port can be found with get_latency_port() ONLY if this function returns true. """ - return plugin_has_latency(self.plugin) + return c.plugin_has_latency(self.plugin) def get_latency_port_index(self): """Return the index of the plugin's latency port. Returns None if the plugin has no latency port. - Any plugin that introduces unwanted latency that should be compensated for - (by hosts with the ability/need) MUST provide this port, which is a control - rate output port that reports the latency for each cycle in frames. + Any plugin that introduces unwanted latency that should be compensated + for (by hosts with the ability/need) MUST provide this port, which is a + control rate output port that reports the latency for each cycle in + frames. """ - return plugin_get_latency_port_index(self.plugin) if self.has_latency() else None + return ( + c.plugin_get_latency_port_index(self.plugin) + if self.has_latency() + else None + ) def get_port(self, key): """Get a port on `plugin` by index or symbol.""" @@ -446,7 +321,7 @@ class Plugin(Structure): def get_port_by_index(self, index): """Get a port on `plugin` by `index`.""" assert type(index) == int - return Port.wrap(self, plugin_get_port_by_index(self.plugin, index)) + return Port.wrap(self, c.plugin_get_port_by_index(self.plugin, index)) def get_port_by_symbol(self, symbol): """Get a port on `plugin` by `symbol`. @@ -460,22 +335,26 @@ class Plugin(Structure): assert isinstance(symbol, Node) assert symbol.node is not None - return Port.wrap(self, plugin_get_port_by_symbol(self.plugin, symbol.node)) + return Port.wrap( + self, c.plugin_get_port_by_symbol(self.plugin, symbol.node) + ) def get_port_by_designation(self, port_class, designation): """Get a port on `plugin` by its lv2:designation. - The designation of a port describes the meaning, assignment, allocation or - role of the port, e.g. "left channel" or "gain". If found, the port with - matching `port_class` and `designation` is be returned, otherwise None is - returned. The `port_class` can be used to distinguish the input and output - ports for a particular designation. If `port_class` is None, any port with - the given designation will be returned. + The designation of a port describes the meaning, assignment, allocation + or role of the port, e.g. "left channel" or "gain". If found, the port + with matching `port_class` and `designation` is be returned, otherwise + None is returned. The `port_class` can be used to distinguish the + input and output ports for a particular designation. If `port_class` + is None, any port with the given designation will be returned. """ - return Port.wrap(self, - plugin_get_port_by_designation(self.plugin, - port_class.node, - designation.node)) + return Port.wrap( + self, + c.plugin_get_port_by_designation( + self.plugin, port_class.node, designation.node + ), + ) def get_project(self): """Get the project the plugin is a part of. @@ -483,28 +362,28 @@ class Plugin(Structure): More information about the project can be read via find_nodes(), typically using properties from DOAP (e.g. doap:name). """ - return Node.wrap(self.world, plugin_get_project(self.plugin)) + return Node.wrap(self.world, c.plugin_get_project(self.plugin)) def get_author_name(self): """Get the full name of the plugin's author. Returns None if author name is not present. """ - return Node.wrap(self.world, plugin_get_author_name(self.plugin)) + return Node.wrap(self.world, c.plugin_get_author_name(self.plugin)) def get_author_email(self): """Get the email address of the plugin's author. Returns None if author email address is not present. """ - return Node.wrap(self.world, plugin_get_author_email(self.plugin)) + return Node.wrap(self.world, c.plugin_get_author_email(self.plugin)) def get_author_homepage(self): """Get the address of the plugin author's home page. Returns None if author homepage is not present. """ - return Node.wrap(self.world, plugin_get_author_homepage(self.plugin)) + return Node.wrap(self.world, c.plugin_get_author_homepage(self.plugin)) def is_replaced(self): """Return true iff `plugin` has been replaced by another plugin. @@ -512,28 +391,35 @@ class Plugin(Structure): The plugin will still be usable, but hosts should hide them from their user interfaces to prevent users from using deprecated plugins. """ - return plugin_is_replaced(self.plugin) + return c.plugin_is_replaced(self.plugin) def get_related(self, resource_type): """Get the resources related to `plugin` with lv2:appliesTo. - Some plugin-related resources are not linked directly to the plugin with - rdfs:seeAlso and thus will not be automatically loaded along with the plugin - data (usually for performance reasons). All such resources of the given @c - type related to `plugin` can be accessed with this function. + Some plugin-related resources are not linked directly to the plugin + with rdfs:seeAlso and thus will not be automatically loaded along with + the plugin data (usually for performance reasons). All such resources + of the given @c type related to `plugin` can be accessed with this + function. - If `resource_type` is None, all such resources will be returned, regardless of type. + If `resource_type` is None, all such resources will be returned, + regardless of type. - To actually load the data for each returned resource, use world.load_resource(). + To actually load the data for each returned resource, use + world.load_resource(). """ - return Nodes(self.world, plugin_get_related(self.plugin, resource_type), True) + return Nodes( + self.world, c.plugin_get_related(self.plugin, resource_type), True + ) def get_uis(self): """Get all UIs for `plugin`.""" - return UIs(self.world, plugin_get_uis(self.plugin)) + return UIs(self.world, c.plugin_get_uis(self.plugin)) + class PluginClass(Structure): """Plugin Class (type/category).""" + def __init__(self, world, plugin_class): assert isinstance(world, World) assert type(plugin_class) == POINTER(PluginClass) @@ -548,24 +434,37 @@ class PluginClass(Structure): def get_parent_uri(self): """Get the URI of this class' superclass. - May return None if class has no parent. + May return None if class has no parent. """ - return Node.wrap(self.world, node_duplicate(plugin_class_get_parent_uri(self.plugin_class))) + return Node.wrap( + self.world, + c.node_duplicate(c.plugin_class_get_parent_uri(self.plugin_class)), + ) def get_uri(self): """Get the URI of this plugin class.""" - return Node.wrap(self.world, node_duplicate(plugin_class_get_uri(self.plugin_class))) + return Node.wrap( + self.world, + c.node_duplicate(c.plugin_class_get_uri(self.plugin_class)), + ) def get_label(self): """Get the label of this plugin class, ie "Oscillators".""" - return Node.wrap(self.world, node_duplicate(plugin_class_get_label(self.plugin_class))) + return Node.wrap( + self.world, + c.node_duplicate(c.plugin_class_get_label(self.plugin_class)), + ) def get_children(self): """Get the subclasses of this plugin class.""" - return PluginClasses(self.world, plugin_class_get_children(self.plugin_class), True) + return PluginClasses( + self.world, c.plugin_class_get_children(self.plugin_class), True + ) + class Port(Structure): """Port on a Plugin.""" + @classmethod def wrap(cls, plugin, port): if plugin is not None and port: @@ -579,71 +478,89 @@ class Port(Structure): assert port self.plugin = plugin - self.port = port + self.port = port def get_node(self): """Get the RDF node of `port`. Ports nodes may be may be URIs or blank nodes. """ - return Node.wrap(self.plugin.world, node_duplicate(port_get_node(self.plugin, self.port))) + return Node.wrap( + self.plugin.world, + c.node_duplicate(c.port_get_node(self.plugin, self.port)), + ) def get_value(self, predicate): """Port analog of Plugin.get_value().""" - return Nodes(self.plugin.world, - port_get_value(self.plugin.plugin, self.port, predicate.node), - True) + return Nodes( + self.plugin.world, + c.port_get_value(self.plugin.plugin, self.port, predicate.node), + True, + ) def get(self, predicate): """Get a single property value of a port. - This is equivalent to lilv_nodes_get_first(lilv_port_get_value(...)) but is - simpler to use in the common case of only caring about one value. The - caller is responsible for freeing the returned node. + This is equivalent to lilv_nodes_get_first(lilv_port_get_value(...)) + but is simpler to use in the common case of only caring about one + value. The caller is responsible for freeing the returned node. """ - return Node.wrap(self.plugin.world, port_get(self.plugin.plugin, self.port, predicate.node)) + return Node.wrap( + self.plugin.world, + c.port_get(self.plugin.plugin, self.port, predicate.node), + ) def get_properties(self): """Return the LV2 port properties of a port.""" - return Nodes(self.plugin.world, - port_get_properties(self.plugin.plugin, self.port), - True) + return Nodes( + self.plugin.world, + c.port_get_properties(self.plugin.plugin, self.port), + True, + ) def has_property(self, property_uri): """Return whether a port has a certain property.""" - return port_has_property(self.plugin.plugin, self.port, property_uri.node) + return c.port_has_property( + self.plugin.plugin, self.port, property_uri.node + ) def supports_event(self, event_type): """Return whether a port supports a certain event type. - More precisely, this returns true iff the port has an atom:supports or an - ev:supportsEvent property with `event_type` as the value. + More precisely, this returns true iff the port has an atom:supports or + an ev:supportsEvent property with `event_type` as the value. """ - return port_supports_event(self.plugin.plugin, self.port, event_type.node) + return c.port_supports_event( + self.plugin.plugin, self.port, event_type.node + ) def get_index(self): """Get the index of a port. - The index is only valid for the life of the plugin and may change between - versions. For a stable identifier, use the symbol. + The index is only valid for the life of the plugin and may change + between versions. For a stable identifier, use the symbol. """ - return port_get_index(self.plugin.plugin, self.port) + return c.port_get_index(self.plugin.plugin, self.port) def get_symbol(self): """Get the symbol of a port. The 'symbol' is a short string, a valid C identifier. """ - return Node.wrap(self.plugin.world, - node_duplicate(port_get_symbol(self.plugin.plugin, self.port))) + return Node.wrap( + self.plugin.world, + c.node_duplicate(c.port_get_symbol(self.plugin.plugin, self.port)), + ) def get_name(self): """Get the name of a port. - This is guaranteed to return the untranslated name (the doap:name in the - data file without a language tag). + This is guaranteed to return the untranslated name (the doap:name in + the data file without a language tag). """ - return Node.wrap(self.plugin.world, port_get_name(self.plugin.plugin, self.port)) + return Node.wrap( + self.plugin.world, c.port_get_name(self.plugin.plugin, self.port) + ) def get_classes(self): """Get all the classes of a port. @@ -653,30 +570,41 @@ class Port(Structure): The returned list does not include lv2:Port, which is implied. Returned value is shared and must not be destroyed by caller. """ - return Nodes(self.plugin.world, - port_get_classes(self.plugin.plugin, self.port), - False) + return Nodes( + self.plugin.world, + c.port_get_classes(self.plugin.plugin, self.port), + False, + ) def is_a(self, port_class): """Determine if a port is of a given class (input, output, audio, etc). - For convenience/performance/extensibility reasons, hosts are expected to - create a LilvNode for each port class they "care about". Well-known type - URI strings are defined (e.g. LILV_URI_INPUT_PORT) for convenience, but - this function is designed so that Lilv is usable with any port types - without requiring explicit support in Lilv. + For convenience/performance/extensibility reasons, hosts are expected + to create a LilvNode for each port class they "care about". Well-known + type URI strings are defined (e.g. LILV_URI_INPUT_PORT) for + convenience, but this function is designed so that Lilv is usable with + any port types without requiring explicit support in Lilv. """ - return port_is_a(self.plugin.plugin, self.port, port_class.node) + return c.port_is_a(self.plugin.plugin, self.port, port_class.node) def get_range(self): - """Return the default, minimum, and maximum values of a port as a tuple.""" + """Return the default, minimum, and maximum values of a port as a tuple. + """ pdef = POINTER(Node)() pmin = POINTER(Node)() pmax = POINTER(Node)() - port_get_range(self.plugin.plugin, self.port, byref(pdef), byref(pmin), byref(pmax)) - return (Node.wrap(self.plugin.world, pdef), - Node.wrap(self.plugin.world, pmin), - Node.wrap(self.plugin.world, pmax)) + c.port_get_range( + self.plugin.plugin, + self.port, + byref(pdef), + byref(pmin), + byref(pmax), + ) + return ( + Node.wrap(self.plugin.world, pdef), + Node.wrap(self.plugin.world, pmin), + Node.wrap(self.plugin.world, pmax), + ) def get_scale_points(self): """Get a list of the scale points (enumeration values) of a port. @@ -685,25 +613,33 @@ class Port(Structure): (e.g. appropriate entries for a UI selector associated with this port). """ - cpoints = port_get_scale_points(self.plugin.plugin, self.port) + cpoints = c.port_get_scale_points(self.plugin.plugin, self.port) points = [] - it = scale_points_begin(cpoints) - while not scale_points_is_end(cpoints, it): - points += [ScalePoint(self.plugin.world, scale_points_get(cpoints, it))] - it = scale_points_next(cpoints, it) - - scale_points_free(cpoints) + it = c.scale_points_begin(cpoints) + while not c.scale_points_is_end(cpoints, it): + points += [ + ScalePoint(self.plugin.world, c.scale_points_get(cpoints, it)) + ] + it = c.scale_points_next(cpoints, it) + + c.scale_points_free(cpoints) return points + class ScalePoint(Structure): """Scale point (detent).""" + def __init__(self, world, point): assert isinstance(world, World) assert type(point) == POINTER(ScalePoint) assert point - self.label = Node.wrap(world, node_duplicate(scale_point_get_label(point))) - self.value = Node.wrap(world, node_duplicate(scale_point_get_value(point))) + self.label = Node.wrap( + world, c.node_duplicate(c.scale_point_get_label(point)) + ) + self.value = Node.wrap( + world, c.node_duplicate(c.scale_point_get_value(point)) + ) def get_label(self): """Get the label of this scale point (enumeration value).""" @@ -713,8 +649,10 @@ class ScalePoint(Structure): """Get the value of this scale point (enumeration value).""" return self.value + class UI(Structure): """Plugin UI.""" + def __init__(self, world, ui): assert isinstance(world, World) assert type(ui) == POINTER(UI) @@ -733,7 +671,7 @@ class UI(Structure): def get_uri(self): """Get the URI of a Plugin UI.""" - return Node.wrap(self.world, node_duplicate(ui_get_uri(self.ui))) + return Node.wrap(self.world, c.node_duplicate(c.ui_get_uri(self.ui))) def get_classes(self): """Get the types (URIs of RDF classes) of a Plugin UI. @@ -741,19 +679,24 @@ class UI(Structure): Note that in most cases is_supported() should be used, which avoids the need to use this function (and type specific logic). """ - return Nodes(self.world, ui_get_classes(self.ui), False) + return Nodes(self.world, c.ui_get_classes(self.ui), False) def is_a(self, class_uri): """Check whether a plugin UI has a given type.""" - return ui_is_a(self.ui, class_uri.node) + return c.ui_is_a(self.ui, class_uri.node) def get_bundle_uri(self): """Get the URI of the UI's bundle.""" - return Node.wrap(self.world, node_duplicate(ui_get_bundle_uri(self.ui))) + return Node.wrap( + self.world, c.node_duplicate(c.ui_get_bundle_uri(self.ui)) + ) def get_binary_uri(self): """Get the URI for the UI's shared library.""" - return Node.wrap(self.world, node_duplicate(ui_get_binary_uri(self.ui))) + return Node.wrap( + self.world, c.node_duplicate(c.ui_get_binary_uri(self.ui)) + ) + class Node(Structure): """Data node (URI, string, integer, etc.). @@ -768,6 +711,7 @@ class Node(Structure): >>> int(i) * 2 84 """ + @classmethod def wrap(cls, world, node): assert isinstance(world, World) @@ -791,7 +735,7 @@ class Node(Structure): # everything has a reference to the world), but this normally only # happens on exit anyway so it shouldn't matter much. if self.world.world: - node_free(self.node) + c.node_free(self.node) def __eq__(self, other): if other is None: @@ -799,82 +743,93 @@ class Node(Structure): otype = type(other) if otype == Node: - return node_equals(self.node, other.node) + return c.node_equals(self.node, other.node) return otype(self) == other def __ne__(self, other): - return not node_equals(self.node, other.node) + return not c.node_equals(self.node, other.node) def __str__(self): - return node_as_string(self.node).decode('utf-8') + return c.node_as_string(self.node).decode("utf-8") def __int__(self): if not self.is_int(): - raise ValueError('node %s is not an integer' % str(self)) - return node_as_int(self.node) + raise ValueError("node %s is not an integer" % str(self)) + return c.node_as_int(self.node) def __float__(self): if not self.is_float(): - raise ValueError('node %s is not a float' % str(self)) - return node_as_float(self.node) + raise ValueError("node %s is not a float" % str(self)) + return c.node_as_float(self.node) def __bool__(self): if not self.is_bool(): - raise ValueError('node %s is not a bool' % str(self)) - return node_as_bool(self.node) + raise ValueError("node %s is not a bool" % str(self)) + return c.node_as_bool(self.node) + __nonzero__ = __bool__ def get_turtle_token(self): """Return this value as a Turtle/SPARQL token.""" - c_str = node_get_turtle_token(self.node) - string = cast(c_str, c_char_p).value.decode('utf-8') - free(c_str) + c_str = c.node_get_turtle_token(self.node) + string = cast(c_str, c_char_p).value.decode("utf-8") + c.free(c_str) return string def is_uri(self): """Return whether the value is a URI (resource).""" - return node_is_uri(self.node) + return c.node_is_uri(self.node) def is_blank(self): """Return whether the value is a blank node (resource with no URI).""" - return node_is_blank(self.node) + return c.node_is_blank(self.node) def is_literal(self): """Return whether this value is a literal (i.e. not a URI).""" - return node_is_literal(self.node) + return c.node_is_literal(self.node) def is_string(self): """Return whether this value is a string literal. Returns true if value is a string value (and not numeric). """ - return node_is_string(self.node) + return c.node_is_string(self.node) def get_path(self, hostname=None): """Return the path of a file URI node. Returns None if value is not a file URI.""" - c_str = node_get_path(self.node, hostname) - string = cast(c_str, c_char_p).value.decode('utf-8') - free(c_str) + c_str = c.node_get_path(self.node, hostname) + string = cast(c_str, c_char_p).value.decode("utf-8") + c.free(c_str) return string def is_float(self): """Return whether this value is a decimal literal.""" - return node_is_float(self.node) + return c.node_is_float(self.node) def is_int(self): """Return whether this value is an integer literal.""" - return node_is_int(self.node) + return c.node_is_int(self.node) def is_bool(self): """Return whether this value is a boolean.""" - return node_is_bool(self.node) + return c.node_is_bool(self.node) + class Iter(Structure): """Collection iterator.""" - def __init__(self, collection, iterator, constructor, iter_get, iter_next, iter_is_end): + + def __init__( + self, + collection, + iterator, + constructor, + iter_get, + iter_next, + iter_is_end, + ): assert isinstance(collection, Collection) self.collection = collection @@ -886,15 +841,19 @@ class Iter(Structure): def get(self): """Get the current item.""" - return self.constructor(self.collection.world, - self.iter_get(self.collection.collection, self.iterator)) + return self.constructor( + self.collection.world, + self.iter_get(self.collection.collection, self.iterator), + ) def next(self): """Move to and return the next item.""" if self.is_end(): raise StopIteration elem = self.get() - self.iterator = self.iter_next(self.collection.collection, self.iterator) + self.iterator = self.iter_next( + self.collection.collection, self.iterator + ) return elem def is_end(self): @@ -903,9 +862,19 @@ class Iter(Structure): __next__ = next + class Collection(Structure): # Base class for all lilv collection wrappers. - def __init__(self, world, collection, iter_begin, constructor, iter_get, iter_next, is_end): + def __init__( + self, + world, + collection, + iter_begin, + constructor, + iter_get, + iter_next, + is_end, + ): assert isinstance(world, World) self.world = world self.collection = collection @@ -916,8 +885,14 @@ class Collection(Structure): self.is_end = is_end def __iter__(self): - return Iter(self, self.iter_begin(self.collection), self.constructor, - self.iter_get, self.iter_next, self.is_end) + return Iter( + self, + self.iter_begin(self.collection), + self.constructor, + self.iter_get, + self.iter_next, + self.is_end, + ) def __getitem__(self, index): pos = 0 @@ -925,8 +900,9 @@ class Collection(Structure): while not self.is_end(self.collection, it): if pos == index: - return self.constructor(self.world, - self.iter_get(self.collection, it)) + return self.constructor( + self.world, self.iter_get(self.collection, it) + ) it = self.iter_next(self.collection, it) pos = pos + 1 @@ -939,8 +915,10 @@ class Collection(Structure): def get(self, iterator): return iterator.get() + class Plugins(Collection): """Collection of plugins.""" + def __init__(self, world, collection): assert type(collection) == POINTER(Plugins) assert collection @@ -948,14 +926,22 @@ class Plugins(Collection): def constructor(world, plugin): return Plugin.wrap(world, plugin) - super(Plugins, self).__init__(world, collection, plugins_begin, constructor, plugins_get, plugins_next, plugins_is_end) + super(Plugins, self).__init__( + world, + collection, + c.plugins_begin, + constructor, + c.plugins_get, + c.plugins_next, + c.plugins_is_end, + ) self.world = world def __contains__(self, key): return bool(self.get_by_uri(_as_uri(key))) def __len__(self): - return plugins_size(self.collection) + return c.plugins_size(self.collection) def __getitem__(self, key): if type(key) == int: @@ -963,28 +949,38 @@ class Plugins(Collection): return self.get_by_uri(key) def get_by_uri(self, uri): - return Plugin.wrap(self.world, plugins_get_by_uri(self.collection, uri.node)) + return Plugin.wrap( + self.world, c.plugins_get_by_uri(self.collection, uri.node) + ) + class PluginClasses(Collection): """Collection of plugin classes.""" + def __init__(self, world, collection, owning=False): assert type(collection) == POINTER(PluginClasses) assert collection self.owning = owning super(PluginClasses, self).__init__( - world, collection, plugin_classes_begin, PluginClass, - plugin_classes_get, plugin_classes_next, plugin_classes_is_end) + world, + collection, + c.plugin_classes_begin, + PluginClass, + c.plugin_classes_get, + c.plugin_classes_next, + c.plugin_classes_is_end, + ) def __del__(self): if self.owning: - plugin_classes_free(self.collection) + c.plugin_classes_free(self.collection) def __contains__(self, key): return bool(self.get_by_uri(_as_uri(key))) def __len__(self): - return plugin_classes_size(self.collection) + return c.plugin_classes_size(self.collection) def __getitem__(self, key): if type(key) == int: @@ -992,30 +988,41 @@ class PluginClasses(Collection): return self.get_by_uri(key) def get_by_uri(self, uri): - plugin_class = plugin_classes_get_by_uri(self.collection, uri.node) + plugin_class = c.plugin_classes_get_by_uri(self.collection, uri.node) return PluginClass(self.world, plugin_class) if plugin_class else None + class ScalePoints(Structure): """Collection of scale points.""" + pass + class UIs(Collection): """Collection of plugin UIs.""" + def __init__(self, world, collection): assert type(collection) == POINTER(UIs) assert collection - super(UIs, self).__init__(world, collection, uis_begin, UI, - uis_get, uis_next, uis_is_end) + super(UIs, self).__init__( + world, + collection, + c.uis_begin, + UI, + c.uis_get, + c.uis_next, + c.uis_is_end, + ) def __del__(self): if self.world.world: - uis_free(self.collection) + c.uis_free(self.collection) def __contains__(self, uri): return bool(self.get_by_uri(_as_uri(uri))) def __len__(self): - return uis_size(self.collection) + return c.uis_size(self.collection) def __getitem__(self, key): if type(key) == int: @@ -1023,38 +1030,50 @@ class UIs(Collection): return self.get_by_uri(key) def get_by_uri(self, uri): - ui = uis_get_by_uri(self.collection, uri.node) + ui = c.uis_get_by_uri(self.collection, uri.node) return UI(self.world, ui) if ui else None + class Nodes(Collection): """Collection of data nodes.""" + @classmethod def constructor(cls, world, node): assert isinstance(world, World) assert type(node) == POINTER(Node) - return Node.wrap(world, node_duplicate(node)) + return Node.wrap(world, c.node_duplicate(node)) def __init__(self, world, collection, owning=False): assert type(collection) == POINTER(Nodes) self.owning = owning - super(Nodes, self).__init__(world, collection, nodes_begin, Nodes.constructor, - nodes_get, nodes_next, nodes_is_end) + super(Nodes, self).__init__( + world, + collection, + c.nodes_begin, + Nodes.constructor, + c.nodes_get, + c.nodes_next, + c.nodes_is_end, + ) def __del__(self): if self.owning and self.world.world: - nodes_free(self.collection) + c.nodes_free(self.collection) def __contains__(self, value): - return nodes_contains(self.collection, value.node) + return c.nodes_contains(self.collection, value.node) def __len__(self): - return nodes_size(self.collection) + return c.nodes_size(self.collection) def merge(self, b): - return Nodes(self.world, nodes_merge(self.collection, b.collection), True) + return Nodes( + self.world, c.nodes_merge(self.collection, b.collection), True + ) + -class Namespace(): +class Namespace: """Namespace prefix. Use attribute syntax to easily create URIs within this namespace, for @@ -1065,11 +1084,12 @@ class Namespace(): >>> print(ns.foo) http://example.org/foo """ + def __init__(self, world, prefix): assert isinstance(world, World) assert type(prefix) == str - self.world = world + self.world = world self.prefix = prefix def __eq__(self, other): @@ -1081,7 +1101,8 @@ class Namespace(): def __getattr__(self, suffix): return self.world.new_uri(self.prefix + suffix) -class Namespaces(): + +class Namespaces: """Set of namespaces. Use to easily construct uris, like: ns.lv2.InputPort""" @@ -1089,33 +1110,39 @@ class Namespaces(): def __init__(self, world): assert isinstance(world, World) self.world = world - self.atom = Namespace(world, 'http://lv2plug.in/ns/ext/atom#') - self.doap = Namespace(world, 'http://usefulinc.com/ns/doap#') - self.foaf = Namespace(world, 'http://xmlns.com/foaf/0.1/') - self.lilv = Namespace(world, 'http://drobilla.net/ns/lilv#') - self.lv2 = Namespace(world, 'http://lv2plug.in/ns/lv2core#') - self.midi = Namespace(world, 'http://lv2plug.in/ns/ext/midi#') - self.owl = Namespace(world, 'http://www.w3.org/2002/07/owl#') - self.rdf = Namespace(world, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') - self.rdfs = Namespace(world, 'http://www.w3.org/2000/01/rdf-schema#') - self.ui = Namespace(world, 'http://lv2plug.in/ns/extensions/ui#') - self.xsd = Namespace(world, 'http://www.w3.org/2001/XMLSchema#') + self.atom = Namespace(world, "http://lv2plug.in/ns/ext/atom#") + self.doap = Namespace(world, "http://usefulinc.com/ns/doap#") + self.foaf = Namespace(world, "http://xmlns.com/foaf/0.1/") + self.lilv = Namespace(world, "http://drobilla.net/ns/lilv#") + self.lv2 = Namespace(world, "http://lv2plug.in/ns/lv2core#") + self.midi = Namespace(world, "http://lv2plug.in/ns/ext/midi#") + self.owl = Namespace(world, "http://www.w3.org/2002/07/owl#") + self.rdf = Namespace( + world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + ) + self.rdfs = Namespace(world, "http://www.w3.org/2000/01/rdf-schema#") + self.ui = Namespace(world, "http://lv2plug.in/ns/extensions/ui#") + self.xsd = Namespace(world, "http://www.w3.org/2001/XMLSchema#") + class World(Structure): """Library context. - Includes a set of namespaces as the instance variable `ns`, so URIs can be constructed like:: + Includes a set of namespaces as the instance variable `ns`, so URIs can be + constructed like:: uri = world.ns.lv2.Plugin - :ivar ns: Common LV2 namespace prefixes: atom, doap, foaf, lilv, lv2, midi, owl, rdf, rdfs, ui, xsd. + Common LV2 namespace prefixes: atom, doap, foaf, lilv, lv2, midi, owl, rdf, + rdfs, ui, xsd. """ + def __init__(self): - self.world = _lib.lilv_world_new() - self.ns = Namespaces(self) + self.world = c.world_new() + self.ns = Namespaces(self) def __del__(self): - world_free(self.world) + c.world_free(self.world) self.world = None def set_option(self, uri, value): @@ -1125,21 +1152,22 @@ class World(Structure): lilv.OPTION_FILTER_LANG lilv.OPTION_DYN_MANIFEST """ - return world_set_option(self.world, uri, value.node) + return c.world_set_option(self.world, uri, value.node) def load_all(self): """Load all installed LV2 bundles on the system. - This is the recommended way for hosts to load LV2 data. It implements the - established/standard best practice for discovering all LV2 data on the - system. The environment variable LV2_PATH may be used to control where - this function will look for bundles. + This is the recommended way for hosts to load LV2 data. It implements + the established/standard best practice for discovering all LV2 data on + the system. The environment variable LV2_PATH may be used to control + where this function will look for bundles. - Hosts should use this function rather than explicitly load bundles, except - in special circumstances (e.g. development utilities, or hosts that ship - with special plugin bundles which are installed to a known location). + Hosts should use this function rather than explicitly load bundles, + except in special circumstances (e.g. development utilities, or hosts + that ship with special plugin bundles which are installed to a known + location). """ - world_load_all(self.world) + c.world_load_all(self.world) def load_bundle(self, bundle_uri): """Load a specific bundle. @@ -1154,7 +1182,7 @@ class World(Structure): unchanged between (or even during) program invocations. Plugins (among other things) MUST be identified by URIs (not paths) in save files. """ - world_load_bundle(self.world, bundle_uri.node) + c.world_load_bundle(self.world, bundle_uri.node) def load_specifications(self): """Load all specifications from currently loaded bundles. @@ -1163,26 +1191,26 @@ class World(Structure): necessary when using load_all(). This function parses the specifications and adds them to the model. """ - world_load_specifications(self.world) + c.world_load_specifications(self.world) def load_plugin_classes(self): """Load all plugin classes from currently loaded specifications. - Must be called after load_specifications(). This is for hosts - that explicitly load specific bundles, its use is not necessary when using + Must be called after load_specifications(). This is for hosts that + explicitly load specific bundles, its use is not necessary when using load_all(). """ - world_load_plugin_classes(self.world) + c.world_load_plugin_classes(self.world) def unload_bundle(self, bundle_uri): """Unload a specific bundle. - This unloads statements loaded by load_bundle(). Note that this - is not necessarily all information loaded from the bundle. If any resources + This unloads statements loaded by load_bundle(). Note that this is not + necessarily all information loaded from the bundle. If any resources have been separately loaded with load_resource(), they must be separately unloaded with unload_resource(). """ - return world_unload_bundle(self.world, bundle_uri.node) + return c.world_unload_bundle(self.world, bundle_uri.node) def load_resource(self, resource): """Load all the data associated with the given `resource`. @@ -1190,11 +1218,11 @@ class World(Structure): The resource must be a subject (i.e. a URI or a blank node). Returns the number of files parsed, or -1 on error. - All accessible data files linked to `resource` with rdfs:seeAlso will be - loaded into the world model. + All accessible data files linked to `resource` with rdfs:seeAlso will + be loaded into the world model. """ uri = _as_uri(resource) - ret = world_load_resource(self.world, uri.node) + ret = c.world_load_resource(self.world, uri.node) return ret def unload_resource(self, resource): @@ -1205,17 +1233,15 @@ class World(Structure): This unloads all data loaded by a previous call to load_resource() with the given `resource`. """ - uri = _as_uri(resource) - ret = world_unload_resource(self.world, uri.node) - return ret + return c.world_unload_resource(self.world, _as_uri(resource).node) def get_plugin_class(self): """Get the parent of all other plugin classes, lv2:Plugin.""" - return PluginClass(self, world_get_plugin_class(self.world)) + return PluginClass(self, c.world_get_plugin_class(self.world)) def get_plugin_classes(self): """Return a list of all found plugin classes.""" - return PluginClasses(self, world_get_plugin_classes(self.world)) + return PluginClasses(self, c.world_get_plugin_classes(self.world)) def get_all_plugins(self): """Return a list of all found plugins. @@ -1229,20 +1255,24 @@ class World(Structure): The returned list and the plugins it contains are owned by `world` and must not be freed by caller. """ - return Plugins(self, _lib.lilv_world_get_all_plugins(self.world)) + return Plugins(self, c.world_get_all_plugins(self.world)) def find_nodes(self, subject, predicate, obj): """Find nodes matching a triple pattern. - Either `subject` or `object` may be None (i.e. a wildcard), but not both. - Returns all matches for the wildcard field, or None. + Either `subject` or `object` may be None (i.e. a wildcard), but not + both. Returns all matches for the wildcard field, or None. """ - return Nodes(self, - world_find_nodes(self.world, - subject.node if subject is not None else None, - predicate.node if predicate is not None else None, - obj.node if obj is not None else None), - True) + return Nodes( + self, + c.world_find_nodes( + self.world, + subject.node if subject is not None else None, + predicate.node if predicate is not None else None, + obj.node if obj is not None else None, + ), + True, + ) def get(self, subject, predicate, obj): """Find a single node that matches a pattern. @@ -1251,68 +1281,101 @@ class World(Structure): Returns the first matching node, or None if no matches are found. """ - return Node.wrap(self, - world_get(self.world, - subject.node if subject is not None else None, - predicate.node if predicate is not None else None, - obj.node if obj is not None else None)) + return Node.wrap( + self, + c.world_get( + self.world, + subject.node if subject is not None else None, + predicate.node if predicate is not None else None, + obj.node if obj is not None else None, + ), + ) def ask(self, subject, predicate, obj): """Return true iff a statement matching a certain pattern exists. - This is useful for checking if particular statement exists without having to - bother with collections and memory management. + This is useful for checking if particular statement exists without + having to bother with collections and memory management. """ - return world_ask(self.world, - subject.node if subject is not None else None, - predicate.node if predicate is not None else None, - obj.node if obj is not None else None) + return c.world_ask( + self.world, + subject.node if subject is not None else None, + predicate.node if predicate is not None else None, + obj.node if obj is not None else None, + ) + + def get_symbol(self, subject): + """Get an LV2 symbol for some subject. + + This will return the lv2:symbol property of the subject if it is given + explicitly, and otherwise will attempt to derive a symbol from the URI. + + Returns a string, which is possibly empty on error. + """ + if isinstance(subject, Port): + return subject.get_symbol() + + uri = _as_uri(subject) + if uri is not None: + node = c.world_get_symbol(self.world, uri.node) + return c.node_as_string(node).decode("ascii") if node else "" + + return "" def new_uri(self, uri): """Create a new URI node.""" - return Node.wrap(self, _lib.lilv_new_uri(self.world, uri)) + return Node.wrap(self, c.new_uri(self.world, uri)) def new_file_uri(self, host, path): """Create a new file URI node. The host may be None.""" - return Node.wrap(self, _lib.lilv_new_file_uri(self.world, host, path)) + return Node.wrap(self, c.new_file_uri(self.world, host, path)) def new_string(self, string): """Create a new string node.""" - return Node.wrap(self, _lib.lilv_new_string(self.world, string)) + return Node.wrap(self, c.new_string(self.world, string)) def new_int(self, val): """Create a new int node.""" - return Node.wrap(self, _lib.lilv_new_int(self.world, val)) + return Node.wrap(self, c.new_int(self.world, val)) def new_float(self, val): """Create a new float node.""" - return Node.wrap(self, _lib.lilv_new_float(self.world, val)) + return Node.wrap(self, c.new_float(self.world, val)) def new_bool(self, val): """Create a new bool node.""" - return Node.wrap(self, _lib.lilv_new_bool(self.world, val)) + return Node.wrap(self, c.new_bool(self.world, val)) + class Instance(Structure): """Plugin instance.""" - __slots__ = [ 'lv2_descriptor', 'lv2_handle', 'pimpl', 'plugin', 'rate', 'instance' ] - _fields_ = [ - ('lv2_descriptor', POINTER(LV2_Descriptor)), - ('lv2_handle', LV2_Handle), - ('pimpl', POINTER(None)), + + __slots__ = [ + "lv2_descriptor", + "lv2_handle", + "pimpl", + "plugin", + "rate", + "instance", + ] + _fields_ = [ + ("lv2_descriptor", POINTER(LV2_Descriptor)), + ("lv2_handle", LV2_Handle), + ("pimpl", POINTER(None)), ] def __init__(self, plugin, rate, features=None): assert isinstance(plugin, Plugin) - self.plugin = plugin - self.rate = rate - self.instance = plugin_instantiate(plugin.plugin, rate, features) + self.plugin = plugin + self.rate = rate + self.instance = c.plugin_instantiate(plugin.plugin, rate, features) def get_uri(self): """Get the URI of the plugin which `instance` is an instance of. Returned string is shared and must not be modified or deleted. """ - return self.get_descriptor().URI.decode('utf-8') + return self.get_descriptor().URI.decode("utf-8") def connect_port(self, port_index, data): """Connect a port to a data location. @@ -1321,25 +1384,26 @@ class Instance(Structure): activation and deactivation does not destroy port connections. """ import numpy + if data is None: self.get_descriptor().connect_port( - self.get_handle(), - port_index, - data) + self.get_handle(), port_index, data + ) elif type(data) == numpy.ndarray: self.get_descriptor().connect_port( self.get_handle(), port_index, - data.ctypes.data_as(POINTER(c_float))) + data.ctypes.data_as(POINTER(c_float)), + ) else: raise Exception("Unsupported data type") def activate(self): """Activate a plugin instance. - This resets all state information in the plugin, except for port data - locations (as set by connect_port()). This MUST be called - before calling run(). + This resets all state information in the plugin, except for port data + locations (as set by connect_port()). This MUST be called before + calling run(). """ if self.get_descriptor().activate: self.get_descriptor().activate(self.get_handle()) @@ -1347,16 +1411,16 @@ class Instance(Structure): def run(self, sample_count): """Run `instance` for `sample_count` frames. - If the hint lv2:hardRTCapable is set for this plugin, this function is - guaranteed not to block. + If the hint lv2:hardRTCapable is set for this plugin, this function is + guaranteed not to block. """ self.get_descriptor().run(self.get_handle(), sample_count) def deactivate(self): """Deactivate a plugin instance. - Note that to run the plugin after this you must activate it, which will - reset all state information (except port connections). + Note that to run the plugin after this you must activate it, which will + reset all state information (except port connections). """ if self.get_descriptor().deactivate: self.get_descriptor().deactivate(self.get_handle()) @@ -1364,529 +1428,372 @@ class Instance(Structure): def get_extension_data(self, uri): """Get extension data from the plugin instance. - The type and semantics of the data returned is specific to the particular - extension, though in all cases it is shared and must not be deleted. + The type and semantics of the data returned is specific to the + particular extension, though in all cases it is shared and must not be + deleted. """ if self.get_descriptor().extension_data: - return self.get_descriptor().extension_data(str(uri).encode('utf-8')) + return self.get_descriptor().extension_data( + str(uri).encode("utf-8") + ) def get_descriptor(self): """Get the LV2_Descriptor of the plugin instance. - Normally hosts should not need to access the LV2_Descriptor directly, - use the lilv_instance_* functions. + Normally hosts should not need to access the LV2_Descriptor directly, + use the lilv_instance_* functions. """ return self.instance[0].lv2_descriptor[0] def get_handle(self): """Get the LV2_Handle of the plugin instance. - Normally hosts should not need to access the LV2_Handle directly, - use the lilv_instance_* functions. + Normally hosts should not need to access the LV2_Handle directly, use + the lilv_instance_* functions. """ return self.instance[0].lv2_handle + class State(Structure): """Plugin state (TODO).""" + pass + class VariadicFunction(object): # Wrapper for calling C variadic functions def __init__(self, function, restype, argtypes): - self.function = function + self.function = function self.function.restype = restype - self.argtypes = argtypes + self.argtypes = argtypes def __call__(self, *args): fixed_args = [] - i = 0 + i = 0 for argtype in self.argtypes: fixed_args.append(argtype.from_param(args[i])) i += 1 return self.function(*(fixed_args + list(args[i:]))) -# Set return and argument types for lilv C functions - -free.argtypes = [POINTER(None)] -free.restype = None - -# uri_to_path.argtypes = [String] -# uri_to_path.restype = c_char_p - -file_uri_parse.argtypes = [String, POINTER(POINTER(c_char))] -file_uri_parse.restype = c_char_p - -new_uri.argtypes = [POINTER(World), String] -new_uri.restype = POINTER(Node) - -new_file_uri.argtypes = [POINTER(World), c_char_p, String] -new_file_uri.restype = POINTER(Node) - -new_string.argtypes = [POINTER(World), String] -new_string.restype = POINTER(Node) - -new_int.argtypes = [POINTER(World), c_int] -new_int.restype = POINTER(Node) - -new_float.argtypes = [POINTER(World), c_float] -new_float.restype = POINTER(Node) - -new_bool.argtypes = [POINTER(World), c_bool] -new_bool.restype = POINTER(Node) - -node_free.argtypes = [POINTER(Node)] -node_free.restype = None - -node_duplicate.argtypes = [POINTER(Node)] -node_duplicate.restype = POINTER(Node) - -node_equals.argtypes = [POINTER(Node), POINTER(Node)] -node_equals.restype = c_bool - -node_get_turtle_token.argtypes = [POINTER(Node)] -node_get_turtle_token.restype = POINTER(c_char) - -node_is_uri.argtypes = [POINTER(Node)] -node_is_uri.restype = c_bool - -node_as_uri.argtypes = [POINTER(Node)] -node_as_uri.restype = c_char_p - -node_is_blank.argtypes = [POINTER(Node)] -node_is_blank.restype = c_bool - -node_as_blank.argtypes = [POINTER(Node)] -node_as_blank.restype = c_char_p - -node_is_literal.argtypes = [POINTER(Node)] -node_is_literal.restype = c_bool - -node_is_string.argtypes = [POINTER(Node)] -node_is_string.restype = c_bool - -node_as_string.argtypes = [POINTER(Node)] -node_as_string.restype = c_char_p - -node_get_path.argtypes = [POINTER(Node), POINTER(POINTER(c_char))] -node_get_path.restype = POINTER(c_char) - -node_is_float.argtypes = [POINTER(Node)] -node_is_float.restype = c_bool - -node_as_float.argtypes = [POINTER(Node)] -node_as_float.restype = c_float - -node_is_int.argtypes = [POINTER(Node)] -node_is_int.restype = c_bool - -node_as_int.argtypes = [POINTER(Node)] -node_as_int.restype = c_int - -node_is_bool.argtypes = [POINTER(Node)] -node_is_bool.restype = c_bool - -node_as_bool.argtypes = [POINTER(Node)] -node_as_bool.restype = c_bool - -plugin_classes_free.argtypes = [POINTER(PluginClasses)] -plugin_classes_free.restype = None - -plugin_classes_size.argtypes = [POINTER(PluginClasses)] -plugin_classes_size.restype = c_uint - -plugin_classes_begin.argtypes = [POINTER(PluginClasses)] -plugin_classes_begin.restype = POINTER(Iter) - -plugin_classes_get.argtypes = [POINTER(PluginClasses), POINTER(Iter)] -plugin_classes_get.restype = POINTER(PluginClass) - -plugin_classes_next.argtypes = [POINTER(PluginClasses), POINTER(Iter)] -plugin_classes_next.restype = POINTER(Iter) - -plugin_classes_is_end.argtypes = [POINTER(PluginClasses), POINTER(Iter)] -plugin_classes_is_end.restype = c_bool - -plugin_classes_get_by_uri.argtypes = [POINTER(PluginClasses), POINTER(Node)] -plugin_classes_get_by_uri.restype = POINTER(PluginClass) - -scale_points_free.argtypes = [POINTER(ScalePoints)] -scale_points_free.restype = None - -scale_points_size.argtypes = [POINTER(ScalePoints)] -scale_points_size.restype = c_uint - -scale_points_begin.argtypes = [POINTER(ScalePoints)] -scale_points_begin.restype = POINTER(Iter) - -scale_points_get.argtypes = [POINTER(ScalePoints), POINTER(Iter)] -scale_points_get.restype = POINTER(ScalePoint) -scale_points_next.argtypes = [POINTER(ScalePoints), POINTER(Iter)] -scale_points_next.restype = POINTER(Iter) +# Set up C bindings -scale_points_is_end.argtypes = [POINTER(ScalePoints), POINTER(Iter)] -scale_points_is_end.restype = c_bool -uis_free.argtypes = [POINTER(UIs)] -uis_free.restype = None - -uis_size.argtypes = [POINTER(UIs)] -uis_size.restype = c_uint - -uis_begin.argtypes = [POINTER(UIs)] -uis_begin.restype = POINTER(Iter) - -uis_get.argtypes = [POINTER(UIs), POINTER(Iter)] -uis_get.restype = POINTER(UI) - -uis_next.argtypes = [POINTER(UIs), POINTER(Iter)] -uis_next.restype = POINTER(Iter) - -uis_is_end.argtypes = [POINTER(UIs), POINTER(Iter)] -uis_is_end.restype = c_bool - -uis_get_by_uri.argtypes = [POINTER(UIs), POINTER(Node)] -uis_get_by_uri.restype = POINTER(UI) - -nodes_free.argtypes = [POINTER(Nodes)] -nodes_free.restype = None - -nodes_size.argtypes = [POINTER(Nodes)] -nodes_size.restype = c_uint - -nodes_begin.argtypes = [POINTER(Nodes)] -nodes_begin.restype = POINTER(Iter) - -nodes_get.argtypes = [POINTER(Nodes), POINTER(Iter)] -nodes_get.restype = POINTER(Node) - -nodes_next.argtypes = [POINTER(Nodes), POINTER(Iter)] -nodes_next.restype = POINTER(Iter) - -nodes_is_end.argtypes = [POINTER(Nodes), POINTER(Iter)] -nodes_is_end.restype = c_bool - -nodes_get_first.argtypes = [POINTER(Nodes)] -nodes_get_first.restype = POINTER(Node) - -nodes_contains.argtypes = [POINTER(Nodes), POINTER(Node)] -nodes_contains.restype = c_bool - -nodes_merge.argtypes = [POINTER(Nodes), POINTER(Nodes)] -nodes_merge.restype = POINTER(Nodes) - -plugins_size.argtypes = [POINTER(Plugins)] -plugins_size.restype = c_uint - -plugins_begin.argtypes = [POINTER(Plugins)] -plugins_begin.restype = POINTER(Iter) - -plugins_get.argtypes = [POINTER(Plugins), POINTER(Iter)] -plugins_get.restype = POINTER(Plugin) - -plugins_next.argtypes = [POINTER(Plugins), POINTER(Iter)] -plugins_next.restype = POINTER(Iter) - -plugins_is_end.argtypes = [POINTER(Plugins), POINTER(Iter)] -plugins_is_end.restype = c_bool - -plugins_get_by_uri.argtypes = [POINTER(Plugins), POINTER(Node)] -plugins_get_by_uri.restype = POINTER(Plugin) - -world_new.argtypes = [] -world_new.restype = POINTER(World) - -world_set_option.argtypes = [POINTER(World), String, POINTER(Node)] -world_set_option.restype = None - -world_free.argtypes = [POINTER(World)] -world_free.restype = None - -world_load_all.argtypes = [POINTER(World)] -world_load_all.restype = None - -world_load_bundle.argtypes = [POINTER(World), POINTER(Node)] -world_load_bundle.restype = None - -world_load_specifications.argtypes = [POINTER(World)] -world_load_specifications.restype = None - -world_load_plugin_classes.argtypes = [POINTER(World)] -world_load_plugin_classes.restype = None - -world_unload_bundle.argtypes = [POINTER(World), POINTER(Node)] -world_unload_bundle.restype = c_int - -world_load_resource.argtypes = [POINTER(World), POINTER(Node)] -world_load_resource.restype = c_int - -world_unload_resource.argtypes = [POINTER(World), POINTER(Node)] -world_unload_resource.restype = c_int - -world_get_plugin_class.argtypes = [POINTER(World)] -world_get_plugin_class.restype = POINTER(PluginClass) - -world_get_plugin_classes.argtypes = [POINTER(World)] -world_get_plugin_classes.restype = POINTER(PluginClasses) - -world_get_all_plugins.argtypes = [POINTER(World)] -world_get_all_plugins.restype = POINTER(Plugins) - -world_find_nodes.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)] -world_find_nodes.restype = POINTER(Nodes) - -world_get.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)] -world_get.restype = POINTER(Node) - -world_ask.argtypes = [POINTER(World), POINTER(Node), POINTER(Node), POINTER(Node)] -world_ask.restype = c_bool - -plugin_verify.argtypes = [POINTER(Plugin)] -plugin_verify.restype = c_bool - -plugin_get_uri.argtypes = [POINTER(Plugin)] -plugin_get_uri.restype = POINTER(Node) - -plugin_get_bundle_uri.argtypes = [POINTER(Plugin)] -plugin_get_bundle_uri.restype = POINTER(Node) - -plugin_get_data_uris.argtypes = [POINTER(Plugin)] -plugin_get_data_uris.restype = POINTER(Nodes) - -plugin_get_library_uri.argtypes = [POINTER(Plugin)] -plugin_get_library_uri.restype = POINTER(Node) - -plugin_get_name.argtypes = [POINTER(Plugin)] -plugin_get_name.restype = POINTER(Node) - -plugin_get_class.argtypes = [POINTER(Plugin)] -plugin_get_class.restype = POINTER(PluginClass) - -plugin_get_value.argtypes = [POINTER(Plugin), POINTER(Node)] -plugin_get_value.restype = POINTER(Nodes) - -plugin_has_feature.argtypes = [POINTER(Plugin), POINTER(Node)] -plugin_has_feature.restype = c_bool - -plugin_get_supported_features.argtypes = [POINTER(Plugin)] -plugin_get_supported_features.restype = POINTER(Nodes) - -plugin_get_required_features.argtypes = [POINTER(Plugin)] -plugin_get_required_features.restype = POINTER(Nodes) - -plugin_get_optional_features.argtypes = [POINTER(Plugin)] -plugin_get_optional_features.restype = POINTER(Nodes) - -plugin_has_extension_data.argtypes = [POINTER(Plugin), POINTER(Node)] -plugin_has_extension_data.restype = c_bool - -plugin_get_extension_data.argtypes = [POINTER(Plugin)] -plugin_get_extension_data.restype = POINTER(Nodes) - -plugin_get_num_ports.argtypes = [POINTER(Plugin)] -plugin_get_num_ports.restype = c_uint32 - -plugin_get_port_ranges_float.argtypes = [POINTER(Plugin), POINTER(c_float), POINTER(c_float), POINTER(c_float)] -plugin_get_port_ranges_float.restype = None - -plugin_get_num_ports_of_class = VariadicFunction(_lib.lilv_plugin_get_num_ports_of_class, - c_uint32, - [POINTER(Plugin), POINTER(Node)]) - -plugin_has_latency.argtypes = [POINTER(Plugin)] -plugin_has_latency.restype = c_bool - -plugin_get_latency_port_index.argtypes = [POINTER(Plugin)] -plugin_get_latency_port_index.restype = c_uint32 - -plugin_get_port_by_index.argtypes = [POINTER(Plugin), c_uint32] -plugin_get_port_by_index.restype = POINTER(Port) - -plugin_get_port_by_symbol.argtypes = [POINTER(Plugin), POINTER(Node)] -plugin_get_port_by_symbol.restype = POINTER(Port) - -plugin_get_port_by_designation.argtypes = [POINTER(Plugin), POINTER(Node), POINTER(Node)] -plugin_get_port_by_designation.restype = POINTER(Port) - -plugin_get_project.argtypes = [POINTER(Plugin)] -plugin_get_project.restype = POINTER(Node) - -plugin_get_author_name.argtypes = [POINTER(Plugin)] -plugin_get_author_name.restype = POINTER(Node) - -plugin_get_author_email.argtypes = [POINTER(Plugin)] -plugin_get_author_email.restype = POINTER(Node) - -plugin_get_author_homepage.argtypes = [POINTER(Plugin)] -plugin_get_author_homepage.restype = POINTER(Node) - -plugin_is_replaced.argtypes = [POINTER(Plugin)] -plugin_is_replaced.restype = c_bool - -plugin_get_related.argtypes = [POINTER(Plugin), POINTER(Node)] -plugin_get_related.restype = POINTER(Nodes) - -port_get_node.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_node.restype = POINTER(Node) - -port_get_value.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)] -port_get_value.restype = POINTER(Nodes) - -port_get.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)] -port_get.restype = POINTER(Node) - -port_get_properties.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_properties.restype = POINTER(Nodes) - -port_has_property.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)] -port_has_property.restype = c_bool - -port_supports_event.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)] -port_supports_event.restype = c_bool - -port_get_index.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_index.restype = c_uint32 - -port_get_symbol.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_symbol.restype = POINTER(Node) - -port_get_name.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_name.restype = POINTER(Node) - -port_get_classes.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_classes.restype = POINTER(Nodes) - -port_is_a.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(Node)] -port_is_a.restype = c_bool - -port_get_range.argtypes = [POINTER(Plugin), POINTER(Port), POINTER(POINTER(Node)), POINTER(POINTER(Node)), POINTER(POINTER(Node))] -port_get_range.restype = None - -port_get_scale_points.argtypes = [POINTER(Plugin), POINTER(Port)] -port_get_scale_points.restype = POINTER(ScalePoints) - -state_new_from_world.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(Node)] -state_new_from_world.restype = POINTER(State) - -state_new_from_file.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(Node), String] -state_new_from_file.restype = POINTER(State) - -state_new_from_string.argtypes = [POINTER(World), POINTER(LV2_URID_Map), String] -state_new_from_string.restype = POINTER(State) - -LilvGetPortValueFunc = CFUNCTYPE(c_void_p, c_char_p, POINTER(None), POINTER(c_uint32), POINTER(c_uint32)) - -state_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))] -state_new_from_instance.restype = POINTER(State) - -state_free.argtypes = [POINTER(State)] -state_free.restype = None - -state_equals.argtypes = [POINTER(State), POINTER(State)] -state_equals.restype = c_bool - -state_get_num_properties.argtypes = [POINTER(State)] -state_get_num_properties.restype = c_uint - -state_get_plugin_uri.argtypes = [POINTER(State)] -state_get_plugin_uri.restype = POINTER(Node) - -state_get_uri.argtypes = [POINTER(State)] -state_get_uri.restype = POINTER(Node) - -state_get_label.argtypes = [POINTER(State)] -state_get_label.restype = c_char_p - -state_set_label.argtypes = [POINTER(State), String] -state_set_label.restype = None - -state_set_metadata.argtypes = [POINTER(State), c_uint32, POINTER(None), c_size_t, c_uint32, c_uint32] -state_set_metadata.restype = c_int - -LilvSetPortValueFunc = CFUNCTYPE(None, c_char_p, POINTER(None), POINTER(None), c_uint32, c_uint32) -state_emit_port_values.argtypes = [POINTER(State), LilvSetPortValueFunc, POINTER(None)] -state_emit_port_values.restype = None - -state_restore.argtypes = [POINTER(State), POINTER(Instance), LilvSetPortValueFunc, POINTER(None), c_uint32, POINTER(POINTER(LV2_Feature))] -state_restore.restype = None - -state_save.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(LV2_URID_Unmap), POINTER(State), c_char_p, c_char_p, String] -state_save.restype = c_int - -state_to_string.argtypes = [POINTER(World), POINTER(LV2_URID_Map), POINTER(LV2_URID_Unmap), POINTER(State), c_char_p, String] -state_to_string.restype = c_char_p - -state_delete.argtypes = [POINTER(World), POINTER(State)] -state_delete.restype = c_int - -scale_point_get_label.argtypes = [POINTER(ScalePoint)] -scale_point_get_label.restype = POINTER(Node) - -scale_point_get_value.argtypes = [POINTER(ScalePoint)] -scale_point_get_value.restype = POINTER(Node) - -plugin_class_get_parent_uri.argtypes = [POINTER(PluginClass)] -plugin_class_get_parent_uri.restype = POINTER(Node) - -plugin_class_get_uri.argtypes = [POINTER(PluginClass)] -plugin_class_get_uri.restype = POINTER(Node) - -plugin_class_get_label.argtypes = [POINTER(PluginClass)] -plugin_class_get_label.restype = POINTER(Node) - -plugin_class_get_children.argtypes = [POINTER(PluginClass)] -plugin_class_get_children.restype = POINTER(PluginClasses) - -plugin_instantiate.argtypes = [POINTER(Plugin), c_double, POINTER(POINTER(LV2_Feature))] -plugin_instantiate.restype = POINTER(Instance) - -instance_free.argtypes = [POINTER(Instance)] -instance_free.restype = None - -plugin_get_uis.argtypes = [POINTER(Plugin)] -plugin_get_uis.restype = POINTER(UIs) +class String(str): + # Wrapper for string parameters to pass as raw C UTF-8 strings + def from_param(cls, obj): + assert isinstance(obj, str) + return obj.encode("utf-8") -ui_get_uri.argtypes = [POINTER(UI)] -ui_get_uri.restype = POINTER(Node) + from_param = classmethod(from_param) -ui_get_classes.argtypes = [POINTER(UI)] -ui_get_classes.restype = POINTER(Nodes) -ui_is_a.argtypes = [POINTER(UI), POINTER(Node)] -ui_is_a.restype = c_bool +def _cfunc(name, restype, *argtypes): + """Set the `name` attribute of the `c` global to a C function""" + assert isinstance(c, _LilvLib) + f = getattr(c.lib, "lilv_" + name) + f.restype = restype + f.argtypes = argtypes + setattr(c, name, f) + + +def P(x): + """Shorthand for ctypes.POINTER""" + return POINTER(x) + + +_cfunc("free", None, c_void_p) + +# Node + +_cfunc("file_uri_parse", c_char_p, String, P(c_char_p)) +_cfunc("new_uri", P(Node), P(World), String) +_cfunc("new_file_uri", P(Node), P(World), c_char_p, String) +_cfunc("new_string", P(Node), P(World), String) +_cfunc("new_int", P(Node), P(World), c_int) +_cfunc("new_float", P(Node), P(World), c_float) +_cfunc("new_bool", P(Node), P(World), c_bool) +_cfunc("node_free", None, P(Node)) +_cfunc("node_duplicate", P(Node), P(Node)) +_cfunc("node_equals", c_bool, P(Node), P(Node)) +_cfunc("node_get_turtle_token", P(c_char), P(Node)) +_cfunc("node_is_uri", c_bool, P(Node)) +_cfunc("node_as_uri", c_char_p, P(Node)) +_cfunc("node_is_blank", c_bool, P(Node)) +_cfunc("node_as_blank", c_char_p, P(Node)) +_cfunc("node_is_literal", c_bool, P(Node)) +_cfunc("node_is_string", c_bool, P(Node)) +_cfunc("node_as_string", c_char_p, P(Node)) +_cfunc("node_get_path", P(c_char), P(Node), P(P(c_char))) +_cfunc("node_is_float", c_bool, P(Node)) +_cfunc("node_as_float", c_float, P(Node)) +_cfunc("node_is_int", c_bool, P(Node)) +_cfunc("node_as_int", c_int, P(Node)) +_cfunc("node_is_bool", c_bool, P(Node)) +_cfunc("node_as_bool", c_bool, P(Node)) + +# Collections + +_cfunc("plugin_classes_free", None, P(PluginClasses)) +_cfunc("plugin_classes_size", c_uint, P(PluginClasses)) +_cfunc("plugin_classes_begin", P(Iter), P(PluginClasses)) +_cfunc("plugin_classes_get", P(PluginClass), P(PluginClasses), P(Iter)) +_cfunc("plugin_classes_next", P(Iter), P(PluginClasses), P(Iter)) +_cfunc("plugin_classes_is_end", c_bool, P(PluginClasses), P(Iter)) +_cfunc("plugin_classes_get_by_uri", P(PluginClass), P(PluginClasses), P(Node)) +_cfunc("scale_points_free", None, P(ScalePoints)) +_cfunc("scale_points_size", c_uint, P(ScalePoints)) +_cfunc("scale_points_begin", P(Iter), P(ScalePoints)) +_cfunc("scale_points_get", P(ScalePoint), P(ScalePoints), P(Iter)) +_cfunc("scale_points_next", P(Iter), P(ScalePoints), P(Iter)) +_cfunc("scale_points_is_end", c_bool, P(ScalePoints), P(Iter)) +_cfunc("uis_free", None, P(UIs)) +_cfunc("uis_size", c_uint, P(UIs)) +_cfunc("uis_begin", P(Iter), P(UIs)) +_cfunc("uis_get", P(UI), P(UIs), P(Iter)) +_cfunc("uis_next", P(Iter), P(UIs), P(Iter)) +_cfunc("uis_is_end", c_bool, P(UIs), P(Iter)) +_cfunc("uis_get_by_uri", P(UI), P(UIs), P(Node)) +_cfunc("nodes_free", None, P(Nodes)) +_cfunc("nodes_size", c_uint, P(Nodes)) +_cfunc("nodes_begin", P(Iter), P(Nodes)) +_cfunc("nodes_get", P(Node), P(Nodes), P(Iter)) +_cfunc("nodes_next", P(Iter), P(Nodes), P(Iter)) +_cfunc("nodes_is_end", c_bool, P(Nodes), P(Iter)) +_cfunc("nodes_get_first", P(Node), P(Nodes)) +_cfunc("nodes_contains", c_bool, P(Nodes), P(Node)) +_cfunc("nodes_merge", P(Nodes), P(Nodes), P(Nodes)) +_cfunc("plugins_size", c_uint, P(Plugins)) +_cfunc("plugins_begin", P(Iter), P(Plugins)) +_cfunc("plugins_get", P(Plugin), P(Plugins), P(Iter)) +_cfunc("plugins_next", P(Iter), P(Plugins), P(Iter)) +_cfunc("plugins_is_end", c_bool, P(Plugins), P(Iter)) +_cfunc("plugins_get_by_uri", P(Plugin), P(Plugins), P(Node)) + +# World + +_cfunc("world_new", P(World)) +_cfunc("world_set_option", None, P(World), String, P(Node)) +_cfunc("world_free", None, P(World)) +_cfunc("world_load_all", None, P(World)) +_cfunc("world_load_bundle", None, P(World), P(Node)) +_cfunc("world_load_specifications", None, P(World)) +_cfunc("world_load_plugin_classes", None, P(World)) +_cfunc("world_unload_bundle", c_int, P(World), P(Node)) +_cfunc("world_load_resource", c_int, P(World), P(Node)) +_cfunc("world_unload_resource", c_int, P(World), P(Node)) +_cfunc("world_get_plugin_class", P(PluginClass), P(World)) +_cfunc("world_get_plugin_classes", P(PluginClasses), P(World)) +_cfunc("world_get_all_plugins", P(Plugins), P(World)) +_cfunc("world_find_nodes", P(Nodes), P(World), P(Node), P(Node), P(Node)) +_cfunc("world_get", P(Node), P(World), P(Node), P(Node), P(Node)) +_cfunc("world_ask", c_bool, P(World), P(Node), P(Node), P(Node)) +_cfunc("world_get_symbol", P(Node), P(World), P(Node)) + +# Plugin + +_cfunc("plugin_verify", c_bool, P(Plugin)) +_cfunc("plugin_get_uri", P(Node), P(Plugin)) +_cfunc("plugin_get_bundle_uri", P(Node), P(Plugin)) +_cfunc("plugin_get_data_uris", P(Nodes), P(Plugin)) +_cfunc("plugin_get_library_uri", P(Node), P(Plugin)) +_cfunc("plugin_get_name", P(Node), P(Plugin)) +_cfunc("plugin_get_class", P(PluginClass), P(Plugin)) +_cfunc("plugin_get_value", P(Nodes), P(Plugin), P(Node)) +_cfunc("plugin_has_feature", c_bool, P(Plugin), P(Node)) +_cfunc("plugin_get_supported_features", P(Nodes), P(Plugin)) +_cfunc("plugin_get_required_features", P(Nodes), P(Plugin)) +_cfunc("plugin_get_optional_features", P(Nodes), P(Plugin)) +_cfunc("plugin_has_extension_data", c_bool, P(Plugin), P(Node)) +_cfunc("plugin_get_extension_data", P(Nodes), P(Plugin)) +_cfunc("plugin_get_num_ports", c_uint32, P(Plugin)) + +c.plugin_get_num_ports_of_class = VariadicFunction( + c.lib.lilv_plugin_get_num_ports_of_class, c_uint32, [P(Plugin), P(Node)] +) + +_cfunc("plugin_has_latency", c_bool, P(Plugin)) +_cfunc("plugin_get_latency_port_index", c_uint32, P(Plugin)) +_cfunc("plugin_get_port_by_index", P(Port), P(Plugin), c_uint32) +_cfunc("plugin_get_port_by_symbol", P(Port), P(Plugin), P(Node)) +_cfunc("plugin_get_port_by_designation", P(Port), P(Plugin), P(Node), P(Node)) +_cfunc("plugin_get_project", P(Node), P(Plugin)) +_cfunc("plugin_get_author_name", P(Node), P(Plugin)) +_cfunc("plugin_get_author_email", P(Node), P(Plugin)) +_cfunc("plugin_get_author_homepage", P(Node), P(Plugin)) +_cfunc("plugin_is_replaced", c_bool, P(Plugin)) +_cfunc("plugin_get_related", P(Nodes), P(Plugin), P(Node)) + +# Port + +_cfunc("port_get_node", P(Node), P(Plugin), P(Port)) +_cfunc("port_get_value", P(Nodes), P(Plugin), P(Port), P(Node)) +_cfunc("port_get", P(Node), P(Plugin), P(Port), P(Node)) +_cfunc("port_get_properties", P(Nodes), P(Plugin), P(Port)) +_cfunc("port_has_property", c_bool, P(Plugin), P(Port), P(Node)) +_cfunc("port_supports_event", c_bool, P(Plugin), P(Port), P(Node)) +_cfunc("port_get_index", c_uint32, P(Plugin), P(Port)) +_cfunc("port_get_symbol", P(Node), P(Plugin), P(Port)) +_cfunc("port_get_name", P(Node), P(Plugin), P(Port)) +_cfunc("port_get_classes", P(Nodes), P(Plugin), P(Port)) +_cfunc("port_is_a", c_bool, P(Plugin), P(Port), P(Node)) + +_cfunc( + "port_get_range", + None, + P(Plugin), + P(Port), + P(P(Node)), + P(P(Node)), + P(P(Node)), +) + +_cfunc("port_get_scale_points", P(ScalePoints), P(Plugin), P(Port)) + +# Plugin State + +_cfunc("state_new_from_world", P(State), P(World), P(LV2_URID_Map), P(Node)) + +_cfunc( + "state_new_from_file", P(State), P(World), P(LV2_URID_Map), P(Node), String +) + +_cfunc("state_new_from_string", P(State), P(World), P(LV2_URID_Map), String) + +LilvGetPortValueFunc = CFUNCTYPE( + c_void_p, c_char_p, P(None), P(c_uint32), P(c_uint32) +) + +_cfunc( + "state_new_from_instance", + P(State), + P(Plugin), + P(Instance), + P(LV2_URID_Map), + c_char_p, + c_char_p, + c_char_p, + String, + LilvGetPortValueFunc, + P(None), + c_uint32, + P(P(LV2_Feature)), +) + +_cfunc("state_free", None, P(State)) +_cfunc("state_equals", c_bool, P(State), P(State)) +_cfunc("state_get_num_properties", c_uint, P(State)) +_cfunc("state_get_plugin_uri", P(Node), P(State)) +_cfunc("state_get_uri", P(Node), P(State)) +_cfunc("state_get_label", c_char_p, P(State)) +_cfunc("state_set_label", None, P(State), String) + +_cfunc( + "state_set_metadata", + c_int, + P(State), + c_uint32, + P(None), + c_size_t, + c_uint32, + c_uint32, +) + +LilvSetPortValueFunc = CFUNCTYPE( + None, c_char_p, P(None), P(None), c_uint32, c_uint32 +) +_cfunc("state_emit_port_values", None, P(State), LilvSetPortValueFunc, P(None)) + +_cfunc( + "state_restore", + None, + P(State), + P(Instance), + LilvSetPortValueFunc, + P(None), + c_uint32, + P(P(LV2_Feature)), +) + +_cfunc( + "state_save", + c_int, + P(World), + P(LV2_URID_Map), + P(LV2_URID_Unmap), + P(State), + c_char_p, + c_char_p, + String, +) + +_cfunc( + "state_to_string", + c_char_p, + P(World), + P(LV2_URID_Map), + P(LV2_URID_Unmap), + P(State), + c_char_p, + String, +) + +_cfunc("state_delete", c_int, P(World), P(State)) + +# Scale Point + +_cfunc("scale_point_get_label", P(Node), P(ScalePoint)) +_cfunc("scale_point_get_value", P(Node), P(ScalePoint)) + +# Plugin Class + +_cfunc("plugin_class_get_parent_uri", P(Node), P(PluginClass)) +_cfunc("plugin_class_get_uri", P(Node), P(PluginClass)) +_cfunc("plugin_class_get_label", P(Node), P(PluginClass)) +_cfunc("plugin_class_get_children", P(PluginClasses), P(PluginClass)) + +# Plugin Instance + +_cfunc( + "plugin_instantiate", P(Instance), P(Plugin), c_double, P(P(LV2_Feature)) +) + +_cfunc("instance_free", None, P(Instance)) +_cfunc("plugin_get_uis", P(UIs), P(Plugin)) + +# Plugin UI + +_cfunc("ui_get_uri", P(Node), P(UI)) +_cfunc("ui_get_classes", P(Nodes), P(UI)) +_cfunc("ui_is_a", c_bool, P(UI), P(Node)) LilvUISupportedFunc = CFUNCTYPE(c_uint, c_char_p, c_char_p) -ui_is_supported.argtypes = [POINTER(UI), LilvUISupportedFunc, POINTER(Node), POINTER(POINTER(Node))] -ui_is_supported.restype = c_uint - -ui_get_bundle_uri.argtypes = [POINTER(UI)] -ui_get_bundle_uri.restype = POINTER(Node) - -ui_get_binary_uri.argtypes = [POINTER(UI)] -ui_get_binary_uri.restype = POINTER(Node) +_cfunc( + "ui_is_supported", c_uint, P(UI), LilvUISupportedFunc, P(Node), P(P(Node)) +) -OPTION_FILTER_LANG = 'http://drobilla.net/ns/lilv#filter-lang' -OPTION_DYN_MANIFEST = 'http://drobilla.net/ns/lilv#dyn-manifest' +_cfunc("ui_get_bundle_uri", P(Node), P(UI)) +_cfunc("ui_get_binary_uri", P(Node), P(UI)) # Define URI constants for compatibility with old Python bindings -LILV_NS_DOAP = 'http://usefulinc.com/ns/doap#' -LILV_NS_FOAF = 'http://xmlns.com/foaf/0.1/' -LILV_NS_LILV = 'http://drobilla.net/ns/lilv#' -LILV_NS_LV2 = 'http://lv2plug.in/ns/lv2core#' -LILV_NS_OWL = 'http://www.w3.org/2002/07/owl#' -LILV_NS_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' -LILV_NS_RDFS = 'http://www.w3.org/2000/01/rdf-schema#' -LILV_NS_XSD = 'http://www.w3.org/2001/XMLSchema#' -LILV_URI_ATOM_PORT = 'http://lv2plug.in/ns/ext/atom#AtomPort' -LILV_URI_AUDIO_PORT = 'http://lv2plug.in/ns/lv2core#AudioPort' -LILV_URI_CONTROL_PORT = 'http://lv2plug.in/ns/lv2core#ControlPort' -LILV_URI_CV_PORT = 'http://lv2plug.in/ns/lv2core#CVPort' -LILV_URI_EVENT_PORT = 'http://lv2plug.in/ns/ext/event#EventPort' -LILV_URI_INPUT_PORT = 'http://lv2plug.in/ns/lv2core#InputPort' -LILV_URI_MIDI_EVENT = 'http://lv2plug.in/ns/ext/midi#MidiEvent' -LILV_URI_OUTPUT_PORT = 'http://lv2plug.in/ns/lv2core#OutputPort' -LILV_URI_PORT = 'http://lv2plug.in/ns/lv2core#Port' -LILV_OPTION_FILTER_LANG = 'http://drobilla.net/ns/lilv#filter-lang' -LILV_OPTION_DYN_MANIFEST = 'http://drobilla.net/ns/lilv#dyn-manifest' +LILV_NS_DOAP = "http://usefulinc.com/ns/doap#" +LILV_NS_FOAF = "http://xmlns.com/foaf/0.1/" +LILV_NS_LILV = "http://drobilla.net/ns/lilv#" +LILV_NS_LV2 = "http://lv2plug.in/ns/lv2core#" +LILV_NS_OWL = "http://www.w3.org/2002/07/owl#" +LILV_NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +LILV_NS_RDFS = "http://www.w3.org/2000/01/rdf-schema#" +LILV_NS_XSD = "http://www.w3.org/2001/XMLSchema#" +LILV_URI_ATOM_PORT = "http://lv2plug.in/ns/ext/atom#AtomPort" +LILV_URI_AUDIO_PORT = "http://lv2plug.in/ns/lv2core#AudioPort" +LILV_URI_CONTROL_PORT = "http://lv2plug.in/ns/lv2core#ControlPort" +LILV_URI_CV_PORT = "http://lv2plug.in/ns/lv2core#CVPort" +LILV_URI_EVENT_PORT = "http://lv2plug.in/ns/ext/event#EventPort" +LILV_URI_INPUT_PORT = "http://lv2plug.in/ns/lv2core#InputPort" +LILV_URI_MIDI_EVENT = "http://lv2plug.in/ns/ext/midi#MidiEvent" +LILV_URI_OUTPUT_PORT = "http://lv2plug.in/ns/lv2core#OutputPort" +LILV_URI_PORT = "http://lv2plug.in/ns/lv2core#Port" +LILV_OPTION_FILTER_LANG = "http://drobilla.net/ns/lilv#filter-lang" +LILV_OPTION_DYN_MANIFEST = "http://drobilla.net/ns/lilv#dyn-manifest" -- cgit v1.2.1