Update local LV2 libraries to latest versions
lilv-0.24.6 lv2-1.16.0 serd-0.30.2 sord-0.16.4 sratom-0.6.4 suil-0.10.6
This commit is contained in:
parent
9dab0a2fee
commit
be336797b3
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "waflib"]
|
||||||
|
path = waflib
|
||||||
|
url = ../../drobilla/autowaf
|
|
@ -8,4 +8,7 @@ Dynamic manifest support:
|
||||||
Stefano D'Angelo
|
Stefano D'Angelo
|
||||||
|
|
||||||
Plugin execution via Python bindings:
|
Plugin execution via Python bindings:
|
||||||
Kaspar Emanuel <kaspar.emanuel@gmail.com>
|
Kaspar Emanuel <kaspar.emanuel@gmail.com>
|
||||||
|
|
||||||
|
Python preset script:
|
||||||
|
Christopher Arndt <chris@chrisarndt.de>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright 2011-2014 David Robillard <http://drobilla.net>
|
Copyright 2011-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
|
@ -8,11 +8,7 @@ Building this software requires only Python. To install with default options:
|
||||||
|
|
||||||
./waf configure
|
./waf configure
|
||||||
./waf
|
./waf
|
||||||
./waf install
|
./waf install # or sudo ./waf install
|
||||||
|
|
||||||
You may need to become root for the install stage, for example:
|
|
||||||
|
|
||||||
sudo ./waf install
|
|
||||||
|
|
||||||
Configuration Options
|
Configuration Options
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -40,12 +36,20 @@ invoked:
|
||||||
* CPPFLAGS: C preprocessor options
|
* CPPFLAGS: C preprocessor options
|
||||||
* LINKFLAGS: Linker options
|
* LINKFLAGS: Linker options
|
||||||
|
|
||||||
Installation Directories
|
Library Versioning
|
||||||
------------------------
|
------------------
|
||||||
|
|
||||||
The --prefix option (or the PREFIX environment variable) can be used to change
|
This library uses semantic versioning <http://semver.org/>.
|
||||||
the prefix which all files are installed under. There are also several options
|
|
||||||
allowing for more fine-tuned control, see the --help output for details.
|
Several major versions can be installed in parallel. The shared library name,
|
||||||
|
include directory, and pkg-config file are suffixed with the major version
|
||||||
|
number. For example, a library named "foo" at version 1.x.y might install:
|
||||||
|
|
||||||
|
/usr/include/foo-1/foo/foo.h
|
||||||
|
/usr/lib/foo-1.so.1.x.y
|
||||||
|
/usr/lib/pkgconfig/foo-1.pc
|
||||||
|
|
||||||
|
Dependencies can check for the package "foo-1" with pkg-config.
|
||||||
|
|
||||||
Packaging
|
Packaging
|
||||||
---------
|
---------
|
||||||
|
@ -57,3 +61,6 @@ which adds a prefix to all install paths. For example:
|
||||||
./waf configure --prefix=/usr
|
./waf configure --prefix=/usr
|
||||||
./waf
|
./waf
|
||||||
./waf install --destdir=/tmp/package
|
./waf install --destdir=/tmp/package
|
||||||
|
|
||||||
|
Packages should allow parallel installation of several major versions. For
|
||||||
|
example, the above would be packaged as "foo-1".
|
|
@ -1,150 +1,236 @@
|
||||||
|
lilv (0.24.6) stable;
|
||||||
|
|
||||||
|
* Add more strict error detection when storing plugin state properties
|
||||||
|
* Add option to override LV2_PATH in applications
|
||||||
|
* Don't print errors when saving state if correct links already exist
|
||||||
|
* Fix GCC8 warnings
|
||||||
|
* Fix creating directories across drives on Windows
|
||||||
|
* Fix issues with loading state with saved files from the model
|
||||||
|
* Fix memory errors and Python 3.4+ compatibility in Python bindings
|
||||||
|
* Fix unit tests on Windows
|
||||||
|
* Make Python bindings more Pythonic
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net> Sun, 10 Nov 2019 21:39:37 +0000
|
||||||
|
|
||||||
|
lilv (0.24.4) stable;
|
||||||
|
|
||||||
|
* Don't attempt to load remote or non-Turtle files
|
||||||
|
* Fix saving state when broken links are encountered
|
||||||
|
* Gracefully handle plugins with missing binary URIs
|
||||||
|
* Install Python bindings when configured without tests (thanks Clement
|
||||||
|
Skau)
|
||||||
|
* Remove use of deprecated readdir_r
|
||||||
|
* lv2apply: Activate plugin before running
|
||||||
|
* lv2apply: Use default values when they are not nan
|
||||||
|
* lv2bench: Improve support for plugins with sequence ports
|
||||||
|
* lv2bench: Support running a single plugin given on the command line
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net> Sun, 22 Jul 2018 18:42:00 +0000
|
||||||
|
|
||||||
|
lilv (0.24.2) stable;
|
||||||
|
|
||||||
|
* Fix comparison of restored states with paths
|
||||||
|
* Fix saving state to paths that contain URI delimiters (#, ?, etc)
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net> Wed, 04 Jan 2017 16:48:08 +0000
|
||||||
|
|
||||||
|
lilv (0.24.0) stable;
|
||||||
|
|
||||||
|
* Add LILV_URI_ATOM_PORT and LILV_URI_CV_PORT defines
|
||||||
|
* Add lilv_state_set_metadata() for adding state banks/comments/etc (based
|
||||||
|
on patch from Hanspeter Portner)
|
||||||
|
* Add lilv_world_get_symbol()
|
||||||
|
* Add lv2apply utility for applying plugins to audio files
|
||||||
|
* Add new hand-crafted Pythonic bindings with full test coverage
|
||||||
|
* Check lv2:binary predicate for UIs
|
||||||
|
* Do not instantiate plugin when data fails to parse
|
||||||
|
* Fix crash when NULL predicate is passed to lilv_world_find_nodes()
|
||||||
|
* Fix crash when state contains non-POD properties
|
||||||
|
* Fix documentation installation
|
||||||
|
* Fix loading dyn-manifest from bundles with spaces in their path
|
||||||
|
* Fix outdated comment references to lilv_uri_to_path()
|
||||||
|
* Fix state file versioning
|
||||||
|
* Replace bundles if bundle with newer plugin version is loaded (based on
|
||||||
|
patch from Robin Gareus)
|
||||||
|
* Support re-loading plugins
|
||||||
|
* Unload contained resources when bundle is unloaded
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net> Tue, 20 Sep 2016 02:24:57 +0000
|
||||||
|
|
||||||
|
lilv (0.22.0) stable;
|
||||||
|
|
||||||
|
* Add lilv_file_uri_parse() for correct URI to path conversion
|
||||||
|
* Add lilv_free() for systems picky about such things
|
||||||
|
* Add lilv_node_get_path() for convenient file URI path access
|
||||||
|
* Add lilv_state_delete() for deleting user saved presets
|
||||||
|
* Add lilv_state_emit_port_values() for special port value handling
|
||||||
|
* Add lilv_state_get_uri()
|
||||||
|
* Configure based on compiler target OS for cross-compilation
|
||||||
|
* Expose lilv_world_load_specifications() and
|
||||||
|
lilv_world_load_plugin_classes()
|
||||||
|
* Fix a few minor/unlikely memory errors
|
||||||
|
* Fix bindings for Python 3
|
||||||
|
* Fix creation of duplicate manifest entries when saving state
|
||||||
|
* Fix directory walking on some systems (thanks Matt Fischer)
|
||||||
|
* Fix lilv_realpath() on pre-POSIX-2008 systems
|
||||||
|
* Fix lilv_world_ask() to work with wildcards
|
||||||
|
* Fix loading files with spaces in their path
|
||||||
|
* Load discovered owl ontologies as specifications
|
||||||
|
* Minor documentation improvements
|
||||||
|
* Preserve absolute paths in state if no link directory is given
|
||||||
|
* Tolerate passing NULL to lilv_state_restore()
|
||||||
|
* Upgrade to waf 1.8.14
|
||||||
|
* Windows fixes (thanks John Emmas)
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net> Thu, 08 Oct 2015 19:39:29 +0000
|
||||||
|
|
||||||
lilv (0.20.0) stable;
|
lilv (0.20.0) stable;
|
||||||
|
|
||||||
|
* Add convenient lilv_new_file_uri for creating file URIs
|
||||||
|
* Add lilv_world_unload_bundle() and lilv_world_unload_resource()
|
||||||
|
* Call lv2_lib_descriptor separately for different bundle paths (fix loading
|
||||||
|
several dynamic plugins like Ingen at once)
|
||||||
* Don't load files multiple times if they are listed as rdfs:seeAlso for
|
* Don't load files multiple times if they are listed as rdfs:seeAlso for
|
||||||
several plugins
|
several plugins
|
||||||
* Call lv2_lib_descriptor separately for different bundle paths
|
* Fix issues with lilv_plugin_get_author_name and friends (thanks Filipe
|
||||||
(fix loading several dynamic plugins like Ingen at once)
|
Coelho)
|
||||||
* Tolerate calling lilv_node_as_uri or lilv_node_as_blank on NULL
|
|
||||||
* Add convenient lilv_new_file_uri for creating file URIs
|
|
||||||
* Fix use of lv2info -m and -p options to write plugin data
|
|
||||||
(useful for porting plugins bridges with NASPRO)
|
|
||||||
* Fix issues with lilv_plugin_get_author_name and friends
|
|
||||||
(thanks Filipe Coelho)
|
|
||||||
* Improved/working lv2_apply.py to apply plugin to a .wav
|
|
||||||
(thanks Joe Button)
|
|
||||||
* Add lilv_world_unload_bundle() and lilv_world_unload_resource()
|
|
||||||
* Fix several minor memory leaks
|
* Fix several minor memory leaks
|
||||||
|
* Fix use of lv2info -m and -p options to write plugin data (useful for
|
||||||
|
porting plugins bridges with NASPRO)
|
||||||
* Improve test coverage
|
* Improve test coverage
|
||||||
|
* Improved/working lv2_apply.py to apply plugin to a .wav (thanks Joe
|
||||||
|
Button)
|
||||||
|
* Tolerate calling lilv_node_as_uri or lilv_node_as_blank on NULL
|
||||||
* Upgrade to waf 1.7.16
|
* Upgrade to waf 1.7.16
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Fri, 08 Aug 2014 18:21:32 -0400
|
-- David Robillard <d@drobilla.net> Fri, 08 Aug 2014 22:21:32 +0000
|
||||||
|
|
||||||
lilv (0.18.0) stable;
|
lilv (0.18.0) stable;
|
||||||
|
|
||||||
* Allow lilv_state_restore() to be used without passing an instance,
|
* Add lilv_port_get_node() for using world query functions with ports
|
||||||
for restoring port values via a callback only
|
* Add support for running plugins from Python by Kaspar Emanuel
|
||||||
* Fix unlikely memory leak in lilv_plugin_instantiate()
|
* Allow lilv_state_restore() to be used without passing an instance, for
|
||||||
* Support denoting latency ports with lv2:designation lv2:latency
|
restoring port values via a callback only
|
||||||
* Allow passing NULL port_class to lilv_plugin_get_port_by_designation
|
* Allow passing NULL port_class to lilv_plugin_get_port_by_designation
|
||||||
* Call GetProcAddress with correct calling convention on Windows
|
* Call GetProcAddress with correct calling convention on Windows
|
||||||
* Add support for running plugins from Python by Kaspar Emanuel
|
|
||||||
* Clean up after test suite so multiple runs are successful
|
* Clean up after test suite so multiple runs are successful
|
||||||
* Add lilv_port_get_node() for using world query functions with ports
|
* Fix unlikely memory leak in lilv_plugin_instantiate()
|
||||||
* lv2info: Don't display invalid control maxes and defaults
|
* Support denoting latency ports with lv2:designation lv2:latency
|
||||||
(patch from Robin Gareus)
|
|
||||||
* lilvmm.hpp: Add wrappers for UI API
|
* lilvmm.hpp: Add wrappers for UI API
|
||||||
|
* lv2info: Don't display invalid control maxes and defaults (patch from
|
||||||
|
Robin Gareus)
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Sat, 04 Jan 2014 16:06:42 -0500
|
-- David Robillard <d@drobilla.net> Sat, 04 Jan 2014 21:06:42 +0000
|
||||||
|
|
||||||
lilv (0.16.0) stable;
|
lilv (0.16.0) stable;
|
||||||
|
|
||||||
|
* Add lilv_nodes_merge()
|
||||||
* Add lilv_world_ask() for easily checking if a statement exists
|
* Add lilv_world_ask() for easily checking if a statement exists
|
||||||
* Add lilv_world_get() and lilv_port_get() for easily getting one value
|
* Add lilv_world_get() and lilv_port_get() for easily getting one value
|
||||||
* Add lilv_nodes_merge()
|
|
||||||
* Make lilv_plugin_get_port_by_designation() return a const pointer
|
|
||||||
* Require a URI for lilv_state_to_string() and fail gracefully otherwise
|
|
||||||
* Fail gracefully when lilv_state_new_from_string() is called on NULL
|
|
||||||
* Make state loading functions fall back to lv2:default for port values,
|
|
||||||
so a plugin description can be loaded as default state
|
|
||||||
* Ignore state ports with no value instead of printing an error
|
|
||||||
* Support atom:supports in lilv_port_supports_event()
|
|
||||||
* Add va_list variant of lilv_plugin_get_num_ports_of_class()
|
* Add va_list variant of lilv_plugin_get_num_ports_of_class()
|
||||||
* Fix several plugin functions that failed to load data if called first
|
|
||||||
* Correctly depend on serd at build time (fix compilation in odd cases)
|
* Correctly depend on serd at build time (fix compilation in odd cases)
|
||||||
* Disable timestamps in HTML documentation for reproducible build
|
* Disable timestamps in HTML documentation for reproducible build
|
||||||
* lilvmm.hpp: Support varargs for Plugin::get_num_ports_of_class()
|
* Fail gracefully when lilv_state_new_from_string() is called on NULL
|
||||||
* lilvmm.hpp: Add several missing methods
|
* Fix several plugin functions that failed to load data if called first
|
||||||
|
* Ignore state ports with no value instead of printing an error
|
||||||
|
* Make lilv_plugin_get_port_by_designation() return a const pointer
|
||||||
|
* Make state loading functions fall back to lv2:default for port values, so
|
||||||
|
a plugin description can be loaded as default state
|
||||||
|
* Require a URI for lilv_state_to_string() and fail gracefully otherwise
|
||||||
|
* Support atom:supports in lilv_port_supports_event()
|
||||||
* Update to waf 1.7.8 and autowaf r90 (install docs to versioned directory)
|
* Update to waf 1.7.8 and autowaf r90 (install docs to versioned directory)
|
||||||
|
* lilvmm.hpp: Add several missing methods
|
||||||
|
* lilvmm.hpp: Support varargs for Plugin::get_num_ports_of_class()
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Mon, 18 Feb 2013 16:43:10 -0500
|
-- David Robillard <d@drobilla.net> Mon, 18 Feb 2013 21:43:10 +0000
|
||||||
|
|
||||||
lilv (0.14.4) stable;
|
lilv (0.14.4) stable;
|
||||||
|
|
||||||
|
* Add lv2bench utility
|
||||||
|
* Add option to build utilities as static binaries
|
||||||
* Deprecate old flawed Lilv::Instance constructors
|
* Deprecate old flawed Lilv::Instance constructors
|
||||||
* Fix documentation for ui_type parameter of lilv_ui_is_supported()
|
* Do not require a C++ compiler to build
|
||||||
* Fix crash when lv2info is run with an invalid URI argument
|
* Fix crash when lv2info is run with an invalid URI argument
|
||||||
|
* Fix documentation for ui_type parameter of lilv_ui_is_supported()
|
||||||
|
* Fix various hyper-strict warnings
|
||||||
* Gracefully handle failure to save plugin state and print error message
|
* Gracefully handle failure to save plugin state and print error message
|
||||||
|
* Make all 'zix' symbols private to avoid symbol clashes in static builds
|
||||||
* Reduce memory usage (per node)
|
* Reduce memory usage (per node)
|
||||||
* Simpler node implementation always backed by a SordNode
|
* Simpler node implementation always backed by a SordNode
|
||||||
* Make all 'zix' symbols private to avoid symbol clashes in static builds
|
|
||||||
* Add lv2bench utility
|
|
||||||
* Fix various hyper-strict warnings
|
|
||||||
* Do not require a C++ compiler to build
|
|
||||||
* Add option to build utilities as static binaries
|
|
||||||
* Upgrade to waf 1.7.2
|
* Upgrade to waf 1.7.2
|
||||||
* lilvmm.hpp: Make Lilv::Instance handle features and failed instantiations
|
|
||||||
* lilvmm.hpp: Add Lilv::Instance::get_handle()
|
|
||||||
* lilvmm.hpp: Add Lilv::Instance::get_extension_data()
|
* lilvmm.hpp: Add Lilv::Instance::get_extension_data()
|
||||||
|
* lilvmm.hpp: Add Lilv::Instance::get_handle()
|
||||||
|
* lilvmm.hpp: Make Lilv::Instance handle features and failed instantiations
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Thu, 23 Aug 2012 01:38:29 -0400
|
-- David Robillard <d@drobilla.net> Thu, 23 Aug 2012 05:38:29 +0000
|
||||||
|
|
||||||
lilv (0.14.2) stable;
|
lilv (0.14.2) stable;
|
||||||
|
|
||||||
* Fix dynmanifest support
|
* Fix dynmanifest support
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 16:11:31 -0400
|
-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 20:11:31 +0000
|
||||||
|
|
||||||
lilv (0.14.0) stable;
|
lilv (0.14.0) stable;
|
||||||
|
|
||||||
|
* Add LilvState API for handling plugin state. This makes it simple to save
|
||||||
|
and restore plugin state both in memory and on disk, as well as save
|
||||||
|
presets in a host-sharable way since the disk format is identical to the
|
||||||
|
LV2 presets format.
|
||||||
* Add lilv_plugin_get_extension_data
|
* Add lilv_plugin_get_extension_data
|
||||||
* Use path variables in pkgconfig files
|
|
||||||
* Install man page to DATADIR (e.g. PREFIX/share/man, not PREFIX/man)
|
|
||||||
* Make Lilv::uri_to_path static inline (fix linking errors)
|
|
||||||
* Use correct URI for dcterms:replaces (for hiding old plugins):
|
|
||||||
"http://purl.org/dc/terms/replaces"
|
|
||||||
* Fix compilation on BSD
|
|
||||||
* Only load dynmanifest libraries once per bundle, not once per plugin
|
|
||||||
* Fix lilv_world_find_nodes to work with wildcard subjects
|
|
||||||
* Add lilv_plugin_get_related to get resources related to plugins that
|
|
||||||
are not directly rdfs:seeAlso linked (e.g. presets)
|
|
||||||
* Add lilv_world_load_resource for related resources (e.g. presets)
|
|
||||||
* Print presets in lv2info
|
|
||||||
* Remove locale smashing kludges and use new serd functions for converting
|
|
||||||
nodes to/from numbers.
|
|
||||||
* Add LilvState API for handling plugin state. This makes it simple to
|
|
||||||
save and restore plugin state both in memory and on disk, as well as
|
|
||||||
save presets in a host-sharable way since the disk format is identical
|
|
||||||
to the LV2 presets format.
|
|
||||||
* Update old references to lv2_list (now lv2ls)
|
|
||||||
* Support compilation as C++ under MSVC++.
|
|
||||||
* Remove use of wordexp.
|
|
||||||
* Add lilv_plugin_get_port_by_designation() and lilv_port_get_index() as an
|
* Add lilv_plugin_get_port_by_designation() and lilv_port_get_index() as an
|
||||||
improved generic alternative to lilv_plugin_get_latency_port_index().
|
improved generic alternative to lilv_plugin_get_latency_port_index().
|
||||||
* Add lilv_plugin_get_project() and get author information from project if
|
* Add lilv_plugin_get_project() and get author information from project if
|
||||||
it is not given directly on the plugin.
|
it is not given directly on the plugin.
|
||||||
|
* Add lilv_plugin_get_related to get resources related to plugins that are
|
||||||
|
not directly rdfs:seeAlso linked (e.g. presets)
|
||||||
|
* Add lilv_world_load_resource for related resources (e.g. presets)
|
||||||
|
* Fix compilation on BSD
|
||||||
|
* Fix lilv_world_find_nodes to work with wildcard subjects
|
||||||
|
* Install man page to DATADIR (e.g. PREFIX/share/man, not PREFIX/man)
|
||||||
|
* Make Lilv::uri_to_path static inline (fix linking errors)
|
||||||
|
* Only load dynmanifest libraries once per bundle, not once per plugin
|
||||||
|
* Print presets in lv2info
|
||||||
|
* Remove locale smashing kludges and use new serd functions for converting
|
||||||
|
nodes to/from numbers.
|
||||||
|
* Remove use of wordexp.
|
||||||
|
* Support compilation as C++ under MSVC++.
|
||||||
|
* Update old references to lv2_list (now lv2ls)
|
||||||
|
* Use correct URI for dcterms:replaces (for hiding old plugins):
|
||||||
|
"http://purl.org/dc/terms/replaces"
|
||||||
|
* Use path variables in pkgconfig files
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Wed, 18 Apr 2012 20:06:28 -0400
|
-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 00:06:28 +0000
|
||||||
|
|
||||||
lilv (0.5.0) stable;
|
lilv (0.5.0) stable;
|
||||||
|
|
||||||
* Remove glib dependency
|
* Add ability to build static library
|
||||||
* Add lv2core as a pkg-config dependency (for lv2.h header include)
|
* Add lv2core as a pkg-config dependency (for lv2.h header include)
|
||||||
* Obey prefix when installing bash completion script
|
* Obey prefix when installing bash completion script
|
||||||
|
* Remove glib dependency
|
||||||
* Support integer minimum, maximum, and default port values in
|
* Support integer minimum, maximum, and default port values in
|
||||||
lilv_plugin_get_port_ranges_float
|
lilv_plugin_get_port_ranges_float
|
||||||
* Add ability to build static library
|
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Thu, 29 Sep 2011 00:00:00 -0400
|
-- David Robillard <d@drobilla.net> Thu, 29 Sep 2011 04:00:00 +0000
|
||||||
|
|
||||||
lilv (0.4.4) stable;
|
lilv (0.4.4) stable;
|
||||||
|
|
||||||
* Fix building python bindings
|
* Fix building python bindings
|
||||||
|
* Fix lilv_ui_is_supported when Lilv is built independently
|
||||||
|
* Fix parsing extra plugin data files in other bundles
|
||||||
* Make free methods tolerate being called on NULL
|
* Make free methods tolerate being called on NULL
|
||||||
* Remove lv2jack (replaced by jalv)
|
* Remove lv2jack (replaced by jalv)
|
||||||
* Fix parsing extra plugin data files in other bundles
|
|
||||||
* Fix lilv_ui_is_supported when Lilv is built independently
|
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Sat, 11 Jun 2011 11:20:11 -0400
|
-- David Robillard <d@drobilla.net> Sat, 11 Jun 2011 15:20:11 +0000
|
||||||
|
|
||||||
lilv (0.4.2) stable;
|
lilv (0.4.2) stable;
|
||||||
|
|
||||||
* Fix compilation issues on some systems
|
|
||||||
* Fix build system Python 3 compatibility
|
* Fix build system Python 3 compatibility
|
||||||
|
* Fix compilation issues on some systems
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Wed, 25 May 2011 19:00:00 -0400
|
-- David Robillard <d@drobilla.net> Wed, 25 May 2011 23:00:00 +0000
|
||||||
|
|
||||||
lilv (0.4.0) stable;
|
lilv (0.4.0) stable;
|
||||||
|
|
||||||
* Initial version (forked from SLV2)
|
* Initial version (forked from SLV2)
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net> Tue, 24 May 2011 23:00:00 -0400
|
-- David Robillard <d@drobilla.net> Wed, 25 May 2011 03:00:00 +0000
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
This library is designed to allow parallel installation of different major
|
|
||||||
versions. To facilitate this, the shared library name, include directory, and
|
|
||||||
pkg-config file are suffixed with the major version number of the library.
|
|
||||||
|
|
||||||
For example, if this library was named "foo" and at version 1.x.y:
|
|
||||||
|
|
||||||
/usr/include/foo-1/foo/foo.h
|
|
||||||
/usr/lib/foo-1.so.1.x.y
|
|
||||||
/usr/lib/pkgconfig/foo-1.pc
|
|
||||||
|
|
||||||
Dependencies check for pkg-config name "foo-1" and will build
|
|
||||||
against a compatible version 1, regardless any other installed versions.
|
|
||||||
|
|
||||||
*** IMPORTANT GUIDELINES FOR PACKAGERS ***
|
|
||||||
|
|
||||||
Packages should follow the same conventions as above, i.e. include the major
|
|
||||||
version (and only the major version) in the name of the package. Continuing the
|
|
||||||
example above, the package(s) would be named foo-1 and foo-1-dev. This way,
|
|
||||||
if/when version 2 comes out, it may be installed at the same time as version 1
|
|
||||||
without breaking anything.
|
|
||||||
|
|
||||||
Please do not create packages of this library that do not follow these
|
|
||||||
guidelines, you will break things and cause unnecessary headaches. Please do
|
|
||||||
not use any number as a suffix other than the actual major version number of the
|
|
||||||
upstream source package.
|
|
||||||
|
|
||||||
Because program and documentation names are not versioned, these should be
|
|
||||||
included in separate packages which may replace previous versions, since
|
|
||||||
there is little use in having parallel installations of them.
|
|
|
@ -1,11 +0,0 @@
|
||||||
Lilv
|
|
||||||
----
|
|
||||||
|
|
||||||
Lilv is a library for LV2 hosts intended to make using LV2 Plugins as simple
|
|
||||||
as possible (without sacrificing capabilities).
|
|
||||||
|
|
||||||
More information about LV2 plugins can be found at <http://lv2plug.in>.
|
|
||||||
|
|
||||||
More information about Lilv can be found at <http://drobilla.net/software/lilv>.
|
|
||||||
|
|
||||||
-- David Robillard <d@drobilla.net>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Lilv
|
||||||
|
====
|
||||||
|
|
||||||
|
Lilv is a C library to make the use of LV2 plugins as simple as possible for
|
||||||
|
applications.
|
||||||
|
For more information, see <http://drobilla.net/software/lilv>.
|
||||||
|
|
||||||
|
-- David Robillard <d@drobilla.net>
|
|
@ -1,62 +0,0 @@
|
||||||
%module lilv
|
|
||||||
%typedef unsigned uint32_t;
|
|
||||||
%{
|
|
||||||
#define SWIG_FILE_WITH_INIT
|
|
||||||
#include "lilv/lilv.h"
|
|
||||||
#include "lilv/lilvmm.hpp"
|
|
||||||
%}
|
|
||||||
|
|
||||||
%include "numpy.i"
|
|
||||||
%init %{
|
|
||||||
import_array();
|
|
||||||
%}
|
|
||||||
%apply (float* INPLACE_ARRAY1) {(void* data_location)}
|
|
||||||
|
|
||||||
%feature("compactdefaultargs") %{
|
|
||||||
lilv_plugin_get_num_ports_of_class;
|
|
||||||
get_num_ports_of_class;
|
|
||||||
%}
|
|
||||||
%varargs(3, LilvNode* node = NULL) lilv_plugin_get_num_ports_of_class;
|
|
||||||
%varargs(3, LilvNode* node = NULL) get_num_ports_of_class;
|
|
||||||
%typemap(in, numinputs=0) LilvNode *node3 ""; // Make sure it's NULL terminated
|
|
||||||
|
|
||||||
%include "lilv/lilv.h"
|
|
||||||
%include "lilv/lilvmm.hpp"
|
|
||||||
|
|
||||||
namespace Lilv {
|
|
||||||
|
|
||||||
%extend Plugins {
|
|
||||||
%pythoncode %{
|
|
||||||
def __iter__(self):
|
|
||||||
class Iterator(object):
|
|
||||||
def __init__(self, plugins):
|
|
||||||
self.plugins = plugins
|
|
||||||
self.iter = plugins.begin()
|
|
||||||
|
|
||||||
def next(self):
|
|
||||||
self.iter = self.plugins.next(self.iter)
|
|
||||||
if not self.plugins.is_end(self.iter):
|
|
||||||
return self.plugins.get(self.iter)
|
|
||||||
else:
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
return Iterator(self)
|
|
||||||
|
|
||||||
def get_by_uri(self, *args):
|
|
||||||
"""get_by_uri(self, LilvNode uri) -> PluginClass"""
|
|
||||||
ret = _lilv.Plugins_get_by_uri(self, *args)
|
|
||||||
if ret.me is None:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return ret
|
|
||||||
%}
|
|
||||||
};
|
|
||||||
|
|
||||||
%extend Node {
|
|
||||||
%pythoncode %{
|
|
||||||
def __str__(self):
|
|
||||||
return self.get_turtle_token()
|
|
||||||
%}
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace Lilv */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,263 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Lilv documentation build configuration file, created by
|
||||||
|
# sphinx-quickstart on Sun Sep 4 18:25:58 2016.
|
||||||
|
#
|
||||||
|
# This file is execfile()d with the current directory set to its
|
||||||
|
# containing dir.
|
||||||
|
#
|
||||||
|
# Note that not all possible configuration values are present in this
|
||||||
|
# autogenerated file.
|
||||||
|
#
|
||||||
|
# All configuration values have a default; values that are commented out
|
||||||
|
# serve to show the default.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
|
#needs_sphinx = '1.0'
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.ifconfig',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# The suffix of source filenames.
|
||||||
|
source_suffix = '.rst'
|
||||||
|
|
||||||
|
# The encoding of source files.
|
||||||
|
#source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
|
# The master toctree document.
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
# General information about the project.
|
||||||
|
project = u'Lilv'
|
||||||
|
copyright = u'2016, David Robillard'
|
||||||
|
|
||||||
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
# built documents.
|
||||||
|
#
|
||||||
|
# The short X.Y version.
|
||||||
|
version = '0.24.2'
|
||||||
|
# The full version, including alpha/beta/rc tags.
|
||||||
|
release = '0.24.2'
|
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
# for a list of supported languages.
|
||||||
|
#language = None
|
||||||
|
|
||||||
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
|
# non-false value, then it is used:
|
||||||
|
#today = ''
|
||||||
|
# Else, today_fmt is used as the format for a strftime call.
|
||||||
|
#today_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
exclude_patterns = ['_build']
|
||||||
|
|
||||||
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
|
# documents.
|
||||||
|
#default_role = None
|
||||||
|
|
||||||
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
|
#add_function_parentheses = True
|
||||||
|
|
||||||
|
# If true, the current module name will be prepended to all description
|
||||||
|
# unit titles (such as .. function::).
|
||||||
|
#add_module_names = True
|
||||||
|
|
||||||
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
|
# output. They are ignored by default.
|
||||||
|
#show_authors = False
|
||||||
|
|
||||||
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
# A list of ignored prefixes for module index sorting.
|
||||||
|
#modindex_common_prefix = []
|
||||||
|
|
||||||
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||||
|
#keep_warnings = False
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output ----------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
#html_theme = ''
|
||||||
|
|
||||||
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
|
# further. For a list of options available for each theme, see the
|
||||||
|
# documentation.
|
||||||
|
html_theme_options = { 'nosidebar': True }
|
||||||
|
|
||||||
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
|
#html_theme_path = []
|
||||||
|
|
||||||
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
|
# "<project> v<release> documentation".
|
||||||
|
#html_title = None
|
||||||
|
|
||||||
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||||
|
#html_short_title = None
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
|
# of the sidebar.
|
||||||
|
#html_logo = None
|
||||||
|
|
||||||
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
|
# pixels large.
|
||||||
|
#html_favicon = None
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['_static']
|
||||||
|
|
||||||
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
|
# directly to the root of the documentation.
|
||||||
|
#html_extra_path = []
|
||||||
|
|
||||||
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
|
# using the given strftime format.
|
||||||
|
#html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
|
||||||
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
|
# typographically correct entities.
|
||||||
|
#html_use_smartypants = True
|
||||||
|
|
||||||
|
# Custom sidebar templates, maps document names to template names.
|
||||||
|
#html_sidebars = {}
|
||||||
|
|
||||||
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
|
# template names.
|
||||||
|
#html_additional_pages = {}
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#html_domain_indices = True
|
||||||
|
|
||||||
|
# If false, no index is generated.
|
||||||
|
#html_use_index = True
|
||||||
|
|
||||||
|
# If true, the index is split into individual pages for each letter.
|
||||||
|
#html_split_index = False
|
||||||
|
|
||||||
|
# If true, links to the reST sources are added to the pages.
|
||||||
|
#html_show_sourcelink = True
|
||||||
|
|
||||||
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_sphinx = True
|
||||||
|
|
||||||
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_copyright = True
|
||||||
|
|
||||||
|
# If true, an OpenSearch description file will be output, and all pages will
|
||||||
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
|
# base URL from which the finished HTML is served.
|
||||||
|
#html_use_opensearch = ''
|
||||||
|
|
||||||
|
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||||
|
#html_file_suffix = None
|
||||||
|
|
||||||
|
# Output file base name for HTML help builder.
|
||||||
|
htmlhelp_basename = 'Lilvdoc'
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for LaTeX output ---------------------------------------------
|
||||||
|
|
||||||
|
latex_elements = {
|
||||||
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
|
#'papersize': 'letterpaper',
|
||||||
|
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
|
#'pointsize': '10pt',
|
||||||
|
|
||||||
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#'preamble': '',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
|
# (source start file, target name, title,
|
||||||
|
# author, documentclass [howto, manual, or own class]).
|
||||||
|
latex_documents = [
|
||||||
|
('index', 'Lilv.tex', u'Lilv Documentation',
|
||||||
|
u'David Robillard', 'manual'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
# the title page.
|
||||||
|
#latex_logo = None
|
||||||
|
|
||||||
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
|
# not chapters.
|
||||||
|
#latex_use_parts = False
|
||||||
|
|
||||||
|
# If true, show page references after internal links.
|
||||||
|
#latex_show_pagerefs = False
|
||||||
|
|
||||||
|
# If true, show URL addresses after external links.
|
||||||
|
#latex_show_urls = False
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#latex_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#latex_domain_indices = True
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for manual page output ---------------------------------------
|
||||||
|
|
||||||
|
# One entry per manual page. List of tuples
|
||||||
|
# (source start file, name, description, authors, manual section).
|
||||||
|
man_pages = [
|
||||||
|
('index', 'lilv', u'Lilv Documentation',
|
||||||
|
[u'David Robillard'], 1)
|
||||||
|
]
|
||||||
|
|
||||||
|
# If true, show URL addresses after external links.
|
||||||
|
#man_show_urls = False
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for Texinfo output -------------------------------------------
|
||||||
|
|
||||||
|
# Grouping the document tree into Texinfo files. List of tuples
|
||||||
|
# (source start file, target name, title, author,
|
||||||
|
# dir menu entry, description, category)
|
||||||
|
texinfo_documents = [
|
||||||
|
('index', 'Lilv', u'Lilv Documentation',
|
||||||
|
u'David Robillard', 'Lilv', 'One line description of project.',
|
||||||
|
'Miscellaneous'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#texinfo_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#texinfo_domain_indices = True
|
||||||
|
|
||||||
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||||
|
#texinfo_show_urls = 'footnote'
|
||||||
|
|
||||||
|
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||||
|
#texinfo_no_detailmenu = False
|
|
@ -0,0 +1,9 @@
|
||||||
|
Lilv Python Documentation
|
||||||
|
=========================
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
.. automodule:: lilv
|
||||||
|
:noindex:
|
||||||
|
:members:
|
File diff suppressed because it is too large
Load Diff
|
@ -41,8 +41,8 @@ class WavFile(object):
|
||||||
data = [(i - float(range/2)) / float(range/2) for i in data]
|
data = [(i - float(range/2)) / float(range/2) for i in data]
|
||||||
|
|
||||||
channels = []
|
channels = []
|
||||||
for i in xrange(self.nchannels):
|
for i in range(self.nchannels):
|
||||||
channels.append([data[j] for j in xrange(0, len(data), self.nchannels) ])
|
channels.append([data[j] for j in range(0, len(data), self.nchannels) ])
|
||||||
|
|
||||||
return channels
|
return channels
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ def main():
|
||||||
|
|
||||||
# Initialise Lilv
|
# Initialise Lilv
|
||||||
world = lilv.World()
|
world = lilv.World()
|
||||||
|
ns = world.ns
|
||||||
world.load_all()
|
world.load_all()
|
||||||
|
|
||||||
plugin_uri = sys.argv[1]
|
plugin_uri = sys.argv[1]
|
||||||
|
@ -65,19 +66,14 @@ def main():
|
||||||
|
|
||||||
# Find plugin
|
# Find plugin
|
||||||
plugin_uri_node = world.new_uri(plugin_uri)
|
plugin_uri_node = world.new_uri(plugin_uri)
|
||||||
plugin = world.get_all_plugins().get_by_uri(plugin_uri_node)
|
plugins = world.get_all_plugins()
|
||||||
if not plugin:
|
if plugin_uri_node not in plugins:
|
||||||
print("Unknown plugin `%s'\n" % plugin_uri)
|
print("Unknown plugin `%s'" % plugin_uri)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
lv2_InputPort = world.new_uri(lilv.LILV_URI_INPUT_PORT)
|
plugin = plugins[plugin_uri_node]
|
||||||
lv2_OutputPort = world.new_uri(lilv.LILV_URI_OUTPUT_PORT)
|
n_audio_in = plugin.get_num_ports_of_class(ns.lv2.InputPort, ns.lv2.AudioPort)
|
||||||
lv2_AudioPort = world.new_uri(lilv.LILV_URI_AUDIO_PORT)
|
n_audio_out = plugin.get_num_ports_of_class(ns.lv2.OutputPort, ns.lv2.AudioPort)
|
||||||
lv2_ControlPort = world.new_uri(lilv.LILV_URI_CONTROL_PORT)
|
|
||||||
lv2_default = world.new_uri("http://lv2plug.in/ns/lv2core#default")
|
|
||||||
|
|
||||||
n_audio_in = plugin.get_num_ports_of_class(lv2_InputPort, lv2_AudioPort)
|
|
||||||
n_audio_out = plugin.get_num_ports_of_class(lv2_OutputPort, lv2_AudioPort)
|
|
||||||
if n_audio_out == 0:
|
if n_audio_out == 0:
|
||||||
print("Plugin has no audio outputs\n")
|
print("Plugin has no audio outputs\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -120,22 +116,21 @@ def main():
|
||||||
control_output_buffers = []
|
control_output_buffers = []
|
||||||
for index in range(plugin.get_num_ports()):
|
for index in range(plugin.get_num_ports()):
|
||||||
port = plugin.get_port_by_index(index)
|
port = plugin.get_port_by_index(index)
|
||||||
if port.is_a(lv2_InputPort):
|
if port.is_a(ns.lv2.InputPort):
|
||||||
if port.is_a(lv2_AudioPort):
|
if port.is_a(ns.lv2.AudioPort):
|
||||||
audio_input_buffers.append(numpy.array(channels[len(audio_input_buffers)], numpy.float32))
|
audio_input_buffers.append(numpy.array(channels[len(audio_input_buffers)], numpy.float32))
|
||||||
instance.connect_port(index, audio_input_buffers[-1])
|
instance.connect_port(index, audio_input_buffers[-1])
|
||||||
elif port.is_a(lv2_ControlPort):
|
elif port.is_a(ns.lv2.ControlPort):
|
||||||
#if port.has_property(lv2_default): # Doesn't seem to work
|
default = float(port.get(ns.lv2.default))
|
||||||
default = lilv.lilv_node_as_float(lilv.lilv_nodes_get_first(port.get_value(lv2_default)))
|
|
||||||
control_input_buffers.append(numpy.array([default], numpy.float32))
|
control_input_buffers.append(numpy.array([default], numpy.float32))
|
||||||
instance.connect_port(index, control_input_buffers[-1])
|
instance.connect_port(index, control_input_buffers[-1])
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unhandled port type")
|
raise ValueError("Unhandled port type")
|
||||||
elif port.is_a(lv2_OutputPort):
|
elif port.is_a(ns.lv2.OutputPort):
|
||||||
if port.is_a(lv2_AudioPort):
|
if port.is_a(ns.lv2.AudioPort):
|
||||||
audio_output_buffers.append(numpy.array([0] * wav_in.nframes, numpy.float32))
|
audio_output_buffers.append(numpy.array([0] * wav_in.nframes, numpy.float32))
|
||||||
instance.connect_port(index, audio_output_buffers[-1])
|
instance.connect_port(index, audio_output_buffers[-1])
|
||||||
elif port.is_a(lv2_ControlPort):
|
elif port.is_a(ns.lv2.ControlPort):
|
||||||
control_output_buffers.append(numpy.array([0], numpy.float32))
|
control_output_buffers.append(numpy.array([0], numpy.float32))
|
||||||
instance.connect_port(index, control_output_buffers[-1])
|
instance.connect_port(index, control_output_buffers[-1])
|
||||||
else:
|
else:
|
||||||
|
@ -156,7 +151,7 @@ def main():
|
||||||
# Write output file in chunks to stop memory usage getting out of hand:
|
# Write output file in chunks to stop memory usage getting out of hand:
|
||||||
CHUNK_SIZE = 8192
|
CHUNK_SIZE = 8192
|
||||||
for chunk in numpy.array_split(data, CHUNK_SIZE):
|
for chunk in numpy.array_split(data, CHUNK_SIZE):
|
||||||
wav_out.writeframes(wave.struct.pack("%u%s" % (len(chunk), wav_in.struct_fmt_code), *chunk))
|
wav_out.writeframes(wave.struct.pack("%u%s" % (len(chunk), wav_in.struct_fmt_code), *chunk.astype(int)))
|
||||||
wav_out.close()
|
wav_out.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import lilv
|
||||||
|
|
||||||
|
|
||||||
|
NS_PRESETS = "http://lv2plug.in/ns/ext/presets#"
|
||||||
|
|
||||||
|
|
||||||
|
def print_presets(uri):
|
||||||
|
"""Print all presets of an LV2 plugin to stdout."""
|
||||||
|
|
||||||
|
world = lilv.World()
|
||||||
|
world.load_all()
|
||||||
|
world.ns.presets = lilv.Namespace(world, NS_PRESETS)
|
||||||
|
plugins = world.get_all_plugins()
|
||||||
|
plugin = plugins[uri]
|
||||||
|
presets = plugin.get_related(world.ns.presets.Preset)
|
||||||
|
|
||||||
|
preset_list = []
|
||||||
|
for preset in presets:
|
||||||
|
world.load_resource(preset)
|
||||||
|
labels = world.find_nodes(preset, world.ns.rdfs.label, None)
|
||||||
|
label = str(labels[0]) if len(labels) > 0 else ""
|
||||||
|
|
||||||
|
if not label:
|
||||||
|
sys.stderr.write("warning: Preset <%s> has no label\n" % preset)
|
||||||
|
|
||||||
|
preset_list.append((str(preset), str(label)))
|
||||||
|
|
||||||
|
for preset in sorted(preset_list):
|
||||||
|
print('<%s> "%s"' % preset)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.stderr.write("Usage: %s PLUGIN_URI\n" % (sys.argv[0]))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print_presets(sys.argv[1])
|
||||||
|
except ValueError as e:
|
||||||
|
sys.stderr.write("error: %s\n" % e)
|
||||||
|
except KeyError as e:
|
||||||
|
sys.stderr.write("error: %s\n" % str(e).strip("'"))
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2006-2011 David Robillard <d@drobilla.net>
|
Copyright 2006-2019 David Robillard <d@drobilla.net>
|
||||||
Copyright 2006 Steve Harris <steve@plugin.org.uk>
|
Copyright 2006 Steve Harris <steve@plugin.org.uk>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
@ -15,10 +15,6 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Include standard C headers */
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
LV2 headers are based on the URI of the specification they come from, so a
|
LV2 headers are based on the URI of the specification they come from, so a
|
||||||
consistent convention can be used even for unofficial extensions. The URI
|
consistent convention can be used even for unofficial extensions. The URI
|
||||||
|
@ -26,7 +22,11 @@
|
||||||
replacing `http:/` with `lv2` any header in the specification bundle can be
|
replacing `http:/` with `lv2` any header in the specification bundle can be
|
||||||
included, in this case `lv2.h`.
|
included, in this case `lv2.h`.
|
||||||
*/
|
*/
|
||||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
/** Include standard C headers */
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The URI is the identifier for a plugin, and how the host associates this
|
The URI is the identifier for a plugin, and how the host associates this
|
||||||
|
@ -54,7 +54,7 @@ typedef enum {
|
||||||
every instance method. In this simple plugin, only port buffers need to be
|
every instance method. In this simple plugin, only port buffers need to be
|
||||||
stored, since there is no additional instance data. */
|
stored, since there is no additional instance data. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Port buffers
|
float* buf;
|
||||||
} Test;
|
} Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,7 +179,7 @@ static const LV2_Descriptor descriptor = {
|
||||||
indices to find all the plugins defined in the library. The index is not an
|
indices to find all the plugins defined in the library. The index is not an
|
||||||
indentifier, the URI of the returned descriptor is used to determine the
|
indentifier, the URI of the returned descriptor is used to determine the
|
||||||
identify of the plugin.
|
identify of the plugin.
|
||||||
|
|
||||||
This method is in the ``discovery'' threading class, so no other functions
|
This method is in the ``discovery'' threading class, so no other functions
|
||||||
or methods in this plugin library will be called concurrently with it.
|
or methods in this plugin library will be called concurrently with it.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Lilv Bindings Test Plugin
|
# Lilv Bindings Test Plugin
|
||||||
# Copyright 2011 David Robillard <d@drobilla.net>
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
# purpose with or without fee is hereby granted, provided that the above
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -16,18 +16,27 @@
|
||||||
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
<http://example.org/lilv-bindings-test-plugin>
|
<http://example.org/lilv-bindings-test-plugin>
|
||||||
a lv2:Plugin ;
|
a lv2:Plugin ;
|
||||||
doap:name "Lilv Bindings Test" ;
|
doap:name "Lilv Bindings Test" ;
|
||||||
doap:license <http://opensource.org/licenses/isc> ;
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
ui:ui <http://example.org/lilv-bindings-test-plugin-ui> ;
|
||||||
lv2:port [
|
lv2:port [
|
||||||
a lv2:InputPort ,
|
a lv2:InputPort ,
|
||||||
lv2:ControlPort ;
|
lv2:ControlPort ;
|
||||||
lv2:index 0 ;
|
lv2:index 0 ;
|
||||||
lv2:symbol "input" ;
|
lv2:symbol "input" ;
|
||||||
lv2:name "Input"
|
lv2:name "Input" ;
|
||||||
|
lv2:default 0.5 ;
|
||||||
|
lv2:minimum 0.0 ;
|
||||||
|
lv2:maximum 1.0 ;
|
||||||
|
lv2:scalePoint [ rdfs:label "off" ; rdf:value 0.0 ] ;
|
||||||
|
lv2:scalePoint [ rdfs:label "on" ; rdf:value 1.0 ] ;
|
||||||
] , [
|
] , [
|
||||||
a lv2:OutputPort ,
|
a lv2:OutputPort ,
|
||||||
lv2:ControlPort ;
|
lv2:ControlPort ;
|
||||||
|
@ -47,3 +56,7 @@
|
||||||
lv2:symbol "audio_output" ;
|
lv2:symbol "audio_output" ;
|
||||||
lv2:name "Audio Output" ;
|
lv2:name "Audio Output" ;
|
||||||
] .
|
] .
|
||||||
|
|
||||||
|
<http://example.org/lilv-bindings-test-plugin-ui>
|
||||||
|
a ui:GtkUI ;
|
||||||
|
ui:binary <TODO> .
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Copyright 2016-2019 David Robillard <d@drobilla.net>
|
||||||
# Copyright 2013 Kaspar Emanuel <kaspar.emanuel@gmail.com>
|
# Copyright 2013 Kaspar Emanuel <kaspar.emanuel@gmail.com>
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
@ -12,73 +13,414 @@
|
||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
from lilv import *
|
import lilv
|
||||||
import unittest
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
path = os.path.abspath("bindings/bindings_test_plugin.lv2/")
|
||||||
|
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
import urllib
|
||||||
|
import urlparse
|
||||||
|
|
||||||
|
location = urlparse.urljoin("file:", urllib.pathname2url(path) + "/")
|
||||||
|
else:
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
from urllib.request import pathname2url
|
||||||
|
|
||||||
|
location = urljoin("file:", pathname2url(path) + "/")
|
||||||
|
|
||||||
|
|
||||||
|
class NodeTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
|
||||||
|
def testNodes(self):
|
||||||
|
aint = self.world.new_int(1)
|
||||||
|
aint2 = self.world.new_int(1)
|
||||||
|
aint3 = self.world.new_int(3)
|
||||||
|
afloat = self.world.new_float(2.0)
|
||||||
|
atrue = self.world.new_bool(True)
|
||||||
|
afalse = self.world.new_bool(False)
|
||||||
|
auri = self.world.new_uri("http://example.org")
|
||||||
|
afile = self.world.new_file_uri(None, "/foo/bar")
|
||||||
|
astring = self.world.new_string("hello")
|
||||||
|
self.assertEqual(auri.get_turtle_token(), "<http://example.org>")
|
||||||
|
self.assertTrue(aint.is_int())
|
||||||
|
self.assertTrue(afloat.is_float())
|
||||||
|
self.assertTrue(auri.is_uri())
|
||||||
|
self.assertTrue(astring.is_string())
|
||||||
|
self.assertTrue(astring.is_literal())
|
||||||
|
self.assertFalse(auri.is_blank())
|
||||||
|
self.assertTrue(int(aint) == 1)
|
||||||
|
self.assertTrue(float(afloat) == 2.0)
|
||||||
|
self.assertTrue(bool(atrue))
|
||||||
|
self.assertFalse(bool(afalse))
|
||||||
|
self.assertEqual(afile.get_path(), "/foo/bar")
|
||||||
|
self.assertTrue(aint == aint2)
|
||||||
|
self.assertTrue(aint != aint3)
|
||||||
|
self.assertTrue(aint != afloat)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
int(atrue)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
float(aint)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
bool(astring)
|
||||||
|
|
||||||
|
|
||||||
class UriTests(unittest.TestCase):
|
class UriTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.world = lilv_world_new()
|
self.world = lilv.World()
|
||||||
lilv_world_load_all(self.world)
|
self.world.load_all()
|
||||||
|
|
||||||
def testInvalidURI(self):
|
def testInvalidURI(self):
|
||||||
self.uri = lilv_new_uri(self.world, "invalid_uri")
|
with self.assertRaises(ValueError):
|
||||||
self.assertIsNone(self.uri)
|
self.plugin_uri = self.world.new_uri("invalid_uri")
|
||||||
def testInvalidURI2(self):
|
|
||||||
self.uri = lilv_new_uri(self.world, "invalid_uri")
|
|
||||||
self.assertFalse( lilv_node_is_uri(self.uri) )
|
|
||||||
def testNonExistentURI(self):
|
def testNonExistentURI(self):
|
||||||
self.uri = lilv_new_uri(self.world, "exist:does_not")
|
self.plugin_uri = self.world.new_uri("exist:does_not")
|
||||||
plugins = lilv_world_get_all_plugins(self.world)
|
self.plugin = self.world.get_all_plugins().get_by_uri(self.plugin_uri)
|
||||||
self.plugin = lilv_plugins_get_by_uri(plugins, self.uri)
|
self.assertEqual(self.plugin, None)
|
||||||
self.assertIsNone(self.plugin)
|
|
||||||
def testPortTypes(self):
|
def testPortTypes(self):
|
||||||
self.uri = lilv_new_uri(self.world, LILV_URI_INPUT_PORT)
|
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_INPUT_PORT))
|
||||||
self.assertIsNotNone(self.uri)
|
|
||||||
def testPortTypes2(self):
|
def testPortTypes2(self):
|
||||||
self.uri = lilv_new_uri(self.world, LILV_URI_OUTPUT_PORT)
|
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT))
|
||||||
self.assertIsNotNone(self.uri)
|
|
||||||
def testPortTypes3(self):
|
def testPortTypes3(self):
|
||||||
self.uri = lilv_new_uri(self.world, LILV_URI_AUDIO_PORT)
|
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_AUDIO_PORT))
|
||||||
self.assertIsNotNone(self.uri)
|
|
||||||
def testPortTypes4(self):
|
def testPortTypes4(self):
|
||||||
self.uri = lilv_new_uri(self.world, LILV_URI_CONTROL_PORT)
|
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_CONTROL_PORT))
|
||||||
self.assertIsNotNone(self.uri)
|
|
||||||
def tearDown(self):
|
|
||||||
lilv_node_free(self.uri)
|
class PluginClassTests(unittest.TestCase):
|
||||||
lilv_world_free(self.world)
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
|
||||||
|
def testPluginClasses(self):
|
||||||
|
pclass = self.world.get_plugin_class()
|
||||||
|
self.assertIsNotNone(pclass)
|
||||||
|
self.assertIsNone(pclass.get_parent_uri())
|
||||||
|
self.assertIsNotNone(pclass.get_uri())
|
||||||
|
self.assertIsNotNone(pclass.get_label())
|
||||||
|
self.assertEqual(str(pclass.get_uri()), str(pclass))
|
||||||
|
for i in pclass.get_children():
|
||||||
|
self.assertIsNotNone(i)
|
||||||
|
self.assertIsNotNone(i.get_uri())
|
||||||
|
self.assertIsNotNone(i.get_label())
|
||||||
|
|
||||||
|
|
||||||
|
class PluginClassesTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
self.world.load_all()
|
||||||
|
|
||||||
|
def testPluginClasses(self):
|
||||||
|
classes = self.world.get_plugin_classes()
|
||||||
|
pclass = self.world.get_plugin_class()
|
||||||
|
self.assertIsNotNone(classes)
|
||||||
|
self.assertIsNotNone(pclass)
|
||||||
|
self.assertTrue(pclass in classes)
|
||||||
|
self.assertTrue(pclass.get_uri() in classes)
|
||||||
|
self.assertGreater(len(classes), 1)
|
||||||
|
self.assertIsNotNone(classes[0])
|
||||||
|
self.assertIsNotNone(classes[pclass.get_uri()])
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
classes["http://example.org/notaclass"].get_uri()
|
||||||
|
|
||||||
|
|
||||||
|
class LoadTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
self.bundle_uri = self.world.new_uri(location)
|
||||||
|
self.world.load_specifications()
|
||||||
|
self.world.load_plugin_classes()
|
||||||
|
|
||||||
|
def testLoadUnload(self):
|
||||||
|
self.world.load_bundle(self.bundle_uri)
|
||||||
|
plugins = self.world.get_all_plugins()
|
||||||
|
plugin = plugins.get(plugins.begin())
|
||||||
|
self.world.load_resource(plugin)
|
||||||
|
self.world.unload_resource(plugin)
|
||||||
|
self.world.unload_bundle(self.bundle_uri)
|
||||||
|
|
||||||
|
|
||||||
class PluginTests(unittest.TestCase):
|
class PluginTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.world = lilv_world_new()
|
self.world = lilv.World()
|
||||||
location = "file://" + os.getcwd() + "/bindings/bindings_test_plugin.lv2/"
|
self.world.set_option(
|
||||||
self.plugin_uri = lilv_new_uri(self.world, location)
|
lilv.OPTION_FILTER_LANG, self.world.new_bool(True)
|
||||||
self.assertIsNotNone(self.plugin_uri, "Invalid URI: '" + location + "'")
|
)
|
||||||
lilv_world_load_bundle(self.world, self.plugin_uri)
|
self.bundle_uri = self.world.new_uri(location)
|
||||||
self.plugins = lilv_world_get_all_plugins(self.world)
|
self.assertIsNotNone(
|
||||||
self.plugin = lilv_plugins_get(self.plugins, lilv_plugins_begin(self.plugins))
|
self.bundle_uri, "Invalid URI: '" + location + "'"
|
||||||
self.assertIsNotNone(self.plugin, msg="Test plugin not found at location: '" + location + "'")
|
)
|
||||||
self.assertEqual(location, lilv_node_as_string(lilv_plugin_get_bundle_uri(self.plugin)))
|
self.world.load_bundle(self.bundle_uri)
|
||||||
self.instance = lilv_plugin_instantiate(self.plugin, 48000, None)
|
self.plugins = self.world.get_all_plugins()
|
||||||
self.assertIsNotNone(self.instance)
|
self.plugin = self.plugins.get(self.plugins.begin())
|
||||||
self.lv2_InputPort = lilv_new_uri(self.world, LILV_URI_INPUT_PORT)
|
self.assertTrue(self.plugin.verify())
|
||||||
self.lv2_OutputPort = lilv_new_uri(self.world, LILV_URI_OUTPUT_PORT)
|
self.assertTrue(self.plugin in self.plugins)
|
||||||
self.lv2_AudioPort = lilv_new_uri(self.world, LILV_URI_AUDIO_PORT)
|
self.assertTrue(self.plugin.get_uri() in self.plugins)
|
||||||
self.lv2_ControlPort = lilv_new_uri(self.world, LILV_URI_CONTROL_PORT)
|
self.assertEqual(self.plugins[self.plugin.get_uri()], self.plugin)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
self.plugins["http://example.org/notaplugin"].get_uri()
|
||||||
|
|
||||||
|
self.assertIsNotNone(
|
||||||
|
self.plugin,
|
||||||
|
msg="Test plugin not found at location: '" + location + "'",
|
||||||
|
)
|
||||||
|
self.assertEqual(location, str(self.plugin.get_bundle_uri()))
|
||||||
|
self.plugin_uri = self.plugin.get_uri()
|
||||||
|
self.assertEqual(
|
||||||
|
self.plugin.get_uri(), self.plugin_uri, "URI equality broken"
|
||||||
|
)
|
||||||
|
self.lv2_InputPort = self.world.new_uri(lilv.LILV_URI_INPUT_PORT)
|
||||||
|
self.lv2_OutputPort = self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT)
|
||||||
|
self.lv2_AudioPort = self.world.new_uri(lilv.LILV_URI_AUDIO_PORT)
|
||||||
|
self.lv2_ControlPort = self.world.new_uri(lilv.LILV_URI_CONTROL_PORT)
|
||||||
|
|
||||||
|
def testGetters(self):
|
||||||
|
self.assertEqual(
|
||||||
|
self.world.get_symbol(self.plugin), "lilv_bindings_test_plugin"
|
||||||
|
)
|
||||||
|
self.assertIsNotNone(self.plugin.get_bundle_uri())
|
||||||
|
self.assertGreater(len(self.plugin.get_data_uris()), 0)
|
||||||
|
self.assertIsNotNone(self.plugin.get_library_uri())
|
||||||
|
self.assertTrue(self.plugin.get_name().is_string())
|
||||||
|
self.assertTrue(self.plugin.get_class().get_uri().is_uri())
|
||||||
|
self.assertEqual(
|
||||||
|
len(self.plugin.get_value(self.world.ns.doap.license)), 1
|
||||||
|
)
|
||||||
|
licenses = self.plugin.get_value(self.world.ns.doap.license)
|
||||||
|
features = self.plugin.get_value(self.world.ns.lv2.optionalFeature)
|
||||||
|
self.assertEqual(len(licenses), 1)
|
||||||
|
self.assertTrue(licenses[0] in licenses)
|
||||||
|
with self.assertRaises(IndexError):
|
||||||
|
self.assertIsNone(licenses[len(licenses)])
|
||||||
|
self.assertEqual(
|
||||||
|
len(licenses) + len(features), len(licenses.merge(features))
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
licenses.get(licenses.begin()),
|
||||||
|
self.world.new_uri("http://opensource.org/licenses/isc"),
|
||||||
|
)
|
||||||
|
self.assertEqual(licenses[0], licenses.get(licenses.begin()))
|
||||||
|
self.assertTrue(
|
||||||
|
self.plugin.has_feature(self.world.ns.lv2.hardRTCapable)
|
||||||
|
)
|
||||||
|
self.assertEqual(len(self.plugin.get_supported_features()), 1)
|
||||||
|
self.assertEqual(len(self.plugin.get_optional_features()), 1)
|
||||||
|
self.assertEqual(len(self.plugin.get_required_features()), 0)
|
||||||
|
self.assertFalse(
|
||||||
|
self.plugin.has_extension_data(
|
||||||
|
self.world.new_uri("http://example.org/nope")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(len(self.plugin.get_extension_data()), 0)
|
||||||
|
self.assertEqual(len(self.plugin.get_extension_data()), 0)
|
||||||
|
self.assertFalse(self.plugin.has_latency())
|
||||||
|
self.assertIsNone(self.plugin.get_latency_port_index())
|
||||||
|
|
||||||
def testPorts(self):
|
def testPorts(self):
|
||||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_InputPort, self.lv2_AudioPort)
|
self.assertEqual(self.plugin.get_num_ports(), 4)
|
||||||
self.assertEqual(n, 1)
|
self.assertIsNotNone(self.plugin.get_port(0))
|
||||||
def testPorts2(self):
|
self.assertIsNotNone(self.plugin.get_port(1))
|
||||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_OutputPort, self.lv2_AudioPort)
|
self.assertIsNotNone(self.plugin.get_port(2))
|
||||||
self.assertEqual(n, 1)
|
self.assertIsNotNone(self.plugin.get_port(3))
|
||||||
def testPorts3(self):
|
self.assertIsNone(self.plugin.get_port_by_index(4))
|
||||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_OutputPort, self.lv2_ControlPort)
|
self.assertIsNotNone(self.plugin.get_port("input"))
|
||||||
self.assertEqual(n, 1)
|
self.assertIsNotNone(self.plugin.get_port("output"))
|
||||||
def testPorts4(self):
|
self.assertIsNotNone(self.plugin.get_port("audio_input"))
|
||||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_InputPort, self.lv2_ControlPort)
|
self.assertIsNotNone(self.plugin.get_port("audio_output"))
|
||||||
self.assertEqual(n, 1)
|
self.assertIsNone(self.plugin.get_port_by_symbol("nonexistent"))
|
||||||
def tearDown(self):
|
self.assertIsNone(
|
||||||
lilv_node_free(self.lv2_InputPort)
|
self.plugin.get_port_by_designation(
|
||||||
lilv_node_free(self.lv2_OutputPort)
|
self.world.ns.lv2.InputPort, self.world.ns.lv2.control
|
||||||
lilv_node_free(self.lv2_AudioPort)
|
)
|
||||||
lilv_node_free(self.plugin_uri)
|
)
|
||||||
lilv_world_free(self.world)
|
self.assertIsNone(self.plugin.get_project())
|
||||||
|
self.assertIsNone(self.plugin.get_author_name())
|
||||||
|
self.assertIsNone(self.plugin.get_author_email())
|
||||||
|
self.assertIsNone(self.plugin.get_author_homepage())
|
||||||
|
self.assertFalse(self.plugin.is_replaced())
|
||||||
|
self.assertEqual(
|
||||||
|
0,
|
||||||
|
len(
|
||||||
|
self.plugin.get_related(
|
||||||
|
self.world.new_uri("http://example.org/Type")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.plugin.get_num_ports_of_class(
|
||||||
|
self.lv2_InputPort, self.lv2_AudioPort
|
||||||
|
),
|
||||||
|
)
|
||||||
|
port = self.plugin.get_port("input")
|
||||||
|
self.assertEqual(self.world.get_symbol(port), "input")
|
||||||
|
self.assertTrue(port.get_node().is_blank())
|
||||||
|
self.assertEqual(0, port.get(self.world.ns.lv2.index))
|
||||||
|
self.assertEqual(1, len(port.get_value(self.world.ns.lv2.symbol)))
|
||||||
|
self.assertEqual(port.get_value(self.world.ns.lv2.symbol)[0], "input")
|
||||||
|
self.assertFalse(port.has_property(self.world.ns.lv2.latency))
|
||||||
|
self.assertFalse(port.supports_event(self.world.ns.midi.MidiEvent))
|
||||||
|
self.assertEqual(0, port.get_index())
|
||||||
|
self.assertEqual("input", port.get_symbol())
|
||||||
|
self.assertEqual("Input", port.get_name())
|
||||||
|
self.assertEqual(
|
||||||
|
[
|
||||||
|
str(self.world.ns.lv2.ControlPort),
|
||||||
|
str(self.world.ns.lv2.InputPort),
|
||||||
|
],
|
||||||
|
sorted(list(map(str, port.get_classes()))),
|
||||||
|
)
|
||||||
|
self.assertTrue(port.is_a(self.world.ns.lv2.ControlPort))
|
||||||
|
self.assertFalse(port.is_a(self.world.ns.lv2.AudioPort))
|
||||||
|
self.assertEqual((0.5, 0.0, 1.0), port.get_range())
|
||||||
|
self.assertEqual(0, len(port.get_properties()))
|
||||||
|
|
||||||
|
def testScalePoints(self):
|
||||||
|
port = self.plugin.get_port("input")
|
||||||
|
points = port.get_scale_points()
|
||||||
|
point_dict = {
|
||||||
|
float(points[0].get_value()): points[0].get_label(),
|
||||||
|
float(points[1].get_value()): points[1].get_label(),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(point_dict, {0.0: "off", 1.0: "on"})
|
||||||
|
|
||||||
|
def testPortCount(self):
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.plugin.get_num_ports_of_class(
|
||||||
|
self.lv2_OutputPort, self.lv2_AudioPort
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.plugin.get_num_ports_of_class(
|
||||||
|
self.lv2_OutputPort, self.lv2_ControlPort
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.plugin.get_num_ports_of_class(
|
||||||
|
self.lv2_InputPort, self.lv2_AudioPort
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
self.plugin.get_num_ports_of_class(
|
||||||
|
self.lv2_InputPort, self.lv2_ControlPort
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class QueryTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
self.world.load_all()
|
||||||
|
self.bundle_uri = self.world.new_uri(location)
|
||||||
|
self.world.load_bundle(self.bundle_uri)
|
||||||
|
self.plugins = self.world.get_all_plugins()
|
||||||
|
self.plugin = self.plugins.get(self.plugins.begin())
|
||||||
|
|
||||||
|
def testNamespaces(self):
|
||||||
|
self.assertEqual(self.world.ns.lv2, "http://lv2plug.in/ns/lv2core#")
|
||||||
|
self.assertEqual(
|
||||||
|
self.world.ns.lv2.Plugin, "http://lv2plug.in/ns/lv2core#Plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
def testQuery(self):
|
||||||
|
self.assertTrue(
|
||||||
|
self.world.ask(
|
||||||
|
None, self.world.ns.rdf.type, self.world.ns.lv2.Plugin
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertLess(
|
||||||
|
0,
|
||||||
|
len(
|
||||||
|
self.world.find_nodes(
|
||||||
|
None, self.world.ns.rdf.type, self.world.ns.lv2.Plugin
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.plugin.get_uri(),
|
||||||
|
self.world.get(
|
||||||
|
None, self.world.ns.rdf.type, self.world.ns.lv2.Plugin
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
self.bundle_uri = self.world.new_uri(location)
|
||||||
|
self.world.load_bundle(self.bundle_uri)
|
||||||
|
self.plugins = self.world.get_all_plugins()
|
||||||
|
self.plugin = self.plugins[0]
|
||||||
|
self.instance = lilv.Instance(self.plugin, 48000)
|
||||||
|
self.assertEqual(self.plugin.get_uri(), self.instance.get_uri())
|
||||||
|
self.assertIsNone(
|
||||||
|
self.instance.get_extension_data(
|
||||||
|
self.world.new_uri("http://example.org/ext")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertIsNone(
|
||||||
|
self.instance.get_extension_data("http://example.org/ext")
|
||||||
|
)
|
||||||
|
|
||||||
|
def testRun(self):
|
||||||
|
try:
|
||||||
|
import numpy
|
||||||
|
except ImportError:
|
||||||
|
sys.stderr.write("warning: Missing numpy, not testing instance\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
n_samples = 100
|
||||||
|
buf = numpy.zeros(n_samples)
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
self.instance.connect_port(0, "hello")
|
||||||
|
self.instance.connect_port(0, None)
|
||||||
|
self.instance.connect_port(0, None)
|
||||||
|
self.instance.connect_port(2, buf)
|
||||||
|
self.instance.connect_port(3, buf)
|
||||||
|
self.instance.activate()
|
||||||
|
self.instance.run(n_samples)
|
||||||
|
self.instance.deactivate()
|
||||||
|
|
||||||
|
|
||||||
|
class UITests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.world = lilv.World()
|
||||||
|
self.bundle_uri = self.world.new_uri(location)
|
||||||
|
self.world.load_bundle(self.bundle_uri)
|
||||||
|
self.plugins = self.world.get_all_plugins()
|
||||||
|
self.plugin = self.plugins[0]
|
||||||
|
|
||||||
|
def testUI(self):
|
||||||
|
uis = self.plugin.get_uis()
|
||||||
|
ui_uri = self.world.new_uri(
|
||||||
|
"http://example.org/lilv-bindings-test-plugin-ui"
|
||||||
|
)
|
||||||
|
self.assertEqual(1, len(uis))
|
||||||
|
self.assertEqual(str(uis[0]), str(ui_uri))
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
uis["http://example.org/notaui"].get_uri()
|
||||||
|
|
||||||
|
self.assertEqual(uis[0], str(ui_uri))
|
||||||
|
self.assertEqual(uis[0].get_uri(), ui_uri)
|
||||||
|
self.assertEqual(uis[0].get_bundle_uri(), self.bundle_uri)
|
||||||
|
self.assertEqual(
|
||||||
|
uis[0].get_binary_uri(), str(self.bundle_uri) + "TODO"
|
||||||
|
)
|
||||||
|
self.assertEqual(uis[uis[0].get_uri()], uis[0])
|
||||||
|
self.assertTrue(uis[0].is_a(self.world.ns.ui.GtkUI))
|
||||||
|
self.assertTrue(uis[0] in uis)
|
||||||
|
self.assertTrue(uis[0].get_uri() in uis)
|
||||||
|
self.assertEqual([self.world.ns.ui.GtkUI], list(uis[0].get_classes()))
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
# Copyright 2013 Kaspar Emanuel <kaspar.emanuel@gmail.com>
|
|
||||||
#
|
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
# purpose with or without fee is hereby granted, provided that the above
|
|
||||||
# copyright notice and this permission notice appear in all copies.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
import lilv
|
|
||||||
import unittest
|
|
||||||
import os
|
|
||||||
|
|
||||||
class UriTests(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.world = lilv.World()
|
|
||||||
self.world.load_all();
|
|
||||||
def testInvalidURI(self):
|
|
||||||
self.plugin_uri = self.world.new_uri("invalid_uri")
|
|
||||||
self.assertEqual(self.plugin_uri, None)
|
|
||||||
def testInvalidURI2(self):
|
|
||||||
self.plugin_uri = self.world.new_uri("invalid_uri")
|
|
||||||
self.assertFalse( lilv.lilv_node_is_uri(self.plugin_uri) )
|
|
||||||
def testNonExistentURI(self):
|
|
||||||
self.plugin_uri = self.world.new_uri("exist:does_not")
|
|
||||||
self.plugin = self.world.get_all_plugins().get_by_uri(self.plugin_uri)
|
|
||||||
self.assertEqual(self.plugin, None)
|
|
||||||
def testPortTypes(self):
|
|
||||||
self.assertIsNotNone( self.world.new_uri(lilv.LILV_URI_INPUT_PORT) )
|
|
||||||
def testPortTypes2(self):
|
|
||||||
self.assertIsNotNone( self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT) )
|
|
||||||
def testPortTypes3(self):
|
|
||||||
self.assertIsNotNone( self.world.new_uri(lilv.LILV_URI_AUDIO_PORT) )
|
|
||||||
def testPortTypes4(self):
|
|
||||||
self.assertIsNotNone( self.world.new_uri(lilv.LILV_URI_CONTROL_PORT) )
|
|
||||||
|
|
||||||
class PluginTests(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.world = lilv.World()
|
|
||||||
location = "file://" + os.getcwd() + "/bindings/bindings_test_plugin.lv2/"
|
|
||||||
self.plugin_uri = self.world.new_uri(location)
|
|
||||||
self.assertIsNotNone(self.plugin_uri, "Invalid URI: '" + location + "'")
|
|
||||||
self.world.load_bundle(self.plugin_uri)
|
|
||||||
self.plugins = self.world.get_all_plugins()
|
|
||||||
self.plugin = self.plugins.get(self.plugins.begin())
|
|
||||||
self.assertIsNotNone(self.plugin, msg="Test plugin not found at location: '" + location + "'")
|
|
||||||
self.assertEqual(location, self.plugin.get_bundle_uri().as_string())
|
|
||||||
self.instance = lilv.Instance(self.plugin, 48000, None)
|
|
||||||
self.assertIsNotNone(self.instance)
|
|
||||||
self.lv2_InputPort = self.world.new_uri(lilv.LILV_URI_INPUT_PORT)
|
|
||||||
self.lv2_OutputPort = self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT)
|
|
||||||
self.lv2_AudioPort = self.world.new_uri(lilv.LILV_URI_AUDIO_PORT)
|
|
||||||
self.lv2_ControlPort = self.world.new_uri(lilv.LILV_URI_CONTROL_PORT)
|
|
||||||
def testPorts(self):
|
|
||||||
n = self.plugin.get_num_ports_of_class(self.lv2_InputPort, self.lv2_AudioPort)
|
|
||||||
self.assertEqual(n, 1)
|
|
||||||
def testPorts2(self):
|
|
||||||
n = self.plugin.get_num_ports_of_class(self.lv2_OutputPort, self.lv2_AudioPort)
|
|
||||||
self.assertEqual(n, 1)
|
|
||||||
def testPorts3(self):
|
|
||||||
n = self.plugin.get_num_ports_of_class(self.lv2_OutputPort, self.lv2_ControlPort)
|
|
||||||
self.assertEqual(n, 1)
|
|
||||||
def testPorts4(self):
|
|
||||||
n = self.plugin.get_num_ports_of_class(self.lv2_InputPort, self.lv2_ControlPort)
|
|
||||||
self.assertEqual(n, 1)
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!-- HTML footer for doxygen 1.8.15-->
|
||||||
|
<!-- start footer part -->
|
||||||
|
<!--BEGIN GENERATE_TREEVIEW-->
|
||||||
|
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||||
|
<ul>
|
||||||
|
$navpath
|
||||||
|
<li class="footer">$generatedby
|
||||||
|
<a href="http://www.doxygen.org/index.html">Doxygen $doxygenversion</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--END GENERATE_TREEVIEW-->
|
||||||
|
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||||
|
<div id="footer">
|
||||||
|
<address class="footer">$generatedby
|
||||||
|
<a href="http://www.doxygen.org/">Doxygen</a> $doxygenversion
|
||||||
|
</address>
|
||||||
|
</div>
|
||||||
|
<!--END !GENERATE_TREEVIEW-->
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||||
|
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||||
|
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||||
|
$extrastylesheet
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
|
||||||
|
<!--BEGIN TITLEAREA-->
|
||||||
|
<div id="titlearea">
|
||||||
|
<div id="header">
|
||||||
|
<div id="titlebox">
|
||||||
|
<!--BEGIN PROJECT_LOGO-->
|
||||||
|
<div id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></div>
|
||||||
|
<!--END PROJECT_LOGO-->
|
||||||
|
<!--BEGIN PROJECT_NAME-->
|
||||||
|
<h1 id="title">$projectname</h1>
|
||||||
|
<!--END PROJECT_NAME-->
|
||||||
|
<!--BEGIN PROJECT_BRIEF-->
|
||||||
|
<div id="shortdesc">$projectbrief</div>
|
||||||
|
<!--END PROJECT_BRIEF-->
|
||||||
|
</div>
|
||||||
|
<div id="metabox">
|
||||||
|
<table id="meta">
|
||||||
|
<!--BEGIN PROJECT_NUMBER-->
|
||||||
|
<tr><th>Version</th><td>$projectnumber</td></tr>
|
||||||
|
<!--END PROJECT_NUMBER-->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--END TITLEAREA-->
|
||||||
|
<!-- end header part -->
|
|
@ -1,4 +1,5 @@
|
||||||
<doxygenlayout version="1.0">
|
<doxygenlayout version="1.0">
|
||||||
|
<!-- Generated by doxygen 1.8.15 -->
|
||||||
<!-- Navigation index tabs for HTML output -->
|
<!-- Navigation index tabs for HTML output -->
|
||||||
<navindex>
|
<navindex>
|
||||||
<tab type="mainpage" visible="yes" title=""/>
|
<tab type="mainpage" visible="yes" title=""/>
|
||||||
|
@ -8,17 +9,31 @@
|
||||||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||||
</tab>
|
</tab>
|
||||||
|
<tab type="interfaces" visible="yes" title="">
|
||||||
|
<tab type="interfacelist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||||
|
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
|
||||||
|
</tab>
|
||||||
<tab type="classes" visible="yes" title="">
|
<tab type="classes" visible="yes" title="">
|
||||||
<tab type="classlist" visible="yes" title="" intro=""/>
|
<tab type="classlist" visible="yes" title="" intro=""/>
|
||||||
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||||
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
||||||
<tab type="classmembers" visible="yes" title="" intro=""/>
|
<tab type="classmembers" visible="yes" title="" intro=""/>
|
||||||
</tab>
|
</tab>
|
||||||
|
<tab type="structs" visible="yes" title="">
|
||||||
|
<tab type="structlist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||||
|
</tab>
|
||||||
|
<tab type="exceptions" visible="yes" title="">
|
||||||
|
<tab type="exceptionlist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||||
|
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
|
||||||
|
</tab>
|
||||||
<tab type="files" visible="yes" title="">
|
<tab type="files" visible="yes" title="">
|
||||||
<tab type="filelist" visible="yes" title="" intro=""/>
|
<tab type="filelist" visible="yes" title="" intro=""/>
|
||||||
<tab type="globals" visible="yes" title="" intro=""/>
|
<tab type="globals" visible="yes" title="" intro=""/>
|
||||||
</tab>
|
</tab>
|
||||||
<tab type="examples" visible="yes" title="" intro=""/>
|
<tab type="examples" visible="yes" title="" intro=""/>
|
||||||
</navindex>
|
</navindex>
|
||||||
|
|
||||||
<!-- Layout definition for a class page -->
|
<!-- Layout definition for a class page -->
|
||||||
|
@ -27,10 +42,11 @@
|
||||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||||
<allmemberslink visible="yes"/>
|
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestedclasses visible="yes" title=""/>
|
<nestedclasses visible="yes" title=""/>
|
||||||
<publictypes title=""/>
|
<publictypes title=""/>
|
||||||
|
<services title=""/>
|
||||||
|
<interfaces title=""/>
|
||||||
<publicslots title=""/>
|
<publicslots title=""/>
|
||||||
<signals title=""/>
|
<signals title=""/>
|
||||||
<publicmethods title=""/>
|
<publicmethods title=""/>
|
||||||
|
@ -65,6 +81,8 @@
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
|
<services title=""/>
|
||||||
|
<interfaces title=""/>
|
||||||
<constructors title=""/>
|
<constructors title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
<related title=""/>
|
<related title=""/>
|
||||||
|
@ -72,6 +90,7 @@
|
||||||
<properties title=""/>
|
<properties title=""/>
|
||||||
<events title=""/>
|
<events title=""/>
|
||||||
</memberdef>
|
</memberdef>
|
||||||
|
<allmemberslink visible="yes"/>
|
||||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||||
<authorsection visible="yes"/>
|
<authorsection visible="yes"/>
|
||||||
</class>
|
</class>
|
||||||
|
@ -81,8 +100,14 @@
|
||||||
<briefdescription visible="yes"/>
|
<briefdescription visible="yes"/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestednamespaces visible="yes" title=""/>
|
<nestednamespaces visible="yes" title=""/>
|
||||||
|
<constantgroups visible="yes" title=""/>
|
||||||
|
<interfaces visible="yes" title=""/>
|
||||||
<classes visible="yes" title=""/>
|
<classes visible="yes" title=""/>
|
||||||
|
<structs visible="yes" title=""/>
|
||||||
|
<exceptions visible="yes" title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
|
@ -92,6 +117,8 @@
|
||||||
<memberdef>
|
<memberdef>
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
|
@ -107,10 +134,16 @@
|
||||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||||
<sourcelink visible="yes"/>
|
<sourcelink visible="yes"/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
|
<interfaces visible="yes" title=""/>
|
||||||
<classes visible="yes" title=""/>
|
<classes visible="yes" title=""/>
|
||||||
|
<structs visible="yes" title=""/>
|
||||||
|
<exceptions visible="yes" title=""/>
|
||||||
<namespaces visible="yes" title=""/>
|
<namespaces visible="yes" title=""/>
|
||||||
|
<constantgroups visible="yes" title=""/>
|
||||||
<defines title=""/>
|
<defines title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
|
@ -121,6 +154,8 @@
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<defines title=""/>
|
<defines title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
<variables title=""/>
|
<variables title=""/>
|
||||||
|
@ -130,9 +165,9 @@
|
||||||
|
|
||||||
<!-- Layout definition for a group page -->
|
<!-- Layout definition for a group page -->
|
||||||
<group>
|
<group>
|
||||||
<briefdescription visible="no"/>
|
<briefdescription visible="yes"/>
|
||||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
|
||||||
<detaileddescription title=""/>
|
<detaileddescription title=""/>
|
||||||
|
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||||
<memberdecl>
|
<memberdecl>
|
||||||
<nestedgroups visible="yes" title=""/>
|
<nestedgroups visible="yes" title=""/>
|
||||||
<dirs visible="yes" title=""/>
|
<dirs visible="yes" title=""/>
|
||||||
|
@ -141,6 +176,8 @@
|
||||||
<classes visible="yes" title=""/>
|
<classes visible="yes" title=""/>
|
||||||
<defines title=""/>
|
<defines title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<enumvalues title=""/>
|
<enumvalues title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
|
@ -159,6 +196,8 @@
|
||||||
<inlineclasses title=""/>
|
<inlineclasses title=""/>
|
||||||
<defines title=""/>
|
<defines title=""/>
|
||||||
<typedefs title=""/>
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
<enums title=""/>
|
<enums title=""/>
|
||||||
<enumvalues title=""/>
|
<enumvalues title=""/>
|
||||||
<functions title=""/>
|
<functions title=""/>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
.TH LV2APPLY 1 "05 Sep 2016"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
.B lv2apply \- apply an LV2 plugin to an audio file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B lv2apply [OPTION]... PLUGIN_URI
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-i IN_FILE\fR
|
||||||
|
Input file
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-o OUT_FILE\fR
|
||||||
|
Output file
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-c SYM VAL\fR
|
||||||
|
Set control port SYM to VAL
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-help\fR
|
||||||
|
Display help and exit
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-version\fR
|
||||||
|
Display version information and exit
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR lv2ls(1)
|
||||||
|
.BR lv2info(1)
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
lv2apply was written by David Robillard <d@drobilla.net>
|
|
@ -1,17 +1,17 @@
|
||||||
.TH LV2INFO 1 "8 Jan 2012"
|
.TH LV2INFO 1 "05 Sep 2016"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.B lv2info \- print information about an installed LV2 plugin.
|
.B lv2info \- print information about an installed LV2 plugin
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B lv2info PLUGIN_URI
|
.B lv2info PLUGIN_URI
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
\fB\-p FILE
|
\fB\-p FILE\fR
|
||||||
Write Turtle description of plugin to FILE
|
Write Turtle description of plugin to FILE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-m FILE
|
\fB\-m FILE\fR
|
||||||
Add record of plugin to manifest FILE
|
Add record of plugin to manifest FILE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
@ -22,7 +22,7 @@ Display help and exit
|
||||||
\fB\-\-version\fR
|
\fB\-\-version\fR
|
||||||
Display version information and exit
|
Display version information and exit
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH "SEE ALSO"
|
||||||
.BR lilv(3),
|
.BR lilv(3),
|
||||||
.BR lv2ls(1)
|
.BR lv2ls(1)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.TH LV2LS 1 "17 Jan 2012"
|
.TH LV2LS 1 "26 Aug 2016"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.B lv2ls \- List all installed LV2 plugins.
|
.B lv2ls \- list all installed LV2 plugins
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B lv2ls [OPTION]...
|
.B lv2ls [OPTION]...
|
||||||
|
@ -19,7 +19,7 @@ Display help and exit
|
||||||
\fB\-\-version\fR
|
\fB\-\-version\fR
|
||||||
Display version information and exit
|
Display version information and exit
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH "SEE ALSO"
|
||||||
.BR lilv(3),
|
.BR lilv(3),
|
||||||
.BR lv2info(1)
|
.BR lv2info(1)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Lilv is a C library to make the use of [LV2] plugins as simple as possible for
|
||||||
|
applications.
|
||||||
|
|
||||||
|
The complete API is documented in the [lilv](@ref lilv) group.
|
||||||
|
|
||||||
|
[LV2]: http://lv2plug.in/
|
File diff suppressed because it is too large
Load Diff
|
@ -1,83 +1,113 @@
|
||||||
body {
|
body {
|
||||||
font-size: medium;
|
background: #FFF;
|
||||||
font-family: sans-serif;
|
color: #222;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 1.6em;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 1em;
|
||||||
|
max-width: 60em;
|
||||||
|
font-family: "DejaVu Serif",Palatino,serif;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
#top {
|
h1, .title, #projectname, h2, h3, h4, h5, h6 {
|
||||||
background-color: #F3F3F3;
|
line-height: 1.0125em;
|
||||||
|
color: #444;
|
||||||
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
|
margin: 1em 0 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, .titlearea .header .titlebox, #projectname {
|
||||||
|
font-size: 300%;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .headertitle .title {
|
||||||
|
font-size: 180%;
|
||||||
|
font-weight: 400;
|
||||||
|
margin: 0.75em 0.25em 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ingroups {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.title .ingroups a {
|
||||||
|
font-size: small;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#titlebox, #metabox {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#titlebox{
|
||||||
|
display: inline-block;
|
||||||
|
width: 75%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#shortdesc {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
color: #666;
|
||||||
border-bottom: 1px solid #DDD;
|
display: inline-block;
|
||||||
margin-bottom: 1ex;
|
font-style: italic;
|
||||||
font-size: xx-large;
|
padding: 0;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header {
|
#titlearea {
|
||||||
display: none;
|
margin: 0.25em auto 0.25em auto;
|
||||||
}
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
.tabs {
|
clear: both;
|
||||||
display: none;
|
line-height: 1.0em;
|
||||||
}
|
|
||||||
|
|
||||||
h1 h2 h3 h4 h5 h6 {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 164%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 132%;
|
font-size: 160%;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 124%;
|
font-size: 140%;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: 116%;
|
font-size: 120%;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5, h6 {
|
||||||
font-size: 108%;
|
font-size: 110%;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h1 a, h1 a:link, h1 a:visited ,
|
||||||
font-size: 100%;
|
h2 a, h2 a:link, h2 a:visited ,
|
||||||
|
h3 a, h3 a:link, h3 a:visited ,
|
||||||
|
h4 a, h4 a:link, h4 a:visited ,
|
||||||
|
h5 a, h5 a:link, h5 a:visited ,
|
||||||
|
h6 a, h6 a:link, h6 a:visited {
|
||||||
|
color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0 0 1ex 0;
|
margin: 0.5em 0 0.5em 0;
|
||||||
}
|
|
||||||
|
|
||||||
br {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dt {
|
dt {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.multicol {
|
dd {
|
||||||
}
|
margin-left: 2em;
|
||||||
|
|
||||||
p.startli,p.startdd,p.starttd {
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.endli {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.enddd {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.endtd {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
caption {
|
caption {
|
||||||
|
@ -85,12 +115,12 @@ caption {
|
||||||
}
|
}
|
||||||
|
|
||||||
span.legend {
|
span.legend {
|
||||||
font-size: 70%;
|
font-size: small;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3.version {
|
h3.version {
|
||||||
font-size: 90%;
|
font-size: small;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,23 +132,18 @@ div.qindex,div.navtab {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.qindex,div.navpath {
|
|
||||||
width: 100%;
|
|
||||||
line-height: 140%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navtab {
|
div.navtab {
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @group Link Styling */
|
/* @group Link Styling */
|
||||||
a {
|
a {
|
||||||
color: #3D8C57;
|
color: #546E00;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contents a:visited {
|
.contents a:visited {
|
||||||
color: #50755E;
|
color: #344E00;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
|
@ -131,12 +156,8 @@ a.qindexHL {
|
||||||
border: 1px double #869DCA;
|
border: 1px double #869DCA;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.code {
|
code {
|
||||||
color: #4665A2;
|
color: #444;
|
||||||
}
|
|
||||||
|
|
||||||
a.codeRef {
|
|
||||||
color: #4665A2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @end */
|
/* @end */
|
||||||
|
@ -145,18 +166,14 @@ dl.el {
|
||||||
}
|
}
|
||||||
|
|
||||||
.fragment {
|
.fragment {
|
||||||
font-family: monospace, fixed;
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
font-size: 105%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre.fragment {
|
pre.fragment {
|
||||||
border: 1px solid #C4C4C4;
|
border: 1px solid #C4C4C4;
|
||||||
background-color: #F9F9F9;
|
background-color: #F9F9F9;
|
||||||
padding: 4px 6px;
|
padding: 0.5em;
|
||||||
margin: 4px 8px 4px 2px;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 9pt;
|
|
||||||
line-height: 125%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.ah {
|
div.ah {
|
||||||
|
@ -176,21 +193,20 @@ div.groupHeader {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a + h2.groupheader {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
div.groupText {
|
div.groupText {
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
div.contents, #content {
|
||||||
background: #FFF;
|
padding: 0 0.25em 0 0.25em;
|
||||||
color: #000;
|
max-width: 60em;
|
||||||
margin: 0;
|
margin-left: auto;
|
||||||
}
|
margin-right: auto;
|
||||||
|
|
||||||
div.contents {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td.indexkey {
|
td.indexkey {
|
||||||
|
@ -208,6 +224,10 @@ td.indexvalue {
|
||||||
margin: 2px 0;
|
margin: 2px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.memname {
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
}
|
||||||
|
|
||||||
tr.memlist {
|
tr.memlist {
|
||||||
background-color: #EEF1F7;
|
background-color: #EEF1F7;
|
||||||
}
|
}
|
||||||
|
@ -216,9 +236,6 @@ p.formulaDsp {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.formulaDsp {
|
|
||||||
}
|
|
||||||
|
|
||||||
img.formulaInl {
|
img.formulaInl {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
@ -236,7 +253,6 @@ div.center img {
|
||||||
|
|
||||||
address.footer {
|
address.footer {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 0 0.25em 0.25em 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
img.footer {
|
img.footer {
|
||||||
|
@ -246,48 +262,36 @@ img.footer {
|
||||||
|
|
||||||
/* @group Code Colorization */
|
/* @group Code Colorization */
|
||||||
span.keyword {
|
span.keyword {
|
||||||
color: green;
|
color: #586E75;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.keywordtype {
|
span.keywordtype {
|
||||||
color: #604020;
|
color: #546E00;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.keywordflow {
|
span.keywordflow {
|
||||||
color: #e08000;
|
color: #586E75;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.comment {
|
span.comment {
|
||||||
color: maroon;
|
color: #6C71C4;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.preprocessor {
|
span.preprocessor {
|
||||||
color: #806020;
|
color: #D33682;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.stringliteral {
|
span.stringliteral {
|
||||||
color: #002080;
|
color: #CB4B16;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.charliteral {
|
span.charliteral {
|
||||||
color: teal;
|
color: #CB4B16;
|
||||||
}
|
|
||||||
|
|
||||||
span.vhdldigit {
|
|
||||||
color: #F0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.vhdlkeyword {
|
|
||||||
color: #700070;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.vhdllogic {
|
|
||||||
color: red;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @end */
|
/* @end */
|
||||||
td.tiny {
|
td.tiny {
|
||||||
font-size: 75%;
|
font-size: x-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dirtab {
|
.dirtab {
|
||||||
|
@ -308,20 +312,25 @@ hr {
|
||||||
margin: 2em 0 1em;
|
margin: 2em 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr.footer {
|
#footer {
|
||||||
height: 1px;
|
bottom: 0;
|
||||||
|
clear: both;
|
||||||
|
font-size: x-small;
|
||||||
|
margin: 2em 0 0;
|
||||||
|
padding: 0 1em 1em 1em;
|
||||||
|
vertical-align: top;
|
||||||
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @group Member Descriptions */
|
/* @group Member Descriptions */
|
||||||
table.memberdecls {
|
table.memberdecls {
|
||||||
border-spacing: 0;
|
border-spacing: 0.125em;
|
||||||
font-size: small;
|
line-height: 1.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams {
|
.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams {
|
||||||
background-color: #FBFBFB;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.25ex;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdescLeft,.mdescRight {
|
.mdescLeft,.mdescRight {
|
||||||
|
@ -329,12 +338,18 @@ table.memberdecls {
|
||||||
}
|
}
|
||||||
|
|
||||||
.memItemLeft,.memItemRight,.memTemplParams {
|
.memItemLeft,.memItemRight,.memTemplParams {
|
||||||
border-top: 1px solid #DDD;
|
border: 0;
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.memItemLeft,.memTemplItemLeft {
|
.memItemLeft,.memTemplItemLeft {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memItemLeft a.el {
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.memTemplParams {
|
.memTemplParams {
|
||||||
|
@ -342,18 +357,33 @@ table.memberdecls {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.memSeparator {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.mlabels-right {
|
||||||
|
vertical-align: top;
|
||||||
|
padding-top: 4px;
|
||||||
|
color: #B4C342;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memtitle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* @end */
|
/* @end */
|
||||||
/* @group Member Details */
|
/* @group Member Details */
|
||||||
/* Styles for detailed member documentation */
|
/* Styles for detailed member documentation */
|
||||||
.memtemplate {
|
.memtemplate {
|
||||||
font-size: 80%;
|
color: #888;
|
||||||
color: #4665A2;
|
font-style: italic;
|
||||||
font-weight: bold;
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.memnav {
|
.memnav {
|
||||||
background-color: #EBEFF6;
|
background-color: #EEE;
|
||||||
border: 1px solid #A3B4D7;
|
border: 1px solid #B4C342;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
|
@ -361,27 +391,25 @@ table.memberdecls {
|
||||||
}
|
}
|
||||||
|
|
||||||
.memitem {
|
.memitem {
|
||||||
padding: 0;
|
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||||
margin: 1ex 0 2ex 0;
|
margin: 0 0 1em 0;
|
||||||
border: 1px solid #CCC;
|
border-radius: 6px;
|
||||||
}
|
border: 1px solid #DDD;
|
||||||
|
|
||||||
.memname {
|
|
||||||
white-space: nowrap;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.memproto {
|
.memproto {
|
||||||
border-bottom: 1px solid #DDD;
|
font-size: 110%;
|
||||||
padding: 0.5ex;
|
font-weight: 400;
|
||||||
font-weight: bold;
|
line-height: 1em;
|
||||||
background-color: #F3F3F3;
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memproto .paramname {
|
||||||
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.memdoc {
|
.memdoc {
|
||||||
padding: 1ex;
|
padding: 0 0.25em 0 0.25em;
|
||||||
background-color: #FBFBFB;
|
|
||||||
border-top-width: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.paramkey {
|
.paramkey {
|
||||||
|
@ -389,16 +417,54 @@ table.memberdecls {
|
||||||
}
|
}
|
||||||
|
|
||||||
.paramtype {
|
.paramtype {
|
||||||
|
color: #666;
|
||||||
|
padding-right: 0.5em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paramname {
|
.paramname {
|
||||||
color: #602020;
|
color: #111;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
font-style: italic;
|
||||||
|
padding-right: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paramname em {
|
.fieldname {
|
||||||
font-style: normal;
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fieldtable {
|
||||||
|
padding-top: 0.25em;
|
||||||
|
border-top: 1px dashed #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fieldtable tbody tr:first-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.fieldname {
|
||||||
|
padding: 0 0.5em 0 0.25em;
|
||||||
|
vertical-align: top;
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.fieldtype {
|
||||||
|
color: #666;
|
||||||
|
padding: 0 0.5em 0 0;
|
||||||
|
vertical-align: top;
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.fielddoc p {
|
||||||
|
margin: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0 0.5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.reference {
|
||||||
|
font-size: x-small;
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @end */
|
/* @end */
|
||||||
|
@ -411,9 +477,8 @@ table.memberdecls {
|
||||||
|
|
||||||
/* these are for tree view when used as main index */
|
/* these are for tree view when used as main index */
|
||||||
.directory {
|
.directory {
|
||||||
font-size: 9pt;
|
font-size: small;
|
||||||
font-weight: bold;
|
margin: 0.5em;
|
||||||
margin: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.directory h3 {
|
.directory h3 {
|
||||||
|
@ -440,6 +505,22 @@ table.memberdecls {
|
||||||
vertical-align: -30%;
|
vertical-align: -30%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.entry {
|
||||||
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.entry .arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.entry b {
|
||||||
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 130%;
|
||||||
|
}
|
||||||
|
|
||||||
/* these are for tree view when not used as main index */
|
/* these are for tree view when not used as main index */
|
||||||
.directory-alt {
|
.directory-alt {
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
|
@ -477,12 +558,12 @@ div.dynheader {
|
||||||
|
|
||||||
address {
|
address {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
color: #2A3D61;
|
color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.doxtable {
|
table.doxtable {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 0.5ex;
|
margin: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.doxtable td,table.doxtable th {
|
table.doxtable td,table.doxtable th {
|
||||||
|
@ -508,56 +589,151 @@ table.doxtable th {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.navpath {
|
||||||
|
color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
.navpath ul {
|
.navpath ul {
|
||||||
font-size: 11px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #8AA0CC;
|
|
||||||
border: 1px solid #C2CDE4;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navpath li {
|
.navpath li {
|
||||||
list-style-type: none;
|
|
||||||
float: left;
|
float: left;
|
||||||
padding-left: 10px;
|
padding-left: 0;
|
||||||
padding-right: 15px;
|
margin-left: 0.5em;
|
||||||
color: #364D7C;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navpath a {
|
.navpath a {
|
||||||
height: 32px;
|
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navpath a:hover {
|
|
||||||
color: #6884BD;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.summary {
|
div.summary {
|
||||||
float: right;
|
font-size: small;
|
||||||
font-size: 8pt;
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
padding-right: 5px;
|
margin: 0;
|
||||||
width: 50%;
|
color: #FFF; /* Hide separator bars */
|
||||||
text-align: right;
|
border-bottom: 1px solid #DDD;
|
||||||
|
padding: 0.25em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.summary a {
|
div.summary a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.header {
|
/* Metadata box (right aligned next to title) */
|
||||||
background-color: #F3F3F3;
|
|
||||||
margin: 0;
|
#metabox {
|
||||||
border-bottom: 1px solid #DDD;
|
display: inline-block;
|
||||||
|
font-size: x-small;
|
||||||
|
margin: 0 0 0.25em 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
color: #666;
|
||||||
|
font-style: italic;
|
||||||
|
padding: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.headertitle {
|
#meta {
|
||||||
padding: 5px 5px 5px 10px;
|
border-style: hidden;
|
||||||
font-size: 180%;
|
margin-right: 0.25em;
|
||||||
font-weight: bold;
|
}
|
||||||
|
|
||||||
|
#meta tr, #meta th, #meta td {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#meta th {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#meta th:after {
|
||||||
|
content: ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
div.line {
|
||||||
|
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||||
|
line-height: 1.4em;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glow {
|
||||||
|
background-color: #2AA198;
|
||||||
|
box-shadow: 0 0 10px #2AA198;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.lineno {
|
||||||
|
padding-right: 4px;
|
||||||
|
text-align: right;
|
||||||
|
border-right: 2px solid #546E00;
|
||||||
|
background-color: #E8E8E8;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
span.lineno a {
|
||||||
|
background-color: #D8D8D8;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.lineno a:hover {
|
||||||
|
background-color: #C8C8C8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs, .tabs2, .navpath {
|
||||||
|
padding: 0.25em 0;
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
font-size: small;
|
||||||
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
font-size: 110%;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mlabel {
|
||||||
|
padding: 0.125em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tabs*/
|
||||||
|
|
||||||
|
.tablist {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tablist li {
|
||||||
|
display: table-cell;
|
||||||
|
line-height: 2em;
|
||||||
|
list-style: none;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tablist a {
|
||||||
|
display: block;
|
||||||
|
padding: 0 1em 0 0;
|
||||||
|
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs3 .tablist a {
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tablist li.current a {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.icon {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ includedir=@INCLUDEDIR@
|
||||||
Name: Lilv
|
Name: Lilv
|
||||||
Version: @LILV_VERSION@
|
Version: @LILV_VERSION@
|
||||||
Description: Simple C library for hosting LV2 plugins
|
Description: Simple C library for hosting LV2 plugins
|
||||||
Requires: lv2 @PKG_serd_0@ @PKG_sord_0@ @PKG_sratom_0@
|
Requires: @LILV_PKG_DEPS@
|
||||||
Libs: -L${libdir} -l@LIB_LILV@ -ldl
|
Libs: -L${libdir} -l@LIB_LILV@ @LILV_PKG_LIBS@
|
||||||
Cflags: -I${includedir}/lilv-@LILV_MAJOR_VERSION@
|
Cflags: -I${includedir}/lilv-@LILV_MAJOR_VERSION@
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -21,14 +21,15 @@
|
||||||
#ifndef LILV_LILV_H
|
#ifndef LILV_LILV_H
|
||||||
#define LILV_LILV_H
|
#define LILV_LILV_H
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#include "lv2/urid/urid.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
|
||||||
|
|
||||||
#ifdef LILV_SHARED
|
#ifdef LILV_SHARED
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
# define LILV_LIB_IMPORT __declspec(dllimport)
|
# define LILV_LIB_IMPORT __declspec(dllimport)
|
||||||
|
@ -45,11 +46,15 @@
|
||||||
#else
|
#else
|
||||||
# define LILV_API
|
# define LILV_API
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ > 3 || \
|
||||||
|
(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||||
|
# define LILV_DEPRECATED __attribute__((__deprecated__))
|
||||||
|
#else
|
||||||
|
# define LILV_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#else
|
|
||||||
# include <stdbool.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LILV_NS_DOAP "http://usefulinc.com/ns/doap#"
|
#define LILV_NS_DOAP "http://usefulinc.com/ns/doap#"
|
||||||
|
@ -61,8 +66,10 @@ extern "C" {
|
||||||
#define LILV_NS_RDFS "http://www.w3.org/2000/01/rdf-schema#"
|
#define LILV_NS_RDFS "http://www.w3.org/2000/01/rdf-schema#"
|
||||||
#define LILV_NS_XSD "http://www.w3.org/2001/XMLSchema#"
|
#define LILV_NS_XSD "http://www.w3.org/2001/XMLSchema#"
|
||||||
|
|
||||||
|
#define LILV_URI_ATOM_PORT "http://lv2plug.in/ns/ext/atom#AtomPort"
|
||||||
#define LILV_URI_AUDIO_PORT "http://lv2plug.in/ns/lv2core#AudioPort"
|
#define LILV_URI_AUDIO_PORT "http://lv2plug.in/ns/lv2core#AudioPort"
|
||||||
#define LILV_URI_CONTROL_PORT "http://lv2plug.in/ns/lv2core#ControlPort"
|
#define LILV_URI_CONTROL_PORT "http://lv2plug.in/ns/lv2core#ControlPort"
|
||||||
|
#define LILV_URI_CV_PORT "http://lv2plug.in/ns/lv2core#CVPort"
|
||||||
#define LILV_URI_EVENT_PORT "http://lv2plug.in/ns/ext/event#EventPort"
|
#define LILV_URI_EVENT_PORT "http://lv2plug.in/ns/ext/event#EventPort"
|
||||||
#define LILV_URI_INPUT_PORT "http://lv2plug.in/ns/lv2core#InputPort"
|
#define LILV_URI_INPUT_PORT "http://lv2plug.in/ns/lv2core#InputPort"
|
||||||
#define LILV_URI_MIDI_EVENT "http://lv2plug.in/ns/ext/midi#MidiEvent"
|
#define LILV_URI_MIDI_EVENT "http://lv2plug.in/ns/ext/midi#MidiEvent"
|
||||||
|
@ -95,6 +102,16 @@ typedef void LilvNodes; /**< set<Node>. */
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free memory allocated by Lilv.
|
||||||
|
|
||||||
|
This function exists because some systems require memory allocated by a
|
||||||
|
library to be freed by code in the same library. It is otherwise equivalent
|
||||||
|
to the standard C free() function.
|
||||||
|
*/
|
||||||
|
LILV_API void
|
||||||
|
lilv_free(void* ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name Node
|
@name Node
|
||||||
@{
|
@{
|
||||||
|
@ -104,11 +121,24 @@ typedef void LilvNodes; /**< set<Node>. */
|
||||||
Convert a file URI string to a local path string.
|
Convert a file URI string to a local path string.
|
||||||
For example, "file://foo/bar/baz.ttl" returns "/foo/bar/baz.ttl".
|
For example, "file://foo/bar/baz.ttl" returns "/foo/bar/baz.ttl".
|
||||||
Return value is shared and must not be deleted by caller.
|
Return value is shared and must not be deleted by caller.
|
||||||
|
This function does not handle escaping correctly and should not be used for
|
||||||
|
general file URIs. Use lilv_file_uri_parse() instead.
|
||||||
@return `uri` converted to a path, or NULL on failure (URI is not local).
|
@return `uri` converted to a path, or NULL on failure (URI is not local).
|
||||||
*/
|
*/
|
||||||
LILV_API const char*
|
LILV_API LILV_DEPRECATED const char*
|
||||||
lilv_uri_to_path(const char* uri);
|
lilv_uri_to_path(const char* uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a file URI string to a local path string.
|
||||||
|
For example, "file://foo/bar%20one/baz.ttl" returns "/foo/bar one/baz.ttl".
|
||||||
|
Return value must be freed by caller with lilv_free().
|
||||||
|
@param uri The file URI to parse.
|
||||||
|
@param hostname If non-NULL, set to the hostname in the URI, if any.
|
||||||
|
@return `uri` converted to a path, or NULL on failure (URI is not local).
|
||||||
|
*/
|
||||||
|
LILV_API char*
|
||||||
|
lilv_file_uri_parse(const char* uri, char** hostname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a new URI value.
|
Create a new URI value.
|
||||||
Returned value must be freed by caller with lilv_node_free().
|
Returned value must be freed by caller with lilv_node_free().
|
||||||
|
@ -178,15 +208,15 @@ lilv_node_equals(const LilvNode* value, const LilvNode* other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return this value as a Turtle/SPARQL token.
|
Return this value as a Turtle/SPARQL token.
|
||||||
Returned value must be freed by caller with free().
|
Returned value must be freed by caller with lilv_free().
|
||||||
<table>
|
<table>
|
||||||
<caption>Example Turtle Tokens</caption>
|
<caption>Example Turtle Tokens</caption>
|
||||||
<tr><th>URI</th><td><http://example.org/foo ></td></tr>
|
<tr><th>URI</th><td><http://example.org/foo ></td></tr>
|
||||||
<tr><th>QName</td><td>doap:name</td></tr>
|
<tr><th>QName</th><td>doap:name</td></tr>
|
||||||
<tr><th>String</td><td>"this is a string"</td></tr>
|
<tr><th>String</th><td>"this is a string"</td></tr>
|
||||||
<tr><th>Float</td><td>1.0</td></tr>
|
<tr><th>Float</th><td>1.0</td></tr>
|
||||||
<tr><th>Integer</td><td>1</td></tr>
|
<tr><th>Integer</th><td>1</td></tr>
|
||||||
<tr><th>Boolean</td><td>true</td></tr>
|
<tr><th>Boolean</th><td>true</td></tr>
|
||||||
</table>
|
</table>
|
||||||
*/
|
*/
|
||||||
LILV_API char*
|
LILV_API char*
|
||||||
|
@ -240,6 +270,14 @@ lilv_node_is_string(const LilvNode* value);
|
||||||
LILV_API const char*
|
LILV_API const char*
|
||||||
lilv_node_as_string(const LilvNode* value);
|
lilv_node_as_string(const LilvNode* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the path of a file URI node.
|
||||||
|
Returns NULL if `value` is not a file URI.
|
||||||
|
Returned value must be freed by caller with lilv_free().
|
||||||
|
*/
|
||||||
|
LILV_API char*
|
||||||
|
lilv_node_get_path(const LilvNode* value, char** hostname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return whether this value is a decimal literal.
|
Return whether this value is a decimal literal.
|
||||||
*/
|
*/
|
||||||
|
@ -314,7 +352,7 @@ lilv_node_as_bool(const LilvNode* value);
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define LILV_FOREACH(colltype, iter, collection) \
|
#define LILV_FOREACH(colltype, iter, collection) \
|
||||||
for (LilvIter* (iter) = lilv_ ## colltype ## _begin(collection); \
|
for (LilvIter* iter = lilv_ ## colltype ## _begin(collection); \
|
||||||
!lilv_ ## colltype ## _is_end(collection, iter); \
|
!lilv_ ## colltype ## _is_end(collection, iter); \
|
||||||
(iter) = lilv_ ## colltype ## _next(collection, iter))
|
(iter) = lilv_ ## colltype ## _next(collection, iter))
|
||||||
|
|
||||||
|
@ -425,7 +463,7 @@ lilv_nodes_get_first(const LilvNodes* collection);
|
||||||
Return whether `values` contains `value`.
|
Return whether `values` contains `value`.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_nodes_contains(const LilvNodes* values, const LilvNode* value);
|
lilv_nodes_contains(const LilvNodes* nodes, const LilvNode* value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return a new LilvNodes that contains all nodes from both `a` and `b`.
|
Return a new LilvNodes that contains all nodes from both `a` and `b`.
|
||||||
|
@ -492,12 +530,20 @@ lilv_world_new(void);
|
||||||
*/
|
*/
|
||||||
#define LILV_OPTION_DYN_MANIFEST "http://drobilla.net/ns/lilv#dyn-manifest"
|
#define LILV_OPTION_DYN_MANIFEST "http://drobilla.net/ns/lilv#dyn-manifest"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set application-specific LV2_PATH. This overrides the LV2_PATH from the
|
||||||
|
environment, so that lilv will only look inside the given path. This can be
|
||||||
|
used to make self-contained applications.
|
||||||
|
*/
|
||||||
|
#define LILV_OPTION_LV2_PATH "http://drobilla.net/ns/lilv#lv2-path"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set an option option for `world`.
|
Set an option option for `world`.
|
||||||
|
|
||||||
Currently recognized options:
|
Currently recognized options:
|
||||||
@ref LILV_OPTION_FILTER_LANG
|
@ref LILV_OPTION_FILTER_LANG
|
||||||
@ref LILV_OPTION_DYN_MANIFEST
|
@ref LILV_OPTION_DYN_MANIFEST
|
||||||
|
@ref LILV_OPTION_LV2_PATH
|
||||||
*/
|
*/
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_world_set_option(LilvWorld* world,
|
lilv_world_set_option(LilvWorld* world,
|
||||||
|
@ -533,7 +579,7 @@ lilv_world_load_all(LilvWorld* world);
|
||||||
`bundle_uri` must be a fully qualified URI to the bundle directory,
|
`bundle_uri` must be a fully qualified URI to the bundle directory,
|
||||||
with the trailing slash, eg. file:///usr/lib/lv2/foo.lv2/
|
with the trailing slash, eg. file:///usr/lib/lv2/foo.lv2/
|
||||||
|
|
||||||
Normal hosts should not need this function (use lilv_world_load_all).
|
Normal hosts should not need this function (use lilv_world_load_all()).
|
||||||
|
|
||||||
Hosts MUST NOT attach any long-term significance to bundle paths
|
Hosts MUST NOT attach any long-term significance to bundle paths
|
||||||
(e.g. in save files), since there are no guarantees they will remain
|
(e.g. in save files), since there are no guarantees they will remain
|
||||||
|
@ -541,19 +587,39 @@ lilv_world_load_all(LilvWorld* world);
|
||||||
other things) MUST be identified by URIs (not paths) in save files.
|
other things) MUST be identified by URIs (not paths) in save files.
|
||||||
*/
|
*/
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_world_load_bundle(LilvWorld* world,
|
lilv_world_load_bundle(LilvWorld* world,
|
||||||
LilvNode* bundle_uri);
|
const LilvNode* bundle_uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Load all specifications from currently loaded bundles.
|
||||||
|
|
||||||
|
This is for hosts that explicitly load specific bundles, its use is not
|
||||||
|
necessary when using lilv_world_load_all(). This function parses the
|
||||||
|
specifications and adds them to the model.
|
||||||
|
*/
|
||||||
|
LILV_API void
|
||||||
|
lilv_world_load_specifications(LilvWorld* world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Load all plugin classes from currently loaded specifications.
|
||||||
|
|
||||||
|
Must be called after lilv_world_load_specifications(). This is for hosts
|
||||||
|
that explicitly load specific bundles, its use is not necessary when using
|
||||||
|
lilv_world_load_all().
|
||||||
|
*/
|
||||||
|
LILV_API void
|
||||||
|
lilv_world_load_plugin_classes(LilvWorld* world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unload a specific bundle.
|
Unload a specific bundle.
|
||||||
|
|
||||||
This unloads statements loaded by lilv_world_load_bundle(). Note that this
|
This unloads statements loaded by lilv_world_load_bundle(). Note that this
|
||||||
is not necessarily all information loaded from the bundle. If any resources
|
is not necessarily all information loaded from the bundle. If any resources
|
||||||
have been separately loaded with liv_world_load_resource(), they must be
|
have been separately loaded with lilv_world_load_resource(), they must be
|
||||||
separately unloaded with lilv_world_unload_resource().
|
separately unloaded with lilv_world_unload_resource().
|
||||||
*/
|
*/
|
||||||
LILV_API int
|
LILV_API int
|
||||||
lilv_world_unload_bundle(LilvWorld* world, LilvNode* bundle_uri);
|
lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load all the data associated with the given `resource`.
|
Load all the data associated with the given `resource`.
|
||||||
|
@ -649,6 +715,16 @@ lilv_world_ask(LilvWorld* world,
|
||||||
const LilvNode* predicate,
|
const LilvNode* predicate,
|
||||||
const LilvNode* object);
|
const LilvNode* object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
||||||
|
@return A string node that is a valid LV2 symbol, or NULL on error.
|
||||||
|
*/
|
||||||
|
LILV_API LilvNode*
|
||||||
|
lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@}
|
@}
|
||||||
@name Plugin
|
@name Plugin
|
||||||
|
@ -687,13 +763,14 @@ lilv_plugin_get_uri(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the (resolvable) URI of the plugin's "main" bundle.
|
Get the (resolvable) URI of the plugin's "main" bundle.
|
||||||
This returns the URI of the bundle where the plugin itself was found.
|
This returns the URI of the bundle where the plugin itself was found. Note
|
||||||
Note that the data for a plugin may be spread over many bundles, that is,
|
that the data for a plugin may be spread over many bundles, that is,
|
||||||
lilv_plugin_get_data_uris may return URIs which are not within this bundle.
|
lilv_plugin_get_data_uris() may return URIs which are not within this
|
||||||
|
bundle.
|
||||||
|
|
||||||
Typical hosts should not need to use this function.
|
Typical hosts should not need to use this function.
|
||||||
Note this always returns a fully qualified URI. If you want a local
|
Note this always returns a fully qualified URI. If you want a local
|
||||||
filesystem path, use lilv_uri_to_path.
|
filesystem path, use lilv_file_uri_parse().
|
||||||
@return a shared string which must not be modified or freed.
|
@return a shared string which must not be modified or freed.
|
||||||
*/
|
*/
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
|
@ -703,7 +780,7 @@ lilv_plugin_get_bundle_uri(const LilvPlugin* plugin);
|
||||||
Get the (resolvable) URIs of the RDF data files that define a plugin.
|
Get the (resolvable) URIs of the RDF data files that define a plugin.
|
||||||
Typical hosts should not need to use this function.
|
Typical hosts should not need to use this function.
|
||||||
Note this always returns fully qualified URIs. If you want local
|
Note this always returns fully qualified URIs. If you want local
|
||||||
filesystem paths, use lilv_uri_to_path.
|
filesystem paths, use lilv_file_uri_parse().
|
||||||
@return a list of complete URLs eg. "file:///foo/ABundle.lv2/aplug.ttl",
|
@return a list of complete URLs eg. "file:///foo/ABundle.lv2/aplug.ttl",
|
||||||
which is shared and must not be modified or freed.
|
which is shared and must not be modified or freed.
|
||||||
*/
|
*/
|
||||||
|
@ -713,7 +790,7 @@ lilv_plugin_get_data_uris(const LilvPlugin* plugin);
|
||||||
/**
|
/**
|
||||||
Get the (resolvable) URI of the shared library for `plugin`.
|
Get the (resolvable) URI of the shared library for `plugin`.
|
||||||
Note this always returns a fully qualified URI. If you want a local
|
Note this always returns a fully qualified URI. If you want a local
|
||||||
filesystem path, use lilv_uri_to_path.
|
filesystem path, use lilv_file_uri_parse().
|
||||||
@return a shared string which must not be modified or freed.
|
@return a shared string which must not be modified or freed.
|
||||||
*/
|
*/
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
|
@ -748,7 +825,7 @@ lilv_plugin_get_class(const LilvPlugin* plugin);
|
||||||
Return value must be freed by caller with lilv_nodes_free().
|
Return value must be freed by caller with lilv_nodes_free().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_value(const LilvPlugin* p,
|
lilv_plugin_get_value(const LilvPlugin* plugin,
|
||||||
const LilvNode* predicate);
|
const LilvNode* predicate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -757,21 +834,21 @@ lilv_plugin_get_value(const LilvPlugin* p,
|
||||||
of the plugin.
|
of the plugin.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_plugin_has_feature(const LilvPlugin* p,
|
lilv_plugin_has_feature(const LilvPlugin* plugin,
|
||||||
const LilvNode* feature_uri);
|
const LilvNode* feature);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the LV2 Features supported (required or optionally) by a plugin.
|
Get the LV2 Features supported (required or optionally) by a plugin.
|
||||||
A feature is "supported" by a plugin if it is required OR optional.
|
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
|
Since required features have special rules the host must obey, this function
|
||||||
probably shouldn't be used by normal hosts. Using lilv_plugin_get_optional_features
|
probably shouldn't be used by normal hosts. Using lilv_plugin_get_optional_features()
|
||||||
and lilv_plugin_get_required_features separately is best in most cases.
|
and lilv_plugin_get_required_features() separately is best in most cases.
|
||||||
|
|
||||||
Returned value must be freed by caller with lilv_nodes_free().
|
Returned value must be freed by caller with lilv_nodes_free().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_supported_features(const LilvPlugin* p);
|
lilv_plugin_get_supported_features(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the LV2 Features required by a plugin.
|
Get the LV2 Features required by a plugin.
|
||||||
|
@ -785,7 +862,7 @@ lilv_plugin_get_supported_features(const LilvPlugin* p);
|
||||||
Return value must be freed by caller with lilv_nodes_free().
|
Return value must be freed by caller with lilv_nodes_free().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_required_features(const LilvPlugin* p);
|
lilv_plugin_get_required_features(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the LV2 Features optionally supported by a plugin.
|
Get the LV2 Features optionally supported by a plugin.
|
||||||
|
@ -796,13 +873,13 @@ lilv_plugin_get_required_features(const LilvPlugin* p);
|
||||||
Return value must be freed by caller with lilv_nodes_free().
|
Return value must be freed by caller with lilv_nodes_free().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_optional_features(const LilvPlugin* p);
|
lilv_plugin_get_optional_features(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return whether or not a plugin provides a specific extension data.
|
Return whether or not a plugin provides a specific extension data.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_plugin_has_extension_data(const LilvPlugin* p,
|
lilv_plugin_has_extension_data(const LilvPlugin* plugin,
|
||||||
const LilvNode* uri);
|
const LilvNode* uri);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -811,13 +888,13 @@ lilv_plugin_has_extension_data(const LilvPlugin* p,
|
||||||
will return a value for without instantiating the plugin.
|
will return a value for without instantiating the plugin.
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_extension_data(const LilvPlugin* p);
|
lilv_plugin_get_extension_data(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the number of ports on this plugin.
|
Get the number of ports on this plugin.
|
||||||
*/
|
*/
|
||||||
LILV_API uint32_t
|
LILV_API uint32_t
|
||||||
lilv_plugin_get_num_ports(const LilvPlugin* p);
|
lilv_plugin_get_num_ports(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the port ranges (minimum, maximum and default values) for all ports.
|
Get the port ranges (minimum, maximum and default values) for all ports.
|
||||||
|
@ -831,10 +908,10 @@ lilv_plugin_get_num_ports(const LilvPlugin* p);
|
||||||
|
|
||||||
This is a convenience method for the common case of getting the range of
|
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
|
all float ports on a plugin, and may be significantly faster than
|
||||||
repeated calls to lilv_port_get_range.
|
repeated calls to lilv_port_get_range().
|
||||||
*/
|
*/
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_plugin_get_port_ranges_float(const LilvPlugin* p,
|
lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin,
|
||||||
float* min_values,
|
float* min_values,
|
||||||
float* max_values,
|
float* max_values,
|
||||||
float* def_values);
|
float* def_values);
|
||||||
|
@ -846,20 +923,18 @@ lilv_plugin_get_port_ranges_float(const LilvPlugin* p,
|
||||||
OF THIS FUNCTION WITH NULL OR VERY NASTY THINGS WILL HAPPEN.
|
OF THIS FUNCTION WITH NULL OR VERY NASTY THINGS WILL HAPPEN.
|
||||||
*/
|
*/
|
||||||
LILV_API uint32_t
|
LILV_API uint32_t
|
||||||
lilv_plugin_get_num_ports_of_class(const LilvPlugin* p,
|
lilv_plugin_get_num_ports_of_class(const LilvPlugin* plugin,
|
||||||
const LilvNode* class_1, ...);
|
const LilvNode* class_1, ...);
|
||||||
|
|
||||||
#ifndef SWIG
|
|
||||||
/**
|
/**
|
||||||
Variant of lilv_plugin_get_num_ports_of_class() that takes a va_list.
|
Variant of lilv_plugin_get_num_ports_of_class() that takes a va_list.
|
||||||
|
|
||||||
This function calls va_arg() on `args` but does not call va_end().
|
This function calls va_arg() on `args` but does not call va_end().
|
||||||
*/
|
*/
|
||||||
LILV_API uint32_t
|
LILV_API uint32_t
|
||||||
lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* p,
|
lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* plugin,
|
||||||
const LilvNode* class_1,
|
const LilvNode* class_1,
|
||||||
va_list args);
|
va_list args);
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return whether or not the plugin introduces (and reports) latency.
|
Return whether or not the plugin introduces (and reports) latency.
|
||||||
|
@ -867,19 +942,19 @@ lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* p,
|
||||||
lilv_plugin_get_latency_port() ONLY if this function returns true.
|
lilv_plugin_get_latency_port() ONLY if this function returns true.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_plugin_has_latency(const LilvPlugin* p);
|
lilv_plugin_has_latency(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the index of the plugin's latency port.
|
Return the index of the plugin's latency port.
|
||||||
It is a fatal error to call this on a plugin without checking if the port
|
It is a fatal error to call this on a plugin without checking if the port
|
||||||
exists by first calling lilv_plugin_has_latency.
|
exists by first calling lilv_plugin_has_latency().
|
||||||
|
|
||||||
Any plugin that introduces unwanted latency that should be compensated for
|
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
|
(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.
|
rate output port that reports the latency for each cycle in frames.
|
||||||
*/
|
*/
|
||||||
LILV_API uint32_t
|
LILV_API uint32_t
|
||||||
lilv_plugin_get_latency_port_index(const LilvPlugin* p);
|
lilv_plugin_get_latency_port_index(const LilvPlugin* plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a port on `plugin` by `index`.
|
Get a port on `plugin` by `index`.
|
||||||
|
@ -890,7 +965,7 @@ lilv_plugin_get_port_by_index(const LilvPlugin* plugin,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a port on `plugin` by `symbol`.
|
Get a port on `plugin` by `symbol`.
|
||||||
Note this function is slower than lilv_plugin_get_port_by_index,
|
Note this function is slower than lilv_plugin_get_port_by_index(),
|
||||||
especially on plugins with a very large number of ports.
|
especially on plugins with a very large number of ports.
|
||||||
*/
|
*/
|
||||||
LILV_API const LilvPort*
|
LILV_API const LilvPort*
|
||||||
|
@ -990,7 +1065,7 @@ lilv_plugin_write_manifest_entry(LilvWorld* world,
|
||||||
If `type` is NULL, all such resources will be returned, regardless of type.
|
If `type` is NULL, all such resources will be returned, regardless of type.
|
||||||
|
|
||||||
To actually load the data for each returned resource, use
|
To actually load the data for each returned resource, use
|
||||||
lilv_world_load_resource.
|
lilv_world_load_resource().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type);
|
lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type);
|
||||||
|
@ -1013,7 +1088,7 @@ lilv_port_get_node(const LilvPlugin* plugin,
|
||||||
const LilvPort* port);
|
const LilvPort* port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Port analog of lilv_plugin_get_value.
|
Port analog of lilv_plugin_get_value().
|
||||||
*/
|
*/
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_port_get_value(const LilvPlugin* plugin,
|
lilv_port_get_value(const LilvPlugin* plugin,
|
||||||
|
@ -1043,9 +1118,9 @@ lilv_port_get_properties(const LilvPlugin* plugin,
|
||||||
Return whether a port has a certain property.
|
Return whether a port has a certain property.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_port_has_property(const LilvPlugin* p,
|
lilv_port_has_property(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* property_uri);
|
const LilvNode* property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return whether a port supports a certain event type.
|
Return whether a port supports a certain event type.
|
||||||
|
@ -1054,7 +1129,7 @@ lilv_port_has_property(const LilvPlugin* p,
|
||||||
ev:supportsEvent property with `event_type` as the value.
|
ev:supportsEvent property with `event_type` as the value.
|
||||||
*/
|
*/
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_port_supports_event(const LilvPlugin* p,
|
lilv_port_supports_event(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* event_type);
|
const LilvNode* event_type);
|
||||||
|
|
||||||
|
@ -1089,7 +1164,7 @@ lilv_port_get_name(const LilvPlugin* plugin,
|
||||||
/**
|
/**
|
||||||
Get all the classes of a port.
|
Get all the classes of a port.
|
||||||
This can be used to determine if a port is an input, output, audio,
|
This can be used to determine if a port is an input, output, audio,
|
||||||
control, midi, etc, etc, though it's simpler to use lilv_port_is_a.
|
control, midi, etc, etc, though it's simpler to use lilv_port_is_a().
|
||||||
The returned list does not include lv2:Port, which is implied.
|
The returned list does not include lv2:Port, which is implied.
|
||||||
Returned value is shared and must not be destroyed by caller.
|
Returned value is shared and must not be destroyed by caller.
|
||||||
*/
|
*/
|
||||||
|
@ -1115,13 +1190,13 @@ lilv_port_is_a(const LilvPlugin* plugin,
|
||||||
|
|
||||||
`def`, `min`, and `max` are outputs, pass pointers to uninitialized
|
`def`, `min`, and `max` are outputs, pass pointers to uninitialized
|
||||||
LilvNode* variables. These will be set to point at new values (which must
|
LilvNode* variables. These will be set to point at new values (which must
|
||||||
be freed by the caller using lilv_node_free), or NULL if the value does not
|
be freed by the caller using lilv_node_free()), or NULL if the value does
|
||||||
exist.
|
not exist.
|
||||||
*/
|
*/
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_port_get_range(const LilvPlugin* plugin,
|
lilv_port_get_range(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
LilvNode** deflt,
|
LilvNode** def,
|
||||||
LilvNode** min,
|
LilvNode** min,
|
||||||
LilvNode** max);
|
LilvNode** max);
|
||||||
|
|
||||||
|
@ -1148,13 +1223,13 @@ lilv_port_get_scale_points(const LilvPlugin* plugin,
|
||||||
the plugin URI as the `subject` parameter.
|
the plugin URI as the `subject` parameter.
|
||||||
@param world The world.
|
@param world The world.
|
||||||
@param map URID mapper.
|
@param map URID mapper.
|
||||||
@param subject The subject of the state description (e.g. a preset URI).
|
@param node The subject of the state description (e.g. a preset URI).
|
||||||
@return A new LilvState which must be freed with lilv_state_free(), or NULL.
|
@return A new LilvState which must be freed with lilv_state_free(), or NULL.
|
||||||
*/
|
*/
|
||||||
LILV_API LilvState*
|
LILV_API LilvState*
|
||||||
lilv_state_new_from_world(LilvWorld* world,
|
lilv_state_new_from_world(LilvWorld* world,
|
||||||
LV2_URID_Map* map,
|
LV2_URID_Map* map,
|
||||||
const LilvNode* subject);
|
const LilvNode* node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load a state snapshot from a file.
|
Load a state snapshot from a file.
|
||||||
|
@ -1209,32 +1284,37 @@ typedef const void* (*LilvGetPortValueFunc)(const char* port_symbol,
|
||||||
|
|
||||||
@param map The map to use for mapping URIs in state.
|
@param map The map to use for mapping URIs in state.
|
||||||
|
|
||||||
@param file_dir Directory of files created by the plugin earlier (or NULL).
|
@param scratch_dir Directory of files created by the plugin earlier, or
|
||||||
This is for hosts that support file creation at any time with state
|
NULL. This is for hosts that support file creation at any time with state
|
||||||
state:makePath. These files will be copied as necessary to `copy_dir` and
|
state:makePath. These files will be copied as necessary to `copy_dir` and
|
||||||
not be referred to directly in state (a temporary directory is appropriate).
|
not be referred to directly in state (a temporary directory is appropriate).
|
||||||
|
|
||||||
@param copy_dir Directory of copies of files in `file_dir` (or NULL). This
|
@param copy_dir Directory of copies of files in `scratch_dir`, or NULL.
|
||||||
directory will have the same structure as `file_dir` but with possibly
|
This directory will have the same structure as `scratch_dir` but with
|
||||||
modified file names to distinguish different revisions. If you only care
|
possibly modified file names to distinguish revisions. This allows the
|
||||||
about saving one state snapshot, it can be the same as `save_dir`. Plugin
|
saved state to contain the exact contents of the scratch file at save time,
|
||||||
state will refer to files in this directory.
|
so that the state is not ruined if the file is later modified (for example,
|
||||||
|
by the plugin continuing to record). This can be the same as `save_dir` to
|
||||||
|
create a copy in the state bundle, but can also be a separate directory
|
||||||
|
which allows multiple state snapshots to share a single copy if the file has
|
||||||
|
not changed.
|
||||||
|
|
||||||
@param save_dir Directory of files created by plugin during save (or NULL).
|
@param link_dir Directory of links to external files, or NULL. A link will
|
||||||
If the state will be saved, this should be the bundle directory later passed
|
|
||||||
to lilv_state_save.
|
|
||||||
|
|
||||||
@param get_value Function to get port values.
|
|
||||||
|
|
||||||
@param user_data User data to pass to `get_value`.
|
|
||||||
|
|
||||||
@param link_dir Directory of links to external files (or NULL). A link will
|
|
||||||
be made in this directory to any external files referred to in plugin state.
|
be made in this directory to any external files referred to in plugin state.
|
||||||
In turn, links will be created in the save directory to these links (e.g.
|
In turn, links will be created in the save directory to these links (e.g.
|
||||||
save_dir/file => link_dir/file => /foo/bar/file). This allows many state
|
save_dir/file => link_dir/file => /foo/bar/file). This allows many state
|
||||||
snapshots to share a single link to an external file, so archival
|
snapshots to share a single link to an external file, so archival (e.g. with
|
||||||
(e.g. with tar -h) will not create several copies of the file. If this is
|
tar -h) will not create several copies of the file. If this is not
|
||||||
not required, it can be the same as save_dir.
|
required, it can be the same as `save_dir`.
|
||||||
|
|
||||||
|
@param save_dir Directory of files created by plugin during save (or NULL).
|
||||||
|
This is typically the bundle directory later passed to lilv_state_save().
|
||||||
|
|
||||||
|
@param get_value Function to get port values (or NULL). If NULL, the
|
||||||
|
returned state will not represent port values. This should only be NULL in
|
||||||
|
hosts that save and restore port values via some other mechanism.
|
||||||
|
|
||||||
|
@param user_data User data to pass to `get_value`.
|
||||||
|
|
||||||
@param flags Bitwise OR of LV2_State_Flags values.
|
@param flags Bitwise OR of LV2_State_Flags values.
|
||||||
|
|
||||||
|
@ -1253,12 +1333,12 @@ typedef const void* (*LilvGetPortValueFunc)(const char* port_symbol,
|
||||||
saving an instances state many times while avoiding any duplication of data.
|
saving an instances state many times while avoiding any duplication of data.
|
||||||
|
|
||||||
If supported (via state:makePath passed to LV2_Descriptor::instantiate()),
|
If supported (via state:makePath passed to LV2_Descriptor::instantiate()),
|
||||||
`file_dir` should be the directory where any files created by the plugin
|
`scratch_dir` should be the directory where any files created by the plugin
|
||||||
(not during save time, e.g. during instantiation) are stored. These files
|
(not during save time, e.g. during instantiation) are stored. These files
|
||||||
will be copied to preserve their state at this time.plugin-created files are stored.
|
will be copied to preserve their state at this time.plugin-created files are
|
||||||
Lilv will assume any files within this directory (recursively) are created
|
stored. Lilv will assume any files within this directory (recursively) are
|
||||||
by the plugin and all other files are immutable. Note that this function
|
created by the plugin and all other files are immutable. Note that this
|
||||||
does not save the state, use lilv_state_save() for that.
|
function does not save the state, use lilv_state_save() for that.
|
||||||
|
|
||||||
See <a href="http://lv2plug.in/ns/ext/state/state.h">state.h</a> from the
|
See <a href="http://lv2plug.in/ns/ext/state/state.h">state.h</a> from the
|
||||||
LV2 State extension for details on the `flags` and `features` parameters.
|
LV2 State extension for details on the `flags` and `features` parameters.
|
||||||
|
@ -1267,7 +1347,7 @@ LILV_API LilvState*
|
||||||
lilv_state_new_from_instance(const LilvPlugin* plugin,
|
lilv_state_new_from_instance(const LilvPlugin* plugin,
|
||||||
LilvInstance* instance,
|
LilvInstance* instance,
|
||||||
LV2_URID_Map* map,
|
LV2_URID_Map* map,
|
||||||
const char* file_dir,
|
const char* scratch_dir,
|
||||||
const char* copy_dir,
|
const char* copy_dir,
|
||||||
const char* link_dir,
|
const char* link_dir,
|
||||||
const char* save_dir,
|
const char* save_dir,
|
||||||
|
@ -1300,6 +1380,14 @@ lilv_state_get_num_properties(const LilvState* state);
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
lilv_state_get_plugin_uri(const LilvState* state);
|
lilv_state_get_plugin_uri(const LilvState* state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the URI of `state`.
|
||||||
|
|
||||||
|
This may return NULL if the state has not been saved and has no URI.
|
||||||
|
*/
|
||||||
|
LILV_API const LilvNode*
|
||||||
|
lilv_state_get_uri(const LilvState* state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the label of `state`.
|
Get the label of `state`.
|
||||||
*/
|
*/
|
||||||
|
@ -1313,6 +1401,28 @@ LILV_API void
|
||||||
lilv_state_set_label(LilvState* state,
|
lilv_state_set_label(LilvState* state,
|
||||||
const char* label);
|
const char* label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set a metadata property on `state`.
|
||||||
|
@param state The state to set the metadata for.
|
||||||
|
@param key The key to store `value` under (URID).
|
||||||
|
@param value Pointer to the value to be stored.
|
||||||
|
@param size The size of `value` in bytes.
|
||||||
|
@param type The type of `value` (URID).
|
||||||
|
@param flags LV2_State_Flags for `value`.
|
||||||
|
@return 0 on success.
|
||||||
|
|
||||||
|
This is a generic version of lilv_state_set_label(), which sets metadata
|
||||||
|
properties visible to hosts, but not plugins. This allows storing useful
|
||||||
|
information such as comments or preset banks.
|
||||||
|
*/
|
||||||
|
LILV_API int
|
||||||
|
lilv_state_set_metadata(LilvState* state,
|
||||||
|
uint32_t key,
|
||||||
|
const void* value,
|
||||||
|
size_t size,
|
||||||
|
uint32_t type,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Function to set a port value.
|
Function to set a port value.
|
||||||
@param port_symbol The symbol of the port.
|
@param port_symbol The symbol of the port.
|
||||||
|
@ -1327,6 +1437,22 @@ typedef void (*LilvSetPortValueFunc)(const char* port_symbol,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
uint32_t type);
|
uint32_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enumerate the port values in a state snapshot.
|
||||||
|
@param state The state to retrieve port values from.
|
||||||
|
@param set_value A function to receive port values.
|
||||||
|
@param user_data User data to pass to `set_value`.
|
||||||
|
|
||||||
|
This function is a subset of lilv_state_restore() that only fires the
|
||||||
|
`set_value` callback and does not directly affect a plugin instance. This
|
||||||
|
is useful in hosts that need to retrieve the port values in a state snapshot
|
||||||
|
for special handling.
|
||||||
|
*/
|
||||||
|
LILV_API void
|
||||||
|
lilv_state_emit_port_values(const LilvState* state,
|
||||||
|
LilvSetPortValueFunc set_value,
|
||||||
|
void* user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Restore a plugin instance from a state snapshot.
|
Restore a plugin instance from a state snapshot.
|
||||||
@param state The state to restore, which must apply to the correct plugin.
|
@param state The state to restore, which must apply to the correct plugin.
|
||||||
|
@ -1337,10 +1463,10 @@ typedef void (*LilvSetPortValueFunc)(const char* port_symbol,
|
||||||
@param features Features to pass LV2_State_Interface.restore().
|
@param features Features to pass LV2_State_Interface.restore().
|
||||||
|
|
||||||
This will set all the properties of `instance`, if given, to the values
|
This will set all the properties of `instance`, if given, to the values
|
||||||
stored in `state`. If `set_value` is provided, it will be called (with
|
stored in `state`. If `set_value` is provided, it will be called (with the
|
||||||
the given `user_data`) to restore each port value, otherwise the host must
|
given `user_data`) to restore each port value, otherwise the host must
|
||||||
restore the port values itself (using lilv_state_get_port_value) in order to
|
restore the port values itself (using lilv_state_get_port_value()) in order
|
||||||
completely restore `state`.
|
to completely restore `state`.
|
||||||
|
|
||||||
If the state has properties and `instance` is given, this function is in
|
If the state has properties and `instance` is given, this function is in
|
||||||
the "instantiation" threading class, i.e. it MUST NOT be called
|
the "instantiation" threading class, i.e. it MUST NOT be called
|
||||||
|
@ -1404,6 +1530,24 @@ lilv_state_to_string(LilvWorld* world,
|
||||||
const char* uri,
|
const char* uri,
|
||||||
const char* base_uri);
|
const char* base_uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Unload a state from the world and delete all associated files.
|
||||||
|
@param world The world.
|
||||||
|
@param state State to remove from the system.
|
||||||
|
|
||||||
|
This function DELETES FILES/DIRECTORIES FROM THE FILESYSTEM! It is intended
|
||||||
|
for removing user-saved presets, but can delete any state the user has
|
||||||
|
permission to delete, including presets shipped with plugins.
|
||||||
|
|
||||||
|
The rdfs:seeAlso file for the state will be removed. The entry in the
|
||||||
|
bundle's manifest.ttl is removed, and if this results in an empty manifest,
|
||||||
|
then the manifest file is removed. If this results in an empty bundle, then
|
||||||
|
the bundle directory is removed as well.
|
||||||
|
*/
|
||||||
|
LILV_API int
|
||||||
|
lilv_state_delete(LilvWorld* world,
|
||||||
|
const LilvState* state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@}
|
@}
|
||||||
@name Scale Point
|
@name Scale Point
|
||||||
|
@ -1471,7 +1615,7 @@ lilv_plugin_class_get_children(const LilvPluginClass* plugin_class);
|
||||||
|
|
||||||
/* Instance of a plugin.
|
/* Instance of a plugin.
|
||||||
This is exposed in the ABI to allow inlining of performance critical
|
This is exposed in the ABI to allow inlining of performance critical
|
||||||
functions like lilv_instance_run (simple wrappers of functions in lv2.h).
|
functions like lilv_instance_run() (simple wrappers of functions in lv2.h).
|
||||||
This is for performance reasons, user code should not use this definition
|
This is for performance reasons, user code should not use this definition
|
||||||
in any way (which is why it is not machine documented).
|
in any way (which is why it is not machine documented).
|
||||||
Truly private implementation details are hidden via `pimpl`.
|
Truly private implementation details are hidden via `pimpl`.
|
||||||
|
@ -1537,14 +1681,15 @@ lilv_instance_connect_port(LilvInstance* instance,
|
||||||
/**
|
/**
|
||||||
Activate a plugin instance.
|
Activate a plugin instance.
|
||||||
This resets all state information in the plugin, except for port data
|
This resets all state information in the plugin, except for port data
|
||||||
locations (as set by lilv_instance_connect_port). This MUST be called
|
locations (as set by lilv_instance_connect_port()). This MUST be called
|
||||||
before calling lilv_instance_run.
|
before calling lilv_instance_run().
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
lilv_instance_activate(LilvInstance* instance)
|
lilv_instance_activate(LilvInstance* instance)
|
||||||
{
|
{
|
||||||
if (instance->lv2_descriptor->activate)
|
if (instance->lv2_descriptor->activate) {
|
||||||
instance->lv2_descriptor->activate(instance->lv2_handle);
|
instance->lv2_descriptor->activate(instance->lv2_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1567,8 +1712,9 @@ lilv_instance_run(LilvInstance* instance,
|
||||||
static inline void
|
static inline void
|
||||||
lilv_instance_deactivate(LilvInstance* instance)
|
lilv_instance_deactivate(LilvInstance* instance)
|
||||||
{
|
{
|
||||||
if (instance->lv2_descriptor->deactivate)
|
if (instance->lv2_descriptor->deactivate) {
|
||||||
instance->lv2_descriptor->deactivate(instance->lv2_handle);
|
instance->lv2_descriptor->deactivate(instance->lv2_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1580,10 +1726,11 @@ static inline const void*
|
||||||
lilv_instance_get_extension_data(const LilvInstance* instance,
|
lilv_instance_get_extension_data(const LilvInstance* instance,
|
||||||
const char* uri)
|
const char* uri)
|
||||||
{
|
{
|
||||||
if (instance->lv2_descriptor->extension_data)
|
if (instance->lv2_descriptor->extension_data) {
|
||||||
return instance->lv2_descriptor->extension_data(uri);
|
return instance->lv2_descriptor->extension_data(uri);
|
||||||
else
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1640,8 +1787,8 @@ lilv_ui_get_uri(const LilvUI* ui);
|
||||||
@param ui The Plugin UI
|
@param ui The Plugin UI
|
||||||
@return a shared value which must not be modified or freed.
|
@return a shared value which must not be modified or freed.
|
||||||
|
|
||||||
Note that in most cases lilv_ui_is_supported should be used which finds the
|
Note that in most cases lilv_ui_is_supported() should be used, which avoids
|
||||||
UI type, avoding the need to use this function (and type specific logic).
|
the need to use this function (and type specific logic).
|
||||||
*/
|
*/
|
||||||
LILV_API const LilvNodes*
|
LILV_API const LilvNodes*
|
||||||
lilv_ui_get_classes(const LilvUI* ui);
|
lilv_ui_get_classes(const LilvUI* ui);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2017 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -19,19 +19,28 @@
|
||||||
|
|
||||||
#include "lilv/lilv.h"
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
|
|
||||||
# define LILV_DEPRECATED __attribute__((__deprecated__))
|
|
||||||
#else
|
|
||||||
# define LILV_DEPRECATED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Lilv {
|
namespace Lilv {
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic push
|
||||||
|
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LILV_DEPRECATED
|
||||||
static inline const char*
|
static inline const char*
|
||||||
uri_to_path(const char* uri) {
|
uri_to_path(const char* uri) {
|
||||||
return lilv_uri_to_path(uri);
|
return lilv_uri_to_path(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic pop
|
||||||
|
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LILV_WRAP0(RT, prefix, name) \
|
#define LILV_WRAP0(RT, prefix, name) \
|
||||||
inline RT name() { return lilv_ ## prefix ## _ ## name (me); }
|
inline RT name() { return lilv_ ## prefix ## _ ## name (me); }
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2008-2014 David Robillard <http://drobilla.net>
|
Copyright 2008-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -16,6 +16,15 @@
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/common.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
lilv_ptr_cmp(const void* a, const void* b, void* user_data)
|
lilv_ptr_cmp(const void* a, const void* b, void* user_data)
|
||||||
{
|
{
|
||||||
|
@ -39,16 +48,17 @@ lilv_collection_new(ZixComparator cmp, ZixDestroyFunc destructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lilv_collection_free(LilvCollection* coll)
|
lilv_collection_free(LilvCollection* collection)
|
||||||
{
|
{
|
||||||
if (coll)
|
if (collection) {
|
||||||
zix_tree_free((ZixTree*)coll);
|
zix_tree_free((ZixTree*)collection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
lilv_collection_size(const LilvCollection* coll)
|
lilv_collection_size(const LilvCollection* collection)
|
||||||
{
|
{
|
||||||
return (coll ? zix_tree_size((const ZixTree*)coll) : 0);
|
return (collection ? zix_tree_size((const ZixTree*)collection) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LilvIter*
|
LilvIter*
|
||||||
|
@ -97,17 +107,17 @@ lilv_plugin_classes_new(void)
|
||||||
/* URI based accessors (for collections of things with URIs) */
|
/* URI based accessors (for collections of things with URIs) */
|
||||||
|
|
||||||
LILV_API const LilvPluginClass*
|
LILV_API const LilvPluginClass*
|
||||||
lilv_plugin_classes_get_by_uri(const LilvPluginClasses* coll,
|
lilv_plugin_classes_get_by_uri(const LilvPluginClasses* classes,
|
||||||
const LilvNode* uri)
|
const LilvNode* uri)
|
||||||
{
|
{
|
||||||
return (LilvPluginClass*)lilv_collection_get_by_uri(
|
return (LilvPluginClass*)lilv_collection_get_by_uri(
|
||||||
(const ZixTree*)coll, uri);
|
(const ZixTree*)classes, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvUI*
|
LILV_API const LilvUI*
|
||||||
lilv_uis_get_by_uri(const LilvUIs* coll, const LilvNode* uri)
|
lilv_uis_get_by_uri(const LilvUIs* uis, const LilvNode* uri)
|
||||||
{
|
{
|
||||||
return (LilvUI*)lilv_collection_get_by_uri((const ZixTree*)coll, uri);
|
return (LilvUI*)lilv_collection_get_by_uri((const ZixTree*)uis, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plugins */
|
/* Plugins */
|
||||||
|
@ -119,19 +129,22 @@ lilv_plugins_new(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvPlugin*
|
LILV_API const LilvPlugin*
|
||||||
lilv_plugins_get_by_uri(const LilvPlugins* list, const LilvNode* uri)
|
lilv_plugins_get_by_uri(const LilvPlugins* plugins, const LilvNode* uri)
|
||||||
{
|
{
|
||||||
return (LilvPlugin*)lilv_collection_get_by_uri((const ZixTree*)list, uri);
|
return (LilvPlugin*)lilv_collection_get_by_uri(
|
||||||
|
(const ZixTree*)plugins, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nodes */
|
/* Nodes */
|
||||||
|
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_nodes_contains(const LilvNodes* list, const LilvNode* value)
|
lilv_nodes_contains(const LilvNodes* nodes, const LilvNode* value)
|
||||||
{
|
{
|
||||||
LILV_FOREACH(nodes, i, list)
|
LILV_FOREACH(nodes, i, nodes) {
|
||||||
if (lilv_node_equals(lilv_nodes_get(list, i), value))
|
if (lilv_node_equals(lilv_nodes_get(nodes, i), value)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,44 +14,46 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
LILV_API LilvInstance*
|
LILV_API LilvInstance*
|
||||||
lilv_plugin_instantiate(const LilvPlugin* plugin,
|
lilv_plugin_instantiate(const LilvPlugin* plugin,
|
||||||
double sample_rate,
|
double sample_rate,
|
||||||
const LV2_Feature*const* features)
|
const LV2_Feature*const* features)
|
||||||
{
|
{
|
||||||
lilv_plugin_load_if_necessary(plugin);
|
lilv_plugin_load_if_necessary(plugin);
|
||||||
|
if (plugin->parse_errors) {
|
||||||
LilvInstance* result = NULL;
|
|
||||||
|
|
||||||
const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin);
|
|
||||||
const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin);
|
|
||||||
|
|
||||||
const char* bundle_path = lilv_uri_to_path(
|
|
||||||
lilv_node_as_uri(lilv_plugin_get_bundle_uri(plugin)));
|
|
||||||
|
|
||||||
LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features);
|
|
||||||
if (!lib) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse bundle URI to use as base URI
|
LilvInstance* result = NULL;
|
||||||
const char* bundle_uri_str = lilv_node_as_uri(bundle_uri);
|
const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin);
|
||||||
SerdURI base_uri;
|
const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin);
|
||||||
if (serd_uri_parse((const uint8_t*)bundle_uri_str, &base_uri)) {
|
if (!lib_uri || !bundle_uri) {
|
||||||
lilv_lib_close(lib);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* const bundle_path = lilv_file_uri_parse(
|
||||||
|
lilv_node_as_uri(bundle_uri), NULL);
|
||||||
|
|
||||||
|
LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features);
|
||||||
|
if (!lib) {
|
||||||
|
serd_free(bundle_path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LV2_Feature** local_features = NULL;
|
const LV2_Feature** local_features = NULL;
|
||||||
if (features == NULL) {
|
if (features == NULL) {
|
||||||
local_features = (const LV2_Feature**)malloc(sizeof(LV2_Feature));
|
local_features = (const LV2_Feature**)malloc(sizeof(LV2_Feature*));
|
||||||
local_features[0] = NULL;
|
local_features[0] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,18 +68,7 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
||||||
break; // return NULL
|
break; // return NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve library plugin URI against base URI
|
if (!strcmp(ld->URI, lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) {
|
||||||
SerdURI abs_uri;
|
|
||||||
SerdNode abs_uri_node = serd_node_new_uri_from_string(
|
|
||||||
(const uint8_t*)ld->URI, &base_uri, &abs_uri);
|
|
||||||
if (!abs_uri_node.buf) {
|
|
||||||
LILV_ERRORF("Failed to parse plugin URI `%s'\n", ld->URI);
|
|
||||||
lilv_lib_close(lib);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp((const char*)abs_uri_node.buf,
|
|
||||||
lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) {
|
|
||||||
// Create LilvInstance to return
|
// Create LilvInstance to return
|
||||||
result = (LilvInstance*)malloc(sizeof(LilvInstance));
|
result = (LilvInstance*)malloc(sizeof(LilvInstance));
|
||||||
result->lv2_descriptor = ld;
|
result->lv2_descriptor = ld;
|
||||||
|
@ -85,25 +76,25 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
||||||
ld, sample_rate, bundle_path,
|
ld, sample_rate, bundle_path,
|
||||||
(features) ? features : local_features);
|
(features) ? features : local_features);
|
||||||
result->pimpl = lib;
|
result->pimpl = lib;
|
||||||
serd_node_free(&abs_uri_node);
|
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
serd_node_free(&abs_uri_node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(local_features);
|
free(local_features);
|
||||||
|
serd_free(bundle_path);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
// Failed to instantiate
|
|
||||||
if (result->lv2_handle == NULL) {
|
if (result->lv2_handle == NULL) {
|
||||||
|
// Failed to instantiate
|
||||||
free(result);
|
free(result);
|
||||||
|
lilv_lib_close(lib);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Connect" all ports to NULL (catches bugs)
|
// "Connect" all ports to NULL (catches bugs)
|
||||||
for (uint32_t i = 0; i < lilv_plugin_get_num_ports(plugin); ++i)
|
for (uint32_t i = 0; i < lilv_plugin_get_num_ports(plugin); ++i) {
|
||||||
result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL);
|
result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -112,8 +103,9 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_instance_free(LilvInstance* instance)
|
lilv_instance_free(LilvInstance* instance)
|
||||||
{
|
{
|
||||||
if (!instance)
|
if (!instance) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
instance->lv2_descriptor->cleanup(instance->lv2_handle);
|
instance->lv2_descriptor->cleanup(instance->lv2_handle);
|
||||||
instance->lv2_descriptor = NULL;
|
instance->lv2_descriptor = NULL;
|
||||||
|
@ -121,4 +113,3 @@ lilv_instance_free(LilvInstance* instance)
|
||||||
instance->pimpl = NULL;
|
instance->pimpl = NULL;
|
||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2012-2014 David Robillard <http://drobilla.net>
|
Copyright 2012-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -16,6 +16,13 @@
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
LilvLib*
|
LilvLib*
|
||||||
lilv_lib_open(LilvWorld* world,
|
lilv_lib_open(LilvWorld* world,
|
||||||
const LilvNode* uri,
|
const LilvNode* uri,
|
||||||
|
@ -33,7 +40,8 @@ lilv_lib_open(LilvWorld* world,
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const lib_uri = lilv_node_as_uri(uri);
|
const char* const lib_uri = lilv_node_as_uri(uri);
|
||||||
const char* const lib_path = lilv_uri_to_path(lib_uri);
|
char* const lib_path = (char*)serd_file_uri_parse(
|
||||||
|
(const uint8_t*)lib_uri, NULL);
|
||||||
if (!lib_path) {
|
if (!lib_path) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +50,13 @@ lilv_lib_open(LilvWorld* world,
|
||||||
void* lib = dlopen(lib_path, RTLD_NOW);
|
void* lib = dlopen(lib_path, RTLD_NOW);
|
||||||
if (!lib) {
|
if (!lib) {
|
||||||
LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror());
|
LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror());
|
||||||
|
serd_free(lib_path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LV2_Descriptor_Function df = (LV2_Descriptor_Function)
|
LV2_Descriptor_Function df = (LV2_Descriptor_Function)
|
||||||
lilv_dlfunc(lib, "lv2_descriptor");
|
lilv_dlfunc(lib, "lv2_descriptor");
|
||||||
|
|
||||||
#ifdef LILV_NEW_LV2
|
|
||||||
LV2_Lib_Descriptor_Function ldf = (LV2_Lib_Descriptor_Function)
|
LV2_Lib_Descriptor_Function ldf = (LV2_Lib_Descriptor_Function)
|
||||||
lilv_dlfunc(lib, "lv2_lib_descriptor");
|
lilv_dlfunc(lib, "lv2_lib_descriptor");
|
||||||
|
|
||||||
|
@ -56,17 +64,19 @@ lilv_lib_open(LilvWorld* world,
|
||||||
if (ldf) {
|
if (ldf) {
|
||||||
desc = ldf(bundle_path, features);
|
desc = ldf(bundle_path, features);
|
||||||
if (!desc) {
|
if (!desc) {
|
||||||
LILV_ERRORF("Call to `lv2_lib_descriptor' in %s failed\n", lib_path);
|
LILV_ERRORF("Call to %s:lv2_lib_descriptor failed\n", lib_path);
|
||||||
|
dlclose(lib);
|
||||||
|
serd_free(lib_path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else
|
} else if (!df) {
|
||||||
#endif
|
|
||||||
if (!df) {
|
|
||||||
LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n",
|
LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n",
|
||||||
lib_path);
|
lib_path);
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
|
serd_free(lib_path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
serd_free(lib_path);
|
||||||
|
|
||||||
LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib));
|
LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib));
|
||||||
llib->world = world;
|
llib->world = world;
|
||||||
|
@ -74,9 +84,7 @@ lilv_lib_open(LilvWorld* world,
|
||||||
llib->bundle_path = lilv_strdup(bundle_path);
|
llib->bundle_path = lilv_strdup(bundle_path);
|
||||||
llib->lib = lib;
|
llib->lib = lib;
|
||||||
llib->lv2_descriptor = df;
|
llib->lv2_descriptor = df;
|
||||||
#ifdef LILV_NEW_LV2
|
|
||||||
llib->desc = desc;
|
llib->desc = desc;
|
||||||
#endif
|
|
||||||
llib->refs = 1;
|
llib->refs = 1;
|
||||||
|
|
||||||
zix_tree_insert(world->libs, llib, NULL);
|
zix_tree_insert(world->libs, llib, NULL);
|
||||||
|
@ -88,12 +96,9 @@ lilv_lib_get_plugin(LilvLib* lib, uint32_t index)
|
||||||
{
|
{
|
||||||
if (lib->lv2_descriptor) {
|
if (lib->lv2_descriptor) {
|
||||||
return lib->lv2_descriptor(index);
|
return lib->lv2_descriptor(index);
|
||||||
}
|
} else if (lib->desc) {
|
||||||
#ifdef LILV_NEW_LV2
|
|
||||||
if (lib->desc) {
|
|
||||||
return lib->desc->get_plugin(lib->desc->handle, index);
|
return lib->desc->get_plugin(lib->desc->handle, index);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -21,38 +21,46 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "lilv_config.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <float.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <direct.h>
|
||||||
|
# include <stdio.h>
|
||||||
# define dlopen(path, flags) LoadLibrary(path)
|
# define dlopen(path, flags) LoadLibrary(path)
|
||||||
# define dlclose(lib) FreeLibrary((HMODULE)lib)
|
# define dlclose(lib) FreeLibrary((HMODULE)lib)
|
||||||
|
# define unlink(path) _unlink(path)
|
||||||
|
# define rmdir(path) _rmdir(path)
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# define __func__ __FUNCTION__
|
# define __func__ __FUNCTION__
|
||||||
# if _MSC_VER < 1800
|
# ifndef snprintf
|
||||||
# define INFINITY DBL_MAX + DBL_MAX
|
|
||||||
# define NAN INFINITY - INFINITY
|
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
static inline char* dlerror(void) { return "Unknown error"; }
|
#ifndef INFINITY
|
||||||
|
# define INFINITY DBL_MAX + DBL_MAX
|
||||||
|
#endif
|
||||||
|
#ifndef NAN
|
||||||
|
# define NAN INFINITY - INFINITY
|
||||||
|
#endif
|
||||||
|
static inline const char* dlerror(void) { return "Unknown error"; }
|
||||||
#else
|
#else
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "serd/serd.h"
|
|
||||||
#include "sord/sord.h"
|
|
||||||
|
|
||||||
#include "zix/tree.h"
|
|
||||||
|
|
||||||
#include "lilv_config.h"
|
|
||||||
#include "lilv/lilv.h"
|
|
||||||
|
|
||||||
#ifdef LILV_DYN_MANIFEST
|
#ifdef LILV_DYN_MANIFEST
|
||||||
# include "lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h"
|
# include "lv2/dynmanifest/dynmanifest.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -104,9 +112,7 @@ typedef struct {
|
||||||
char* bundle_path;
|
char* bundle_path;
|
||||||
void* lib;
|
void* lib;
|
||||||
LV2_Descriptor_Function lv2_descriptor;
|
LV2_Descriptor_Function lv2_descriptor;
|
||||||
#ifdef LILV_NEW_LV2
|
|
||||||
const LV2_Lib_Descriptor* desc;
|
const LV2_Lib_Descriptor* desc;
|
||||||
#endif
|
|
||||||
uint32_t refs;
|
uint32_t refs;
|
||||||
} LilvLib;
|
} LilvLib;
|
||||||
|
|
||||||
|
@ -123,6 +129,7 @@ struct LilvPluginImpl {
|
||||||
LilvPort** ports;
|
LilvPort** ports;
|
||||||
uint32_t num_ports;
|
uint32_t num_ports;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
|
bool parse_errors;
|
||||||
bool replaced;
|
bool replaced;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,8 +146,9 @@ struct LilvInstancePimpl {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool dyn_manifest;
|
bool dyn_manifest;
|
||||||
bool filter_language;
|
bool filter_language;
|
||||||
|
char* lv2_path;
|
||||||
} LilvOptions;
|
} LilvOptions;
|
||||||
|
|
||||||
struct LilvWorldImpl {
|
struct LilvWorldImpl {
|
||||||
|
@ -152,6 +160,7 @@ struct LilvWorldImpl {
|
||||||
LilvPluginClasses* plugin_classes;
|
LilvPluginClasses* plugin_classes;
|
||||||
LilvSpec* specs;
|
LilvSpec* specs;
|
||||||
LilvPlugins* plugins;
|
LilvPlugins* plugins;
|
||||||
|
LilvPlugins* zombies;
|
||||||
LilvNodes* loaded_files;
|
LilvNodes* loaded_files;
|
||||||
ZixTree* libs;
|
ZixTree* libs;
|
||||||
struct {
|
struct {
|
||||||
|
@ -168,7 +177,9 @@ struct LilvWorldImpl {
|
||||||
SordNode* lv2_index;
|
SordNode* lv2_index;
|
||||||
SordNode* lv2_latency;
|
SordNode* lv2_latency;
|
||||||
SordNode* lv2_maximum;
|
SordNode* lv2_maximum;
|
||||||
|
SordNode* lv2_microVersion;
|
||||||
SordNode* lv2_minimum;
|
SordNode* lv2_minimum;
|
||||||
|
SordNode* lv2_minorVersion;
|
||||||
SordNode* lv2_name;
|
SordNode* lv2_name;
|
||||||
SordNode* lv2_optionalFeature;
|
SordNode* lv2_optionalFeature;
|
||||||
SordNode* lv2_port;
|
SordNode* lv2_port;
|
||||||
|
@ -177,7 +188,7 @@ struct LilvWorldImpl {
|
||||||
SordNode* lv2_requiredFeature;
|
SordNode* lv2_requiredFeature;
|
||||||
SordNode* lv2_symbol;
|
SordNode* lv2_symbol;
|
||||||
SordNode* lv2_prototype;
|
SordNode* lv2_prototype;
|
||||||
SordNode* null_uri;
|
SordNode* owl_Ontology;
|
||||||
SordNode* pset_value;
|
SordNode* pset_value;
|
||||||
SordNode* rdf_a;
|
SordNode* rdf_a;
|
||||||
SordNode* rdf_value;
|
SordNode* rdf_value;
|
||||||
|
@ -190,6 +201,7 @@ struct LilvWorldImpl {
|
||||||
SordNode* xsd_decimal;
|
SordNode* xsd_decimal;
|
||||||
SordNode* xsd_double;
|
SordNode* xsd_double;
|
||||||
SordNode* xsd_integer;
|
SordNode* xsd_integer;
|
||||||
|
SordNode* null_uri;
|
||||||
} uris;
|
} uris;
|
||||||
LilvOptions opt;
|
LilvOptions opt;
|
||||||
};
|
};
|
||||||
|
@ -228,6 +240,11 @@ struct LilvUIImpl {
|
||||||
LilvNodes* classes;
|
LilvNodes* classes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct LilvVersion {
|
||||||
|
int minor;
|
||||||
|
int micro;
|
||||||
|
} LilvVersion;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Functions
|
* Functions
|
||||||
|
@ -243,9 +260,10 @@ void lilv_port_free(const LilvPlugin* plugin, LilvPort* port);
|
||||||
LilvPlugin* lilv_plugin_new(LilvWorld* world,
|
LilvPlugin* lilv_plugin_new(LilvWorld* world,
|
||||||
LilvNode* uri,
|
LilvNode* uri,
|
||||||
LilvNode* bundle_uri);
|
LilvNode* bundle_uri);
|
||||||
void lilv_plugin_load_if_necessary(const LilvPlugin* p);
|
void lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri);
|
||||||
|
void lilv_plugin_load_if_necessary(const LilvPlugin* plugin);
|
||||||
void lilv_plugin_free(LilvPlugin* plugin);
|
void lilv_plugin_free(LilvPlugin* plugin);
|
||||||
LilvNode* lilv_plugin_get_unique(const LilvPlugin* p,
|
LilvNode* lilv_plugin_get_unique(const LilvPlugin* plugin,
|
||||||
const SordNode* subject,
|
const SordNode* subject,
|
||||||
const SordNode* predicate);
|
const SordNode* predicate);
|
||||||
|
|
||||||
|
@ -256,7 +274,7 @@ void* lilv_collection_get(const LilvCollection* collection,
|
||||||
const LilvIter* i);
|
const LilvIter* i);
|
||||||
|
|
||||||
LilvPluginClass* lilv_plugin_class_new(LilvWorld* world,
|
LilvPluginClass* lilv_plugin_class_new(LilvWorld* world,
|
||||||
const SordNode* parent_uri,
|
const SordNode* parent_node,
|
||||||
const SordNode* uri,
|
const SordNode* uri,
|
||||||
const char* label);
|
const char* label);
|
||||||
|
|
||||||
|
@ -277,6 +295,9 @@ LilvScalePoints* lilv_scale_points_new(void);
|
||||||
LilvPluginClasses* lilv_plugin_classes_new(void);
|
LilvPluginClasses* lilv_plugin_classes_new(void);
|
||||||
LilvUIs* lilv_uis_new(void);
|
LilvUIs* lilv_uis_new(void);
|
||||||
|
|
||||||
|
LilvNode* lilv_world_get_manifest_uri(LilvWorld* world,
|
||||||
|
const LilvNode* bundle_uri);
|
||||||
|
|
||||||
const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world);
|
const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world);
|
||||||
|
|
||||||
SerdStatus lilv_world_load_file(LilvWorld* world,
|
SerdStatus lilv_world_load_file(LilvWorld* world,
|
||||||
|
@ -295,7 +316,7 @@ LilvUI* lilv_ui_new(LilvWorld* world,
|
||||||
|
|
||||||
void lilv_ui_free(LilvUI* ui);
|
void lilv_ui_free(LilvUI* ui);
|
||||||
|
|
||||||
LilvNode* lilv_node_new(LilvWorld* world, LilvNodeType type, const char* val);
|
LilvNode* lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str);
|
||||||
LilvNode* lilv_node_new_from_node(LilvWorld* world, const SordNode* node);
|
LilvNode* lilv_node_new_from_node(LilvWorld* world, const SordNode* node);
|
||||||
|
|
||||||
int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data);
|
int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data);
|
||||||
|
@ -304,6 +325,19 @@ int lilv_lib_compare(const void* a, const void* b, void* user_data);
|
||||||
int lilv_ptr_cmp(const void* a, const void* b, void* user_data);
|
int lilv_ptr_cmp(const void* a, const void* b, void* user_data);
|
||||||
int lilv_resource_node_cmp(const void* a, const void* b, void* user_data);
|
int lilv_resource_node_cmp(const void* a, const void* b, void* user_data);
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
lilv_version_cmp(const LilvVersion* a, const LilvVersion* b)
|
||||||
|
{
|
||||||
|
if (a->minor == b->minor && a->micro == b->micro) {
|
||||||
|
return 0;
|
||||||
|
} else if ((a->minor < b->minor)
|
||||||
|
|| (a->minor == b->minor && a->micro < b->micro)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct LilvHeader*
|
struct LilvHeader*
|
||||||
lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri);
|
lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri);
|
||||||
|
|
||||||
|
@ -328,10 +362,18 @@ lilv_world_find_nodes_internal(LilvWorld* world,
|
||||||
const SordNode* predicate,
|
const SordNode* predicate,
|
||||||
const SordNode* object);
|
const SordNode* object);
|
||||||
|
|
||||||
|
SordModel*
|
||||||
|
lilv_world_filter_model(LilvWorld* world,
|
||||||
|
SordModel* model,
|
||||||
|
const SordNode* subject,
|
||||||
|
const SordNode* predicate,
|
||||||
|
const SordNode* object,
|
||||||
|
const SordNode* graph);
|
||||||
|
|
||||||
#define FOREACH_MATCH(iter) \
|
#define FOREACH_MATCH(iter) \
|
||||||
for (; !sord_iter_end(iter); sord_iter_next(iter))
|
for (; !sord_iter_end(iter); sord_iter_next(iter))
|
||||||
|
|
||||||
LilvNodes* lilv_nodes_from_stream_objects(LilvWorld* w,
|
LilvNodes* lilv_nodes_from_stream_objects(LilvWorld* world,
|
||||||
SordIter* stream,
|
SordIter* stream,
|
||||||
SordQuadIndex field);
|
SordQuadIndex field);
|
||||||
|
|
||||||
|
@ -341,7 +383,7 @@ char* lilv_get_lang(void);
|
||||||
char* lilv_expand(const char* path);
|
char* lilv_expand(const char* path);
|
||||||
char* lilv_dirname(const char* path);
|
char* lilv_dirname(const char* path);
|
||||||
int lilv_copy_file(const char* src, const char* dst);
|
int lilv_copy_file(const char* src, const char* dst);
|
||||||
bool lilv_path_exists(const char* path, void* ignored);
|
bool lilv_path_exists(const char* path, const void* ignored);
|
||||||
char* lilv_path_absolute(const char* path);
|
char* lilv_path_absolute(const char* path);
|
||||||
bool lilv_path_is_absolute(const char* path);
|
bool lilv_path_is_absolute(const char* path);
|
||||||
char* lilv_get_latest_copy(const char* path, const char* copy_path);
|
char* lilv_get_latest_copy(const char* path, const char* copy_path);
|
||||||
|
@ -350,13 +392,14 @@ bool lilv_path_is_child(const char* path, const char* dir);
|
||||||
int lilv_flock(FILE* file, bool lock);
|
int lilv_flock(FILE* file, bool lock);
|
||||||
char* lilv_realpath(const char* path);
|
char* lilv_realpath(const char* path);
|
||||||
int lilv_symlink(const char* oldpath, const char* newpath);
|
int lilv_symlink(const char* oldpath, const char* newpath);
|
||||||
int lilv_mkdir_p(const char* path);
|
int lilv_mkdir_p(const char* dir_path);
|
||||||
char* lilv_path_join(const char* a, const char* b);
|
char* lilv_path_join(const char* a, const char* b);
|
||||||
bool lilv_file_equals(const char* a_path, const char* b_path);
|
bool lilv_file_equals(const char* a_path, const char* b_path);
|
||||||
|
|
||||||
char*
|
char*
|
||||||
lilv_find_free_path(const char* in_path,
|
lilv_find_free_path(const char* in_path,
|
||||||
bool (*exists)(const char*, void*), void* user_data);
|
bool (*exists)(const char*, const void*),
|
||||||
|
const void* user_data);
|
||||||
|
|
||||||
void
|
void
|
||||||
lilv_dir_for_each(const char* path,
|
lilv_dir_for_each(const char* path,
|
||||||
|
@ -390,6 +433,10 @@ static const LV2_Feature* const dman_features = { NULL };
|
||||||
__func__)
|
__func__)
|
||||||
#define LILV_WARNF(fmt, ...) fprintf(stderr, "%s(): warning: " fmt, \
|
#define LILV_WARNF(fmt, ...) fprintf(stderr, "%s(): warning: " fmt, \
|
||||||
__func__, __VA_ARGS__)
|
__func__, __VA_ARGS__)
|
||||||
|
#define LILV_NOTE(str) fprintf(stderr, "%s(): note: " str, \
|
||||||
|
__func__)
|
||||||
|
#define LILV_NOTEF(fmt, ...) fprintf(stderr, "%s(): note: " fmt, \
|
||||||
|
__func__, __VA_ARGS__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,17 +14,23 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lilv_node_set_numerics_from_string(LilvNode* val, size_t len)
|
lilv_node_set_numerics_from_string(LilvNode* val)
|
||||||
{
|
{
|
||||||
const char* str = (const char*)sord_node_get_string(val->node);
|
const char* str = (const char*)sord_node_get_string(val->node);
|
||||||
char* endptr;
|
|
||||||
|
|
||||||
switch (val->type) {
|
switch (val->type) {
|
||||||
case LILV_VALUE_URI:
|
case LILV_VALUE_URI:
|
||||||
|
@ -33,10 +39,10 @@ lilv_node_set_numerics_from_string(LilvNode* val, size_t len)
|
||||||
case LILV_VALUE_BLOB:
|
case LILV_VALUE_BLOB:
|
||||||
break;
|
break;
|
||||||
case LILV_VALUE_INT:
|
case LILV_VALUE_INT:
|
||||||
val->val.int_val = strtol(str, &endptr, 10);
|
val->val.int_val = strtol(str, NULL, 10);
|
||||||
break;
|
break;
|
||||||
case LILV_VALUE_FLOAT:
|
case LILV_VALUE_FLOAT:
|
||||||
val->val.float_val = serd_strtod(str, &endptr);
|
val->val.float_val = serd_strtod(str, NULL);
|
||||||
break;
|
break;
|
||||||
case LILV_VALUE_BOOL:
|
case LILV_VALUE_BOOL:
|
||||||
val->val.bool_val = !strcmp(str, "true");
|
val->val.bool_val = !strcmp(str, "true");
|
||||||
|
@ -104,44 +110,42 @@ lilv_node_new_from_node(LilvWorld* world, const SordNode* node)
|
||||||
LilvNode* result = NULL;
|
LilvNode* result = NULL;
|
||||||
SordNode* datatype_uri = NULL;
|
SordNode* datatype_uri = NULL;
|
||||||
LilvNodeType type = LILV_VALUE_STRING;
|
LilvNodeType type = LILV_VALUE_STRING;
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
switch (sord_node_get_type(node)) {
|
switch (sord_node_get_type(node)) {
|
||||||
case SORD_URI:
|
case SORD_URI:
|
||||||
result = (LilvNode*)malloc(sizeof(LilvNode));
|
result = (LilvNode*)malloc(sizeof(LilvNode));
|
||||||
result->world = (LilvWorld*)world;
|
result->world = world;
|
||||||
result->type = LILV_VALUE_URI;
|
result->type = LILV_VALUE_URI;
|
||||||
result->node = sord_node_copy(node);
|
result->node = sord_node_copy(node);
|
||||||
break;
|
break;
|
||||||
case SORD_BLANK:
|
case SORD_BLANK:
|
||||||
result = (LilvNode*)malloc(sizeof(LilvNode));
|
result = (LilvNode*)malloc(sizeof(LilvNode));
|
||||||
result->world = (LilvWorld*)world;
|
result->world = world;
|
||||||
result->type = LILV_VALUE_BLANK;
|
result->type = LILV_VALUE_BLANK;
|
||||||
result->node = sord_node_copy(node);
|
result->node = sord_node_copy(node);
|
||||||
break;
|
break;
|
||||||
case SORD_LITERAL:
|
case SORD_LITERAL:
|
||||||
datatype_uri = sord_node_get_datatype(node);
|
datatype_uri = sord_node_get_datatype(node);
|
||||||
if (datatype_uri) {
|
if (datatype_uri) {
|
||||||
if (sord_node_equals(datatype_uri, world->uris.xsd_boolean))
|
if (sord_node_equals(datatype_uri, world->uris.xsd_boolean)) {
|
||||||
type = LILV_VALUE_BOOL;
|
type = LILV_VALUE_BOOL;
|
||||||
else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal)
|
} else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) ||
|
||||||
|| sord_node_equals(datatype_uri, world->uris.xsd_double))
|
sord_node_equals(datatype_uri, world->uris.xsd_double)) {
|
||||||
type = LILV_VALUE_FLOAT;
|
type = LILV_VALUE_FLOAT;
|
||||||
else if (sord_node_equals(datatype_uri, world->uris.xsd_integer))
|
} else if (sord_node_equals(datatype_uri, world->uris.xsd_integer)) {
|
||||||
type = LILV_VALUE_INT;
|
type = LILV_VALUE_INT;
|
||||||
else if (sord_node_equals(datatype_uri,
|
} else if (sord_node_equals(datatype_uri,
|
||||||
world->uris.xsd_base64Binary))
|
world->uris.xsd_base64Binary)) {
|
||||||
type = LILV_VALUE_BLOB;
|
type = LILV_VALUE_BLOB;
|
||||||
else
|
} else {
|
||||||
LILV_ERRORF("Unknown datatype `%s'\n",
|
LILV_ERRORF("Unknown datatype `%s'\n",
|
||||||
sord_node_get_string(datatype_uri));
|
sord_node_get_string(datatype_uri));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = lilv_node_new(
|
result = lilv_node_new(
|
||||||
world, type, (const char*)sord_node_get_string_counted(node, &len));
|
world, type, (const char*)sord_node_get_string(node));
|
||||||
lilv_node_set_numerics_from_string(result, len);
|
lilv_node_set_numerics_from_string(result);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -228,12 +232,13 @@ lilv_node_free(LilvNode* val)
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_node_equals(const LilvNode* value, const LilvNode* other)
|
lilv_node_equals(const LilvNode* value, const LilvNode* other)
|
||||||
{
|
{
|
||||||
if (value == NULL && other == NULL)
|
if (value == NULL && other == NULL) {
|
||||||
return true;
|
return true;
|
||||||
else if (value == NULL || other == NULL)
|
} else if (value == NULL || other == NULL) {
|
||||||
return false;
|
return false;
|
||||||
else if (value->type != other->type)
|
} else if (value->type != other->type) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
case LILV_VALUE_URI:
|
case LILV_VALUE_URI:
|
||||||
|
@ -278,11 +283,13 @@ lilv_node_get_turtle_token(const LilvNode* value)
|
||||||
break;
|
break;
|
||||||
case LILV_VALUE_INT:
|
case LILV_VALUE_INT:
|
||||||
node = serd_node_new_integer(value->val.int_val);
|
node = serd_node_new_integer(value->val.int_val);
|
||||||
result = (char*)node.buf;
|
result = lilv_strdup((char*)node.buf);
|
||||||
|
serd_node_free(&node);
|
||||||
break;
|
break;
|
||||||
case LILV_VALUE_FLOAT:
|
case LILV_VALUE_FLOAT:
|
||||||
node = serd_node_new_decimal(value->val.float_val, 8);
|
node = serd_node_new_decimal(value->val.float_val, 8);
|
||||||
result = (char*)node.buf;
|
result = lilv_strdup((char*)node.buf);
|
||||||
|
serd_node_free(&node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,13 +327,15 @@ lilv_node_as_blank(const LilvNode* value)
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_node_is_literal(const LilvNode* value)
|
lilv_node_is_literal(const LilvNode* value)
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
case LILV_VALUE_STRING:
|
case LILV_VALUE_STRING:
|
||||||
case LILV_VALUE_INT:
|
case LILV_VALUE_INT:
|
||||||
case LILV_VALUE_FLOAT:
|
case LILV_VALUE_FLOAT:
|
||||||
|
case LILV_VALUE_BLOB:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -366,12 +375,12 @@ lilv_node_is_float(const LilvNode* value)
|
||||||
LILV_API float
|
LILV_API float
|
||||||
lilv_node_as_float(const LilvNode* value)
|
lilv_node_as_float(const LilvNode* value)
|
||||||
{
|
{
|
||||||
assert(lilv_node_is_float(value) || lilv_node_is_int(value));
|
|
||||||
if (lilv_node_is_float(value)) {
|
if (lilv_node_is_float(value)) {
|
||||||
return value->val.float_val;
|
return value->val.float_val;
|
||||||
} else { // lilv_node_is_int(value)
|
} else if (lilv_node_is_int(value)) {
|
||||||
return (float)value->val.int_val;
|
return (float)value->val.int_val;
|
||||||
}
|
}
|
||||||
|
return NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
|
@ -385,3 +394,12 @@ lilv_node_as_bool(const LilvNode* value)
|
||||||
{
|
{
|
||||||
return lilv_node_is_bool(value) ? value->val.bool_val : false;
|
return lilv_node_is_bool(value) ? value->val.bool_val : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LILV_API char*
|
||||||
|
lilv_node_get_path(const LilvNode* value, char** hostname)
|
||||||
|
{
|
||||||
|
if (lilv_node_is_uri(value)) {
|
||||||
|
return lilv_file_uri_parse(lilv_node_as_uri(value), hostname);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,21 +14,21 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
LilvPluginClass*
|
LilvPluginClass*
|
||||||
lilv_plugin_class_new(LilvWorld* world,
|
lilv_plugin_class_new(LilvWorld* world,
|
||||||
const SordNode* parent_node,
|
const SordNode* parent_node,
|
||||||
const SordNode* uri,
|
const SordNode* uri,
|
||||||
const char* label)
|
const char* label)
|
||||||
{
|
{
|
||||||
if (parent_node && sord_node_get_type(parent_node) != SORD_URI) {
|
|
||||||
return NULL; // Not an LV2 plugin superclass (FIXME: discover properly)
|
|
||||||
}
|
|
||||||
LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass));
|
LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass));
|
||||||
pc->world = world;
|
pc->world = world;
|
||||||
pc->uri = lilv_node_new_from_node(world, uri);
|
pc->uri = lilv_node_new_from_node(world, uri);
|
||||||
|
@ -42,7 +42,10 @@ lilv_plugin_class_new(LilvWorld* world,
|
||||||
void
|
void
|
||||||
lilv_plugin_class_free(LilvPluginClass* plugin_class)
|
lilv_plugin_class_free(LilvPluginClass* plugin_class)
|
||||||
{
|
{
|
||||||
assert(plugin_class->uri);
|
if (!plugin_class) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lilv_node_free(plugin_class->uri);
|
lilv_node_free(plugin_class->uri);
|
||||||
lilv_node_free(plugin_class->parent_uri);
|
lilv_node_free(plugin_class->parent_uri);
|
||||||
lilv_node_free(plugin_class->label);
|
lilv_node_free(plugin_class->label);
|
||||||
|
@ -80,8 +83,9 @@ lilv_plugin_class_get_children(const LilvPluginClass* plugin_class)
|
||||||
const LilvPluginClass* c = (LilvPluginClass*)zix_tree_get(i);
|
const LilvPluginClass* c = (LilvPluginClass*)zix_tree_get(i);
|
||||||
const LilvNode* parent = lilv_plugin_class_get_parent_uri(c);
|
const LilvNode* parent = lilv_plugin_class_get_parent_uri(c);
|
||||||
if (parent && lilv_node_equals(lilv_plugin_class_get_uri(plugin_class),
|
if (parent && lilv_node_equals(lilv_plugin_class_get_uri(plugin_class),
|
||||||
parent))
|
parent)) {
|
||||||
zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL);
|
zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,16 +14,21 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lv2/atom/atom.h"
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#include "lv2/event/event.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/event/event.h"
|
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
LilvPort*
|
LilvPort*
|
||||||
lilv_port_new(LilvWorld* world,
|
lilv_port_new(LilvWorld* world,
|
||||||
|
@ -55,38 +60,40 @@ lilv_port_is_a(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* port_class)
|
const LilvNode* port_class)
|
||||||
{
|
{
|
||||||
LILV_FOREACH(nodes, i, port->classes)
|
LILV_FOREACH(nodes, i, port->classes) {
|
||||||
if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class))
|
if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_port_has_property(const LilvPlugin* p,
|
lilv_port_has_property(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* property)
|
const LilvNode* property)
|
||||||
{
|
{
|
||||||
return lilv_world_ask_internal(p->world,
|
return lilv_world_ask_internal(plugin->world,
|
||||||
port->node->node,
|
port->node->node,
|
||||||
p->world->uris.lv2_portProperty,
|
plugin->world->uris.lv2_portProperty,
|
||||||
property->node);
|
property->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_port_supports_event(const LilvPlugin* p,
|
lilv_port_supports_event(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* event)
|
const LilvNode* event_type)
|
||||||
{
|
{
|
||||||
const uint8_t* predicates[] = { (const uint8_t*)LV2_EVENT__supportsEvent,
|
const uint8_t* predicates[] = { (const uint8_t*)LV2_EVENT__supportsEvent,
|
||||||
(const uint8_t*)LV2_ATOM__supports,
|
(const uint8_t*)LV2_ATOM__supports,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
for (const uint8_t** pred = predicates; *pred; ++pred) {
|
for (const uint8_t** pred = predicates; *pred; ++pred) {
|
||||||
if (lilv_world_ask_internal(p->world,
|
if (lilv_world_ask_internal(plugin->world,
|
||||||
port->node->node,
|
port->node->node,
|
||||||
sord_new_uri(p->world->world, *pred),
|
sord_new_uri(plugin->world->world, *pred),
|
||||||
event->node)) {
|
event_type->node)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,11 +101,11 @@ lilv_port_supports_event(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
|
|
||||||
static LilvNodes*
|
static LilvNodes*
|
||||||
lilv_port_get_value_by_node(const LilvPlugin* p,
|
lilv_port_get_value_by_node(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const SordNode* predicate)
|
const SordNode* predicate)
|
||||||
{
|
{
|
||||||
return lilv_world_find_nodes_internal(p->world,
|
return lilv_world_find_nodes_internal(plugin->world,
|
||||||
port->node->node,
|
port->node->node,
|
||||||
predicate,
|
predicate,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -112,7 +119,7 @@ lilv_port_get_node(const LilvPlugin* plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_port_get_value(const LilvPlugin* p,
|
lilv_port_get_value(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* predicate)
|
const LilvNode* predicate)
|
||||||
{
|
{
|
||||||
|
@ -122,15 +129,15 @@ lilv_port_get_value(const LilvPlugin* p,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lilv_port_get_value_by_node(p, port, predicate->node);
|
return lilv_port_get_value_by_node(plugin, port, predicate->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvNode*
|
LILV_API LilvNode*
|
||||||
lilv_port_get(const LilvPlugin* p,
|
lilv_port_get(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
const LilvNode* predicate)
|
const LilvNode* predicate)
|
||||||
{
|
{
|
||||||
LilvNodes* values = lilv_port_get_value(p, port, predicate);
|
LilvNodes* values = lilv_port_get_value(plugin, port, predicate);
|
||||||
|
|
||||||
LilvNode* value = lilv_node_duplicate(
|
LilvNode* value = lilv_node_duplicate(
|
||||||
values ? lilv_nodes_get_first(values) : NULL);
|
values ? lilv_nodes_get_first(values) : NULL);
|
||||||
|
@ -140,50 +147,52 @@ lilv_port_get(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API uint32_t
|
LILV_API uint32_t
|
||||||
lilv_port_get_index(const LilvPlugin* p,
|
lilv_port_get_index(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
return port->index;
|
return port->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
lilv_port_get_symbol(const LilvPlugin* p,
|
lilv_port_get_symbol(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
return port->symbol;
|
return port->symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvNode*
|
LILV_API LilvNode*
|
||||||
lilv_port_get_name(const LilvPlugin* p,
|
lilv_port_get_name(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
LilvNodes* results = lilv_port_get_value_by_node(
|
LilvNodes* results = lilv_port_get_value_by_node(
|
||||||
p, port, p->world->uris.lv2_name);
|
plugin, port, plugin->world->uris.lv2_name);
|
||||||
|
|
||||||
LilvNode* ret = NULL;
|
LilvNode* ret = NULL;
|
||||||
if (results) {
|
if (results) {
|
||||||
LilvNode* val = lilv_nodes_get_first(results);
|
LilvNode* val = lilv_nodes_get_first(results);
|
||||||
if (lilv_node_is_string(val))
|
if (lilv_node_is_string(val)) {
|
||||||
ret = lilv_node_duplicate(val);
|
ret = lilv_node_duplicate(val);
|
||||||
|
}
|
||||||
lilv_nodes_free(results);
|
lilv_nodes_free(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n",
|
LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n",
|
||||||
lilv_node_as_string(lilv_plugin_get_uri(p)));
|
lilv_node_as_string(lilv_plugin_get_uri(plugin)));
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvNodes*
|
LILV_API const LilvNodes*
|
||||||
lilv_port_get_classes(const LilvPlugin* p,
|
lilv_port_get_classes(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
return port->classes;
|
return port->classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_port_get_range(const LilvPlugin* p,
|
lilv_port_get_range(const LilvPlugin* plugin,
|
||||||
const LilvPort* port,
|
const LilvPort* port,
|
||||||
LilvNode** def,
|
LilvNode** def,
|
||||||
LilvNode** min,
|
LilvNode** min,
|
||||||
|
@ -191,7 +200,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
||||||
{
|
{
|
||||||
if (def) {
|
if (def) {
|
||||||
LilvNodes* defaults = lilv_port_get_value_by_node(
|
LilvNodes* defaults = lilv_port_get_value_by_node(
|
||||||
p, port, p->world->uris.lv2_default);
|
plugin, port, plugin->world->uris.lv2_default);
|
||||||
*def = defaults
|
*def = defaults
|
||||||
? lilv_node_duplicate(lilv_nodes_get_first(defaults))
|
? lilv_node_duplicate(lilv_nodes_get_first(defaults))
|
||||||
: NULL;
|
: NULL;
|
||||||
|
@ -199,7 +208,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
if (min) {
|
if (min) {
|
||||||
LilvNodes* minimums = lilv_port_get_value_by_node(
|
LilvNodes* minimums = lilv_port_get_value_by_node(
|
||||||
p, port, p->world->uris.lv2_minimum);
|
plugin, port, plugin->world->uris.lv2_minimum);
|
||||||
*min = minimums
|
*min = minimums
|
||||||
? lilv_node_duplicate(lilv_nodes_get_first(minimums))
|
? lilv_node_duplicate(lilv_nodes_get_first(minimums))
|
||||||
: NULL;
|
: NULL;
|
||||||
|
@ -207,7 +216,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
if (max) {
|
if (max) {
|
||||||
LilvNodes* maximums = lilv_port_get_value_by_node(
|
LilvNodes* maximums = lilv_port_get_value_by_node(
|
||||||
p, port, p->world->uris.lv2_maximum);
|
plugin, port, plugin->world->uris.lv2_maximum);
|
||||||
*max = maximums
|
*max = maximums
|
||||||
? lilv_node_duplicate(lilv_nodes_get_first(maximums))
|
? lilv_node_duplicate(lilv_nodes_get_first(maximums))
|
||||||
: NULL;
|
: NULL;
|
||||||
|
@ -216,29 +225,30 @@ lilv_port_get_range(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvScalePoints*
|
LILV_API LilvScalePoints*
|
||||||
lilv_port_get_scale_points(const LilvPlugin* p,
|
lilv_port_get_scale_points(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
SordIter* points = lilv_world_query_internal(
|
SordIter* points = lilv_world_query_internal(
|
||||||
p->world,
|
plugin->world,
|
||||||
port->node->node,
|
port->node->node,
|
||||||
sord_new_uri(p->world->world, (const uint8_t*)LV2_CORE__scalePoint),
|
sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__scalePoint),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
LilvScalePoints* ret = NULL;
|
LilvScalePoints* ret = NULL;
|
||||||
if (!sord_iter_end(points))
|
if (!sord_iter_end(points)) {
|
||||||
ret = lilv_scale_points_new();
|
ret = lilv_scale_points_new();
|
||||||
|
}
|
||||||
|
|
||||||
FOREACH_MATCH(points) {
|
FOREACH_MATCH(points) {
|
||||||
const SordNode* point = sord_iter_get_node(points, SORD_OBJECT);
|
const SordNode* point = sord_iter_get_node(points, SORD_OBJECT);
|
||||||
|
|
||||||
LilvNode* value = lilv_plugin_get_unique(p,
|
LilvNode* value = lilv_plugin_get_unique(plugin,
|
||||||
point,
|
point,
|
||||||
p->world->uris.rdf_value);
|
plugin->world->uris.rdf_value);
|
||||||
|
|
||||||
LilvNode* label = lilv_plugin_get_unique(p,
|
LilvNode* label = lilv_plugin_get_unique(plugin,
|
||||||
point,
|
point,
|
||||||
p->world->uris.rdfs_label);
|
plugin->world->uris.rdfs_label);
|
||||||
|
|
||||||
if (value && label) {
|
if (value && label) {
|
||||||
zix_tree_insert(
|
zix_tree_insert(
|
||||||
|
@ -252,12 +262,12 @@ lilv_port_get_scale_points(const LilvPlugin* p,
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
lilv_port_get_properties(const LilvPlugin* p,
|
lilv_port_get_properties(const LilvPlugin* plugin,
|
||||||
const LilvPort* port)
|
const LilvPort* port)
|
||||||
{
|
{
|
||||||
LilvNode* pred = lilv_node_new_from_node(
|
LilvNode* pred = lilv_node_new_from_node(
|
||||||
p->world, p->world->uris.lv2_portProperty);
|
plugin->world, plugin->world->uris.lv2_portProperty);
|
||||||
LilvNodes* ret = lilv_port_get_value(p, port, pred);
|
LilvNodes* ret = lilv_port_get_value(plugin, port, pred);
|
||||||
lilv_node_free(pred);
|
lilv_node_free(pred);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,13 +14,15 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include "lilv_internal.h"
|
||||||
#include <limits.h>
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LILV_LANG_MATCH_NONE, ///< Language does not match at all
|
LILV_LANG_MATCH_NONE, ///< Language does not match at all
|
||||||
LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match
|
LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/** Ownership of value and label is taken */
|
/** Ownership of value and label is taken */
|
||||||
LilvScalePoint*
|
LilvScalePoint*
|
||||||
lilv_scale_point_new(LilvNode* value, LilvNode* label)
|
lilv_scale_point_new(LilvNode* value, LilvNode* label)
|
||||||
|
@ -37,13 +41,13 @@ lilv_scale_point_free(LilvScalePoint* point)
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
lilv_scale_point_get_value(const LilvScalePoint* p)
|
lilv_scale_point_get_value(const LilvScalePoint* point)
|
||||||
{
|
{
|
||||||
return p->value;
|
return point->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
lilv_scale_point_get_label(const LilvScalePoint* p)
|
lilv_scale_point_get_label(const LilvScalePoint* point)
|
||||||
{
|
{
|
||||||
return p->label;
|
return point->label;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,12 +14,16 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
LilvUI*
|
LilvUI*
|
||||||
lilv_ui_new(LilvWorld* world,
|
lilv_ui_new(LilvWorld* world,
|
||||||
LilvNode* uri,
|
LilvNode* uri,
|
||||||
|
@ -93,9 +97,9 @@ lilv_ui_get_classes(const LilvUI* ui)
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API bool
|
LILV_API bool
|
||||||
lilv_ui_is_a(const LilvUI* ui, const LilvNode* ui_class_uri)
|
lilv_ui_is_a(const LilvUI* ui, const LilvNode* class_uri)
|
||||||
{
|
{
|
||||||
return lilv_nodes_contains(ui->classes, ui_class_uri);
|
return lilv_nodes_contains(ui->classes, class_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API const LilvNode*
|
LILV_API const LilvNode*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,45 +14,76 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 1 /* for fileno */
|
#define _POSIX_C_SOURCE 200809L /* for fileno */
|
||||||
#define _BSD_SOURCE 1 /* for realpath, symlink */
|
#define _BSD_SOURCE 1 /* for realpath, symlink */
|
||||||
|
#define _DEFAULT_SOURCE 1 /* for realpath, symlink */
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define _DARWIN_C_SOURCE 1 /* for flock */
|
# define _DARWIN_C_SOURCE 1 /* for flock */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include "lilv_config.h"
|
||||||
#include <ctype.h>
|
#include "lilv_internal.h"
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
#include "lilv/lilv.h"
|
||||||
#include <stdlib.h>
|
#include "serd/serd.h"
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x0600 /* for CreateSymbolicLink */
|
# define _WIN32_WINNT 0x0600 /* for CreateSymbolicLink */
|
||||||
|
#endif
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <direct.h>
|
# include <direct.h>
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
# define F_OK 0
|
# define F_OK 0
|
||||||
# define mkdir(path, flags) _mkdir(path)
|
# define mkdir(path, flags) _mkdir(path)
|
||||||
|
# if (defined(_MSC_VER) && _MSC_VER <= 1400) || defined(__MINGW64__) || defined(__MINGW32__)
|
||||||
|
/** Implement 'CreateSymbolicLink()' for MSVC 8 or earlier */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
static BOOLEAN WINAPI
|
||||||
|
CreateSymbolicLink(LPCTSTR linkpath, LPCTSTR targetpath, DWORD flags)
|
||||||
|
{
|
||||||
|
typedef BOOLEAN (WINAPI* PFUNC)(LPCTSTR, LPCTSTR, DWORD);
|
||||||
|
|
||||||
|
PFUNC pfn = (PFUNC)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
|
||||||
|
"CreateSymbolicLinkA");
|
||||||
|
return pfn ? pfn(linkpath, targetpath, flags) : 0;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_FLOCK) && defined(HAVE_FILENO)
|
#if defined(HAVE_FLOCK) && defined(HAVE_FILENO)
|
||||||
# include <sys/file.h>
|
# include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef PAGE_SIZE
|
#ifndef PAGE_SIZE
|
||||||
# define PAGE_SIZE 4096
|
# define PAGE_SIZE 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
lilv_free(void* ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
lilv_strjoin(const char* first, ...)
|
lilv_strjoin(const char* first, ...)
|
||||||
{
|
{
|
||||||
|
@ -65,16 +96,18 @@ lilv_strjoin(const char* first, ...)
|
||||||
va_start(args, first);
|
va_start(args, first);
|
||||||
while (1) {
|
while (1) {
|
||||||
const char* const s = va_arg(args, const char *);
|
const char* const s = va_arg(args, const char *);
|
||||||
if (s == NULL)
|
if (s == NULL) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t this_len = strlen(s);
|
const size_t this_len = strlen(s);
|
||||||
if (!(result = (char*)realloc(result, len + this_len + 1))) {
|
char* new_result = (char*)realloc(result, len + this_len + 1);
|
||||||
|
if (!new_result) {
|
||||||
free(result);
|
free(result);
|
||||||
LILV_ERROR("realloc() failed\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = new_result;
|
||||||
memcpy(result + len, s, this_len);
|
memcpy(result + len, s, this_len);
|
||||||
len += this_len;
|
len += this_len;
|
||||||
}
|
}
|
||||||
|
@ -104,6 +137,12 @@ lilv_uri_to_path(const char* uri)
|
||||||
return (const char*)serd_uri_to_path((const uint8_t*)uri);
|
return (const char*)serd_uri_to_path((const uint8_t*)uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
lilv_file_uri_parse(const char* uri, char** hostname)
|
||||||
|
{
|
||||||
|
return (char*)serd_file_uri_parse((const uint8_t*)uri, (uint8_t**)hostname);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the current LANG converted to Turtle (i.e. RFC3066) style.
|
/** Return the current LANG converted to Turtle (i.e. RFC3066) style.
|
||||||
* For example, if LANG is set to "en_CA.utf-8", this returns "en-ca".
|
* For example, if LANG is set to "en_CA.utf-8", this returns "en-ca".
|
||||||
*/
|
*/
|
||||||
|
@ -141,6 +180,8 @@ lilv_get_lang(void)
|
||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
/** Append suffix to dst, update dst_len, and return the realloc'd result. */
|
/** Append suffix to dst, update dst_len, and return the realloc'd result. */
|
||||||
static char*
|
static char*
|
||||||
strappend(char* dst, size_t* dst_len, const char* suffix, size_t suffix_len)
|
strappend(char* dst, size_t* dst_len, const char* suffix, size_t suffix_len)
|
||||||
|
@ -165,6 +206,8 @@ append_var(char* dst, size_t* dst_len, const char* var)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Expand variables (e.g. POSIX ~ or $FOO, Windows %FOO%) in `path`. */
|
/** Expand variables (e.g. POSIX ~ or $FOO, Windows %FOO%) in `path`. */
|
||||||
char*
|
char*
|
||||||
lilv_expand(const char* path)
|
lilv_expand(const char* path)
|
||||||
|
@ -239,14 +282,20 @@ lilv_dirname(const char* path)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
lilv_path_exists(const char* path, void* ignored)
|
lilv_path_exists(const char* path, const void* ignored)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_LSTAT
|
||||||
|
struct stat st;
|
||||||
|
return !lstat(path, &st);
|
||||||
|
#else
|
||||||
return !access(path, F_OK);
|
return !access(path, F_OK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
lilv_find_free_path(const char* in_path,
|
lilv_find_free_path(const char* in_path,
|
||||||
bool (*exists)(const char*, void*), void* user_data)
|
bool (*exists)(const char*, const void*),
|
||||||
|
const void* user_data)
|
||||||
{
|
{
|
||||||
const size_t in_path_len = strlen(in_path);
|
const size_t in_path_len = strlen(in_path);
|
||||||
char* path = (char*)malloc(in_path_len + 7);
|
char* path = (char*)malloc(in_path_len + 7);
|
||||||
|
@ -267,36 +316,41 @@ lilv_copy_file(const char* src, const char* dst)
|
||||||
{
|
{
|
||||||
FILE* in = fopen(src, "r");
|
FILE* in = fopen(src, "r");
|
||||||
if (!in) {
|
if (!in) {
|
||||||
LILV_ERRORF("error opening %s (%s)\n", src, strerror(errno));
|
return errno;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* out = fopen(dst, "w");
|
FILE* out = fopen(dst, "w");
|
||||||
if (!out) {
|
if (!out) {
|
||||||
LILV_ERRORF("error opening %s (%s)\n", dst, strerror(errno));
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
return 2;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* page = (char*)malloc(PAGE_SIZE);
|
char* page = (char*)malloc(PAGE_SIZE);
|
||||||
size_t n_read = 0;
|
size_t n_read = 0;
|
||||||
|
int st = 0;
|
||||||
while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) {
|
while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) {
|
||||||
if (fwrite(page, 1, n_read, out) != n_read) {
|
if (fwrite(page, 1, n_read, out) != n_read) {
|
||||||
LILV_ERRORF("write to %s failed (%s)\n", dst, strerror(errno));
|
st = errno;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ret = ferror(in) || ferror(out);
|
if (!st && (ferror(in) || ferror(out))) {
|
||||||
if (ferror(in)) {
|
st = EBADF;
|
||||||
LILV_ERRORF("read from %s failed (%s)\n", src, strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(page);
|
free(page);
|
||||||
fclose(in);
|
fclose(in);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
return ret;
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
is_windows_path(const char* path)
|
||||||
|
{
|
||||||
|
return (isalpha(path[0]) && (path[1] == ':' || path[1] == '|') &&
|
||||||
|
(path[2] == '/' || path[2] == '\\'));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -307,7 +361,7 @@ lilv_path_is_absolute(const char* path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (isalpha(path[0]) && path[1] == ':' && lilv_is_dir_sep(path[2])) {
|
if (is_windows_path(path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -349,25 +403,8 @@ lilv_path_join(const char* a, const char* b)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
lilv_size_mtime(const char* path, off_t* size, time_t* time)
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
if (stat(path, &buf)) {
|
|
||||||
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size) {
|
|
||||||
*size = buf.st_size;
|
|
||||||
}
|
|
||||||
if (time) {
|
|
||||||
*time = buf.st_mtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* pattern;
|
char* pattern;
|
||||||
off_t orig_size;
|
|
||||||
time_t time;
|
time_t time;
|
||||||
char* latest;
|
char* latest;
|
||||||
} Latest;
|
} Latest;
|
||||||
|
@ -375,16 +412,18 @@ typedef struct {
|
||||||
static void
|
static void
|
||||||
update_latest(const char* path, const char* name, void* data)
|
update_latest(const char* path, const char* name, void* data)
|
||||||
{
|
{
|
||||||
Latest* latest = (Latest*)data;
|
Latest* latest = (Latest*)data;
|
||||||
char* entry_path = lilv_path_join(path, name);
|
char* entry_path = lilv_path_join(path, name);
|
||||||
unsigned num;
|
unsigned num;
|
||||||
if (sscanf(entry_path, latest->pattern, &num) == 1) {
|
if (sscanf(entry_path, latest->pattern, &num) == 1) {
|
||||||
off_t entry_size = 0;
|
struct stat st;
|
||||||
time_t entry_time = 0;
|
if (!stat(entry_path, &st)) {
|
||||||
lilv_size_mtime(entry_path, &entry_size, &entry_time);
|
if (st.st_mtime >= latest->time) {
|
||||||
if (entry_size == latest->orig_size && entry_time >= latest->time) {
|
free(latest->latest);
|
||||||
free(latest->latest);
|
latest->latest = entry_path;
|
||||||
latest->latest = entry_path;
|
}
|
||||||
|
} else {
|
||||||
|
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entry_path != latest->latest) {
|
if (entry_path != latest->latest) {
|
||||||
|
@ -397,8 +436,14 @@ char*
|
||||||
lilv_get_latest_copy(const char* path, const char* copy_path)
|
lilv_get_latest_copy(const char* path, const char* copy_path)
|
||||||
{
|
{
|
||||||
char* copy_dir = lilv_dirname(copy_path);
|
char* copy_dir = lilv_dirname(copy_path);
|
||||||
Latest latest = { lilv_strjoin(copy_path, "%u", NULL), 0, 0, NULL };
|
Latest latest = { lilv_strjoin(copy_path, ".%u", NULL), 0, NULL };
|
||||||
lilv_size_mtime(path, &latest.orig_size, &latest.time);
|
|
||||||
|
struct stat st;
|
||||||
|
if (!stat(path, &st)) {
|
||||||
|
latest.time = st.st_mtime;
|
||||||
|
} else {
|
||||||
|
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
lilv_dir_for_each(copy_dir, &latest, update_latest);
|
lilv_dir_for_each(copy_dir, &latest, update_latest);
|
||||||
|
|
||||||
|
@ -410,7 +455,11 @@ lilv_get_latest_copy(const char* path, const char* copy_path)
|
||||||
char*
|
char*
|
||||||
lilv_realpath(const char* path)
|
lilv_realpath(const char* path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
if (!path) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
char* out = (char*)malloc(MAX_PATH);
|
char* out = (char*)malloc(MAX_PATH);
|
||||||
GetFullPathName(path, MAX_PATH, out, NULL);
|
GetFullPathName(path, MAX_PATH, out, NULL);
|
||||||
return out;
|
return out;
|
||||||
|
@ -427,6 +476,9 @@ lilv_symlink(const char* oldpath, const char* newpath)
|
||||||
if (strcmp(oldpath, newpath)) {
|
if (strcmp(oldpath, newpath)) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ret = !CreateSymbolicLink(newpath, oldpath, 0);
|
ret = !CreateSymbolicLink(newpath, oldpath, 0);
|
||||||
|
if (ret) {
|
||||||
|
ret = !CreateHardLink(newpath, oldpath, 0);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
ret = symlink(oldpath, newpath);
|
ret = symlink(oldpath, newpath);
|
||||||
#endif
|
#endif
|
||||||
|
@ -517,10 +569,8 @@ lilv_dir_for_each(const char* path,
|
||||||
#else
|
#else
|
||||||
DIR* dir = opendir(path);
|
DIR* dir = opendir(path);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
struct dirent entry;
|
for (struct dirent* entry; (entry = readdir(dir));) {
|
||||||
struct dirent* result;
|
f(path, entry->d_name, data);
|
||||||
while (!readdir_r(dir, &entry, &result) && result) {
|
|
||||||
f(path, entry.d_name, data);
|
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
@ -532,16 +582,23 @@ lilv_mkdir_p(const char* dir_path)
|
||||||
{
|
{
|
||||||
char* path = lilv_strdup(dir_path);
|
char* path = lilv_strdup(dir_path);
|
||||||
const size_t path_len = strlen(path);
|
const size_t path_len = strlen(path);
|
||||||
for (size_t i = 1; i <= path_len; ++i) {
|
size_t i = 1;
|
||||||
if (path[i] == LILV_DIR_SEP[0] || path[i] == '\0') {
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (is_windows_path(dir_path)) {
|
||||||
|
i = 3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (; i <= path_len; ++i) {
|
||||||
|
const char c = path[i];
|
||||||
|
if (c == LILV_DIR_SEP[0] || c == '/' || c == '\0') {
|
||||||
path[i] = '\0';
|
path[i] = '\0';
|
||||||
if (mkdir(path, 0755) && errno != EEXIST) {
|
if (mkdir(path, 0755) && errno != EEXIST) {
|
||||||
LILV_ERRORF("Failed to create %s (%s)\n",
|
|
||||||
path, strerror(errno));
|
|
||||||
free(path);
|
free(path);
|
||||||
return 1;
|
return errno;
|
||||||
}
|
}
|
||||||
path[i] = LILV_DIR_SEP[0];
|
path[i] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,19 +629,16 @@ lilv_file_equals(const char* a_path, const char* b_path)
|
||||||
FILE* b_file = NULL;
|
FILE* b_file = NULL;
|
||||||
char* const a_real = lilv_realpath(a_path);
|
char* const a_real = lilv_realpath(a_path);
|
||||||
char* const b_real = lilv_realpath(b_path);
|
char* const b_real = lilv_realpath(b_path);
|
||||||
if (!a_real || !b_real) {
|
if (!strcmp(a_real, b_real)) {
|
||||||
match = false; // Missing file matches nothing
|
|
||||||
} else if (!strcmp(a_real, b_real)) {
|
|
||||||
match = true; // Real paths match
|
match = true; // Real paths match
|
||||||
} else if (lilv_file_size(a_path) != lilv_file_size(b_path)) {
|
} else if (lilv_file_size(a_path) != lilv_file_size(b_path)) {
|
||||||
match = false; // Sizes differ
|
match = false; // Sizes differ
|
||||||
} else if (!(a_file = fopen(a_real, "rb"))) {
|
} else if (!(a_file = fopen(a_real, "rb")) ||
|
||||||
match = false; // Missing file matches nothing
|
!(b_file = fopen(b_real, "rb"))) {
|
||||||
} else if (!(b_file = fopen(b_real, "rb"))) {
|
|
||||||
match = false; // Missing file matches nothing
|
match = false; // Missing file matches nothing
|
||||||
} else {
|
} else {
|
||||||
match = true;
|
|
||||||
// TODO: Improve performance by reading chunks
|
// TODO: Improve performance by reading chunks
|
||||||
|
match = true;
|
||||||
while (!feof(a_file) && !feof(b_file)) {
|
while (!feof(a_file) && !feof(b_file)) {
|
||||||
if (fgetc(a_file) != fgetc(b_file)) {
|
if (fgetc(a_file) != fgetc(b_file)) {
|
||||||
match = false;
|
match = false;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2007-2014 David Robillard <http://drobilla.net>
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,42 +14,62 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lilv_config.h"
|
||||||
|
#include "lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "sord/sord.h"
|
||||||
|
#include "zix/common.h"
|
||||||
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#include "lv2/presets/presets.h"
|
||||||
|
|
||||||
|
#ifdef LILV_DYN_MANIFEST
|
||||||
|
# include "lv2/dynmanifest/dynmanifest.h"
|
||||||
|
# include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/presets/presets.h"
|
static int
|
||||||
|
lilv_world_drop_graph(LilvWorld* world, const SordNode* graph);
|
||||||
#include "lilv_internal.h"
|
|
||||||
|
|
||||||
LILV_API LilvWorld*
|
LILV_API LilvWorld*
|
||||||
lilv_world_new(void)
|
lilv_world_new(void)
|
||||||
{
|
{
|
||||||
LilvWorld* world = (LilvWorld*)malloc(sizeof(LilvWorld));
|
LilvWorld* world = (LilvWorld*)calloc(1, sizeof(LilvWorld));
|
||||||
|
|
||||||
world->world = sord_world_new();
|
world->world = sord_world_new();
|
||||||
if (!world->world)
|
if (!world->world) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
world->model = sord_new(world->world, SORD_SPO|SORD_OPS, true);
|
world->model = sord_new(world->world, SORD_SPO|SORD_OPS, true);
|
||||||
if (!world->model)
|
if (!world->model) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
world->specs = NULL;
|
world->specs = NULL;
|
||||||
world->plugin_classes = lilv_plugin_classes_new();
|
world->plugin_classes = lilv_plugin_classes_new();
|
||||||
world->plugins = lilv_plugins_new();
|
world->plugins = lilv_plugins_new();
|
||||||
|
world->zombies = lilv_plugins_new();
|
||||||
world->loaded_files = zix_tree_new(
|
world->loaded_files = zix_tree_new(
|
||||||
false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free);
|
false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free);
|
||||||
|
|
||||||
#ifdef LILV_NEW_LV2
|
|
||||||
world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL);
|
world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NS_DCTERMS "http://purl.org/dc/terms/"
|
#define NS_DCTERMS "http://purl.org/dc/terms/"
|
||||||
#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#"
|
#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#"
|
||||||
|
#define NS_OWL "http://www.w3.org/2002/07/owl#"
|
||||||
|
|
||||||
#define NEW_URI(uri) sord_new_uri(world->world, (const uint8_t*)uri)
|
#define NEW_URI(uri) sord_new_uri(world->world, (const uint8_t*)(uri))
|
||||||
|
|
||||||
world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces");
|
world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces");
|
||||||
world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest");
|
world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest");
|
||||||
|
@ -64,7 +84,9 @@ lilv_world_new(void)
|
||||||
world->uris.lv2_index = NEW_URI(LV2_CORE__index);
|
world->uris.lv2_index = NEW_URI(LV2_CORE__index);
|
||||||
world->uris.lv2_latency = NEW_URI(LV2_CORE__latency);
|
world->uris.lv2_latency = NEW_URI(LV2_CORE__latency);
|
||||||
world->uris.lv2_maximum = NEW_URI(LV2_CORE__maximum);
|
world->uris.lv2_maximum = NEW_URI(LV2_CORE__maximum);
|
||||||
|
world->uris.lv2_microVersion = NEW_URI(LV2_CORE__microVersion);
|
||||||
world->uris.lv2_minimum = NEW_URI(LV2_CORE__minimum);
|
world->uris.lv2_minimum = NEW_URI(LV2_CORE__minimum);
|
||||||
|
world->uris.lv2_minorVersion = NEW_URI(LV2_CORE__minorVersion);
|
||||||
world->uris.lv2_name = NEW_URI(LV2_CORE__name);
|
world->uris.lv2_name = NEW_URI(LV2_CORE__name);
|
||||||
world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature);
|
world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature);
|
||||||
world->uris.lv2_port = NEW_URI(LV2_CORE__port);
|
world->uris.lv2_port = NEW_URI(LV2_CORE__port);
|
||||||
|
@ -73,6 +95,7 @@ lilv_world_new(void)
|
||||||
world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature);
|
world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature);
|
||||||
world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol);
|
world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol);
|
||||||
world->uris.lv2_prototype = NEW_URI(LV2_CORE__prototype);
|
world->uris.lv2_prototype = NEW_URI(LV2_CORE__prototype);
|
||||||
|
world->uris.owl_Ontology = NEW_URI(NS_OWL "Ontology");
|
||||||
world->uris.pset_value = NEW_URI(LV2_PRESETS__value);
|
world->uris.pset_value = NEW_URI(LV2_PRESETS__value);
|
||||||
world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type");
|
world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type");
|
||||||
world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value");
|
world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value");
|
||||||
|
@ -133,13 +156,18 @@ lilv_world_free(LilvWorld* world)
|
||||||
zix_tree_free((ZixTree*)world->plugins);
|
zix_tree_free((ZixTree*)world->plugins);
|
||||||
world->plugins = NULL;
|
world->plugins = NULL;
|
||||||
|
|
||||||
|
LILV_FOREACH(plugins, i, world->zombies) {
|
||||||
|
const LilvPlugin* p = lilv_plugins_get(world->zombies, i);
|
||||||
|
lilv_plugin_free((LilvPlugin*)p);
|
||||||
|
}
|
||||||
|
zix_tree_free((ZixTree*)world->zombies);
|
||||||
|
world->zombies = NULL;
|
||||||
|
|
||||||
zix_tree_free((ZixTree*)world->loaded_files);
|
zix_tree_free((ZixTree*)world->loaded_files);
|
||||||
world->loaded_files = NULL;
|
world->loaded_files = NULL;
|
||||||
|
|
||||||
#ifdef LILV_NEW_LV2
|
zix_tree_free(world->libs);
|
||||||
zix_tree_free((ZixTree*)world->libs);
|
|
||||||
world->libs = NULL;
|
world->libs = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
zix_tree_free((ZixTree*)world->plugin_classes);
|
zix_tree_free((ZixTree*)world->plugin_classes);
|
||||||
world->plugin_classes = NULL;
|
world->plugin_classes = NULL;
|
||||||
|
@ -150,26 +178,32 @@ lilv_world_free(LilvWorld* world)
|
||||||
sord_world_free(world->world);
|
sord_world_free(world->world);
|
||||||
world->world = NULL;
|
world->world = NULL;
|
||||||
|
|
||||||
|
free(world->opt.lv2_path);
|
||||||
free(world);
|
free(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_world_set_option(LilvWorld* world,
|
lilv_world_set_option(LilvWorld* world,
|
||||||
const char* option,
|
const char* uri,
|
||||||
const LilvNode* value)
|
const LilvNode* value)
|
||||||
{
|
{
|
||||||
if (!strcmp(option, LILV_OPTION_DYN_MANIFEST)) {
|
if (!strcmp(uri, LILV_OPTION_DYN_MANIFEST)) {
|
||||||
if (lilv_node_is_bool(value)) {
|
if (lilv_node_is_bool(value)) {
|
||||||
world->opt.dyn_manifest = lilv_node_as_bool(value);
|
world->opt.dyn_manifest = lilv_node_as_bool(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(option, LILV_OPTION_FILTER_LANG)) {
|
} else if (!strcmp(uri, LILV_OPTION_FILTER_LANG)) {
|
||||||
if (lilv_node_is_bool(value)) {
|
if (lilv_node_is_bool(value)) {
|
||||||
world->opt.filter_language = lilv_node_as_bool(value);
|
world->opt.filter_language = lilv_node_as_bool(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(uri, LILV_OPTION_LV2_PATH)) {
|
||||||
|
if (lilv_node_is_string(value)) {
|
||||||
|
world->opt.lv2_path = lilv_strdup(lilv_node_as_string(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LILV_WARNF("Unrecognized or invalid option `%s'\n", option);
|
LILV_WARNF("Unrecognized or invalid option `%s'\n", uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API LilvNodes*
|
LILV_API LilvNodes*
|
||||||
|
@ -182,6 +216,9 @@ lilv_world_find_nodes(LilvWorld* world,
|
||||||
LILV_ERRORF("Subject `%s' is not a resource\n",
|
LILV_ERRORF("Subject `%s' is not a resource\n",
|
||||||
sord_node_get_string(subject->node));
|
sord_node_get_string(subject->node));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
} else if (!predicate) {
|
||||||
|
LILV_ERROR("Missing required predicate\n");
|
||||||
|
return NULL;
|
||||||
} else if (!lilv_node_is_uri(predicate)) {
|
} else if (!lilv_node_is_uri(predicate)) {
|
||||||
LILV_ERRORF("Predicate `%s' is not a URI\n",
|
LILV_ERRORF("Predicate `%s' is not a URI\n",
|
||||||
sord_node_get_string(predicate->node));
|
sord_node_get_string(predicate->node));
|
||||||
|
@ -190,7 +227,7 @@ lilv_world_find_nodes(LilvWorld* world,
|
||||||
LILV_ERROR("Both subject and object are NULL\n");
|
LILV_ERROR("Both subject and object are NULL\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lilv_world_find_nodes_internal(world,
|
return lilv_world_find_nodes_internal(world,
|
||||||
subject ? subject->node : NULL,
|
subject ? subject->node : NULL,
|
||||||
predicate->node,
|
predicate->node,
|
||||||
|
@ -237,8 +274,30 @@ lilv_world_ask(LilvWorld* world,
|
||||||
const LilvNode* predicate,
|
const LilvNode* predicate,
|
||||||
const LilvNode* object)
|
const LilvNode* object)
|
||||||
{
|
{
|
||||||
return sord_ask(
|
return sord_ask(world->model,
|
||||||
world->model, subject->node, predicate->node, object->node, NULL);
|
subject ? subject->node : NULL,
|
||||||
|
predicate ? predicate->node : NULL,
|
||||||
|
object ? object->node : NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SordModel*
|
||||||
|
lilv_world_filter_model(LilvWorld* world,
|
||||||
|
SordModel* model,
|
||||||
|
const SordNode* subject,
|
||||||
|
const SordNode* predicate,
|
||||||
|
const SordNode* object,
|
||||||
|
const SordNode* graph)
|
||||||
|
{
|
||||||
|
SordModel* results = sord_new(world->world, SORD_SPO, false);
|
||||||
|
SordIter* i = sord_search(model, subject, predicate, object, graph);
|
||||||
|
for (; !sord_iter_end(i); sord_iter_next(i)) {
|
||||||
|
SordQuad quad;
|
||||||
|
sord_iter_get(i, quad);
|
||||||
|
sord_add(results, quad);
|
||||||
|
}
|
||||||
|
sord_iter_free(i);
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
LilvNodes*
|
LilvNodes*
|
||||||
|
@ -258,12 +317,8 @@ lilv_new_uri_relative_to_base(const uint8_t* uri_str,
|
||||||
const uint8_t* base_uri_str)
|
const uint8_t* base_uri_str)
|
||||||
{
|
{
|
||||||
SerdURI base_uri;
|
SerdURI base_uri;
|
||||||
if (serd_uri_parse(base_uri_str, &base_uri)) {
|
serd_uri_parse(base_uri_str, &base_uri);
|
||||||
return SERD_NODE_NULL;
|
return serd_node_new_uri_from_string(uri_str, &base_uri, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
SerdURI ignored;
|
|
||||||
return serd_node_new_uri_from_string(uri_str, &base_uri, &ignored);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t*
|
const uint8_t*
|
||||||
|
@ -302,23 +357,24 @@ lilv_lib_compare(const void* a, const void* b, void* user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get an element of a collection of any object with an LilvHeader by URI. */
|
/** Get an element of a collection of any object with an LilvHeader by URI. */
|
||||||
struct LilvHeader*
|
static ZixTreeIter*
|
||||||
lilv_collection_get_by_uri(const ZixTree* const_seq,
|
lilv_collection_find_by_uri(const ZixTree* seq, const LilvNode* uri)
|
||||||
const LilvNode* uri)
|
|
||||||
{
|
{
|
||||||
if (!lilv_node_is_uri(uri)) {
|
ZixTreeIter* i = NULL;
|
||||||
return NULL;
|
if (lilv_node_is_uri(uri)) {
|
||||||
|
struct LilvHeader key = { NULL, (LilvNode*)uri };
|
||||||
|
zix_tree_find(seq, &key, &i);
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
ZixTree* seq = (ZixTree*)const_seq;
|
/** Get an element of a collection of any object with an LilvHeader by URI. */
|
||||||
struct LilvHeader key = { NULL, (LilvNode*)uri };
|
struct LilvHeader*
|
||||||
ZixTreeIter* i = NULL;
|
lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri)
|
||||||
ZixStatus st = zix_tree_find(seq, &key, &i);
|
{
|
||||||
if (!st) {
|
ZixTreeIter* const i = lilv_collection_find_by_uri(seq, uri);
|
||||||
return (struct LilvHeader*)zix_tree_get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return i ? (struct LilvHeader*)zix_tree_get(i) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -351,33 +407,55 @@ lilv_world_add_spec(LilvWorld* world,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lilv_world_add_plugin(LilvWorld* world,
|
lilv_world_add_plugin(LilvWorld* world,
|
||||||
const SordNode* plugin_node,
|
const SordNode* plugin_node,
|
||||||
const LilvNode* manifest_uri,
|
const LilvNode* manifest_uri,
|
||||||
void* dynmanifest,
|
void* dynmanifest,
|
||||||
const SordNode* bundle_node)
|
const SordNode* bundle)
|
||||||
{
|
{
|
||||||
LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node);
|
LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node);
|
||||||
|
ZixTreeIter* z = NULL;
|
||||||
|
LilvPlugin* plugin = (LilvPlugin*)lilv_plugins_get_by_uri(
|
||||||
|
world->plugins, plugin_uri);
|
||||||
|
|
||||||
const LilvPlugin* last = lilv_plugins_get_by_uri(world->plugins,
|
if (plugin) {
|
||||||
plugin_uri);
|
// Existing plugin, if this is different bundle, ignore it
|
||||||
if (last) {
|
// (use the first plugin found in LV2_PATH)
|
||||||
LILV_ERRORF("Duplicate plugin <%s>\n", lilv_node_as_uri(plugin_uri));
|
const LilvNode* last_bundle = lilv_plugin_get_bundle_uri(plugin);
|
||||||
LILV_ERRORF("... found in %s\n", lilv_node_as_string(
|
const char* plugin_uri_str = lilv_node_as_uri(plugin_uri);
|
||||||
lilv_plugin_get_bundle_uri(last)));
|
if (sord_node_equals(bundle, last_bundle->node)) {
|
||||||
LILV_ERRORF("... and %s\n", sord_node_get_string(bundle_node));
|
LILV_WARNF("Reloading plugin <%s>\n", plugin_uri_str);
|
||||||
|
plugin->loaded = false;
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
} else {
|
||||||
|
LILV_WARNF("Duplicate plugin <%s>\n", plugin_uri_str);
|
||||||
|
LILV_WARNF("... found in %s\n", lilv_node_as_string(last_bundle));
|
||||||
|
LILV_WARNF("... and %s (ignored)\n", sord_node_get_string(bundle));
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if ((z = lilv_collection_find_by_uri((const ZixTree*)world->zombies,
|
||||||
|
plugin_uri))) {
|
||||||
|
// Plugin bundle has been re-loaded, move from zombies to plugins
|
||||||
|
plugin = (LilvPlugin*)zix_tree_get(z);
|
||||||
|
zix_tree_remove((ZixTree*)world->zombies, z);
|
||||||
|
zix_tree_insert((ZixTree*)world->plugins, plugin, NULL);
|
||||||
lilv_node_free(plugin_uri);
|
lilv_node_free(plugin_uri);
|
||||||
return;
|
lilv_plugin_clear(plugin, lilv_node_new_from_node(world, bundle));
|
||||||
|
} else {
|
||||||
|
// Add new plugin to the world
|
||||||
|
plugin = lilv_plugin_new(
|
||||||
|
world, plugin_uri, lilv_node_new_from_node(world, bundle));
|
||||||
|
|
||||||
|
// Add manifest as plugin data file (as if it were rdfs:seeAlso)
|
||||||
|
zix_tree_insert((ZixTree*)plugin->data_uris,
|
||||||
|
lilv_node_duplicate(manifest_uri),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// Add plugin to world plugin sequence
|
||||||
|
zix_tree_insert((ZixTree*)world->plugins, plugin, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create LilvPlugin
|
|
||||||
LilvNode* bundle_uri = lilv_node_new_from_node(world, bundle_node);
|
|
||||||
LilvPlugin* plugin = lilv_plugin_new(world, plugin_uri, bundle_uri);
|
|
||||||
|
|
||||||
// Add manifest as plugin data file (as if it were rdfs:seeAlso)
|
|
||||||
zix_tree_insert((ZixTree*)plugin->data_uris,
|
|
||||||
lilv_node_duplicate(manifest_uri),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
#ifdef LILV_DYN_MANIFEST
|
#ifdef LILV_DYN_MANIFEST
|
||||||
// Set dynamic manifest library URI, if applicable
|
// Set dynamic manifest library URI, if applicable
|
||||||
|
@ -400,9 +478,6 @@ lilv_world_add_plugin(LilvWorld* world,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
sord_iter_free(files);
|
sord_iter_free(files);
|
||||||
|
|
||||||
// Add plugin to world plugin sequence
|
|
||||||
zix_tree_insert((ZixTree*)world->plugins, plugin, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SerdStatus
|
SerdStatus
|
||||||
|
@ -430,17 +505,18 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void* LV2_Dyn_Manifest_Handle;
|
|
||||||
LV2_Dyn_Manifest_Handle handle = NULL;
|
LV2_Dyn_Manifest_Handle handle = NULL;
|
||||||
|
|
||||||
// ?dman a dynman:DynManifest
|
// ?dman a dynman:DynManifest bundle_node
|
||||||
SordIter* dmanifests = sord_search(world->model,
|
SordModel* model = lilv_world_filter_model(world,
|
||||||
NULL,
|
world->model,
|
||||||
world->uris.rdf_a,
|
NULL,
|
||||||
world->uris.dman_DynManifest,
|
world->uris.rdf_a,
|
||||||
bundle_node);
|
world->uris.dman_DynManifest,
|
||||||
FOREACH_MATCH(dmanifests) {
|
bundle_node);
|
||||||
const SordNode* dmanifest = sord_iter_get_node(dmanifests, SORD_SUBJECT);
|
SordIter* iter = sord_begin(model);
|
||||||
|
for (; !sord_iter_end(iter); sord_iter_next(iter)) {
|
||||||
|
const SordNode* dmanifest = sord_iter_get_node(iter, SORD_SUBJECT);
|
||||||
|
|
||||||
// ?dman lv2:binary ?binary
|
// ?dman lv2:binary ?binary
|
||||||
SordIter* binaries = sord_search(world->model,
|
SordIter* binaries = sord_search(world->model,
|
||||||
|
@ -458,7 +534,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
// Get binary path
|
// Get binary path
|
||||||
const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT);
|
const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT);
|
||||||
const uint8_t* lib_uri = sord_node_get_string(binary);
|
const uint8_t* lib_uri = sord_node_get_string(binary);
|
||||||
const char* lib_path = lilv_uri_to_path((const char*)lib_uri);
|
char* lib_path = lilv_file_uri_parse((const char*)lib_uri, 0);
|
||||||
if (!lib_path) {
|
if (!lib_path) {
|
||||||
LILV_ERROR("No dynamic manifest library path\n");
|
LILV_ERROR("No dynamic manifest library path\n");
|
||||||
sord_iter_free(binaries);
|
sord_iter_free(binaries);
|
||||||
|
@ -466,10 +542,13 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open library
|
// Open library
|
||||||
|
dlerror();
|
||||||
void* lib = dlopen(lib_path, RTLD_LAZY);
|
void* lib = dlopen(lib_path, RTLD_LAZY);
|
||||||
if (!lib) {
|
if (!lib) {
|
||||||
LILV_ERRORF("Failed to open dynmanifest library `%s'\n", lib_path);
|
LILV_ERRORF("Failed to open dynmanifest library `%s' (%s)\n",
|
||||||
|
lib_path, dlerror());
|
||||||
sord_iter_free(binaries);
|
sord_iter_free(binaries);
|
||||||
|
lilv_free(lib_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +560,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path);
|
LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path);
|
||||||
sord_iter_free(binaries);
|
sord_iter_free(binaries);
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
|
lilv_free(lib_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,21 +573,25 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
lib_path);
|
lib_path);
|
||||||
sord_iter_free(binaries);
|
sord_iter_free(binaries);
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
|
lilv_free(lib_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LilvDynManifest* desc = malloc(sizeof(LilvDynManifest));
|
LilvDynManifest* desc = (LilvDynManifest*)malloc(sizeof(LilvDynManifest));
|
||||||
desc->bundle = lilv_node_new_from_node(world, bundle_node);
|
desc->bundle = lilv_node_new_from_node(world, bundle_node);
|
||||||
desc->lib = lib;
|
desc->lib = lib;
|
||||||
desc->handle = handle;
|
desc->handle = handle;
|
||||||
desc->refs = 0;
|
desc->refs = 0;
|
||||||
|
|
||||||
|
sord_iter_free(binaries);
|
||||||
|
|
||||||
// Generate data file
|
// Generate data file
|
||||||
FILE* fd = tmpfile();
|
FILE* fd = tmpfile();
|
||||||
get_subjects_func(handle, fd);
|
get_subjects_func(handle, fd);
|
||||||
rewind(fd);
|
rewind(fd);
|
||||||
|
|
||||||
// Parse generated data file
|
// Parse generated data file into temporary model
|
||||||
|
// FIXME
|
||||||
const SerdNode* base = sord_node_to_serd_node(dmanifest);
|
const SerdNode* base = sord_node_to_serd_node(dmanifest);
|
||||||
SerdEnv* env = serd_env_new(base);
|
SerdEnv* env = serd_env_new(base);
|
||||||
SerdReader* reader = sord_new_reader(
|
SerdReader* reader = sord_new_reader(
|
||||||
|
@ -523,38 +607,101 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
// ?plugin a lv2:Plugin
|
// ?plugin a lv2:Plugin
|
||||||
SordIter* plug_results = sord_search(
|
SordModel* plugins = lilv_world_filter_model(world,
|
||||||
world->model,
|
world->model,
|
||||||
NULL,
|
NULL,
|
||||||
world->uris.rdf_a,
|
world->uris.rdf_a,
|
||||||
world->uris.lv2_Plugin,
|
world->uris.lv2_Plugin,
|
||||||
dmanifest);
|
dmanifest);
|
||||||
FOREACH_MATCH(plug_results) {
|
SordIter* p = sord_begin(plugins);
|
||||||
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
FOREACH_MATCH(p) {
|
||||||
|
const SordNode* plug = sord_iter_get_node(p, SORD_SUBJECT);
|
||||||
lilv_world_add_plugin(world, plug, manifest, desc, bundle_node);
|
lilv_world_add_plugin(world, plug, manifest, desc, bundle_node);
|
||||||
}
|
}
|
||||||
sord_iter_free(plug_results);
|
if (desc->refs == 0) {
|
||||||
|
free(desc);
|
||||||
sord_iter_free(binaries);
|
}
|
||||||
|
sord_iter_free(p);
|
||||||
|
sord_free(plugins);
|
||||||
|
lilv_free(lib_path);
|
||||||
}
|
}
|
||||||
sord_iter_free(dmanifests);
|
sord_iter_free(iter);
|
||||||
|
sord_free(model);
|
||||||
#endif // LILV_DYN_MANIFEST
|
#endif // LILV_DYN_MANIFEST
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
LilvNode*
|
LilvNode*
|
||||||
lilv_world_get_manifest_uri(LilvWorld* world, LilvNode* bundle_uri)
|
lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri)
|
||||||
{
|
{
|
||||||
SerdNode manifest_uri = lilv_new_uri_relative_to_base(
|
SerdNode manifest_uri = lilv_new_uri_relative_to_base(
|
||||||
(const uint8_t*)"manifest.ttl",
|
(const uint8_t*)"manifest.ttl",
|
||||||
(const uint8_t*)sord_node_get_string(bundle_uri->node));
|
sord_node_get_string(bundle_uri->node));
|
||||||
LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf);
|
LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf);
|
||||||
serd_node_free(&manifest_uri);
|
serd_node_free(&manifest_uri);
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SordModel*
|
||||||
|
load_plugin_model(LilvWorld* world,
|
||||||
|
const LilvNode* bundle_uri,
|
||||||
|
const LilvNode* plugin_uri)
|
||||||
|
{
|
||||||
|
// Create model and reader for loading into it
|
||||||
|
SordNode* bundle_node = bundle_uri->node;
|
||||||
|
SordModel* model = sord_new(world->world, SORD_SPO|SORD_OPS, false);
|
||||||
|
SerdEnv* env = serd_env_new(sord_node_to_serd_node(bundle_node));
|
||||||
|
SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
|
||||||
|
|
||||||
|
// Load manifest
|
||||||
|
LilvNode* manifest_uri = lilv_world_get_manifest_uri(world, bundle_uri);
|
||||||
|
serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world));
|
||||||
|
serd_reader_read_file(
|
||||||
|
reader, (const uint8_t*)lilv_node_as_string(manifest_uri));
|
||||||
|
|
||||||
|
// Load any seeAlso files
|
||||||
|
SordModel* files = lilv_world_filter_model(
|
||||||
|
world, model, plugin_uri->node, world->uris.rdfs_seeAlso, NULL, NULL);
|
||||||
|
|
||||||
|
SordIter* f = sord_begin(files);
|
||||||
|
FOREACH_MATCH(f) {
|
||||||
|
const SordNode* file = sord_iter_get_node(f, SORD_OBJECT);
|
||||||
|
const uint8_t* file_str = sord_node_get_string(file);
|
||||||
|
if (sord_node_get_type(file) == SORD_URI) {
|
||||||
|
serd_reader_add_blank_prefix(
|
||||||
|
reader, lilv_world_blank_node_prefix(world));
|
||||||
|
serd_reader_read_file(reader, file_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sord_iter_free(f);
|
||||||
|
sord_free(files);
|
||||||
|
serd_reader_free(reader);
|
||||||
|
serd_env_free(env);
|
||||||
|
lilv_node_free(manifest_uri);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LilvVersion
|
||||||
|
get_version(LilvWorld* world, SordModel* model, const LilvNode* subject)
|
||||||
|
{
|
||||||
|
const SordNode* minor_node = sord_get(
|
||||||
|
model, subject->node, world->uris.lv2_minorVersion, NULL, NULL);
|
||||||
|
const SordNode* micro_node = sord_get(
|
||||||
|
model, subject->node, world->uris.lv2_microVersion, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
LilvVersion version = { 0, 0 };
|
||||||
|
if (minor_node && micro_node) {
|
||||||
|
version.minor = atoi((const char*)sord_node_get_string(minor_node));
|
||||||
|
version.micro = atoi((const char*)sord_node_get_string(micro_node));
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
|
lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri)
|
||||||
{
|
{
|
||||||
if (!lilv_node_is_uri(bundle_uri)) {
|
if (!lilv_node_is_uri(bundle_uri)) {
|
||||||
LILV_ERRORF("Bundle URI `%s' is not a URI\n",
|
LILV_ERRORF("Bundle URI `%s' is not a URI\n",
|
||||||
|
@ -572,13 +719,95 @@ lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
|
||||||
lilv_node_free(manifest);
|
lilv_node_free(manifest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?plugin a lv2:Plugin
|
// ?plugin a lv2:Plugin
|
||||||
SordIter* plug_results = sord_search(world->model,
|
SordIter* plug_results = sord_search(world->model,
|
||||||
NULL,
|
NULL,
|
||||||
world->uris.rdf_a,
|
world->uris.rdf_a,
|
||||||
world->uris.lv2_Plugin,
|
world->uris.lv2_Plugin,
|
||||||
bundle_node);
|
bundle_node);
|
||||||
|
|
||||||
|
// Find any loaded plugins that will be replaced with a newer version
|
||||||
|
LilvNodes* unload_uris = lilv_nodes_new();
|
||||||
|
FOREACH_MATCH(plug_results) {
|
||||||
|
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_node_new_from_node(world, plug);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, plugin_uri);
|
||||||
|
const LilvNode* last_bundle = plugin ? lilv_plugin_get_bundle_uri(plugin) : NULL;
|
||||||
|
if (!plugin || sord_node_equals(bundle_node, last_bundle->node)) {
|
||||||
|
// No previously loaded version, or it's from the same bundle
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare versions
|
||||||
|
SordModel* this_model = load_plugin_model(world, bundle_uri, plugin_uri);
|
||||||
|
LilvVersion this_version = get_version(world, this_model, plugin_uri);
|
||||||
|
SordModel* last_model = load_plugin_model(world, last_bundle, plugin_uri);
|
||||||
|
LilvVersion last_version = get_version(world, last_model, plugin_uri);
|
||||||
|
sord_free(this_model);
|
||||||
|
sord_free(last_model);
|
||||||
|
const int cmp = lilv_version_cmp(&this_version, &last_version);
|
||||||
|
if (cmp > 0) {
|
||||||
|
zix_tree_insert((ZixTree*)unload_uris,
|
||||||
|
lilv_node_duplicate(plugin_uri),
|
||||||
|
NULL);
|
||||||
|
LILV_WARNF("Replacing version %d.%d of <%s> from <%s>\n",
|
||||||
|
last_version.minor, last_version.micro,
|
||||||
|
sord_node_get_string(plug),
|
||||||
|
sord_node_get_string(last_bundle->node));
|
||||||
|
LILV_NOTEF("New version %d.%d found in <%s>\n",
|
||||||
|
this_version.minor, this_version.micro,
|
||||||
|
sord_node_get_string(bundle_node));
|
||||||
|
} else if (cmp < 0) {
|
||||||
|
LILV_WARNF("Ignoring bundle <%s>\n",
|
||||||
|
sord_node_get_string(bundle_node));
|
||||||
|
LILV_NOTEF("Newer version of <%s> loaded from <%s>\n",
|
||||||
|
sord_node_get_string(plug),
|
||||||
|
sord_node_get_string(last_bundle->node));
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
sord_iter_free(plug_results);
|
||||||
|
lilv_world_drop_graph(world, bundle_node);
|
||||||
|
lilv_node_free(manifest);
|
||||||
|
lilv_nodes_free(unload_uris);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
sord_iter_free(plug_results);
|
||||||
|
|
||||||
|
// Unload any old conflicting plugins
|
||||||
|
LilvNodes* unload_bundles = lilv_nodes_new();
|
||||||
|
LILV_FOREACH(nodes, i, unload_uris) {
|
||||||
|
const LilvNode* uri = lilv_nodes_get(unload_uris, i);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, uri);
|
||||||
|
const LilvNode* bundle = lilv_plugin_get_bundle_uri(plugin);
|
||||||
|
|
||||||
|
// Unload plugin and record bundle for later unloading
|
||||||
|
lilv_world_unload_resource(world, uri);
|
||||||
|
zix_tree_insert((ZixTree*)unload_bundles,
|
||||||
|
lilv_node_duplicate(bundle),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
lilv_nodes_free(unload_uris);
|
||||||
|
|
||||||
|
// Now unload the associated bundles
|
||||||
|
// This must be done last since several plugins could be in the same bundle
|
||||||
|
LILV_FOREACH(nodes, i, unload_bundles) {
|
||||||
|
lilv_world_unload_bundle(world, lilv_nodes_get(unload_bundles, i));
|
||||||
|
}
|
||||||
|
lilv_nodes_free(unload_bundles);
|
||||||
|
|
||||||
|
// Re-search for plugin results now that old plugins are gone
|
||||||
|
plug_results = sord_search(world->model,
|
||||||
|
NULL,
|
||||||
|
world->uris.rdf_a,
|
||||||
|
world->uris.lv2_Plugin,
|
||||||
|
bundle_node);
|
||||||
|
|
||||||
FOREACH_MATCH(plug_results) {
|
FOREACH_MATCH(plug_results) {
|
||||||
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
||||||
lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node);
|
lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node);
|
||||||
|
@ -587,34 +816,35 @@ lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
|
||||||
|
|
||||||
lilv_world_load_dyn_manifest(world, bundle_node, manifest);
|
lilv_world_load_dyn_manifest(world, bundle_node, manifest);
|
||||||
|
|
||||||
// ?specification a lv2:Specification
|
// ?spec a lv2:Specification
|
||||||
SordIter* spec_results = sord_search(world->model,
|
// ?spec a owl:Ontology
|
||||||
NULL,
|
const SordNode* spec_preds[] = { world->uris.lv2_Specification,
|
||||||
world->uris.rdf_a,
|
world->uris.owl_Ontology,
|
||||||
world->uris.lv2_Specification,
|
NULL };
|
||||||
bundle_node);
|
for (const SordNode** p = spec_preds; *p; ++p) {
|
||||||
FOREACH_MATCH(spec_results) {
|
SordIter* i = sord_search(
|
||||||
const SordNode* spec = sord_iter_get_node(spec_results, SORD_SUBJECT);
|
world->model, NULL, world->uris.rdf_a, *p, bundle_node);
|
||||||
lilv_world_add_spec(world, spec, bundle_node);
|
FOREACH_MATCH(i) {
|
||||||
|
const SordNode* spec = sord_iter_get_node(i, SORD_SUBJECT);
|
||||||
|
lilv_world_add_spec(world, spec, bundle_node);
|
||||||
|
}
|
||||||
|
sord_iter_free(i);
|
||||||
}
|
}
|
||||||
sord_iter_free(spec_results);
|
|
||||||
|
|
||||||
lilv_node_free(manifest);
|
lilv_node_free(manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lilv_world_drop_graph(LilvWorld* world, LilvNode* graph)
|
lilv_world_drop_graph(LilvWorld* world, const SordNode* graph)
|
||||||
{
|
{
|
||||||
SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph->node);
|
SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph);
|
||||||
|
|
||||||
while (!sord_iter_end(i)) {
|
while (!sord_iter_end(i)) {
|
||||||
// Get quad and increment iter so sord_remove doesn't invalidate it
|
const SerdStatus st = sord_erase(world->model, i);
|
||||||
SordQuad quad;
|
if (st) {
|
||||||
sord_iter_get(i, quad);
|
LILV_ERRORF("Error removing statement from <%s> (%s)\n",
|
||||||
sord_iter_next(i);
|
sord_node_get_string(graph), serd_strerror(st));
|
||||||
|
return st;
|
||||||
// Remove quad (nodes may now be deleted, quad is invalid)
|
}
|
||||||
sord_remove(world->model, quad);
|
|
||||||
}
|
}
|
||||||
sord_iter_free(i);
|
sord_iter_free(i);
|
||||||
|
|
||||||
|
@ -623,7 +853,7 @@ lilv_world_drop_graph(LilvWorld* world, LilvNode* graph)
|
||||||
|
|
||||||
/** Remove loaded_files entry so file will be reloaded if requested. */
|
/** Remove loaded_files entry so file will be reloaded if requested. */
|
||||||
static int
|
static int
|
||||||
lilv_world_unload_file(LilvWorld* world, LilvNode* file)
|
lilv_world_unload_file(LilvWorld* world, const LilvNode* file)
|
||||||
{
|
{
|
||||||
ZixTreeIter* iter;
|
ZixTreeIter* iter;
|
||||||
if (!zix_tree_find((ZixTree*)world->loaded_files, file, &iter)) {
|
if (!zix_tree_find((ZixTree*)world->loaded_files, file, &iter)) {
|
||||||
|
@ -634,31 +864,72 @@ lilv_world_unload_file(LilvWorld* world, LilvNode* file)
|
||||||
}
|
}
|
||||||
|
|
||||||
LILV_API int
|
LILV_API int
|
||||||
lilv_world_unload_bundle(LilvWorld* world, LilvNode* bundle_uri)
|
lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri)
|
||||||
{
|
{
|
||||||
// Remove loaded_files entry for manifest.ttl
|
if (!bundle_uri) {
|
||||||
LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri);
|
return 0;
|
||||||
lilv_world_unload_file(world, manifest);
|
}
|
||||||
lilv_node_free(manifest);
|
|
||||||
|
// Find all loaded files that are inside the bundle
|
||||||
|
LilvNodes* files = lilv_nodes_new();
|
||||||
|
LILV_FOREACH(nodes, i, world->loaded_files) {
|
||||||
|
const LilvNode* file = lilv_nodes_get(world->loaded_files, i);
|
||||||
|
if (!strncmp(lilv_node_as_string(file),
|
||||||
|
lilv_node_as_string(bundle_uri),
|
||||||
|
strlen(lilv_node_as_string(bundle_uri)))) {
|
||||||
|
zix_tree_insert((ZixTree*)files,
|
||||||
|
lilv_node_duplicate(file),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload all loaded files in the bundle
|
||||||
|
LILV_FOREACH(nodes, i, files) {
|
||||||
|
const LilvNode* file = lilv_nodes_get(world->plugins, i);
|
||||||
|
lilv_world_unload_file(world, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
lilv_nodes_free(files);
|
||||||
|
|
||||||
|
/* Remove any plugins in the bundle from the plugin list. Since the
|
||||||
|
application may still have a pointer to the LilvPlugin, it can not be
|
||||||
|
destroyed here. Instead, we move it to the zombie plugin list, so it
|
||||||
|
will not be in the list returned by lilv_world_get_all_plugins() but can
|
||||||
|
still be used.
|
||||||
|
*/
|
||||||
|
ZixTreeIter* i = zix_tree_begin((ZixTree*)world->plugins);
|
||||||
|
while (i != zix_tree_end((ZixTree*)world->plugins)) {
|
||||||
|
LilvPlugin* p = (LilvPlugin*)zix_tree_get(i);
|
||||||
|
ZixTreeIter* next = zix_tree_iter_next(i);
|
||||||
|
|
||||||
|
if (lilv_node_equals(lilv_plugin_get_bundle_uri(p), bundle_uri)) {
|
||||||
|
zix_tree_remove((ZixTree*)world->plugins, i);
|
||||||
|
zix_tree_insert((ZixTree*)world->zombies, p, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = next;
|
||||||
|
}
|
||||||
|
|
||||||
// Drop everything in bundle graph
|
// Drop everything in bundle graph
|
||||||
return lilv_world_drop_graph(world, bundle_uri);
|
return lilv_world_drop_graph(world, bundle_uri->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_dir_entry(const char* dir, const char* name, void* data)
|
load_dir_entry(const char* dir, const char* name, void* data)
|
||||||
{
|
{
|
||||||
LilvWorld* world = (LilvWorld*)data;
|
LilvWorld* world = (LilvWorld*)data;
|
||||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* scheme = (dir[0] == '/') ? "file://" : "file:///";
|
char* path = lilv_strjoin(dir, "/", name, "/", NULL);
|
||||||
char* uri = lilv_strjoin(scheme, dir, "/", name, "/", NULL);
|
SerdNode suri = serd_node_new_file_uri((const uint8_t*)path, 0, 0, true);
|
||||||
LilvNode* uri_val = lilv_new_uri(world, uri);
|
LilvNode* node = lilv_new_uri(world, (const char*)suri.buf);
|
||||||
|
|
||||||
lilv_world_load_bundle(world, uri_val);
|
lilv_world_load_bundle(world, node);
|
||||||
lilv_node_free(uri_val);
|
lilv_node_free(node);
|
||||||
free(uri);
|
serd_node_free(&suri);
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load all bundles in the directory at `dir_path`. */
|
/** Load all bundles in the directory at `dir_path`. */
|
||||||
|
@ -709,7 +980,7 @@ lilv_world_load_path(LilvWorld* world,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
lilv_world_load_specifications(LilvWorld* world)
|
lilv_world_load_specifications(LilvWorld* world)
|
||||||
{
|
{
|
||||||
for (LilvSpec* spec = world->specs; spec; spec = spec->next) {
|
for (LilvSpec* spec = world->specs; spec; spec = spec->next) {
|
||||||
|
@ -720,7 +991,7 @@ lilv_world_load_specifications(LilvWorld* world)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
lilv_world_load_plugin_classes(LilvWorld* world)
|
lilv_world_load_plugin_classes(LilvWorld* world)
|
||||||
{
|
{
|
||||||
/* FIXME: This loads all classes, not just lv2:Plugin subclasses.
|
/* FIXME: This loads all classes, not just lv2:Plugin subclasses.
|
||||||
|
@ -766,9 +1037,13 @@ lilv_world_load_plugin_classes(LilvWorld* world)
|
||||||
LILV_API void
|
LILV_API void
|
||||||
lilv_world_load_all(LilvWorld* world)
|
lilv_world_load_all(LilvWorld* world)
|
||||||
{
|
{
|
||||||
const char* lv2_path = getenv("LV2_PATH");
|
const char* lv2_path = world->opt.lv2_path;
|
||||||
if (!lv2_path)
|
if (!lv2_path) {
|
||||||
|
lv2_path = getenv("LV2_PATH");
|
||||||
|
}
|
||||||
|
if (!lv2_path) {
|
||||||
lv2_path = LILV_DEFAULT_LV2_PATH;
|
lv2_path = LILV_DEFAULT_LV2_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
// Discover bundles and read all manifest files into model
|
// Discover bundles and read all manifest files into model
|
||||||
lilv_world_load_path(world, lv2_path);
|
lilv_world_load_path(world, lv2_path);
|
||||||
|
@ -801,14 +1076,22 @@ lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri)
|
||||||
return SERD_FAILURE; // File has already been loaded
|
return SERD_FAILURE; // File has already been loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t uri_len;
|
||||||
|
const uint8_t* const uri_str = sord_node_get_string_counted(
|
||||||
|
uri->node, &uri_len);
|
||||||
|
if (strncmp((const char*)uri_str, "file:", 5)) {
|
||||||
|
return SERD_FAILURE; // Not a local file
|
||||||
|
} else if (strcmp((const char*)uri_str + uri_len - 4, ".ttl")) {
|
||||||
|
return SERD_FAILURE; // Not a Turtle file
|
||||||
|
}
|
||||||
|
|
||||||
serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world));
|
serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world));
|
||||||
const SerdStatus st = serd_reader_read_file(
|
const SerdStatus st = serd_reader_read_file(reader, uri_str);
|
||||||
reader, sord_node_get_string(uri->node));
|
|
||||||
if (st) {
|
if (st) {
|
||||||
LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri));
|
LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri));
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
zix_tree_insert((ZixTree*)world->loaded_files,
|
zix_tree_insert((ZixTree*)world->loaded_files,
|
||||||
lilv_node_duplicate(uri),
|
lilv_node_duplicate(uri),
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -825,13 +1108,16 @@ lilv_world_load_resource(LilvWorld* world,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SordModel* files = lilv_world_filter_model(world,
|
||||||
|
world->model,
|
||||||
|
resource->node,
|
||||||
|
world->uris.rdfs_seeAlso,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
SordIter* f = sord_begin(files);
|
||||||
int n_read = 0;
|
int n_read = 0;
|
||||||
SordIter* files = sord_search(world->model,
|
FOREACH_MATCH(f) {
|
||||||
resource->node,
|
const SordNode* file = sord_iter_get_node(f, SORD_OBJECT);
|
||||||
world->uris.rdfs_seeAlso,
|
|
||||||
NULL, NULL);
|
|
||||||
FOREACH_MATCH(files) {
|
|
||||||
const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
|
|
||||||
const uint8_t* file_str = sord_node_get_string(file);
|
const uint8_t* file_str = sord_node_get_string(file);
|
||||||
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
||||||
if (sord_node_get_type(file) != SORD_URI) {
|
if (sord_node_get_type(file) != SORD_URI) {
|
||||||
|
@ -841,8 +1127,9 @@ lilv_world_load_resource(LilvWorld* world,
|
||||||
}
|
}
|
||||||
lilv_node_free(file_node);
|
lilv_node_free(file_node);
|
||||||
}
|
}
|
||||||
sord_iter_free(files);
|
sord_iter_free(f);
|
||||||
|
|
||||||
|
sord_free(files);
|
||||||
return n_read;
|
return n_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,25 +1143,29 @@ lilv_world_unload_resource(LilvWorld* world,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SordModel* files = lilv_world_filter_model(world,
|
||||||
|
world->model,
|
||||||
|
resource->node,
|
||||||
|
world->uris.rdfs_seeAlso,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
SordIter* f = sord_begin(files);
|
||||||
int n_dropped = 0;
|
int n_dropped = 0;
|
||||||
SordIter* files = sord_search(world->model,
|
FOREACH_MATCH(f) {
|
||||||
resource->node,
|
const SordNode* file = sord_iter_get_node(f, SORD_OBJECT);
|
||||||
world->uris.rdfs_seeAlso,
|
|
||||||
NULL, NULL);
|
|
||||||
FOREACH_MATCH(files) {
|
|
||||||
const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
|
|
||||||
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
||||||
if (sord_node_get_type(file) != SORD_URI) {
|
if (sord_node_get_type(file) != SORD_URI) {
|
||||||
LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n",
|
LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n",
|
||||||
sord_node_get_string(file));
|
sord_node_get_string(file));
|
||||||
} else if (!lilv_world_drop_graph(world, file_node)) {
|
} else if (!lilv_world_drop_graph(world, file_node->node)) {
|
||||||
lilv_world_unload_file(world, file_node);
|
lilv_world_unload_file(world, file_node);
|
||||||
++n_dropped;
|
++n_dropped;
|
||||||
}
|
}
|
||||||
lilv_node_free(file_node);
|
lilv_node_free(file_node);
|
||||||
}
|
}
|
||||||
sord_iter_free(files);
|
sord_iter_free(f);
|
||||||
|
|
||||||
|
sord_free(files);
|
||||||
return n_dropped;
|
return n_dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,3 +1186,51 @@ lilv_world_get_all_plugins(const LilvWorld* world)
|
||||||
{
|
{
|
||||||
return world->plugins;
|
return world->plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LILV_API LilvNode*
|
||||||
|
lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject)
|
||||||
|
{
|
||||||
|
// Check for explicitly given symbol
|
||||||
|
SordNode* snode = sord_get(
|
||||||
|
world->model, subject->node, world->uris.lv2_symbol, NULL, NULL);
|
||||||
|
|
||||||
|
if (snode) {
|
||||||
|
LilvNode* ret = lilv_node_new_from_node(world, snode);
|
||||||
|
sord_node_free(world->world, snode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lilv_node_is_uri(subject)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find rightmost segment of URI
|
||||||
|
SerdURI uri;
|
||||||
|
serd_uri_parse((const uint8_t*)lilv_node_as_uri(subject), &uri);
|
||||||
|
const char* str = "_";
|
||||||
|
if (uri.fragment.buf) {
|
||||||
|
str = (const char*)uri.fragment.buf + 1;
|
||||||
|
} else if (uri.query.buf) {
|
||||||
|
str = (const char*)uri.query.buf;
|
||||||
|
} else if (uri.path.buf) {
|
||||||
|
const char* last_slash = strrchr((const char*)uri.path.buf, '/');
|
||||||
|
str = last_slash ? (last_slash + 1) : (const char*)uri.path.buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace invalid characters
|
||||||
|
const size_t len = strlen(str);
|
||||||
|
char* const sym = (char*)calloc(1, len + 1);
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
const char c = str[i];
|
||||||
|
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||||
|
(c == '_') || (i > 0 && c >= '0' && c <= '9'))) {
|
||||||
|
sym[i] = '_';
|
||||||
|
} else {
|
||||||
|
sym[i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LilvNode* ret = lilv_new_string(world, sym);
|
||||||
|
free(sym);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2011 David Robillard <http://drobilla.net>
|
Copyright 2016 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -59,7 +59,7 @@ typedef enum {
|
||||||
ZIX_STATUS_NOT_FOUND,
|
ZIX_STATUS_NOT_FOUND,
|
||||||
ZIX_STATUS_EXISTS,
|
ZIX_STATUS_EXISTS,
|
||||||
ZIX_STATUS_BAD_ARG,
|
ZIX_STATUS_BAD_ARG,
|
||||||
ZIX_STATUS_BAD_PERMS,
|
ZIX_STATUS_BAD_PERMS
|
||||||
} ZixStatus;
|
} ZixStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2011-2014 David Robillard <http://drobilla.net>
|
Copyright 2011-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,15 +14,14 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "zix/common.h"
|
#include "zix/common.h"
|
||||||
#include "zix/tree.h"
|
#include "zix/tree.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
typedef struct ZixTreeNodeImpl ZixTreeNode;
|
typedef struct ZixTreeNodeImpl ZixTreeNode;
|
||||||
|
|
||||||
struct ZixTreeImpl {
|
struct ZixTreeImpl {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2011-2014 David Robillard <http://drobilla.net>
|
Copyright 2011-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,10 +17,11 @@
|
||||||
#ifndef ZIX_TREE_H
|
#ifndef ZIX_TREE_H
|
||||||
#define ZIX_TREE_H
|
#define ZIX_TREE_H
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "zix/common.h"
|
#include "zix/common.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Bad syntax in plugin data file
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/bad-syntax"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Lilv Test Plugin - Bad syntax in plugin data file
|
||||||
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/bad-syntax>
|
||||||
|
a plugin with a clearly broken data file
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/bad-syntax>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <bad_syntax@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <bad_syntax.ttl> .
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/bad-syntax"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
|
||||||
|
TEST_ASSERT(!lilv_plugin_get_name(plugin));
|
||||||
|
TEST_ASSERT(!lilv_plugin_instantiate(plugin, 48000, NULL));
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://lv2plug.in/ns/lv2core>
|
||||||
|
a owl:Ontology .
|
||||||
|
|
||||||
|
lv2:PluginBase
|
||||||
|
a rdfs:Class ,
|
||||||
|
owl:Class ;
|
||||||
|
rdfs:label "Plugin Base" .
|
||||||
|
|
||||||
|
lv2:Plugin
|
||||||
|
a rdfs:Class ,
|
||||||
|
owl:Class ;
|
||||||
|
rdfs:subClassOf lv2:PluginBase ;
|
||||||
|
rdfs:label "Plugin" .
|
||||||
|
|
||||||
|
lv2:DynamicsPlugin
|
||||||
|
a rdfs:Class ,
|
||||||
|
owl:Class ;
|
||||||
|
rdfs:subClassOf lv2:Plugin ;
|
||||||
|
rdfs:label "Dynamics" .
|
||||||
|
|
||||||
|
lv2:CompressorPlugin
|
||||||
|
a rdfs:Class ,
|
||||||
|
owl:Class ;
|
||||||
|
rdfs:subClassOf lv2:DynamicsPlugin ;
|
||||||
|
rdfs:label "Compressor" .
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
||||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
<http://lv2plug.in/ns/lv2core>
|
<http://lv2plug.in/ns/lv2core>
|
||||||
a lv2:Specification ;
|
a lv2:Specification ;
|
||||||
lv2:minorVersion 12 ;
|
lv2:minorVersion 16 ;
|
||||||
lv2:microVersion 2 ;
|
lv2:microVersion 0 ;
|
||||||
rdfs:seeAlso <lv2core.ttl> .
|
rdfs:seeAlso <lv2core.ttl> .
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Failed instantiation
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/failed-instantiation"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Lilv Test Plugin - Failed instantiation
|
||||||
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/failed-instantiation>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
doap:name "New version" ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:minorVersion 2 ;
|
||||||
|
lv2:microVersion 1 ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/failed-instantiation>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <failed_instantiation@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <failed_instantiation.ttl> .
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
#include "serd/serd.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/failed-instantiation"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
TEST_ASSERT(!lilv_plugin_instantiate(plugin, 48000, NULL));
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2012 David Robillard <http://drobilla.net>
|
Lilv Test Plugin - Failed lib descriptor
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,21 +15,16 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LV2_MORPH_H
|
#include "lv2/core/lv2.h"
|
||||||
#define LV2_MORPH_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
#define PLUGIN_URI "http://example.org/failed-lib-descriptor"
|
||||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
|
||||||
|
|
||||||
#define LV2_MORPH_URI "http://lv2plug.in/ns/ext/morph"
|
LV2_SYMBOL_EXPORT
|
||||||
#define LV2_MORPH_PREFIX LV2_MORPH_URI "#"
|
const LV2_Lib_Descriptor*
|
||||||
|
lv2_lib_descriptor(const char* bundle_path,
|
||||||
#define LV2_MORPH__AutoMorphPort LV2_MORPH_PREFIX "AutoMorphPort"
|
const LV2_Feature*const* features)
|
||||||
#define LV2_MORPH__MorphPort LV2_MORPH_PREFIX "MorphPort"
|
{
|
||||||
#define LV2_MORPH__interface LV2_MORPH_PREFIX "interface"
|
return NULL;
|
||||||
#define LV2_MORPH__supportsType LV2_MORPH_PREFIX "supportsType"
|
}
|
||||||
#define LV2_MORPH__currentType LV2_MORPH_PREFIX "currentType"
|
|
||||||
|
|
||||||
#endif /* LV2_MORPH_H */
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Lilv Test Plugin - Failed lib descriptor
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/failed-lib-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:name "Missing descriptor test" ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/failed-lib-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <failed_lib_descriptor@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <failed_lib_descriptor.ttl> .
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/failed-lib-descriptor"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL);
|
||||||
|
TEST_ASSERT(!instance);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Missing descriptor
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/lib-descriptor"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LV2_Descriptor*
|
||||||
|
get_plugin(LV2_Lib_Handle handle, uint32_t index)
|
||||||
|
{
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return &descriptor;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Lib_Descriptor lib = {
|
||||||
|
NULL,
|
||||||
|
sizeof(LV2_Lib_Descriptor),
|
||||||
|
NULL,
|
||||||
|
get_plugin };
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Lib_Descriptor*
|
||||||
|
lv2_lib_descriptor(const char* bundle_path,
|
||||||
|
const LV2_Feature*const* features)
|
||||||
|
{
|
||||||
|
return &lib;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Lilv Test Plugin - Missing descriptor
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
|
||||||
|
<http://example.org/lib-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:name "Missing descriptor test" ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
<http://example.org/blob> "aGVsbG8sIHdvcmxk"^^xsd:base64Binary ;
|
||||||
|
<http://example.org/junk> "opaque"^^<http://example.org/binary> ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/lib-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <lib_descriptor@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <lib_descriptor.ttl> .
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/lib-descriptor"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL);
|
||||||
|
TEST_ASSERT(instance);
|
||||||
|
lilv_instance_free(instance);
|
||||||
|
|
||||||
|
LilvNode* eg_blob = lilv_new_uri(world, "http://example.org/blob");
|
||||||
|
LilvNode* blob = lilv_world_get(world, plugin_uri, eg_blob, NULL);
|
||||||
|
TEST_ASSERT(lilv_node_is_literal(blob));
|
||||||
|
lilv_node_free(blob);
|
||||||
|
lilv_node_free(eg_blob);
|
||||||
|
|
||||||
|
LilvNode* eg_junk = lilv_new_uri(world, "http://example.org/junk");
|
||||||
|
LilvNode* junk = lilv_world_get(world, plugin_uri, eg_junk, NULL);
|
||||||
|
TEST_ASSERT(lilv_node_is_literal(junk));
|
||||||
|
lilv_node_free(junk);
|
||||||
|
lilv_node_free(eg_junk);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lilv/lilvmm.hpp"
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
Lilv::World world;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <missing_descriptor@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <missing_descriptor.ttl> .
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Missing descriptor
|
||||||
|
Copyright 2011-2018 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const char* msg = "this is not the thing you're looking for";
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Lilv Test Plugin - Missing descriptor
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-descriptor>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:name "Missing descriptor test" ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-descriptor"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL);
|
||||||
|
TEST_ASSERT(!instance);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-name>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <missing_name@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <missing_name.ttl> .
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Missing name
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-name"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Lilv Test Plugin - Missing plugin name
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-name>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-name"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL);
|
||||||
|
TEST_ASSERT(instance);
|
||||||
|
lilv_instance_free(instance);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-plugin>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <missing_plugin@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <missing_plugin.ttl> .
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2012 David Robillard <http://drobilla.net>
|
Lilv Test Plugin - Missing plugin
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -14,21 +15,30 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
#include "lv2/core/lv2.h"
|
||||||
@file presets.h
|
|
||||||
|
|
||||||
C definitions for the LV2 Presets extension
|
#include <stdint.h>
|
||||||
<http://lv2plug.in/ns/ext/presets>.
|
#include <stdlib.h>
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LV2_PRESETS_H
|
#define PLUGIN_URI "http://example.org/missing-plugin"
|
||||||
#define LV2_PRESETS_H
|
|
||||||
|
|
||||||
#define LV2_PRESETS_URI "http://lv2plug.in/ns/ext/presets"
|
static const LV2_Descriptor descriptor = {
|
||||||
#define LV2_PRESETS_PREFIX LV2_PRESETS_URI "#"
|
"http://example.org/not-the-plugin-you-are-looking-for",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
#define LV2_PRESETS__Preset LV2_PRESETS_PREFIX "Preset"
|
LV2_SYMBOL_EXPORT
|
||||||
#define LV2_PRESETS__preset LV2_PRESETS_PREFIX "preset"
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
#define LV2_PRESETS__value LV2_PRESETS_PREFIX "value"
|
{
|
||||||
|
if (index == 0) {
|
||||||
|
return &descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LV2_PRESETS_H */
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Lilv Test Plugin - Missing plugin
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-plugin>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:name "Missing descriptor test" ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-plugin"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL);
|
||||||
|
TEST_ASSERT(!instance);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-port>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <missing_port@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <missing_port.ttl> .
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Missing port
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-port"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Lilv Test Plugin - Missing plugin port
|
||||||
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-port>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-port"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
|
||||||
|
// Check that all ports are ignored
|
||||||
|
TEST_ASSERT(lilv_plugin_get_num_ports(plugin) == 0);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-port-name>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <missing_port_name@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <missing_port_name.ttl> .
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Missing port name
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-port-name"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Lilv Test Plugin - Missing port name
|
||||||
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/missing-port-name>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
] .
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "../src/lilv_internal.h"
|
||||||
|
|
||||||
|
#include "serd/serd.h"
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/missing-port-name"
|
||||||
|
|
||||||
|
#define TEST_ASSERT(check) do {\
|
||||||
|
if (!(check)) {\
|
||||||
|
fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
|
||||||
|
return 1;\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* bundle_path = argv[1];
|
||||||
|
LilvWorld* world = lilv_world_new();
|
||||||
|
|
||||||
|
// Load test plugin bundle
|
||||||
|
uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
|
||||||
|
SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
|
||||||
|
LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
|
||||||
|
lilv_world_load_bundle(world, bundle_uri);
|
||||||
|
free(abs_bundle);
|
||||||
|
serd_node_free(&bundle);
|
||||||
|
lilv_node_free(bundle_uri);
|
||||||
|
|
||||||
|
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
|
||||||
|
TEST_ASSERT(plugin);
|
||||||
|
|
||||||
|
const LilvPort* port = lilv_plugin_get_port_by_index(plugin, 0);
|
||||||
|
TEST_ASSERT(port);
|
||||||
|
LilvNode* name = lilv_port_get_name(plugin, port);
|
||||||
|
TEST_ASSERT(!name);
|
||||||
|
lilv_node_free(name);
|
||||||
|
|
||||||
|
lilv_node_free(plugin_uri);
|
||||||
|
lilv_world_free(world);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/versioned>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <new_version@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <new_version.ttl> .
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - New version
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/versioned"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Lilv Test Plugin - New version
|
||||||
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/versioned>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
doap:name "New version" ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:minorVersion 2 ;
|
||||||
|
lv2:microVersion 1 ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -0,0 +1,7 @@
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<http://example.org/versioned>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
lv2:binary <old_version@SHLIB_EXT@> ;
|
||||||
|
rdfs:seeAlso <old_version.ttl> .
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Lilv Test Plugin - Old version
|
||||||
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PLUGIN_URI "http://example.org/versioned"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEST_INPUT = 0,
|
||||||
|
TEST_OUTPUT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float* input;
|
||||||
|
float* output;
|
||||||
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(LV2_Handle instance)
|
||||||
|
{
|
||||||
|
free((Test*)instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance, uint32_t port, void* data)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
switch (port) {
|
||||||
|
case TEST_INPUT:
|
||||||
|
test->input = (float*)data;
|
||||||
|
break;
|
||||||
|
case TEST_OUTPUT:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* path,
|
||||||
|
const LV2_Feature* const* features)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
|
if (!test) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (LV2_Handle)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
{
|
||||||
|
Test* test = (Test*)instance;
|
||||||
|
|
||||||
|
*test->output = *test->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
PLUGIN_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
NULL, // activate,
|
||||||
|
run,
|
||||||
|
NULL, // deactivate,
|
||||||
|
cleanup,
|
||||||
|
NULL // extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
return (index == 0) ? &descriptor : NULL;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Lilv Test Plugin - Old version
|
||||||
|
# Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
<http://example.org/versioned>
|
||||||
|
a lv2:Plugin ;
|
||||||
|
doap:license <http://opensource.org/licenses/isc> ;
|
||||||
|
doap:name "Old version" ;
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
|
lv2:minorVersion 1 ;
|
||||||
|
lv2:microVersion 0 ;
|
||||||
|
lv2:port [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 0 ;
|
||||||
|
lv2:symbol "input" ;
|
||||||
|
lv2:name "Input"
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 1 ;
|
||||||
|
lv2:symbol "output" ;
|
||||||
|
lv2:name "Output"
|
||||||
|
] .
|
|
@ -3,5 +3,5 @@
|
||||||
|
|
||||||
<http://example.org/lilv-test-plugin>
|
<http://example.org/lilv-test-plugin>
|
||||||
a lv2:Plugin ;
|
a lv2:Plugin ;
|
||||||
lv2:binary <test_plugin@SHLIB_EXT@> ;
|
lv2:binary <test@SHLIB_EXT@> ;
|
||||||
rdfs:seeAlso <test_plugin.ttl> .
|
rdfs:seeAlso <test.ttl> .
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Lilv Test Plugin
|
Lilv Test Plugin
|
||||||
Copyright 2011-2012 David Robillard <d@drobilla.net>
|
Copyright 2011-2019 David Robillard <d@drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -15,21 +15,31 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include "lv2/atom/atom.h"
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#include "lv2/state/state.h"
|
||||||
|
#include "lv2/urid/urid.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# include <io.h>
|
||||||
|
# define mkstemp(pat) _mktemp(pat)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/state/state.h"
|
|
||||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
|
||||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
|
||||||
|
|
||||||
#define TEST_URI "http://example.org/lilv-test-plugin"
|
#define TEST_URI "http://example.org/lilv-test-plugin"
|
||||||
|
|
||||||
|
#define TMP_TEMPLATE "lilv_testXXXXXX"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TEST_INPUT = 0,
|
TEST_INPUT = 0,
|
||||||
TEST_OUTPUT = 1
|
TEST_OUTPUT = 1,
|
||||||
|
TEST_CONTROL = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -39,7 +49,7 @@ typedef struct {
|
||||||
LV2_URID atom_Float;
|
LV2_URID atom_Float;
|
||||||
} uris;
|
} uris;
|
||||||
|
|
||||||
char* tmp_file_path;
|
char tmp_file_path[sizeof(TMP_TEMPLATE)];
|
||||||
char* rec_file_path;
|
char* rec_file_path;
|
||||||
FILE* rec_file;
|
FILE* rec_file;
|
||||||
|
|
||||||
|
@ -48,6 +58,16 @@ typedef struct {
|
||||||
unsigned num_runs;
|
unsigned num_runs;
|
||||||
} Test;
|
} Test;
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_path(char* path)
|
||||||
|
{
|
||||||
|
/* FIXME: Temporary hack to avoid mismatched malloc/free crashes on
|
||||||
|
Windows. The specifications needs a feature for this. */
|
||||||
|
#ifndef _WIN32
|
||||||
|
free(path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup(LV2_Handle instance)
|
cleanup(LV2_Handle instance)
|
||||||
{
|
{
|
||||||
|
@ -55,8 +75,7 @@ cleanup(LV2_Handle instance)
|
||||||
if (test->rec_file) {
|
if (test->rec_file) {
|
||||||
fclose(test->rec_file);
|
fclose(test->rec_file);
|
||||||
}
|
}
|
||||||
free(test->tmp_file_path);
|
free_path(test->rec_file_path);
|
||||||
free(test->rec_file_path);
|
|
||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +92,9 @@ connect_port(LV2_Handle instance,
|
||||||
case TEST_OUTPUT:
|
case TEST_OUTPUT:
|
||||||
test->output = (float*)data;
|
test->output = (float*)data;
|
||||||
break;
|
break;
|
||||||
|
case TEST_CONTROL:
|
||||||
|
test->output = (float*)data;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -84,20 +106,13 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||||
const char* path,
|
const char* path,
|
||||||
const LV2_Feature* const* features)
|
const LV2_Feature* const* features)
|
||||||
{
|
{
|
||||||
Test* test = (Test*)malloc(sizeof(Test));
|
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||||
if (!test) {
|
if (!test) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
test->map = NULL;
|
strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1);
|
||||||
test->input = NULL;
|
mkstemp(test->tmp_file_path);
|
||||||
test->output = NULL;
|
|
||||||
test->num_runs = 0;
|
|
||||||
test->tmp_file_path = (char*)malloc(L_tmpnam);
|
|
||||||
test->rec_file_path = NULL;
|
|
||||||
test->rec_file = NULL;
|
|
||||||
|
|
||||||
tmpnam(test->tmp_file_path);
|
|
||||||
|
|
||||||
LV2_State_Make_Path* make_path = NULL;
|
LV2_State_Make_Path* make_path = NULL;
|
||||||
|
|
||||||
|
@ -187,6 +202,27 @@ save(LV2_Handle instance,
|
||||||
map_uri(plugin, LV2_ATOM__URID),
|
map_uri(plugin, LV2_ATOM__URID),
|
||||||
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
|
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
|
||||||
|
|
||||||
|
// Try to store second value for the same property (should fail)
|
||||||
|
const uint32_t urid2 = map_uri(plugin, "http://example.org/urivalue2");
|
||||||
|
if (!store(callback_data,
|
||||||
|
map_uri(plugin, "http://example.org/uri"),
|
||||||
|
&urid2,
|
||||||
|
sizeof(uint32_t),
|
||||||
|
map_uri(plugin, LV2_ATOM__URID),
|
||||||
|
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) {
|
||||||
|
return LV2_STATE_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to store with a null key (should fail)
|
||||||
|
if (!store(callback_data,
|
||||||
|
0,
|
||||||
|
&urid2,
|
||||||
|
sizeof(uint32_t),
|
||||||
|
map_uri(plugin, LV2_ATOM__URID),
|
||||||
|
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) {
|
||||||
|
return LV2_STATE_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
store(callback_data,
|
store(callback_data,
|
||||||
map_uri(plugin, "http://example.org/num-runs"),
|
map_uri(plugin, "http://example.org/num-runs"),
|
||||||
&plugin->num_runs,
|
&plugin->num_runs,
|
||||||
|
@ -243,10 +279,10 @@ save(LV2_Handle instance,
|
||||||
apath,
|
apath,
|
||||||
strlen(apath) + 1,
|
strlen(apath) + 1,
|
||||||
map_uri(plugin, LV2_ATOM__Path),
|
map_uri(plugin, LV2_ATOM__Path),
|
||||||
LV2_STATE_IS_PORTABLE);
|
LV2_STATE_IS_POD);
|
||||||
|
|
||||||
free(apath);
|
free_path(apath);
|
||||||
free(apath2);
|
free_path(apath2);
|
||||||
|
|
||||||
if (plugin->rec_file) {
|
if (plugin->rec_file) {
|
||||||
fflush(plugin->rec_file);
|
fflush(plugin->rec_file);
|
||||||
|
@ -258,9 +294,9 @@ save(LV2_Handle instance,
|
||||||
apath,
|
apath,
|
||||||
strlen(apath) + 1,
|
strlen(apath) + 1,
|
||||||
map_uri(plugin, LV2_ATOM__Path),
|
map_uri(plugin, LV2_ATOM__Path),
|
||||||
LV2_STATE_IS_PORTABLE);
|
LV2_STATE_IS_POD);
|
||||||
|
|
||||||
free(apath);
|
free_path(apath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (make_path) {
|
if (make_path) {
|
||||||
|
@ -275,9 +311,9 @@ save(LV2_Handle instance,
|
||||||
apath,
|
apath,
|
||||||
strlen(apath) + 1,
|
strlen(apath) + 1,
|
||||||
map_uri(plugin, LV2_ATOM__Path),
|
map_uri(plugin, LV2_ATOM__Path),
|
||||||
LV2_STATE_IS_PORTABLE);
|
LV2_STATE_IS_POD);
|
||||||
free(apath);
|
free_path(apath);
|
||||||
free(spath);
|
free_path(spath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +354,11 @@ restore(LV2_Handle instance,
|
||||||
map_uri(plugin, "http://example.org/extfile"),
|
map_uri(plugin, "http://example.org/extfile"),
|
||||||
&size, &type, &valflags);
|
&size, &type, &valflags);
|
||||||
|
|
||||||
|
if (valflags != LV2_STATE_IS_POD) {
|
||||||
|
fprintf(stderr, "error: Restored bad file flags\n");
|
||||||
|
return LV2_STATE_ERR_BAD_FLAGS;
|
||||||
|
}
|
||||||
|
|
||||||
if (apath) {
|
if (apath) {
|
||||||
char* path = map_path->absolute_path(map_path->handle, apath);
|
char* path = map_path->absolute_path(map_path->handle, apath);
|
||||||
FILE* f = fopen(path, "r");
|
FILE* f = fopen(path, "r");
|
||||||
|
@ -328,7 +369,7 @@ restore(LV2_Handle instance,
|
||||||
fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n",
|
fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n",
|
||||||
str);
|
str);
|
||||||
}
|
}
|
||||||
free(path);
|
free_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
apath = (char*)retrieve(
|
apath = (char*)retrieve(
|
||||||
|
@ -343,7 +384,7 @@ restore(LV2_Handle instance,
|
||||||
} else {
|
} else {
|
||||||
fclose(sfile);
|
fclose(sfile);
|
||||||
}
|
}
|
||||||
free(spath);
|
free_path(spath);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "error: Failed to restore save file.\n");
|
fprintf(stderr, "error: Failed to restore save file.\n");
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
# Lilv Test Plugin
|
# Lilv Test Plugin
|
||||||
# Copyright 2011 David Robillard <d@drobilla.net>
|
# Copyright 2011-2015 David Robillard <d@drobilla.net>
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
# purpose with or without fee is hereby granted, provided that the above
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -37,4 +37,10 @@
|
||||||
lv2:index 1 ;
|
lv2:index 1 ;
|
||||||
lv2:symbol "output" ;
|
lv2:symbol "output" ;
|
||||||
lv2:name "Output"
|
lv2:name "Output"
|
||||||
|
] , [
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
lv2:index 2 ;
|
||||||
|
lv2:symbol "control" ;
|
||||||
|
lv2:name "Control"
|
||||||
] .
|
] .
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2011-2014 David Robillard <http://drobilla.net>
|
Copyright 2011-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -21,10 +21,10 @@
|
||||||
#ifndef BENCH_H
|
#ifndef BENCH_H
|
||||||
#define BENCH_H
|
#define BENCH_H
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 199309L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
static inline double
|
static inline double
|
||||||
bench_elapsed_s(const struct timespec* start, const struct timespec* end)
|
bench_elapsed_s(const struct timespec* start, const struct timespec* end)
|
||||||
|
|
|
@ -14,12 +14,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "lilv/lilv.h"
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
#include "lilv_config.h"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,357 @@
|
||||||
|
/*
|
||||||
|
Copyright 2007-2019 David Robillard <http://drobilla.net>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lilv/lilv.h"
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <sndfile.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/** Control port value set from the command line */
|
||||||
|
typedef struct Param {
|
||||||
|
const char* sym; ///< Port symbol
|
||||||
|
float value; ///< Control value
|
||||||
|
} Param;
|
||||||
|
|
||||||
|
/** Port type (only float ports are supported) */
|
||||||
|
typedef enum {
|
||||||
|
TYPE_CONTROL,
|
||||||
|
TYPE_AUDIO
|
||||||
|
} PortType;
|
||||||
|
|
||||||
|
/** Runtime port information */
|
||||||
|
typedef struct {
|
||||||
|
const LilvPort* lilv_port; ///< Port description
|
||||||
|
PortType type; ///< Datatype
|
||||||
|
uint32_t index; ///< Port index
|
||||||
|
float value; ///< Control value (if applicable)
|
||||||
|
bool is_input; ///< True iff an input port
|
||||||
|
bool optional; ///< True iff connection optional
|
||||||
|
} Port;
|
||||||
|
|
||||||
|
/** Application state */
|
||||||
|
typedef struct {
|
||||||
|
LilvWorld* world;
|
||||||
|
const LilvPlugin* plugin;
|
||||||
|
LilvInstance* instance;
|
||||||
|
const char* in_path;
|
||||||
|
const char* out_path;
|
||||||
|
SNDFILE* in_file;
|
||||||
|
SNDFILE* out_file;
|
||||||
|
unsigned n_params;
|
||||||
|
Param* params;
|
||||||
|
unsigned n_ports;
|
||||||
|
unsigned n_audio_in;
|
||||||
|
unsigned n_audio_out;
|
||||||
|
Port* ports;
|
||||||
|
} LV2Apply;
|
||||||
|
|
||||||
|
static int fatal(LV2Apply* self, int status, const char* fmt, ...);
|
||||||
|
|
||||||
|
/** Open a sound file with error handling. */
|
||||||
|
static SNDFILE*
|
||||||
|
sopen(LV2Apply* self, const char* path, int mode, SF_INFO* fmt)
|
||||||
|
{
|
||||||
|
SNDFILE* file = sf_open(path, mode, fmt);
|
||||||
|
const int st = sf_error(file);
|
||||||
|
if (st) {
|
||||||
|
fatal(self, 1, "Failed to open %s (%s)\n", path, sf_error_number(st));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close a sound file with error handling. */
|
||||||
|
static void
|
||||||
|
sclose(const char* path, SNDFILE* file)
|
||||||
|
{
|
||||||
|
int st;
|
||||||
|
if (file && (st = sf_close(file))) {
|
||||||
|
fatal(NULL, 1, "Failed to close %s (%s)\n", path, sf_error_number(st));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read a single frame from a file into an interleaved buffer.
|
||||||
|
|
||||||
|
If more channels are required than are available in the file, the remaining
|
||||||
|
channels are distributed in a round-robin fashion (LRLRL).
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
sread(SNDFILE* file, unsigned file_chans, float* buf, unsigned buf_chans)
|
||||||
|
{
|
||||||
|
const sf_count_t n_read = sf_readf_float(file, buf, 1);
|
||||||
|
for (unsigned i = file_chans - 1; i < buf_chans; ++i) {
|
||||||
|
buf[i] = buf[i % file_chans];
|
||||||
|
}
|
||||||
|
return n_read == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Clean up all resources. */
|
||||||
|
static int
|
||||||
|
cleanup(int status, LV2Apply* self)
|
||||||
|
{
|
||||||
|
sclose(self->in_path, self->in_file);
|
||||||
|
sclose(self->out_path, self->out_file);
|
||||||
|
lilv_instance_free(self->instance);
|
||||||
|
lilv_world_free(self->world);
|
||||||
|
free(self->ports);
|
||||||
|
free(self->params);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Print a fatal error and clean up for exit. */
|
||||||
|
static int
|
||||||
|
fatal(LV2Apply* self, int status, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
fprintf(stderr, "error: ");
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return self ? cleanup(status, self) : status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create port structures from data (via create_port()) for all ports.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
create_ports(LV2Apply* self)
|
||||||
|
{
|
||||||
|
LilvWorld* world = self->world;
|
||||||
|
const uint32_t n_ports = lilv_plugin_get_num_ports(self->plugin);
|
||||||
|
|
||||||
|
self->n_ports = n_ports;
|
||||||
|
self->ports = (Port*)calloc(self->n_ports, sizeof(Port));
|
||||||
|
|
||||||
|
/* Get default values for all ports */
|
||||||
|
float* values = (float*)calloc(n_ports, sizeof(float));
|
||||||
|
lilv_plugin_get_port_ranges_float(self->plugin, NULL, NULL, values);
|
||||||
|
|
||||||
|
LilvNode* lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort);
|
||||||
|
LilvNode* lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort);
|
||||||
|
LilvNode* lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort);
|
||||||
|
LilvNode* lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort);
|
||||||
|
LilvNode* lv2_connectionOptional = lilv_new_uri(world, LV2_CORE__connectionOptional);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < n_ports; ++i) {
|
||||||
|
Port* port = &self->ports[i];
|
||||||
|
const LilvPort* lport = lilv_plugin_get_port_by_index(self->plugin, i);
|
||||||
|
|
||||||
|
port->lilv_port = lport;
|
||||||
|
port->index = i;
|
||||||
|
port->value = isnan(values[i]) ? 0.0f : values[i];
|
||||||
|
port->optional = lilv_port_has_property(
|
||||||
|
self->plugin, lport, lv2_connectionOptional);
|
||||||
|
|
||||||
|
/* Check if port is an input or output */
|
||||||
|
if (lilv_port_is_a(self->plugin, lport, lv2_InputPort)) {
|
||||||
|
port->is_input = true;
|
||||||
|
} else if (!lilv_port_is_a(self->plugin, lport, lv2_OutputPort) &&
|
||||||
|
!port->optional) {
|
||||||
|
return fatal(self, 1, "Port %d is neither input nor output\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if port is an audio or control port */
|
||||||
|
if (lilv_port_is_a(self->plugin, lport, lv2_ControlPort)) {
|
||||||
|
port->type = TYPE_CONTROL;
|
||||||
|
} else if (lilv_port_is_a(self->plugin, lport, lv2_AudioPort)) {
|
||||||
|
port->type = TYPE_AUDIO;
|
||||||
|
if (port->is_input) {
|
||||||
|
++self->n_audio_in;
|
||||||
|
} else {
|
||||||
|
++self->n_audio_out;
|
||||||
|
}
|
||||||
|
} else if (!port->optional) {
|
||||||
|
return fatal(self, 1, "Port %d has unsupported type\n", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lilv_node_free(lv2_connectionOptional);
|
||||||
|
lilv_node_free(lv2_ControlPort);
|
||||||
|
lilv_node_free(lv2_AudioPort);
|
||||||
|
lilv_node_free(lv2_OutputPort);
|
||||||
|
lilv_node_free(lv2_InputPort);
|
||||||
|
free(values);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_version(void)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"lv2apply (lilv) " LILV_VERSION "\n"
|
||||||
|
"Copyright 2007-2019 David Robillard <http://drobilla.net>\n"
|
||||||
|
"License: <http://www.opensource.org/licenses/isc-license>\n"
|
||||||
|
"This is free software: you are free to change and redistribute it.\n"
|
||||||
|
"There is NO WARRANTY, to the extent permitted by law.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_usage(int status)
|
||||||
|
{
|
||||||
|
fprintf(status ? stderr : stdout,
|
||||||
|
"Usage: lv2apply [OPTION]... PLUGIN_URI\n"
|
||||||
|
"Apply an LV2 plugin to an audio file.\n\n"
|
||||||
|
" -i IN_FILE Input file\n"
|
||||||
|
" -o OUT_FILE Output file\n"
|
||||||
|
" -c SYM VAL Control value\n"
|
||||||
|
" --help Display this help and exit\n"
|
||||||
|
" --version Display version information and exit\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
LV2Apply self = {
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Parse command line arguments */
|
||||||
|
const char* plugin_uri = NULL;
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
if (!strcmp(argv[i], "--version")) {
|
||||||
|
free(self.params);
|
||||||
|
print_version();
|
||||||
|
return 0;
|
||||||
|
} else if (!strcmp(argv[i], "--help")) {
|
||||||
|
free(self.params);
|
||||||
|
return print_usage(0);
|
||||||
|
} else if (!strcmp(argv[i], "-i")) {
|
||||||
|
self.in_path = argv[++i];
|
||||||
|
} else if (!strcmp(argv[i], "-o")) {
|
||||||
|
self.out_path = argv[++i];
|
||||||
|
} else if (!strcmp(argv[i], "-c")) {
|
||||||
|
if (argc < i + 3) {
|
||||||
|
return fatal(&self, 1, "Missing argument for -c\n");
|
||||||
|
}
|
||||||
|
self.params = (Param*)realloc(self.params,
|
||||||
|
++self.n_params * sizeof(Param));
|
||||||
|
self.params[self.n_params - 1].sym = argv[++i];
|
||||||
|
self.params[self.n_params - 1].value = atof(argv[++i]);
|
||||||
|
} else if (argv[i][0] == '-') {
|
||||||
|
free(self.params);
|
||||||
|
return print_usage(1);
|
||||||
|
} else if (i == argc - 1) {
|
||||||
|
plugin_uri = argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that required arguments are given */
|
||||||
|
if (!self.in_path || !self.out_path || !plugin_uri) {
|
||||||
|
free(self.params);
|
||||||
|
return print_usage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create world and plugin URI */
|
||||||
|
self.world = lilv_world_new();
|
||||||
|
LilvNode* uri = lilv_new_uri(self.world, plugin_uri);
|
||||||
|
if (!uri) {
|
||||||
|
return fatal(&self, 2, "Invalid plugin URI <%s>\n", plugin_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Discover world */
|
||||||
|
lilv_world_load_all(self.world);
|
||||||
|
|
||||||
|
/* Get plugin */
|
||||||
|
const LilvPlugins* plugins = lilv_world_get_all_plugins(self.world);
|
||||||
|
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, uri);
|
||||||
|
lilv_node_free(uri);
|
||||||
|
if (!(self.plugin = plugin)) {
|
||||||
|
return fatal(&self, 3, "Plugin <%s> not found\n", plugin_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open input file */
|
||||||
|
SF_INFO in_fmt = { 0, 0, 0, 0, 0, 0 };
|
||||||
|
if (!(self.in_file = sopen(&self, self.in_path, SFM_READ, &in_fmt))) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create port structures */
|
||||||
|
if (create_ports(&self)) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.n_audio_in == 0 ||
|
||||||
|
(in_fmt.channels != (int)self.n_audio_in && in_fmt.channels != 1)) {
|
||||||
|
return fatal(&self, 6, "Unable to map %d inputs to %d ports\n",
|
||||||
|
in_fmt.channels, self.n_audio_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set control values */
|
||||||
|
for (unsigned i = 0; i < self.n_params; ++i) {
|
||||||
|
const Param* param = &self.params[i];
|
||||||
|
LilvNode* sym = lilv_new_string(self.world, param->sym);
|
||||||
|
const LilvPort* port = lilv_plugin_get_port_by_symbol(plugin, sym);
|
||||||
|
lilv_node_free(sym);
|
||||||
|
if (!port) {
|
||||||
|
return fatal(&self, 7, "Unknown port `%s'\n", param->sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ports[lilv_port_get_index(plugin, port)].value = param->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open output file */
|
||||||
|
SF_INFO out_fmt = in_fmt;
|
||||||
|
out_fmt.channels = self.n_audio_out;
|
||||||
|
if (!(self.out_file = sopen(&self, self.out_path, SFM_WRITE, &out_fmt))) {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Instantiate plugin and connect ports */
|
||||||
|
const uint32_t n_ports = lilv_plugin_get_num_ports(plugin);
|
||||||
|
float in_buf[self.n_audio_in];
|
||||||
|
float out_buf[self.n_audio_out];
|
||||||
|
self.instance = lilv_plugin_instantiate(
|
||||||
|
self.plugin, in_fmt.samplerate, NULL);
|
||||||
|
for (uint32_t p = 0, i = 0, o = 0; p < n_ports; ++p) {
|
||||||
|
if (self.ports[p].type == TYPE_CONTROL) {
|
||||||
|
lilv_instance_connect_port(self.instance, p, &self.ports[p].value);
|
||||||
|
} else if (self.ports[p].type == TYPE_AUDIO) {
|
||||||
|
if (self.ports[p].is_input) {
|
||||||
|
lilv_instance_connect_port(self.instance, p, in_buf + i++);
|
||||||
|
} else {
|
||||||
|
lilv_instance_connect_port(self.instance, p, out_buf + o++);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lilv_instance_connect_port(self.instance, p, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ports are now connected to buffers in interleaved format, so we can run
|
||||||
|
a single frame at a time and avoid having to interleave buffers to
|
||||||
|
read/write from/to sndfile. */
|
||||||
|
|
||||||
|
lilv_instance_activate(self.instance);
|
||||||
|
while (sread(self.in_file, in_fmt.channels, in_buf, self.n_audio_in)) {
|
||||||
|
lilv_instance_run(self.instance, 1);
|
||||||
|
if (sf_writef_float(self.out_file, out_buf, 1) != 1) {
|
||||||
|
return fatal(&self, 9, "Failed to write to output file\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lilv_instance_deactivate(self.instance);
|
||||||
|
|
||||||
|
return cleanup(0, &self);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue