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
|
||||
|
||||
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
|
||||
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
|
||||
./waf install
|
||||
|
||||
You may need to become root for the install stage, for example:
|
||||
|
||||
sudo ./waf install
|
||||
./waf install # or sudo ./waf install
|
||||
|
||||
Configuration Options
|
||||
---------------------
|
||||
|
@ -40,12 +36,20 @@ invoked:
|
|||
* CPPFLAGS: C preprocessor options
|
||||
* LINKFLAGS: Linker options
|
||||
|
||||
Installation Directories
|
||||
------------------------
|
||||
Library Versioning
|
||||
------------------
|
||||
|
||||
The --prefix option (or the PREFIX environment variable) can be used to change
|
||||
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.
|
||||
This library uses semantic versioning <http://semver.org/>.
|
||||
|
||||
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
|
||||
---------
|
||||
|
@ -57,3 +61,6 @@ which adds a prefix to all install paths. For example:
|
|||
./waf configure --prefix=/usr
|
||||
./waf
|
||||
./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;
|
||||
|
||||
* 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
|
||||
several plugins
|
||||
* Call lv2_lib_descriptor separately for different bundle paths
|
||||
(fix loading several dynamic plugins like Ingen at once)
|
||||
* 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 issues with lilv_plugin_get_author_name and friends (thanks Filipe
|
||||
Coelho)
|
||||
* 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
|
||||
* 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
|
||||
|
||||
-- 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;
|
||||
|
||||
* Allow lilv_state_restore() to be used without passing an instance,
|
||||
for restoring port values via a callback only
|
||||
* Fix unlikely memory leak in lilv_plugin_instantiate()
|
||||
* Support denoting latency ports with lv2:designation lv2:latency
|
||||
* Add lilv_port_get_node() for using world query functions with ports
|
||||
* Add support for running plugins from Python by Kaspar Emanuel
|
||||
* Allow lilv_state_restore() to be used without passing an instance, for
|
||||
restoring port values via a callback only
|
||||
* Allow passing NULL port_class to lilv_plugin_get_port_by_designation
|
||||
* 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
|
||||
* Add lilv_port_get_node() for using world query functions with ports
|
||||
* lv2info: Don't display invalid control maxes and defaults
|
||||
(patch from Robin Gareus)
|
||||
* Fix unlikely memory leak in lilv_plugin_instantiate()
|
||||
* Support denoting latency ports with lv2:designation lv2:latency
|
||||
* 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;
|
||||
|
||||
* Add lilv_nodes_merge()
|
||||
* 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_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()
|
||||
* Fix several plugin functions that failed to load data if called first
|
||||
* Correctly depend on serd at build time (fix compilation in odd cases)
|
||||
* Disable timestamps in HTML documentation for reproducible build
|
||||
* lilvmm.hpp: Support varargs for Plugin::get_num_ports_of_class()
|
||||
* lilvmm.hpp: Add several missing methods
|
||||
* Fail gracefully when lilv_state_new_from_string() is called on NULL
|
||||
* 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)
|
||||
* 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;
|
||||
|
||||
* Add lv2bench utility
|
||||
* Add option to build utilities as static binaries
|
||||
* 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 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
|
||||
* Make all 'zix' symbols private to avoid symbol clashes in static builds
|
||||
* Reduce memory usage (per node)
|
||||
* 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
|
||||
* 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_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;
|
||||
|
||||
* 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;
|
||||
|
||||
* 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
|
||||
* 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
|
||||
improved generic alternative to lilv_plugin_get_latency_port_index().
|
||||
* Add lilv_plugin_get_project() and get author information from project if
|
||||
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;
|
||||
|
||||
* Remove glib dependency
|
||||
* Add ability to build static library
|
||||
* Add lv2core as a pkg-config dependency (for lv2.h header include)
|
||||
* Obey prefix when installing bash completion script
|
||||
* Remove glib dependency
|
||||
* Support integer minimum, maximum, and default port values in
|
||||
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;
|
||||
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
* Fix compilation issues on some systems
|
||||
* 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;
|
||||
|
||||
* 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]
|
||||
|
||||
channels = []
|
||||
for i in xrange(self.nchannels):
|
||||
channels.append([data[j] for j in xrange(0, len(data), self.nchannels) ])
|
||||
for i in range(self.nchannels):
|
||||
channels.append([data[j] for j in range(0, len(data), self.nchannels) ])
|
||||
|
||||
return channels
|
||||
|
||||
|
@ -57,6 +57,7 @@ def main():
|
|||
|
||||
# Initialise Lilv
|
||||
world = lilv.World()
|
||||
ns = world.ns
|
||||
world.load_all()
|
||||
|
||||
plugin_uri = sys.argv[1]
|
||||
|
@ -65,19 +66,14 @@ def main():
|
|||
|
||||
# Find plugin
|
||||
plugin_uri_node = world.new_uri(plugin_uri)
|
||||
plugin = world.get_all_plugins().get_by_uri(plugin_uri_node)
|
||||
if not plugin:
|
||||
print("Unknown plugin `%s'\n" % plugin_uri)
|
||||
plugins = world.get_all_plugins()
|
||||
if plugin_uri_node not in plugins:
|
||||
print("Unknown plugin `%s'" % plugin_uri)
|
||||
sys.exit(1)
|
||||
|
||||
lv2_InputPort = world.new_uri(lilv.LILV_URI_INPUT_PORT)
|
||||
lv2_OutputPort = world.new_uri(lilv.LILV_URI_OUTPUT_PORT)
|
||||
lv2_AudioPort = world.new_uri(lilv.LILV_URI_AUDIO_PORT)
|
||||
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)
|
||||
plugin = plugins[plugin_uri_node]
|
||||
n_audio_in = plugin.get_num_ports_of_class(ns.lv2.InputPort, ns.lv2.AudioPort)
|
||||
n_audio_out = plugin.get_num_ports_of_class(ns.lv2.OutputPort, ns.lv2.AudioPort)
|
||||
if n_audio_out == 0:
|
||||
print("Plugin has no audio outputs\n")
|
||||
sys.exit(1)
|
||||
|
@ -120,22 +116,21 @@ def main():
|
|||
control_output_buffers = []
|
||||
for index in range(plugin.get_num_ports()):
|
||||
port = plugin.get_port_by_index(index)
|
||||
if port.is_a(lv2_InputPort):
|
||||
if port.is_a(lv2_AudioPort):
|
||||
if port.is_a(ns.lv2.InputPort):
|
||||
if port.is_a(ns.lv2.AudioPort):
|
||||
audio_input_buffers.append(numpy.array(channels[len(audio_input_buffers)], numpy.float32))
|
||||
instance.connect_port(index, audio_input_buffers[-1])
|
||||
elif port.is_a(lv2_ControlPort):
|
||||
#if port.has_property(lv2_default): # Doesn't seem to work
|
||||
default = lilv.lilv_node_as_float(lilv.lilv_nodes_get_first(port.get_value(lv2_default)))
|
||||
elif port.is_a(ns.lv2.ControlPort):
|
||||
default = float(port.get(ns.lv2.default))
|
||||
control_input_buffers.append(numpy.array([default], numpy.float32))
|
||||
instance.connect_port(index, control_input_buffers[-1])
|
||||
else:
|
||||
raise ValueError("Unhandled port type")
|
||||
elif port.is_a(lv2_OutputPort):
|
||||
if port.is_a(lv2_AudioPort):
|
||||
elif port.is_a(ns.lv2.OutputPort):
|
||||
if port.is_a(ns.lv2.AudioPort):
|
||||
audio_output_buffers.append(numpy.array([0] * wav_in.nframes, numpy.float32))
|
||||
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))
|
||||
instance.connect_port(index, control_output_buffers[-1])
|
||||
else:
|
||||
|
@ -156,7 +151,7 @@ def main():
|
|||
# Write output file in chunks to stop memory usage getting out of hand:
|
||||
CHUNK_SIZE = 8192
|
||||
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()
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/** 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
|
||||
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
|
||||
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
|
||||
|
@ -54,7 +54,7 @@ typedef enum {
|
|||
every instance method. In this simple plugin, only port buffers need to be
|
||||
stored, since there is no additional instance data. */
|
||||
typedef struct {
|
||||
// Port buffers
|
||||
float* buf;
|
||||
} 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
|
||||
indentifier, the URI of the returned descriptor is used to determine the
|
||||
identify of the plugin.
|
||||
|
||||
|
||||
This method is in the ``discovery'' threading class, so no other functions
|
||||
or methods in this plugin library will be called concurrently with it.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,18 +16,27 @@
|
|||
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||
@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#> .
|
||||
|
||||
<http://example.org/lilv-bindings-test-plugin>
|
||||
a lv2:Plugin ;
|
||||
doap:name "Lilv Bindings Test" ;
|
||||
doap:license <http://opensource.org/licenses/isc> ;
|
||||
lv2:optionalFeature lv2:hardRTCapable ;
|
||||
ui:ui <http://example.org/lilv-bindings-test-plugin-ui> ;
|
||||
lv2:port [
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
lv2:index 0 ;
|
||||
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 ,
|
||||
lv2:ControlPort ;
|
||||
|
@ -47,3 +56,7 @@
|
|||
lv2:symbol "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>
|
||||
#
|
||||
# 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
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
from lilv import *
|
||||
import unittest
|
||||
import lilv
|
||||
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):
|
||||
def setUp(self):
|
||||
self.world = lilv_world_new()
|
||||
lilv_world_load_all(self.world)
|
||||
self.world = lilv.World()
|
||||
self.world.load_all()
|
||||
|
||||
def testInvalidURI(self):
|
||||
self.uri = lilv_new_uri(self.world, "invalid_uri")
|
||||
self.assertIsNone(self.uri)
|
||||
def testInvalidURI2(self):
|
||||
self.uri = lilv_new_uri(self.world, "invalid_uri")
|
||||
self.assertFalse( lilv_node_is_uri(self.uri) )
|
||||
with self.assertRaises(ValueError):
|
||||
self.plugin_uri = self.world.new_uri("invalid_uri")
|
||||
|
||||
def testNonExistentURI(self):
|
||||
self.uri = lilv_new_uri(self.world, "exist:does_not")
|
||||
plugins = lilv_world_get_all_plugins(self.world)
|
||||
self.plugin = lilv_plugins_get_by_uri(plugins, self.uri)
|
||||
self.assertIsNone(self.plugin)
|
||||
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.uri = lilv_new_uri(self.world, LILV_URI_INPUT_PORT)
|
||||
self.assertIsNotNone(self.uri)
|
||||
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_INPUT_PORT))
|
||||
|
||||
def testPortTypes2(self):
|
||||
self.uri = lilv_new_uri(self.world, LILV_URI_OUTPUT_PORT)
|
||||
self.assertIsNotNone(self.uri)
|
||||
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT))
|
||||
|
||||
def testPortTypes3(self):
|
||||
self.uri = lilv_new_uri(self.world, LILV_URI_AUDIO_PORT)
|
||||
self.assertIsNotNone(self.uri)
|
||||
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_AUDIO_PORT))
|
||||
|
||||
def testPortTypes4(self):
|
||||
self.uri = lilv_new_uri(self.world, LILV_URI_CONTROL_PORT)
|
||||
self.assertIsNotNone(self.uri)
|
||||
def tearDown(self):
|
||||
lilv_node_free(self.uri)
|
||||
lilv_world_free(self.world)
|
||||
self.assertIsNotNone(self.world.new_uri(lilv.LILV_URI_CONTROL_PORT))
|
||||
|
||||
|
||||
class PluginClassTests(unittest.TestCase):
|
||||
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):
|
||||
def setUp(self):
|
||||
self.world = lilv_world_new()
|
||||
location = "file://" + os.getcwd() + "/bindings/bindings_test_plugin.lv2/"
|
||||
self.plugin_uri = lilv_new_uri(self.world, location)
|
||||
self.assertIsNotNone(self.plugin_uri, "Invalid URI: '" + location + "'")
|
||||
lilv_world_load_bundle(self.world, self.plugin_uri)
|
||||
self.plugins = lilv_world_get_all_plugins(self.world)
|
||||
self.plugin = lilv_plugins_get(self.plugins, lilv_plugins_begin(self.plugins))
|
||||
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.instance = lilv_plugin_instantiate(self.plugin, 48000, None)
|
||||
self.assertIsNotNone(self.instance)
|
||||
self.lv2_InputPort = lilv_new_uri(self.world, LILV_URI_INPUT_PORT)
|
||||
self.lv2_OutputPort = lilv_new_uri(self.world, LILV_URI_OUTPUT_PORT)
|
||||
self.lv2_AudioPort = lilv_new_uri(self.world, LILV_URI_AUDIO_PORT)
|
||||
self.lv2_ControlPort = lilv_new_uri(self.world, LILV_URI_CONTROL_PORT)
|
||||
self.world = lilv.World()
|
||||
self.world.set_option(
|
||||
lilv.OPTION_FILTER_LANG, self.world.new_bool(True)
|
||||
)
|
||||
self.bundle_uri = self.world.new_uri(location)
|
||||
self.assertIsNotNone(
|
||||
self.bundle_uri, "Invalid URI: '" + location + "'"
|
||||
)
|
||||
self.world.load_bundle(self.bundle_uri)
|
||||
self.plugins = self.world.get_all_plugins()
|
||||
self.plugin = self.plugins.get(self.plugins.begin())
|
||||
self.assertTrue(self.plugin.verify())
|
||||
self.assertTrue(self.plugin in self.plugins)
|
||||
self.assertTrue(self.plugin.get_uri() in self.plugins)
|
||||
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):
|
||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_InputPort, self.lv2_AudioPort)
|
||||
self.assertEqual(n, 1)
|
||||
def testPorts2(self):
|
||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_OutputPort, self.lv2_AudioPort)
|
||||
self.assertEqual(n, 1)
|
||||
def testPorts3(self):
|
||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_OutputPort, self.lv2_ControlPort)
|
||||
self.assertEqual(n, 1)
|
||||
def testPorts4(self):
|
||||
n = lilv_plugin_get_num_ports_of_class(self.plugin, self.lv2_InputPort, self.lv2_ControlPort)
|
||||
self.assertEqual(n, 1)
|
||||
def tearDown(self):
|
||||
lilv_node_free(self.lv2_InputPort)
|
||||
lilv_node_free(self.lv2_OutputPort)
|
||||
lilv_node_free(self.lv2_AudioPort)
|
||||
lilv_node_free(self.plugin_uri)
|
||||
lilv_world_free(self.world)
|
||||
self.assertEqual(self.plugin.get_num_ports(), 4)
|
||||
self.assertIsNotNone(self.plugin.get_port(0))
|
||||
self.assertIsNotNone(self.plugin.get_port(1))
|
||||
self.assertIsNotNone(self.plugin.get_port(2))
|
||||
self.assertIsNotNone(self.plugin.get_port(3))
|
||||
self.assertIsNone(self.plugin.get_port_by_index(4))
|
||||
self.assertIsNotNone(self.plugin.get_port("input"))
|
||||
self.assertIsNotNone(self.plugin.get_port("output"))
|
||||
self.assertIsNotNone(self.plugin.get_port("audio_input"))
|
||||
self.assertIsNotNone(self.plugin.get_port("audio_output"))
|
||||
self.assertIsNone(self.plugin.get_port_by_symbol("nonexistent"))
|
||||
self.assertIsNone(
|
||||
self.plugin.get_port_by_designation(
|
||||
self.world.ns.lv2.InputPort, self.world.ns.lv2.control
|
||||
)
|
||||
)
|
||||
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">
|
||||
<!-- Generated by doxygen 1.8.15 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title=""/>
|
||||
|
@ -8,17 +9,31 @@
|
|||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||
</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="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="classmembers" visible="yes" title="" intro=""/>
|
||||
</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="filelist" visible="yes" title="" intro=""/>
|
||||
<tab type="globals" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="examples" visible="yes" title="" intro=""/>
|
||||
<tab type="examples" visible="yes" title="" intro=""/>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
|
@ -27,10 +42,11 @@
|
|||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<allmemberslink visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
|
@ -65,6 +81,8 @@
|
|||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
|
@ -72,6 +90,7 @@
|
|||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
@ -81,8 +100,14 @@
|
|||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<interfaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<structs visible="yes" title=""/>
|
||||
<exceptions visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
|
@ -92,6 +117,8 @@
|
|||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
|
@ -107,10 +134,16 @@
|
|||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<interfaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<structs visible="yes" title=""/>
|
||||
<exceptions visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
|
@ -121,6 +154,8 @@
|
|||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
|
@ -130,9 +165,9 @@
|
|||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="no"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<briefdescription visible="yes"/>
|
||||
<detaileddescription title=""/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
|
@ -141,6 +176,8 @@
|
|||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
|
@ -159,6 +196,8 @@
|
|||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues 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
|
||||
.B lv2info \- print information about an installed LV2 plugin.
|
||||
.B lv2info \- print information about an installed LV2 plugin
|
||||
.SH SYNOPSIS
|
||||
.B lv2info PLUGIN_URI
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-p FILE
|
||||
\fB\-p FILE\fR
|
||||
Write Turtle description of plugin to FILE
|
||||
|
||||
.TP
|
||||
\fB\-m FILE
|
||||
\fB\-m FILE\fR
|
||||
Add record of plugin to manifest FILE
|
||||
|
||||
.TP
|
||||
|
@ -22,7 +22,7 @@ Display help and exit
|
|||
\fB\-\-version\fR
|
||||
Display version information and exit
|
||||
|
||||
.SH SEE ALSO
|
||||
.SH "SEE ALSO"
|
||||
.BR lilv(3),
|
||||
.BR lv2ls(1)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.TH LV2LS 1 "17 Jan 2012"
|
||||
.TH LV2LS 1 "26 Aug 2016"
|
||||
|
||||
.SH NAME
|
||||
.B lv2ls \- List all installed LV2 plugins.
|
||||
.B lv2ls \- list all installed LV2 plugins
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lv2ls [OPTION]...
|
||||
|
@ -19,7 +19,7 @@ Display help and exit
|
|||
\fB\-\-version\fR
|
||||
Display version information and exit
|
||||
|
||||
.SH SEE ALSO
|
||||
.SH "SEE ALSO"
|
||||
.BR lilv(3),
|
||||
.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 {
|
||||
font-size: medium;
|
||||
font-family: sans-serif;
|
||||
background: #FFF;
|
||||
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 {
|
||||
background-color: #F3F3F3;
|
||||
h1, .title, #projectname, h2, h3, h4, h5, h6 {
|
||||
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;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #DDD;
|
||||
margin-bottom: 1ex;
|
||||
font-size: xx-large;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
display: inline-block;
|
||||
font-style: italic;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 h2 h3 h4 h5 h6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 164%;
|
||||
#titlearea {
|
||||
margin: 0.25em auto 0.25em auto;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
clear: both;
|
||||
line-height: 1.0em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 132%;
|
||||
font-size: 160%;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 124%;
|
||||
font-size: 140%;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 116%;
|
||||
font-size: 120%;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 108%;
|
||||
h5, h6 {
|
||||
font-size: 110%;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 100%;
|
||||
h1 a, h1 a:link, h1 a:visited ,
|
||||
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 {
|
||||
margin: 0 0 1ex 0;
|
||||
}
|
||||
|
||||
br {
|
||||
display: none;
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
div.multicol {
|
||||
}
|
||||
|
||||
p.startli,p.startdd,p.starttd {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
p.endli {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p.enddd {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
p.endtd {
|
||||
margin-bottom: 2px;
|
||||
dd {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
caption {
|
||||
|
@ -85,12 +115,12 @@ caption {
|
|||
}
|
||||
|
||||
span.legend {
|
||||
font-size: 70%;
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3.version {
|
||||
font-size: 90%;
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -102,23 +132,18 @@ div.qindex,div.navtab {
|
|||
padding: 2px;
|
||||
}
|
||||
|
||||
div.qindex,div.navpath {
|
||||
width: 100%;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
div.navtab {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* @group Link Styling */
|
||||
a {
|
||||
color: #3D8C57;
|
||||
color: #546E00;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.contents a:visited {
|
||||
color: #50755E;
|
||||
color: #344E00;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
|
@ -131,12 +156,8 @@ a.qindexHL {
|
|||
border: 1px double #869DCA;
|
||||
}
|
||||
|
||||
a.code {
|
||||
color: #4665A2;
|
||||
}
|
||||
|
||||
a.codeRef {
|
||||
color: #4665A2;
|
||||
code {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -145,18 +166,14 @@ dl.el {
|
|||
}
|
||||
|
||||
.fragment {
|
||||
font-family: monospace, fixed;
|
||||
font-size: 105%;
|
||||
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border: 1px solid #C4C4C4;
|
||||
background-color: #F9F9F9;
|
||||
padding: 4px 6px;
|
||||
margin: 4px 8px 4px 2px;
|
||||
padding: 0.5em;
|
||||
overflow: auto;
|
||||
font-size: 9pt;
|
||||
line-height: 125%;
|
||||
}
|
||||
|
||||
div.ah {
|
||||
|
@ -176,21 +193,20 @@ div.groupHeader {
|
|||
font-weight: 700;
|
||||
}
|
||||
|
||||
a + h2.groupheader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #FFF;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.contents {
|
||||
margin-top: 10px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
div.contents, #content {
|
||||
padding: 0 0.25em 0 0.25em;
|
||||
max-width: 60em;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
td.indexkey {
|
||||
|
@ -208,6 +224,10 @@ td.indexvalue {
|
|||
margin: 2px 0;
|
||||
}
|
||||
|
||||
table.memname {
|
||||
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||
}
|
||||
|
||||
tr.memlist {
|
||||
background-color: #EEF1F7;
|
||||
}
|
||||
|
@ -216,9 +236,6 @@ p.formulaDsp {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
img.formulaDsp {
|
||||
}
|
||||
|
||||
img.formulaInl {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -236,7 +253,6 @@ div.center img {
|
|||
|
||||
address.footer {
|
||||
text-align: right;
|
||||
padding: 0 0.25em 0.25em 0;
|
||||
}
|
||||
|
||||
img.footer {
|
||||
|
@ -246,48 +262,36 @@ img.footer {
|
|||
|
||||
/* @group Code Colorization */
|
||||
span.keyword {
|
||||
color: green;
|
||||
color: #586E75;
|
||||
}
|
||||
|
||||
span.keywordtype {
|
||||
color: #604020;
|
||||
color: #546E00;
|
||||
}
|
||||
|
||||
span.keywordflow {
|
||||
color: #e08000;
|
||||
color: #586E75;
|
||||
}
|
||||
|
||||
span.comment {
|
||||
color: maroon;
|
||||
color: #6C71C4;
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #806020;
|
||||
color: #D33682;
|
||||
}
|
||||
|
||||
span.stringliteral {
|
||||
color: #002080;
|
||||
color: #CB4B16;
|
||||
}
|
||||
|
||||
span.charliteral {
|
||||
color: teal;
|
||||
}
|
||||
|
||||
span.vhdldigit {
|
||||
color: #F0F;
|
||||
}
|
||||
|
||||
span.vhdlkeyword {
|
||||
color: #700070;
|
||||
}
|
||||
|
||||
span.vhdllogic {
|
||||
color: red;
|
||||
color: #CB4B16;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
td.tiny {
|
||||
font-size: 75%;
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
.dirtab {
|
||||
|
@ -308,20 +312,25 @@ hr {
|
|||
margin: 2em 0 1em;
|
||||
}
|
||||
|
||||
hr.footer {
|
||||
height: 1px;
|
||||
#footer {
|
||||
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 */
|
||||
table.memberdecls {
|
||||
border-spacing: 0;
|
||||
font-size: small;
|
||||
border-spacing: 0.125em;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams {
|
||||
background-color: #FBFBFB;
|
||||
margin: 0;
|
||||
padding: 0.25ex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mdescLeft,.mdescRight {
|
||||
|
@ -329,12 +338,18 @@ table.memberdecls {
|
|||
}
|
||||
|
||||
.memItemLeft,.memItemRight,.memTemplParams {
|
||||
border-top: 1px solid #DDD;
|
||||
border: 0;
|
||||
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||
}
|
||||
|
||||
.memItemLeft,.memTemplItemLeft {
|
||||
white-space: nowrap;
|
||||
padding-left: 2em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.memItemLeft a.el {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.memTemplParams {
|
||||
|
@ -342,18 +357,33 @@ table.memberdecls {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td.memSeparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
td.mlabels-right {
|
||||
vertical-align: top;
|
||||
padding-top: 4px;
|
||||
color: #B4C342;
|
||||
}
|
||||
|
||||
.memtitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
/* @group Member Details */
|
||||
/* Styles for detailed member documentation */
|
||||
.memtemplate {
|
||||
font-size: 80%;
|
||||
color: #4665A2;
|
||||
font-weight: bold;
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.memnav {
|
||||
background-color: #EBEFF6;
|
||||
border: 1px solid #A3B4D7;
|
||||
background-color: #EEE;
|
||||
border: 1px solid #B4C342;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
|
@ -361,27 +391,25 @@ table.memberdecls {
|
|||
}
|
||||
|
||||
.memitem {
|
||||
padding: 0;
|
||||
margin: 1ex 0 2ex 0;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
margin: 0 0 1em 0;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding: 0.5ex;
|
||||
font-weight: bold;
|
||||
background-color: #F3F3F3;
|
||||
font-size: 110%;
|
||||
font-weight: 400;
|
||||
line-height: 1em;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.memproto .paramname {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.memdoc {
|
||||
padding: 1ex;
|
||||
background-color: #FBFBFB;
|
||||
border-top-width: 0;
|
||||
padding: 0 0.25em 0 0.25em;
|
||||
}
|
||||
|
||||
.paramkey {
|
||||
|
@ -389,16 +417,54 @@ table.memberdecls {
|
|||
}
|
||||
|
||||
.paramtype {
|
||||
color: #666;
|
||||
padding-right: 0.5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.paramname {
|
||||
color: #602020;
|
||||
color: #111;
|
||||
white-space: nowrap;
|
||||
font-family: "DejaVu Sans Mono",monospace,fixed;
|
||||
font-style: italic;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.paramname em {
|
||||
font-style: normal;
|
||||
.fieldname {
|
||||
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 */
|
||||
|
@ -411,9 +477,8 @@ table.memberdecls {
|
|||
|
||||
/* these are for tree view when used as main index */
|
||||
.directory {
|
||||
font-size: 9pt;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
font-size: small;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
.directory h3 {
|
||||
|
@ -440,6 +505,22 @@ table.memberdecls {
|
|||
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 */
|
||||
.directory-alt {
|
||||
font-size: 100%;
|
||||
|
@ -477,12 +558,12 @@ div.dynheader {
|
|||
|
||||
address {
|
||||
font-style: normal;
|
||||
color: #2A3D61;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
table.doxtable {
|
||||
border-collapse: collapse;
|
||||
margin: 0.5ex;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
table.doxtable td,table.doxtable th {
|
||||
|
@ -508,56 +589,151 @@ table.doxtable th {
|
|||
font-size: 13px;
|
||||
}
|
||||
|
||||
div.navpath {
|
||||
color: #DDD;
|
||||
}
|
||||
|
||||
.navpath ul {
|
||||
font-size: 11px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
color: #8AA0CC;
|
||||
border: 1px solid #C2CDE4;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navpath li {
|
||||
list-style-type: none;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 15px;
|
||||
color: #364D7C;
|
||||
padding-left: 0;
|
||||
margin-left: 0.5em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.navpath a {
|
||||
height: 32px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navpath a:hover {
|
||||
color: #6884BD;
|
||||
}
|
||||
|
||||
div.summary {
|
||||
float: right;
|
||||
font-size: 8pt;
|
||||
padding-right: 5px;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
font-size: small;
|
||||
font-family: "DejaVu Sans",Helvetica,Arial,sans-serif;
|
||||
margin: 0;
|
||||
color: #FFF; /* Hide separator bars */
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding: 0.25em 0;
|
||||
}
|
||||
|
||||
div.summary a {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.header {
|
||||
background-color: #F3F3F3;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid #DDD;
|
||||
/* Metadata box (right aligned next to title) */
|
||||
|
||||
#metabox {
|
||||
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 {
|
||||
padding: 5px 5px 5px 10px;
|
||||
font-size: 180%;
|
||||
font-weight: bold;
|
||||
#meta {
|
||||
border-style: hidden;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
#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
|
||||
Version: @LILV_VERSION@
|
||||
Description: Simple C library for hosting LV2 plugins
|
||||
Requires: lv2 @PKG_serd_0@ @PKG_sord_0@ @PKG_sratom_0@
|
||||
Libs: -L${libdir} -l@LIB_LILV@ -ldl
|
||||
Requires: @LILV_PKG_DEPS@
|
||||
Libs: -L${libdir} -l@LIB_LILV@ @LILV_PKG_LIBS@
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,14 +21,15 @@
|
|||
#ifndef LILV_LILV_H
|
||||
#define LILV_LILV_H
|
||||
|
||||
#include "lv2/core/lv2.h"
|
||||
#include "lv2/urid/urid.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.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 _WIN32
|
||||
# define LILV_LIB_IMPORT __declspec(dllimport)
|
||||
|
@ -45,11 +46,15 @@
|
|||
#else
|
||||
# define LILV_API
|
||||
#endif
|
||||
#if defined(__GNUC__) && (__GNUC__ > 3 || \
|
||||
(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# define LILV_DEPRECATED __attribute__((__deprecated__))
|
||||
#else
|
||||
# define LILV_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#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_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_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_INPUT_PORT "http://lv2plug.in/ns/lv2core#InputPort"
|
||||
#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
|
||||
@{
|
||||
|
@ -104,11 +121,24 @@ typedef void LilvNodes; /**< set<Node>. */
|
|||
Convert a file URI string to a local path string.
|
||||
For example, "file://foo/bar/baz.ttl" returns "/foo/bar/baz.ttl".
|
||||
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).
|
||||
*/
|
||||
LILV_API const char*
|
||||
LILV_API LILV_DEPRECATED const char*
|
||||
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.
|
||||
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.
|
||||
Returned value must be freed by caller with free().
|
||||
Returned value must be freed by caller with lilv_free().
|
||||
<table>
|
||||
<caption>Example Turtle Tokens</caption>
|
||||
<tr><th>URI</th><td><http://example.org/foo ></td></tr>
|
||||
<tr><th>QName</td><td>doap:name</td></tr>
|
||||
<tr><th>String</td><td>"this is a string"</td></tr>
|
||||
<tr><th>Float</td><td>1.0</td></tr>
|
||||
<tr><th>Integer</td><td>1</td></tr>
|
||||
<tr><th>Boolean</td><td>true</td></tr>
|
||||
<tr><th>QName</th><td>doap:name</td></tr>
|
||||
<tr><th>String</th><td>"this is a string"</td></tr>
|
||||
<tr><th>Float</th><td>1.0</td></tr>
|
||||
<tr><th>Integer</th><td>1</td></tr>
|
||||
<tr><th>Boolean</th><td>true</td></tr>
|
||||
</table>
|
||||
*/
|
||||
LILV_API char*
|
||||
|
@ -240,6 +270,14 @@ lilv_node_is_string(const LilvNode* value);
|
|||
LILV_API const char*
|
||||
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.
|
||||
*/
|
||||
|
@ -314,7 +352,7 @@ lilv_node_as_bool(const LilvNode* value);
|
|||
@endcode
|
||||
*/
|
||||
#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); \
|
||||
(iter) = lilv_ ## colltype ## _next(collection, iter))
|
||||
|
||||
|
@ -425,7 +463,7 @@ lilv_nodes_get_first(const LilvNodes* collection);
|
|||
Return whether `values` contains `value`.
|
||||
*/
|
||||
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`.
|
||||
|
@ -492,12 +530,20 @@ lilv_world_new(void);
|
|||
*/
|
||||
#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`.
|
||||
|
||||
Currently recognized options:
|
||||
@ref LILV_OPTION_FILTER_LANG
|
||||
@ref LILV_OPTION_DYN_MANIFEST
|
||||
@ref LILV_OPTION_LV2_PATH
|
||||
*/
|
||||
LILV_API void
|
||||
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,
|
||||
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
|
||||
(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.
|
||||
*/
|
||||
LILV_API void
|
||||
lilv_world_load_bundle(LilvWorld* world,
|
||||
LilvNode* bundle_uri);
|
||||
lilv_world_load_bundle(LilvWorld* world,
|
||||
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.
|
||||
|
||||
This unloads statements loaded by lilv_world_load_bundle(). Note that this
|
||||
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().
|
||||
*/
|
||||
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`.
|
||||
|
@ -649,6 +715,16 @@ lilv_world_ask(LilvWorld* world,
|
|||
const LilvNode* predicate,
|
||||
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
|
||||
|
@ -687,13 +763,14 @@ lilv_plugin_get_uri(const LilvPlugin* plugin);
|
|||
|
||||
/**
|
||||
Get the (resolvable) URI of the plugin's "main" bundle.
|
||||
This returns the URI of the bundle where the plugin itself was found.
|
||||
Note that the data for a plugin may be spread over many bundles, that is,
|
||||
lilv_plugin_get_data_uris may return URIs which are not within this bundle.
|
||||
This returns the URI of the bundle where the plugin itself was found. Note
|
||||
that the data for a plugin may be spread over many bundles, that is,
|
||||
lilv_plugin_get_data_uris() may return URIs which are not within this
|
||||
bundle.
|
||||
|
||||
Typical hosts should not need to use this function.
|
||||
Note this always returns a fully qualified URI. If you want a local
|
||||
filesystem path, use lilv_uri_to_path.
|
||||
filesystem path, use lilv_file_uri_parse().
|
||||
@return a shared string which must not be modified or freed.
|
||||
*/
|
||||
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.
|
||||
Typical hosts should not need to use this function.
|
||||
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",
|
||||
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`.
|
||||
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.
|
||||
*/
|
||||
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().
|
||||
*/
|
||||
LILV_API LilvNodes*
|
||||
lilv_plugin_get_value(const LilvPlugin* p,
|
||||
lilv_plugin_get_value(const LilvPlugin* plugin,
|
||||
const LilvNode* predicate);
|
||||
|
||||
/**
|
||||
|
@ -757,21 +834,21 @@ lilv_plugin_get_value(const LilvPlugin* p,
|
|||
of the plugin.
|
||||
*/
|
||||
LILV_API bool
|
||||
lilv_plugin_has_feature(const LilvPlugin* p,
|
||||
const LilvNode* feature_uri);
|
||||
lilv_plugin_has_feature(const LilvPlugin* plugin,
|
||||
const LilvNode* feature);
|
||||
|
||||
/**
|
||||
Get the LV2 Features supported (required or optionally) by a plugin.
|
||||
A feature is "supported" by a plugin if it is required OR optional.
|
||||
|
||||
Since required features have special rules the host must obey, this function
|
||||
probably shouldn't be used by normal hosts. Using lilv_plugin_get_optional_features
|
||||
and lilv_plugin_get_required_features separately is best in most cases.
|
||||
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.
|
||||
|
||||
Returned value must be freed by caller with lilv_nodes_free().
|
||||
*/
|
||||
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.
|
||||
|
@ -785,7 +862,7 @@ lilv_plugin_get_supported_features(const LilvPlugin* p);
|
|||
Return value must be freed by caller with lilv_nodes_free().
|
||||
*/
|
||||
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.
|
||||
|
@ -796,13 +873,13 @@ lilv_plugin_get_required_features(const LilvPlugin* p);
|
|||
Return value must be freed by caller with lilv_nodes_free().
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
LILV_API bool
|
||||
lilv_plugin_has_extension_data(const LilvPlugin* p,
|
||||
lilv_plugin_has_extension_data(const LilvPlugin* plugin,
|
||||
const LilvNode* uri);
|
||||
|
||||
/**
|
||||
|
@ -811,13 +888,13 @@ lilv_plugin_has_extension_data(const LilvPlugin* p,
|
|||
will return a value for without instantiating the plugin.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
@ -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
|
||||
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_plugin_get_port_ranges_float(const LilvPlugin* p,
|
||||
lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin,
|
||||
float* min_values,
|
||||
float* max_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.
|
||||
*/
|
||||
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, ...);
|
||||
|
||||
#ifndef SWIG
|
||||
/**
|
||||
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().
|
||||
*/
|
||||
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,
|
||||
va_list args);
|
||||
#endif
|
||||
|
||||
/**
|
||||
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_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.
|
||||
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
|
||||
(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.
|
||||
*/
|
||||
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`.
|
||||
|
@ -890,7 +965,7 @@ lilv_plugin_get_port_by_index(const LilvPlugin* plugin,
|
|||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
||||
To actually load the data for each returned resource, use
|
||||
lilv_world_load_resource.
|
||||
lilv_world_load_resource().
|
||||
*/
|
||||
LILV_API LilvNodes*
|
||||
lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type);
|
||||
|
@ -1013,7 +1088,7 @@ lilv_port_get_node(const LilvPlugin* plugin,
|
|||
const LilvPort* port);
|
||||
|
||||
/**
|
||||
Port analog of lilv_plugin_get_value.
|
||||
Port analog of lilv_plugin_get_value().
|
||||
*/
|
||||
LILV_API LilvNodes*
|
||||
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.
|
||||
*/
|
||||
LILV_API bool
|
||||
lilv_port_has_property(const LilvPlugin* p,
|
||||
lilv_port_has_property(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const LilvNode* property_uri);
|
||||
const LilvNode* property);
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
LILV_API bool
|
||||
lilv_port_supports_event(const LilvPlugin* p,
|
||||
lilv_port_supports_event(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const LilvNode* event_type);
|
||||
|
||||
|
@ -1089,7 +1164,7 @@ lilv_port_get_name(const LilvPlugin* plugin,
|
|||
/**
|
||||
Get all the classes of a port.
|
||||
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.
|
||||
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
|
||||
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
|
||||
exist.
|
||||
be freed by the caller using lilv_node_free()), or NULL if the value does
|
||||
not exist.
|
||||
*/
|
||||
LILV_API void
|
||||
lilv_port_get_range(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
LilvNode** deflt,
|
||||
LilvNode** def,
|
||||
LilvNode** min,
|
||||
LilvNode** max);
|
||||
|
||||
|
@ -1148,13 +1223,13 @@ lilv_port_get_scale_points(const LilvPlugin* plugin,
|
|||
the plugin URI as the `subject` parameter.
|
||||
@param world The world.
|
||||
@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.
|
||||
*/
|
||||
LILV_API LilvState*
|
||||
lilv_state_new_from_world(LilvWorld* world,
|
||||
LV2_URID_Map* map,
|
||||
const LilvNode* subject);
|
||||
const LilvNode* node);
|
||||
|
||||
/**
|
||||
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 file_dir Directory of files created by the plugin earlier (or NULL).
|
||||
This is for hosts that support file creation at any time with state
|
||||
@param scratch_dir Directory of files created by the plugin earlier, or
|
||||
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
|
||||
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
|
||||
directory will have the same structure as `file_dir` but with possibly
|
||||
modified file names to distinguish different revisions. If you only care
|
||||
about saving one state snapshot, it can be the same as `save_dir`. Plugin
|
||||
state will refer to files in this directory.
|
||||
@param copy_dir Directory of copies of files in `scratch_dir`, or NULL.
|
||||
This directory will have the same structure as `scratch_dir` but with
|
||||
possibly modified file names to distinguish revisions. This allows the
|
||||
saved state to contain the exact contents of the scratch file at save time,
|
||||
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).
|
||||
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
|
||||
@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.
|
||||
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
|
||||
snapshots to share a single link to an external file, so archival
|
||||
(e.g. with tar -h) will not create several copies of the file. If this is
|
||||
not required, it can be the same as save_dir.
|
||||
snapshots to share a single link to an external file, so archival (e.g. with
|
||||
tar -h) will not create several copies of the file. If this is not
|
||||
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.
|
||||
|
||||
|
@ -1253,12 +1333,12 @@ typedef const void* (*LilvGetPortValueFunc)(const char* port_symbol,
|
|||
saving an instances state many times while avoiding any duplication of data.
|
||||
|
||||
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
|
||||
will be copied to preserve their state at this time.plugin-created files are stored.
|
||||
Lilv will assume any files within this directory (recursively) are created
|
||||
by the plugin and all other files are immutable. Note that this function
|
||||
does not save the state, use lilv_state_save() for that.
|
||||
will be copied to preserve their state at this time.plugin-created files are
|
||||
stored. Lilv will assume any files within this directory (recursively) are
|
||||
created by the plugin and all other files are immutable. Note that this
|
||||
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
|
||||
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,
|
||||
LilvInstance* instance,
|
||||
LV2_URID_Map* map,
|
||||
const char* file_dir,
|
||||
const char* scratch_dir,
|
||||
const char* copy_dir,
|
||||
const char* link_dir,
|
||||
const char* save_dir,
|
||||
|
@ -1300,6 +1380,14 @@ lilv_state_get_num_properties(const LilvState* state);
|
|||
LILV_API const LilvNode*
|
||||
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`.
|
||||
*/
|
||||
|
@ -1313,6 +1401,28 @@ LILV_API void
|
|||
lilv_state_set_label(LilvState* state,
|
||||
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.
|
||||
@param port_symbol The symbol of the port.
|
||||
|
@ -1327,6 +1437,22 @@ typedef void (*LilvSetPortValueFunc)(const char* port_symbol,
|
|||
uint32_t size,
|
||||
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.
|
||||
@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().
|
||||
|
||||
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
|
||||
the 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
|
||||
completely restore `state`.
|
||||
stored in `state`. If `set_value` is provided, it will be called (with the
|
||||
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 completely restore `state`.
|
||||
|
||||
If the state has properties and `instance` is given, this function is in
|
||||
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* 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
|
||||
|
@ -1471,7 +1615,7 @@ lilv_plugin_class_get_children(const LilvPluginClass* plugin_class);
|
|||
|
||||
/* Instance of a plugin.
|
||||
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
|
||||
in any way (which is why it is not machine documented).
|
||||
Truly private implementation details are hidden via `pimpl`.
|
||||
|
@ -1537,14 +1681,15 @@ lilv_instance_connect_port(LilvInstance* instance,
|
|||
/**
|
||||
Activate a plugin instance.
|
||||
This resets all state information in the plugin, except for port data
|
||||
locations (as set by lilv_instance_connect_port). This MUST be called
|
||||
before calling lilv_instance_run.
|
||||
locations (as set by lilv_instance_connect_port()). This MUST be called
|
||||
before calling lilv_instance_run().
|
||||
*/
|
||||
static inline void
|
||||
lilv_instance_activate(LilvInstance* instance)
|
||||
{
|
||||
if (instance->lv2_descriptor->activate)
|
||||
if (instance->lv2_descriptor->activate) {
|
||||
instance->lv2_descriptor->activate(instance->lv2_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1567,8 +1712,9 @@ lilv_instance_run(LilvInstance* instance,
|
|||
static inline void
|
||||
lilv_instance_deactivate(LilvInstance* instance)
|
||||
{
|
||||
if (instance->lv2_descriptor->deactivate)
|
||||
if (instance->lv2_descriptor->deactivate) {
|
||||
instance->lv2_descriptor->deactivate(instance->lv2_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1580,10 +1726,11 @@ static inline const void*
|
|||
lilv_instance_get_extension_data(const LilvInstance* instance,
|
||||
const char* uri)
|
||||
{
|
||||
if (instance->lv2_descriptor->extension_data)
|
||||
if (instance->lv2_descriptor->extension_data) {
|
||||
return instance->lv2_descriptor->extension_data(uri);
|
||||
else
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1640,8 +1787,8 @@ lilv_ui_get_uri(const LilvUI* ui);
|
|||
@param ui The Plugin UI
|
||||
@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
|
||||
UI type, avoding the need to use this function (and type specific logic).
|
||||
Note that in most cases lilv_ui_is_supported() should be used, which avoids
|
||||
the need to use this function (and type specific logic).
|
||||
*/
|
||||
LILV_API const LilvNodes*
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,19 +19,28 @@
|
|||
|
||||
#include "lilv/lilv.h"
|
||||
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
|
||||
# define LILV_DEPRECATED __attribute__((__deprecated__))
|
||||
#else
|
||||
# define LILV_DEPRECATED
|
||||
#endif
|
||||
|
||||
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*
|
||||
uri_to_path(const char* 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) \
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,6 +16,15 @@
|
|||
|
||||
#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
|
||||
lilv_ptr_cmp(const void* a, const void* b, void* user_data)
|
||||
{
|
||||
|
@ -39,16 +48,17 @@ lilv_collection_new(ZixComparator cmp, ZixDestroyFunc destructor)
|
|||
}
|
||||
|
||||
void
|
||||
lilv_collection_free(LilvCollection* coll)
|
||||
lilv_collection_free(LilvCollection* collection)
|
||||
{
|
||||
if (coll)
|
||||
zix_tree_free((ZixTree*)coll);
|
||||
if (collection) {
|
||||
zix_tree_free((ZixTree*)collection);
|
||||
}
|
||||
}
|
||||
|
||||
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*
|
||||
|
@ -97,17 +107,17 @@ lilv_plugin_classes_new(void)
|
|||
/* URI based accessors (for collections of things with URIs) */
|
||||
|
||||
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)
|
||||
{
|
||||
return (LilvPluginClass*)lilv_collection_get_by_uri(
|
||||
(const ZixTree*)coll, uri);
|
||||
(const ZixTree*)classes, uri);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -119,19 +129,22 @@ lilv_plugins_new(void)
|
|||
}
|
||||
|
||||
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 */
|
||||
|
||||
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)
|
||||
if (lilv_node_equals(lilv_nodes_get(list, i), value))
|
||||
LILV_FOREACH(nodes, i, nodes) {
|
||||
if (lilv_node_equals(lilv_nodes_get(nodes, i), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
LILV_API LilvInstance*
|
||||
lilv_plugin_instantiate(const LilvPlugin* plugin,
|
||||
double sample_rate,
|
||||
const LV2_Feature*const* features)
|
||||
{
|
||||
lilv_plugin_load_if_necessary(plugin);
|
||||
|
||||
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) {
|
||||
if (plugin->parse_errors) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Parse bundle URI to use as base URI
|
||||
const char* bundle_uri_str = lilv_node_as_uri(bundle_uri);
|
||||
SerdURI base_uri;
|
||||
if (serd_uri_parse((const uint8_t*)bundle_uri_str, &base_uri)) {
|
||||
lilv_lib_close(lib);
|
||||
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);
|
||||
if (!lib_uri || !bundle_uri) {
|
||||
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;
|
||||
}
|
||||
|
||||
const LV2_Feature** local_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;
|
||||
}
|
||||
|
||||
|
@ -66,18 +68,7 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
|||
break; // return NULL
|
||||
}
|
||||
|
||||
// Resolve library plugin URI against base URI
|
||||
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)))) {
|
||||
if (!strcmp(ld->URI, lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) {
|
||||
// Create LilvInstance to return
|
||||
result = (LilvInstance*)malloc(sizeof(LilvInstance));
|
||||
result->lv2_descriptor = ld;
|
||||
|
@ -85,25 +76,25 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
|||
ld, sample_rate, bundle_path,
|
||||
(features) ? features : local_features);
|
||||
result->pimpl = lib;
|
||||
serd_node_free(&abs_uri_node);
|
||||
break;
|
||||
} else {
|
||||
serd_node_free(&abs_uri_node);
|
||||
}
|
||||
}
|
||||
|
||||
free(local_features);
|
||||
serd_free(bundle_path);
|
||||
|
||||
if (result) {
|
||||
// Failed to instantiate
|
||||
if (result->lv2_handle == NULL) {
|
||||
// Failed to instantiate
|
||||
free(result);
|
||||
lilv_lib_close(lib);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// "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);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -112,8 +103,9 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
|
|||
LILV_API void
|
||||
lilv_instance_free(LilvInstance* instance)
|
||||
{
|
||||
if (!instance)
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance->lv2_descriptor->cleanup(instance->lv2_handle);
|
||||
instance->lv2_descriptor = NULL;
|
||||
|
@ -121,4 +113,3 @@ lilv_instance_free(LilvInstance* instance)
|
|||
instance->pimpl = NULL;
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,6 +16,13 @@
|
|||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
#include "lv2/core/lv2.h"
|
||||
#include "zix/tree.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
LilvLib*
|
||||
lilv_lib_open(LilvWorld* world,
|
||||
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_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) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -42,13 +50,13 @@ lilv_lib_open(LilvWorld* world,
|
|||
void* lib = dlopen(lib_path, RTLD_NOW);
|
||||
if (!lib) {
|
||||
LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror());
|
||||
serd_free(lib_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LV2_Descriptor_Function df = (LV2_Descriptor_Function)
|
||||
lilv_dlfunc(lib, "lv2_descriptor");
|
||||
|
||||
#ifdef LILV_NEW_LV2
|
||||
LV2_Lib_Descriptor_Function ldf = (LV2_Lib_Descriptor_Function)
|
||||
lilv_dlfunc(lib, "lv2_lib_descriptor");
|
||||
|
||||
|
@ -56,17 +64,19 @@ lilv_lib_open(LilvWorld* world,
|
|||
if (ldf) {
|
||||
desc = ldf(bundle_path, features);
|
||||
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;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (!df) {
|
||||
} else if (!df) {
|
||||
LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n",
|
||||
lib_path);
|
||||
dlclose(lib);
|
||||
serd_free(lib_path);
|
||||
return NULL;
|
||||
}
|
||||
serd_free(lib_path);
|
||||
|
||||
LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib));
|
||||
llib->world = world;
|
||||
|
@ -74,9 +84,7 @@ lilv_lib_open(LilvWorld* world,
|
|||
llib->bundle_path = lilv_strdup(bundle_path);
|
||||
llib->lib = lib;
|
||||
llib->lv2_descriptor = df;
|
||||
#ifdef LILV_NEW_LV2
|
||||
llib->desc = desc;
|
||||
#endif
|
||||
llib->refs = 1;
|
||||
|
||||
zix_tree_insert(world->libs, llib, NULL);
|
||||
|
@ -88,12 +96,9 @@ lilv_lib_get_plugin(LilvLib* lib, uint32_t index)
|
|||
{
|
||||
if (lib->lv2_descriptor) {
|
||||
return lib->lv2_descriptor(index);
|
||||
}
|
||||
#ifdef LILV_NEW_LV2
|
||||
if (lib->desc) {
|
||||
} else if (lib->desc) {
|
||||
return lib->desc->get_plugin(lib->desc->handle, index);
|
||||
}
|
||||
#endif
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,38 +21,46 @@
|
|||
extern "C" {
|
||||
#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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
# include <stdio.h>
|
||||
# define dlopen(path, flags) LoadLibrary(path)
|
||||
# define dlclose(lib) FreeLibrary((HMODULE)lib)
|
||||
# define unlink(path) _unlink(path)
|
||||
# define rmdir(path) _rmdir(path)
|
||||
# ifdef _MSC_VER
|
||||
# define __func__ __FUNCTION__
|
||||
# if _MSC_VER < 1800
|
||||
# define INFINITY DBL_MAX + DBL_MAX
|
||||
# define NAN INFINITY - INFINITY
|
||||
# ifndef snprintf
|
||||
# define snprintf _snprintf
|
||||
# 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
|
||||
# include <dlfcn.h>
|
||||
# include <unistd.h>
|
||||
#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
|
||||
# include "lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h"
|
||||
# include "lv2/dynmanifest/dynmanifest.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -104,9 +112,7 @@ typedef struct {
|
|||
char* bundle_path;
|
||||
void* lib;
|
||||
LV2_Descriptor_Function lv2_descriptor;
|
||||
#ifdef LILV_NEW_LV2
|
||||
const LV2_Lib_Descriptor* desc;
|
||||
#endif
|
||||
uint32_t refs;
|
||||
} LilvLib;
|
||||
|
||||
|
@ -123,6 +129,7 @@ struct LilvPluginImpl {
|
|||
LilvPort** ports;
|
||||
uint32_t num_ports;
|
||||
bool loaded;
|
||||
bool parse_errors;
|
||||
bool replaced;
|
||||
};
|
||||
|
||||
|
@ -139,8 +146,9 @@ struct LilvInstancePimpl {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
bool dyn_manifest;
|
||||
bool filter_language;
|
||||
bool dyn_manifest;
|
||||
bool filter_language;
|
||||
char* lv2_path;
|
||||
} LilvOptions;
|
||||
|
||||
struct LilvWorldImpl {
|
||||
|
@ -152,6 +160,7 @@ struct LilvWorldImpl {
|
|||
LilvPluginClasses* plugin_classes;
|
||||
LilvSpec* specs;
|
||||
LilvPlugins* plugins;
|
||||
LilvPlugins* zombies;
|
||||
LilvNodes* loaded_files;
|
||||
ZixTree* libs;
|
||||
struct {
|
||||
|
@ -168,7 +177,9 @@ struct LilvWorldImpl {
|
|||
SordNode* lv2_index;
|
||||
SordNode* lv2_latency;
|
||||
SordNode* lv2_maximum;
|
||||
SordNode* lv2_microVersion;
|
||||
SordNode* lv2_minimum;
|
||||
SordNode* lv2_minorVersion;
|
||||
SordNode* lv2_name;
|
||||
SordNode* lv2_optionalFeature;
|
||||
SordNode* lv2_port;
|
||||
|
@ -177,7 +188,7 @@ struct LilvWorldImpl {
|
|||
SordNode* lv2_requiredFeature;
|
||||
SordNode* lv2_symbol;
|
||||
SordNode* lv2_prototype;
|
||||
SordNode* null_uri;
|
||||
SordNode* owl_Ontology;
|
||||
SordNode* pset_value;
|
||||
SordNode* rdf_a;
|
||||
SordNode* rdf_value;
|
||||
|
@ -190,6 +201,7 @@ struct LilvWorldImpl {
|
|||
SordNode* xsd_decimal;
|
||||
SordNode* xsd_double;
|
||||
SordNode* xsd_integer;
|
||||
SordNode* null_uri;
|
||||
} uris;
|
||||
LilvOptions opt;
|
||||
};
|
||||
|
@ -228,6 +240,11 @@ struct LilvUIImpl {
|
|||
LilvNodes* classes;
|
||||
};
|
||||
|
||||
typedef struct LilvVersion {
|
||||
int minor;
|
||||
int micro;
|
||||
} LilvVersion;
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions
|
||||
|
@ -243,9 +260,10 @@ void lilv_port_free(const LilvPlugin* plugin, LilvPort* port);
|
|||
LilvPlugin* lilv_plugin_new(LilvWorld* world,
|
||||
LilvNode* 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);
|
||||
LilvNode* lilv_plugin_get_unique(const LilvPlugin* p,
|
||||
LilvNode* lilv_plugin_get_unique(const LilvPlugin* plugin,
|
||||
const SordNode* subject,
|
||||
const SordNode* predicate);
|
||||
|
||||
|
@ -256,7 +274,7 @@ void* lilv_collection_get(const LilvCollection* collection,
|
|||
const LilvIter* i);
|
||||
|
||||
LilvPluginClass* lilv_plugin_class_new(LilvWorld* world,
|
||||
const SordNode* parent_uri,
|
||||
const SordNode* parent_node,
|
||||
const SordNode* uri,
|
||||
const char* label);
|
||||
|
||||
|
@ -277,6 +295,9 @@ LilvScalePoints* lilv_scale_points_new(void);
|
|||
LilvPluginClasses* lilv_plugin_classes_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);
|
||||
|
||||
SerdStatus lilv_world_load_file(LilvWorld* world,
|
||||
|
@ -295,7 +316,7 @@ LilvUI* lilv_ui_new(LilvWorld* world,
|
|||
|
||||
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);
|
||||
|
||||
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_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*
|
||||
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* 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) \
|
||||
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,
|
||||
SordQuadIndex field);
|
||||
|
||||
|
@ -341,7 +383,7 @@ char* lilv_get_lang(void);
|
|||
char* lilv_expand(const char* path);
|
||||
char* lilv_dirname(const char* path);
|
||||
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);
|
||||
bool lilv_path_is_absolute(const char* 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);
|
||||
char* lilv_realpath(const char* path);
|
||||
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);
|
||||
bool lilv_file_equals(const char* a_path, const char* b_path);
|
||||
|
||||
char*
|
||||
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
|
||||
lilv_dir_for_each(const char* path,
|
||||
|
@ -390,6 +433,10 @@ static const LV2_Feature* const dman_features = { NULL };
|
|||
__func__)
|
||||
#define LILV_WARNF(fmt, ...) fprintf(stderr, "%s(): warning: " fmt, \
|
||||
__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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <string.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
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);
|
||||
char* endptr;
|
||||
|
||||
switch (val->type) {
|
||||
case LILV_VALUE_URI:
|
||||
|
@ -33,10 +39,10 @@ lilv_node_set_numerics_from_string(LilvNode* val, size_t len)
|
|||
case LILV_VALUE_BLOB:
|
||||
break;
|
||||
case LILV_VALUE_INT:
|
||||
val->val.int_val = strtol(str, &endptr, 10);
|
||||
val->val.int_val = strtol(str, NULL, 10);
|
||||
break;
|
||||
case LILV_VALUE_FLOAT:
|
||||
val->val.float_val = serd_strtod(str, &endptr);
|
||||
val->val.float_val = serd_strtod(str, NULL);
|
||||
break;
|
||||
case LILV_VALUE_BOOL:
|
||||
val->val.bool_val = !strcmp(str, "true");
|
||||
|
@ -104,44 +110,42 @@ lilv_node_new_from_node(LilvWorld* world, const SordNode* node)
|
|||
LilvNode* result = NULL;
|
||||
SordNode* datatype_uri = NULL;
|
||||
LilvNodeType type = LILV_VALUE_STRING;
|
||||
size_t len = 0;
|
||||
|
||||
switch (sord_node_get_type(node)) {
|
||||
case SORD_URI:
|
||||
result = (LilvNode*)malloc(sizeof(LilvNode));
|
||||
result->world = (LilvWorld*)world;
|
||||
result->world = world;
|
||||
result->type = LILV_VALUE_URI;
|
||||
result->node = sord_node_copy(node);
|
||||
break;
|
||||
case SORD_BLANK:
|
||||
result = (LilvNode*)malloc(sizeof(LilvNode));
|
||||
result->world = (LilvWorld*)world;
|
||||
result->world = world;
|
||||
result->type = LILV_VALUE_BLANK;
|
||||
result->node = sord_node_copy(node);
|
||||
break;
|
||||
case SORD_LITERAL:
|
||||
datatype_uri = sord_node_get_datatype(node);
|
||||
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;
|
||||
else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal)
|
||||
|| sord_node_equals(datatype_uri, world->uris.xsd_double))
|
||||
} else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) ||
|
||||
sord_node_equals(datatype_uri, world->uris.xsd_double)) {
|
||||
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;
|
||||
else if (sord_node_equals(datatype_uri,
|
||||
world->uris.xsd_base64Binary))
|
||||
} else if (sord_node_equals(datatype_uri,
|
||||
world->uris.xsd_base64Binary)) {
|
||||
type = LILV_VALUE_BLOB;
|
||||
else
|
||||
} else {
|
||||
LILV_ERRORF("Unknown datatype `%s'\n",
|
||||
sord_node_get_string(datatype_uri));
|
||||
}
|
||||
}
|
||||
result = lilv_node_new(
|
||||
world, type, (const char*)sord_node_get_string_counted(node, &len));
|
||||
lilv_node_set_numerics_from_string(result, len);
|
||||
world, type, (const char*)sord_node_get_string(node));
|
||||
lilv_node_set_numerics_from_string(result);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -228,12 +232,13 @@ lilv_node_free(LilvNode* val)
|
|||
LILV_API bool
|
||||
lilv_node_equals(const LilvNode* value, const LilvNode* other)
|
||||
{
|
||||
if (value == NULL && other == NULL)
|
||||
if (value == NULL && other == NULL) {
|
||||
return true;
|
||||
else if (value == NULL || other == NULL)
|
||||
} else if (value == NULL || other == NULL) {
|
||||
return false;
|
||||
else if (value->type != other->type)
|
||||
} else if (value->type != other->type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (value->type) {
|
||||
case LILV_VALUE_URI:
|
||||
|
@ -278,11 +283,13 @@ lilv_node_get_turtle_token(const LilvNode* value)
|
|||
break;
|
||||
case LILV_VALUE_INT:
|
||||
node = serd_node_new_integer(value->val.int_val);
|
||||
result = (char*)node.buf;
|
||||
result = lilv_strdup((char*)node.buf);
|
||||
serd_node_free(&node);
|
||||
break;
|
||||
case LILV_VALUE_FLOAT:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -320,13 +327,15 @@ lilv_node_as_blank(const LilvNode* value)
|
|||
LILV_API bool
|
||||
lilv_node_is_literal(const LilvNode* value)
|
||||
{
|
||||
if (!value)
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (value->type) {
|
||||
case LILV_VALUE_STRING:
|
||||
case LILV_VALUE_INT:
|
||||
case LILV_VALUE_FLOAT:
|
||||
case LILV_VALUE_BLOB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -366,12 +375,12 @@ lilv_node_is_float(const LilvNode* value)
|
|||
LILV_API float
|
||||
lilv_node_as_float(const LilvNode* value)
|
||||
{
|
||||
assert(lilv_node_is_float(value) || lilv_node_is_int(value));
|
||||
if (lilv_node_is_float(value)) {
|
||||
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 NAN;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
#include "sord/sord.h"
|
||||
#include "zix/tree.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
LilvPluginClass*
|
||||
lilv_plugin_class_new(LilvWorld* world,
|
||||
const SordNode* parent_node,
|
||||
const SordNode* uri,
|
||||
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));
|
||||
pc->world = world;
|
||||
pc->uri = lilv_node_new_from_node(world, uri);
|
||||
|
@ -42,7 +42,10 @@ lilv_plugin_class_new(LilvWorld* world,
|
|||
void
|
||||
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->parent_uri);
|
||||
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 LilvNode* parent = lilv_plugin_class_get_parent_uri(c);
|
||||
if (parent && lilv_node_equals(lilv_plugin_class_get_uri(plugin_class),
|
||||
parent))
|
||||
parent)) {
|
||||
zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.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*
|
||||
lilv_port_new(LilvWorld* world,
|
||||
|
@ -55,38 +60,40 @@ lilv_port_is_a(const LilvPlugin* plugin,
|
|||
const LilvPort* port,
|
||||
const LilvNode* port_class)
|
||||
{
|
||||
LILV_FOREACH(nodes, i, port->classes)
|
||||
if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class))
|
||||
LILV_FOREACH(nodes, i, port->classes) {
|
||||
if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LILV_API bool
|
||||
lilv_port_has_property(const LilvPlugin* p,
|
||||
lilv_port_has_property(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const LilvNode* property)
|
||||
{
|
||||
return lilv_world_ask_internal(p->world,
|
||||
return lilv_world_ask_internal(plugin->world,
|
||||
port->node->node,
|
||||
p->world->uris.lv2_portProperty,
|
||||
plugin->world->uris.lv2_portProperty,
|
||||
property->node);
|
||||
}
|
||||
|
||||
LILV_API bool
|
||||
lilv_port_supports_event(const LilvPlugin* p,
|
||||
lilv_port_supports_event(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const LilvNode* event)
|
||||
const LilvNode* event_type)
|
||||
{
|
||||
const uint8_t* predicates[] = { (const uint8_t*)LV2_EVENT__supportsEvent,
|
||||
(const uint8_t*)LV2_ATOM__supports,
|
||||
NULL };
|
||||
|
||||
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,
|
||||
sord_new_uri(p->world->world, *pred),
|
||||
event->node)) {
|
||||
sord_new_uri(plugin->world->world, *pred),
|
||||
event_type->node)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -94,11 +101,11 @@ lilv_port_supports_event(const LilvPlugin* p,
|
|||
}
|
||||
|
||||
static LilvNodes*
|
||||
lilv_port_get_value_by_node(const LilvPlugin* p,
|
||||
lilv_port_get_value_by_node(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const SordNode* predicate)
|
||||
{
|
||||
return lilv_world_find_nodes_internal(p->world,
|
||||
return lilv_world_find_nodes_internal(plugin->world,
|
||||
port->node->node,
|
||||
predicate,
|
||||
NULL);
|
||||
|
@ -112,7 +119,7 @@ lilv_port_get_node(const LilvPlugin* plugin,
|
|||
}
|
||||
|
||||
LILV_API LilvNodes*
|
||||
lilv_port_get_value(const LilvPlugin* p,
|
||||
lilv_port_get_value(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
const LilvNode* predicate)
|
||||
{
|
||||
|
@ -122,15 +129,15 @@ lilv_port_get_value(const LilvPlugin* p,
|
|||
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_port_get(const LilvPlugin* p,
|
||||
lilv_port_get(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
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(
|
||||
values ? lilv_nodes_get_first(values) : NULL);
|
||||
|
@ -140,50 +147,52 @@ lilv_port_get(const LilvPlugin* p,
|
|||
}
|
||||
|
||||
LILV_API uint32_t
|
||||
lilv_port_get_index(const LilvPlugin* p,
|
||||
lilv_port_get_index(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
return port->index;
|
||||
}
|
||||
|
||||
LILV_API const LilvNode*
|
||||
lilv_port_get_symbol(const LilvPlugin* p,
|
||||
lilv_port_get_symbol(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
return port->symbol;
|
||||
}
|
||||
|
||||
LILV_API LilvNode*
|
||||
lilv_port_get_name(const LilvPlugin* p,
|
||||
lilv_port_get_name(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
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;
|
||||
if (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);
|
||||
}
|
||||
lilv_nodes_free(results);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
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;
|
||||
}
|
||||
|
||||
LILV_API const LilvNodes*
|
||||
lilv_port_get_classes(const LilvPlugin* p,
|
||||
lilv_port_get_classes(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
return port->classes;
|
||||
}
|
||||
|
||||
LILV_API void
|
||||
lilv_port_get_range(const LilvPlugin* p,
|
||||
lilv_port_get_range(const LilvPlugin* plugin,
|
||||
const LilvPort* port,
|
||||
LilvNode** def,
|
||||
LilvNode** min,
|
||||
|
@ -191,7 +200,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
|||
{
|
||||
if (def) {
|
||||
LilvNodes* defaults = lilv_port_get_value_by_node(
|
||||
p, port, p->world->uris.lv2_default);
|
||||
plugin, port, plugin->world->uris.lv2_default);
|
||||
*def = defaults
|
||||
? lilv_node_duplicate(lilv_nodes_get_first(defaults))
|
||||
: NULL;
|
||||
|
@ -199,7 +208,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
|||
}
|
||||
if (min) {
|
||||
LilvNodes* minimums = lilv_port_get_value_by_node(
|
||||
p, port, p->world->uris.lv2_minimum);
|
||||
plugin, port, plugin->world->uris.lv2_minimum);
|
||||
*min = minimums
|
||||
? lilv_node_duplicate(lilv_nodes_get_first(minimums))
|
||||
: NULL;
|
||||
|
@ -207,7 +216,7 @@ lilv_port_get_range(const LilvPlugin* p,
|
|||
}
|
||||
if (max) {
|
||||
LilvNodes* maximums = lilv_port_get_value_by_node(
|
||||
p, port, p->world->uris.lv2_maximum);
|
||||
plugin, port, plugin->world->uris.lv2_maximum);
|
||||
*max = maximums
|
||||
? lilv_node_duplicate(lilv_nodes_get_first(maximums))
|
||||
: NULL;
|
||||
|
@ -216,29 +225,30 @@ lilv_port_get_range(const LilvPlugin* p,
|
|||
}
|
||||
|
||||
LILV_API LilvScalePoints*
|
||||
lilv_port_get_scale_points(const LilvPlugin* p,
|
||||
lilv_port_get_scale_points(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
SordIter* points = lilv_world_query_internal(
|
||||
p->world,
|
||||
plugin->world,
|
||||
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);
|
||||
|
||||
LilvScalePoints* ret = NULL;
|
||||
if (!sord_iter_end(points))
|
||||
if (!sord_iter_end(points)) {
|
||||
ret = lilv_scale_points_new();
|
||||
}
|
||||
|
||||
FOREACH_MATCH(points) {
|
||||
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,
|
||||
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,
|
||||
p->world->uris.rdfs_label);
|
||||
plugin->world->uris.rdfs_label);
|
||||
|
||||
if (value && label) {
|
||||
zix_tree_insert(
|
||||
|
@ -252,12 +262,12 @@ lilv_port_get_scale_points(const LilvPlugin* p,
|
|||
}
|
||||
|
||||
LILV_API LilvNodes*
|
||||
lilv_port_get_properties(const LilvPlugin* p,
|
||||
lilv_port_get_properties(const LilvPlugin* plugin,
|
||||
const LilvPort* port)
|
||||
{
|
||||
LilvNode* pred = lilv_node_new_from_node(
|
||||
p->world, p->world->uris.lv2_portProperty);
|
||||
LilvNodes* ret = lilv_port_get_value(p, port, pred);
|
||||
plugin->world, plugin->world->uris.lv2_portProperty);
|
||||
LilvNodes* ret = lilv_port_get_value(plugin, port, pred);
|
||||
lilv_node_free(pred);
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
#include "sord/sord.h"
|
||||
#include "zix/tree.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
typedef enum {
|
||||
LILV_LANG_MATCH_NONE, ///< Language does not match at all
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Ownership of value and label is taken */
|
||||
LilvScalePoint*
|
||||
lilv_scale_point_new(LilvNode* value, LilvNode* label)
|
||||
|
@ -37,13 +41,13 @@ lilv_scale_point_free(LilvScalePoint* point)
|
|||
}
|
||||
|
||||
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_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
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
#include "zix/tree.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
LilvUI*
|
||||
lilv_ui_new(LilvWorld* world,
|
||||
LilvNode* uri,
|
||||
|
@ -93,9 +97,9 @@ lilv_ui_get_classes(const LilvUI* ui)
|
|||
}
|
||||
|
||||
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*
|
||||
|
|
|
@ -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
|
||||
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.
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 1 /* for fileno */
|
||||
#define _BSD_SOURCE 1 /* for realpath, symlink */
|
||||
#define _POSIX_C_SOURCE 200809L /* for fileno */
|
||||
#define _BSD_SOURCE 1 /* for realpath, symlink */
|
||||
#define _DEFAULT_SOURCE 1 /* for realpath, symlink */
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define _DARWIN_C_SOURCE 1 /* for flock */
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "lilv_config.h"
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
#include "serd/serd.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0600 /* for CreateSymbolicLink */
|
||||
#endif
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# define F_OK 0
|
||||
# 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
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lilv_internal.h"
|
||||
|
||||
#if defined(HAVE_FLOCK) && defined(HAVE_FILENO)
|
||||
# include <sys/file.h>
|
||||
#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
|
||||
# define PAGE_SIZE 4096
|
||||
# define PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
void
|
||||
lilv_free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
char*
|
||||
lilv_strjoin(const char* first, ...)
|
||||
{
|
||||
|
@ -65,16 +96,18 @@ lilv_strjoin(const char* first, ...)
|
|||
va_start(args, first);
|
||||
while (1) {
|
||||
const char* const s = va_arg(args, const char *);
|
||||
if (s == NULL)
|
||||
if (s == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t this_len = strlen(s);
|
||||
if (!(result = (char*)realloc(result, len + this_len + 1))) {
|
||||
const size_t this_len = strlen(s);
|
||||
char* new_result = (char*)realloc(result, len + this_len + 1);
|
||||
if (!new_result) {
|
||||
free(result);
|
||||
LILV_ERROR("realloc() failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = new_result;
|
||||
memcpy(result + len, s, 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);
|
||||
}
|
||||
|
||||
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.
|
||||
* 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;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
/** Append suffix to dst, update dst_len, and return the realloc'd result. */
|
||||
static char*
|
||||
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`. */
|
||||
char*
|
||||
lilv_expand(const char* path)
|
||||
|
@ -239,14 +282,20 @@ lilv_dirname(const char* path)
|
|||
}
|
||||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
char*
|
||||
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);
|
||||
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");
|
||||
if (!in) {
|
||||
LILV_ERRORF("error opening %s (%s)\n", src, strerror(errno));
|
||||
return 1;
|
||||
return errno;
|
||||
}
|
||||
|
||||
FILE* out = fopen(dst, "w");
|
||||
if (!out) {
|
||||
LILV_ERRORF("error opening %s (%s)\n", dst, strerror(errno));
|
||||
fclose(in);
|
||||
return 2;
|
||||
return errno;
|
||||
}
|
||||
|
||||
char* page = (char*)malloc(PAGE_SIZE);
|
||||
size_t n_read = 0;
|
||||
int st = 0;
|
||||
while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) {
|
||||
if (fwrite(page, 1, n_read, out) != n_read) {
|
||||
LILV_ERRORF("write to %s failed (%s)\n", dst, strerror(errno));
|
||||
st = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int ret = ferror(in) || ferror(out);
|
||||
if (ferror(in)) {
|
||||
LILV_ERRORF("read from %s failed (%s)\n", src, strerror(errno));
|
||||
if (!st && (ferror(in) || ferror(out))) {
|
||||
st = EBADF;
|
||||
}
|
||||
|
||||
free(page);
|
||||
fclose(in);
|
||||
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
|
||||
|
@ -307,7 +361,7 @@ lilv_path_is_absolute(const char* path)
|
|||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (isalpha(path[0]) && path[1] == ':' && lilv_is_dir_sep(path[2])) {
|
||||
if (is_windows_path(path)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -349,25 +403,8 @@ lilv_path_join(const char* a, const char* b)
|
|||
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 {
|
||||
char* pattern;
|
||||
off_t orig_size;
|
||||
time_t time;
|
||||
char* latest;
|
||||
} Latest;
|
||||
|
@ -375,16 +412,18 @@ typedef struct {
|
|||
static void
|
||||
update_latest(const char* path, const char* name, void* data)
|
||||
{
|
||||
Latest* latest = (Latest*)data;
|
||||
char* entry_path = lilv_path_join(path, name);
|
||||
Latest* latest = (Latest*)data;
|
||||
char* entry_path = lilv_path_join(path, name);
|
||||
unsigned num;
|
||||
if (sscanf(entry_path, latest->pattern, &num) == 1) {
|
||||
off_t entry_size = 0;
|
||||
time_t entry_time = 0;
|
||||
lilv_size_mtime(entry_path, &entry_size, &entry_time);
|
||||
if (entry_size == latest->orig_size && entry_time >= latest->time) {
|
||||
free(latest->latest);
|
||||
latest->latest = entry_path;
|
||||
struct stat st;
|
||||
if (!stat(entry_path, &st)) {
|
||||
if (st.st_mtime >= latest->time) {
|
||||
free(latest->latest);
|
||||
latest->latest = entry_path;
|
||||
}
|
||||
} else {
|
||||
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
if (entry_path != latest->latest) {
|
||||
|
@ -397,8 +436,14 @@ char*
|
|||
lilv_get_latest_copy(const char* path, const char* copy_path)
|
||||
{
|
||||
char* copy_dir = lilv_dirname(copy_path);
|
||||
Latest latest = { lilv_strjoin(copy_path, "%u", NULL), 0, 0, NULL };
|
||||
lilv_size_mtime(path, &latest.orig_size, &latest.time);
|
||||
Latest latest = { lilv_strjoin(copy_path, ".%u", NULL), 0, NULL };
|
||||
|
||||
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);
|
||||
|
||||
|
@ -410,7 +455,11 @@ lilv_get_latest_copy(const char* path, const char* copy_path)
|
|||
char*
|
||||
lilv_realpath(const char* path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
char* out = (char*)malloc(MAX_PATH);
|
||||
GetFullPathName(path, MAX_PATH, out, NULL);
|
||||
return out;
|
||||
|
@ -427,6 +476,9 @@ lilv_symlink(const char* oldpath, const char* newpath)
|
|||
if (strcmp(oldpath, newpath)) {
|
||||
#ifdef _WIN32
|
||||
ret = !CreateSymbolicLink(newpath, oldpath, 0);
|
||||
if (ret) {
|
||||
ret = !CreateHardLink(newpath, oldpath, 0);
|
||||
}
|
||||
#else
|
||||
ret = symlink(oldpath, newpath);
|
||||
#endif
|
||||
|
@ -517,10 +569,8 @@ lilv_dir_for_each(const char* path,
|
|||
#else
|
||||
DIR* dir = opendir(path);
|
||||
if (dir) {
|
||||
struct dirent entry;
|
||||
struct dirent* result;
|
||||
while (!readdir_r(dir, &entry, &result) && result) {
|
||||
f(path, entry.d_name, data);
|
||||
for (struct dirent* entry; (entry = readdir(dir));) {
|
||||
f(path, entry->d_name, data);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
@ -532,16 +582,23 @@ lilv_mkdir_p(const char* dir_path)
|
|||
{
|
||||
char* path = lilv_strdup(dir_path);
|
||||
const size_t path_len = strlen(path);
|
||||
for (size_t i = 1; i <= path_len; ++i) {
|
||||
if (path[i] == LILV_DIR_SEP[0] || path[i] == '\0') {
|
||||
size_t i = 1;
|
||||
|
||||
#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';
|
||||
if (mkdir(path, 0755) && errno != EEXIST) {
|
||||
LILV_ERRORF("Failed to create %s (%s)\n",
|
||||
path, strerror(errno));
|
||||
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;
|
||||
char* const a_real = lilv_realpath(a_path);
|
||||
char* const b_real = lilv_realpath(b_path);
|
||||
if (!a_real || !b_real) {
|
||||
match = false; // Missing file matches nothing
|
||||
} else if (!strcmp(a_real, b_real)) {
|
||||
if (!strcmp(a_real, b_real)) {
|
||||
match = true; // Real paths match
|
||||
} else if (lilv_file_size(a_path) != lilv_file_size(b_path)) {
|
||||
match = false; // Sizes differ
|
||||
} else if (!(a_file = fopen(a_real, "rb"))) {
|
||||
match = false; // Missing file matches nothing
|
||||
} else if (!(b_file = fopen(b_real, "rb"))) {
|
||||
} else if (!(a_file = fopen(a_real, "rb")) ||
|
||||
!(b_file = fopen(b_real, "rb"))) {
|
||||
match = false; // Missing file matches nothing
|
||||
} else {
|
||||
match = true;
|
||||
// TODO: Improve performance by reading chunks
|
||||
match = true;
|
||||
while (!feof(a_file) && !feof(b_file)) {
|
||||
if (fgetc(a_file) != fgetc(b_file)) {
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lv2/lv2plug.in/ns/ext/presets/presets.h"
|
||||
|
||||
#include "lilv_internal.h"
|
||||
static int
|
||||
lilv_world_drop_graph(LilvWorld* world, const SordNode* graph);
|
||||
|
||||
LILV_API LilvWorld*
|
||||
lilv_world_new(void)
|
||||
{
|
||||
LilvWorld* world = (LilvWorld*)malloc(sizeof(LilvWorld));
|
||||
LilvWorld* world = (LilvWorld*)calloc(1, sizeof(LilvWorld));
|
||||
|
||||
world->world = sord_world_new();
|
||||
if (!world->world)
|
||||
if (!world->world) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
world->model = sord_new(world->world, SORD_SPO|SORD_OPS, true);
|
||||
if (!world->model)
|
||||
if (!world->model) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
world->specs = NULL;
|
||||
world->plugin_classes = lilv_plugin_classes_new();
|
||||
world->plugins = lilv_plugins_new();
|
||||
world->zombies = lilv_plugins_new();
|
||||
world->loaded_files = zix_tree_new(
|
||||
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);
|
||||
#endif
|
||||
|
||||
#define NS_DCTERMS "http://purl.org/dc/terms/"
|
||||
#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.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_latency = NEW_URI(LV2_CORE__latency);
|
||||
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_minorVersion = NEW_URI(LV2_CORE__minorVersion);
|
||||
world->uris.lv2_name = NEW_URI(LV2_CORE__name);
|
||||
world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature);
|
||||
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_symbol = NEW_URI(LV2_CORE__symbol);
|
||||
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.rdf_a = NEW_URI(LILV_NS_RDF "type");
|
||||
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);
|
||||
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);
|
||||
world->loaded_files = NULL;
|
||||
|
||||
#ifdef LILV_NEW_LV2
|
||||
zix_tree_free((ZixTree*)world->libs);
|
||||
zix_tree_free(world->libs);
|
||||
world->libs = NULL;
|
||||
#endif
|
||||
|
||||
zix_tree_free((ZixTree*)world->plugin_classes);
|
||||
world->plugin_classes = NULL;
|
||||
|
@ -150,26 +178,32 @@ lilv_world_free(LilvWorld* world)
|
|||
sord_world_free(world->world);
|
||||
world->world = NULL;
|
||||
|
||||
free(world->opt.lv2_path);
|
||||
free(world);
|
||||
}
|
||||
|
||||
LILV_API void
|
||||
lilv_world_set_option(LilvWorld* world,
|
||||
const char* option,
|
||||
const char* uri,
|
||||
const LilvNode* value)
|
||||
{
|
||||
if (!strcmp(option, LILV_OPTION_DYN_MANIFEST)) {
|
||||
if (!strcmp(uri, LILV_OPTION_DYN_MANIFEST)) {
|
||||
if (lilv_node_is_bool(value)) {
|
||||
world->opt.dyn_manifest = lilv_node_as_bool(value);
|
||||
return;
|
||||
}
|
||||
} else if (!strcmp(option, LILV_OPTION_FILTER_LANG)) {
|
||||
} else if (!strcmp(uri, LILV_OPTION_FILTER_LANG)) {
|
||||
if (lilv_node_is_bool(value)) {
|
||||
world->opt.filter_language = lilv_node_as_bool(value);
|
||||
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*
|
||||
|
@ -182,6 +216,9 @@ lilv_world_find_nodes(LilvWorld* world,
|
|||
LILV_ERRORF("Subject `%s' is not a resource\n",
|
||||
sord_node_get_string(subject->node));
|
||||
return NULL;
|
||||
} else if (!predicate) {
|
||||
LILV_ERROR("Missing required predicate\n");
|
||||
return NULL;
|
||||
} else if (!lilv_node_is_uri(predicate)) {
|
||||
LILV_ERRORF("Predicate `%s' is not a URI\n",
|
||||
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");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return lilv_world_find_nodes_internal(world,
|
||||
subject ? subject->node : NULL,
|
||||
predicate->node,
|
||||
|
@ -237,8 +274,30 @@ lilv_world_ask(LilvWorld* world,
|
|||
const LilvNode* predicate,
|
||||
const LilvNode* object)
|
||||
{
|
||||
return sord_ask(
|
||||
world->model, subject->node, predicate->node, object->node, NULL);
|
||||
return sord_ask(world->model,
|
||||
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*
|
||||
|
@ -258,12 +317,8 @@ lilv_new_uri_relative_to_base(const uint8_t* uri_str,
|
|||
const uint8_t* base_uri_str)
|
||||
{
|
||||
SerdURI base_uri;
|
||||
if (serd_uri_parse(base_uri_str, &base_uri)) {
|
||||
return SERD_NODE_NULL;
|
||||
}
|
||||
|
||||
SerdURI ignored;
|
||||
return serd_node_new_uri_from_string(uri_str, &base_uri, &ignored);
|
||||
serd_uri_parse(base_uri_str, &base_uri);
|
||||
return serd_node_new_uri_from_string(uri_str, &base_uri, NULL);
|
||||
}
|
||||
|
||||
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. */
|
||||
struct LilvHeader*
|
||||
lilv_collection_get_by_uri(const ZixTree* const_seq,
|
||||
const LilvNode* uri)
|
||||
static ZixTreeIter*
|
||||
lilv_collection_find_by_uri(const ZixTree* seq, const LilvNode* uri)
|
||||
{
|
||||
if (!lilv_node_is_uri(uri)) {
|
||||
return NULL;
|
||||
ZixTreeIter* i = 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;
|
||||
struct LilvHeader key = { NULL, (LilvNode*)uri };
|
||||
ZixTreeIter* i = NULL;
|
||||
ZixStatus st = zix_tree_find(seq, &key, &i);
|
||||
if (!st) {
|
||||
return (struct LilvHeader*)zix_tree_get(i);
|
||||
}
|
||||
/** Get an element of a collection of any object with an LilvHeader by URI. */
|
||||
struct LilvHeader*
|
||||
lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri)
|
||||
{
|
||||
ZixTreeIter* const i = lilv_collection_find_by_uri(seq, uri);
|
||||
|
||||
return NULL;
|
||||
return i ? (struct LilvHeader*)zix_tree_get(i) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -351,33 +407,55 @@ lilv_world_add_spec(LilvWorld* world,
|
|||
}
|
||||
|
||||
static void
|
||||
lilv_world_add_plugin(LilvWorld* world,
|
||||
const SordNode* plugin_node,
|
||||
const LilvNode* manifest_uri,
|
||||
void* dynmanifest,
|
||||
const SordNode* bundle_node)
|
||||
lilv_world_add_plugin(LilvWorld* world,
|
||||
const SordNode* plugin_node,
|
||||
const LilvNode* manifest_uri,
|
||||
void* dynmanifest,
|
||||
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,
|
||||
plugin_uri);
|
||||
if (last) {
|
||||
LILV_ERRORF("Duplicate plugin <%s>\n", lilv_node_as_uri(plugin_uri));
|
||||
LILV_ERRORF("... found in %s\n", lilv_node_as_string(
|
||||
lilv_plugin_get_bundle_uri(last)));
|
||||
LILV_ERRORF("... and %s\n", sord_node_get_string(bundle_node));
|
||||
if (plugin) {
|
||||
// Existing plugin, if this is different bundle, ignore it
|
||||
// (use the first plugin found in LV2_PATH)
|
||||
const LilvNode* last_bundle = lilv_plugin_get_bundle_uri(plugin);
|
||||
const char* plugin_uri_str = lilv_node_as_uri(plugin_uri);
|
||||
if (sord_node_equals(bundle, last_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);
|
||||
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
|
||||
// Set dynamic manifest library URI, if applicable
|
||||
|
@ -400,9 +478,6 @@ lilv_world_add_plugin(LilvWorld* world,
|
|||
NULL);
|
||||
}
|
||||
sord_iter_free(files);
|
||||
|
||||
// Add plugin to world plugin sequence
|
||||
zix_tree_insert((ZixTree*)world->plugins, plugin, NULL);
|
||||
}
|
||||
|
||||
SerdStatus
|
||||
|
@ -430,17 +505,18 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
return;
|
||||
}
|
||||
|
||||
typedef void* LV2_Dyn_Manifest_Handle;
|
||||
LV2_Dyn_Manifest_Handle handle = NULL;
|
||||
|
||||
// ?dman a dynman:DynManifest
|
||||
SordIter* dmanifests = sord_search(world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.dman_DynManifest,
|
||||
bundle_node);
|
||||
FOREACH_MATCH(dmanifests) {
|
||||
const SordNode* dmanifest = sord_iter_get_node(dmanifests, SORD_SUBJECT);
|
||||
// ?dman a dynman:DynManifest bundle_node
|
||||
SordModel* model = lilv_world_filter_model(world,
|
||||
world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.dman_DynManifest,
|
||||
bundle_node);
|
||||
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
|
||||
SordIter* binaries = sord_search(world->model,
|
||||
|
@ -458,7 +534,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
// Get binary path
|
||||
const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT);
|
||||
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) {
|
||||
LILV_ERROR("No dynamic manifest library path\n");
|
||||
sord_iter_free(binaries);
|
||||
|
@ -466,10 +542,13 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
}
|
||||
|
||||
// Open library
|
||||
dlerror();
|
||||
void* lib = dlopen(lib_path, RTLD_LAZY);
|
||||
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);
|
||||
lilv_free(lib_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -481,6 +560,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path);
|
||||
sord_iter_free(binaries);
|
||||
dlclose(lib);
|
||||
lilv_free(lib_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -493,21 +573,25 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
lib_path);
|
||||
sord_iter_free(binaries);
|
||||
dlclose(lib);
|
||||
lilv_free(lib_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
LilvDynManifest* desc = malloc(sizeof(LilvDynManifest));
|
||||
LilvDynManifest* desc = (LilvDynManifest*)malloc(sizeof(LilvDynManifest));
|
||||
desc->bundle = lilv_node_new_from_node(world, bundle_node);
|
||||
desc->lib = lib;
|
||||
desc->handle = handle;
|
||||
desc->refs = 0;
|
||||
|
||||
sord_iter_free(binaries);
|
||||
|
||||
// Generate data file
|
||||
FILE* fd = tmpfile();
|
||||
get_subjects_func(handle, fd);
|
||||
rewind(fd);
|
||||
|
||||
// Parse generated data file
|
||||
// Parse generated data file into temporary model
|
||||
// FIXME
|
||||
const SerdNode* base = sord_node_to_serd_node(dmanifest);
|
||||
SerdEnv* env = serd_env_new(base);
|
||||
SerdReader* reader = sord_new_reader(
|
||||
|
@ -523,38 +607,101 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
|
|||
fclose(fd);
|
||||
|
||||
// ?plugin a lv2:Plugin
|
||||
SordIter* plug_results = sord_search(
|
||||
world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.lv2_Plugin,
|
||||
dmanifest);
|
||||
FOREACH_MATCH(plug_results) {
|
||||
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
||||
SordModel* plugins = lilv_world_filter_model(world,
|
||||
world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.lv2_Plugin,
|
||||
dmanifest);
|
||||
SordIter* p = sord_begin(plugins);
|
||||
FOREACH_MATCH(p) {
|
||||
const SordNode* plug = sord_iter_get_node(p, SORD_SUBJECT);
|
||||
lilv_world_add_plugin(world, plug, manifest, desc, bundle_node);
|
||||
}
|
||||
sord_iter_free(plug_results);
|
||||
|
||||
sord_iter_free(binaries);
|
||||
if (desc->refs == 0) {
|
||||
free(desc);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
static
|
||||
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(
|
||||
(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);
|
||||
serd_node_free(&manifest_uri);
|
||||
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_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)) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ?plugin a lv2:Plugin
|
||||
SordIter* plug_results = sord_search(world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.lv2_Plugin,
|
||||
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) {
|
||||
const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
|
||||
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);
|
||||
|
||||
// ?specification a lv2:Specification
|
||||
SordIter* spec_results = sord_search(world->model,
|
||||
NULL,
|
||||
world->uris.rdf_a,
|
||||
world->uris.lv2_Specification,
|
||||
bundle_node);
|
||||
FOREACH_MATCH(spec_results) {
|
||||
const SordNode* spec = sord_iter_get_node(spec_results, SORD_SUBJECT);
|
||||
lilv_world_add_spec(world, spec, bundle_node);
|
||||
// ?spec a lv2:Specification
|
||||
// ?spec a owl:Ontology
|
||||
const SordNode* spec_preds[] = { world->uris.lv2_Specification,
|
||||
world->uris.owl_Ontology,
|
||||
NULL };
|
||||
for (const SordNode** p = spec_preds; *p; ++p) {
|
||||
SordIter* i = sord_search(
|
||||
world->model, NULL, world->uris.rdf_a, *p, 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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
// Get quad and increment iter so sord_remove doesn't invalidate it
|
||||
SordQuad quad;
|
||||
sord_iter_get(i, quad);
|
||||
sord_iter_next(i);
|
||||
|
||||
// Remove quad (nodes may now be deleted, quad is invalid)
|
||||
sord_remove(world->model, quad);
|
||||
const SerdStatus st = sord_erase(world->model, i);
|
||||
if (st) {
|
||||
LILV_ERRORF("Error removing statement from <%s> (%s)\n",
|
||||
sord_node_get_string(graph), serd_strerror(st));
|
||||
return st;
|
||||
}
|
||||
}
|
||||
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. */
|
||||
static int
|
||||
lilv_world_unload_file(LilvWorld* world, LilvNode* file)
|
||||
lilv_world_unload_file(LilvWorld* world, const LilvNode* file)
|
||||
{
|
||||
ZixTreeIter* 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_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
|
||||
LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri);
|
||||
lilv_world_unload_file(world, manifest);
|
||||
lilv_node_free(manifest);
|
||||
if (!bundle_uri) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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
|
||||
return lilv_world_drop_graph(world, bundle_uri);
|
||||
return lilv_world_drop_graph(world, bundle_uri->node);
|
||||
}
|
||||
|
||||
static void
|
||||
load_dir_entry(const char* dir, const char* name, void* data)
|
||||
{
|
||||
LilvWorld* world = (LilvWorld*)data;
|
||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* scheme = (dir[0] == '/') ? "file://" : "file:///";
|
||||
char* uri = lilv_strjoin(scheme, dir, "/", name, "/", NULL);
|
||||
LilvNode* uri_val = lilv_new_uri(world, uri);
|
||||
char* path = lilv_strjoin(dir, "/", name, "/", NULL);
|
||||
SerdNode suri = serd_node_new_file_uri((const uint8_t*)path, 0, 0, true);
|
||||
LilvNode* node = lilv_new_uri(world, (const char*)suri.buf);
|
||||
|
||||
lilv_world_load_bundle(world, uri_val);
|
||||
lilv_node_free(uri_val);
|
||||
free(uri);
|
||||
lilv_world_load_bundle(world, node);
|
||||
lilv_node_free(node);
|
||||
serd_node_free(&suri);
|
||||
free(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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_world_load_all(LilvWorld* world)
|
||||
{
|
||||
const char* lv2_path = getenv("LV2_PATH");
|
||||
if (!lv2_path)
|
||||
const char* lv2_path = world->opt.lv2_path;
|
||||
if (!lv2_path) {
|
||||
lv2_path = getenv("LV2_PATH");
|
||||
}
|
||||
if (!lv2_path) {
|
||||
lv2_path = LILV_DEFAULT_LV2_PATH;
|
||||
}
|
||||
|
||||
// Discover bundles and read all manifest files into model
|
||||
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
|
||||
}
|
||||
|
||||
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));
|
||||
const SerdStatus st = serd_reader_read_file(
|
||||
reader, sord_node_get_string(uri->node));
|
||||
const SerdStatus st = serd_reader_read_file(reader, uri_str);
|
||||
if (st) {
|
||||
LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri));
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
zix_tree_insert((ZixTree*)world->loaded_files,
|
||||
lilv_node_duplicate(uri),
|
||||
NULL);
|
||||
|
@ -825,13 +1108,16 @@ lilv_world_load_resource(LilvWorld* world,
|
|||
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;
|
||||
SordIter* files = sord_search(world->model,
|
||||
resource->node,
|
||||
world->uris.rdfs_seeAlso,
|
||||
NULL, NULL);
|
||||
FOREACH_MATCH(files) {
|
||||
const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
|
||||
FOREACH_MATCH(f) {
|
||||
const SordNode* file = sord_iter_get_node(f, SORD_OBJECT);
|
||||
const uint8_t* file_str = sord_node_get_string(file);
|
||||
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
||||
if (sord_node_get_type(file) != SORD_URI) {
|
||||
|
@ -841,8 +1127,9 @@ lilv_world_load_resource(LilvWorld* world,
|
|||
}
|
||||
lilv_node_free(file_node);
|
||||
}
|
||||
sord_iter_free(files);
|
||||
sord_iter_free(f);
|
||||
|
||||
sord_free(files);
|
||||
return n_read;
|
||||
}
|
||||
|
||||
|
@ -856,25 +1143,29 @@ lilv_world_unload_resource(LilvWorld* world,
|
|||
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;
|
||||
SordIter* files = sord_search(world->model,
|
||||
resource->node,
|
||||
world->uris.rdfs_seeAlso,
|
||||
NULL, NULL);
|
||||
FOREACH_MATCH(files) {
|
||||
const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
|
||||
FOREACH_MATCH(f) {
|
||||
const SordNode* file = sord_iter_get_node(f, SORD_OBJECT);
|
||||
LilvNode* file_node = lilv_node_new_from_node(world, file);
|
||||
if (sord_node_get_type(file) != SORD_URI) {
|
||||
LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n",
|
||||
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);
|
||||
++n_dropped;
|
||||
}
|
||||
lilv_node_free(file_node);
|
||||
}
|
||||
sord_iter_free(files);
|
||||
sord_iter_free(f);
|
||||
|
||||
sord_free(files);
|
||||
return n_dropped;
|
||||
}
|
||||
|
||||
|
@ -895,3 +1186,51 @@ lilv_world_get_all_plugins(const LilvWorld* world)
|
|||
{
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -59,7 +59,7 @@ typedef enum {
|
|||
ZIX_STATUS_NOT_FOUND,
|
||||
ZIX_STATUS_EXISTS,
|
||||
ZIX_STATUS_BAD_ARG,
|
||||
ZIX_STATUS_BAD_PERMS,
|
||||
ZIX_STATUS_BAD_PERMS
|
||||
} 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
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zix/common.h"
|
||||
#include "zix/tree.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct ZixTreeNodeImpl ZixTreeNode;
|
||||
|
||||
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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,10 +17,11 @@
|
|||
#ifndef ZIX_TREE_H
|
||||
#define ZIX_TREE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "zix/common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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 owl: <http://www.w3.org/2002/07/owl#> .
|
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
|
||||
<http://lv2plug.in/ns/lv2core>
|
||||
a lv2:Specification ;
|
||||
lv2:minorVersion 12 ;
|
||||
lv2:microVersion 2 ;
|
||||
lv2:minorVersion 16 ;
|
||||
lv2:microVersion 0 ;
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef LV2_MORPH_H
|
||||
#define LV2_MORPH_H
|
||||
#include "lv2/core/lv2.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
||||
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
|
||||
#define PLUGIN_URI "http://example.org/failed-lib-descriptor"
|
||||
|
||||
#define LV2_MORPH_URI "http://lv2plug.in/ns/ext/morph"
|
||||
#define LV2_MORPH_PREFIX LV2_MORPH_URI "#"
|
||||
|
||||
#define LV2_MORPH__AutoMorphPort LV2_MORPH_PREFIX "AutoMorphPort"
|
||||
#define LV2_MORPH__MorphPort LV2_MORPH_PREFIX "MorphPort"
|
||||
#define LV2_MORPH__interface LV2_MORPH_PREFIX "interface"
|
||||
#define LV2_MORPH__supportsType LV2_MORPH_PREFIX "supportsType"
|
||||
#define LV2_MORPH__currentType LV2_MORPH_PREFIX "currentType"
|
||||
|
||||
#endif /* LV2_MORPH_H */
|
||||
LV2_SYMBOL_EXPORT
|
||||
const LV2_Lib_Descriptor*
|
||||
lv2_lib_descriptor(const char* bundle_path,
|
||||
const LV2_Feature*const* features)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -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
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file presets.h
|
||||
#include "lv2/core/lv2.h"
|
||||
|
||||
C definitions for the LV2 Presets extension
|
||||
<http://lv2plug.in/ns/ext/presets>.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef LV2_PRESETS_H
|
||||
#define LV2_PRESETS_H
|
||||
#define PLUGIN_URI "http://example.org/missing-plugin"
|
||||
|
||||
#define LV2_PRESETS_URI "http://lv2plug.in/ns/ext/presets"
|
||||
#define LV2_PRESETS_PREFIX LV2_PRESETS_URI "#"
|
||||
static const LV2_Descriptor descriptor = {
|
||||
"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"
|
||||
#define LV2_PRESETS__preset LV2_PRESETS_PREFIX "preset"
|
||||
#define LV2_PRESETS__value LV2_PRESETS_PREFIX "value"
|
||||
LV2_SYMBOL_EXPORT
|
||||
const LV2_Descriptor* lv2_descriptor(uint32_t index)
|
||||
{
|
||||
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>
|
||||
a lv2:Plugin ;
|
||||
lv2:binary <test_plugin@SHLIB_EXT@> ;
|
||||
rdfs:seeAlso <test_plugin.ttl> .
|
||||
lv2:binary <test@SHLIB_EXT@> ;
|
||||
rdfs:seeAlso <test.ttl> .
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <stdlib.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 TMP_TEMPLATE "lilv_testXXXXXX"
|
||||
|
||||
enum {
|
||||
TEST_INPUT = 0,
|
||||
TEST_OUTPUT = 1
|
||||
TEST_INPUT = 0,
|
||||
TEST_OUTPUT = 1,
|
||||
TEST_CONTROL = 2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -39,7 +49,7 @@ typedef struct {
|
|||
LV2_URID atom_Float;
|
||||
} uris;
|
||||
|
||||
char* tmp_file_path;
|
||||
char tmp_file_path[sizeof(TMP_TEMPLATE)];
|
||||
char* rec_file_path;
|
||||
FILE* rec_file;
|
||||
|
||||
|
@ -48,6 +58,16 @@ typedef struct {
|
|||
unsigned num_runs;
|
||||
} 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
|
||||
cleanup(LV2_Handle instance)
|
||||
{
|
||||
|
@ -55,8 +75,7 @@ cleanup(LV2_Handle instance)
|
|||
if (test->rec_file) {
|
||||
fclose(test->rec_file);
|
||||
}
|
||||
free(test->tmp_file_path);
|
||||
free(test->rec_file_path);
|
||||
free_path(test->rec_file_path);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
@ -73,6 +92,9 @@ connect_port(LV2_Handle instance,
|
|||
case TEST_OUTPUT:
|
||||
test->output = (float*)data;
|
||||
break;
|
||||
case TEST_CONTROL:
|
||||
test->output = (float*)data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -84,20 +106,13 @@ instantiate(const LV2_Descriptor* descriptor,
|
|||
const char* path,
|
||||
const LV2_Feature* const* features)
|
||||
{
|
||||
Test* test = (Test*)malloc(sizeof(Test));
|
||||
Test* test = (Test*)calloc(1, sizeof(Test));
|
||||
if (!test) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
test->map = NULL;
|
||||
test->input = NULL;
|
||||
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);
|
||||
strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1);
|
||||
mkstemp(test->tmp_file_path);
|
||||
|
||||
LV2_State_Make_Path* make_path = NULL;
|
||||
|
||||
|
@ -187,6 +202,27 @@ save(LV2_Handle instance,
|
|||
map_uri(plugin, LV2_ATOM__URID),
|
||||
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,
|
||||
map_uri(plugin, "http://example.org/num-runs"),
|
||||
&plugin->num_runs,
|
||||
|
@ -243,10 +279,10 @@ save(LV2_Handle instance,
|
|||
apath,
|
||||
strlen(apath) + 1,
|
||||
map_uri(plugin, LV2_ATOM__Path),
|
||||
LV2_STATE_IS_PORTABLE);
|
||||
LV2_STATE_IS_POD);
|
||||
|
||||
free(apath);
|
||||
free(apath2);
|
||||
free_path(apath);
|
||||
free_path(apath2);
|
||||
|
||||
if (plugin->rec_file) {
|
||||
fflush(plugin->rec_file);
|
||||
|
@ -258,9 +294,9 @@ save(LV2_Handle instance,
|
|||
apath,
|
||||
strlen(apath) + 1,
|
||||
map_uri(plugin, LV2_ATOM__Path),
|
||||
LV2_STATE_IS_PORTABLE);
|
||||
LV2_STATE_IS_POD);
|
||||
|
||||
free(apath);
|
||||
free_path(apath);
|
||||
}
|
||||
|
||||
if (make_path) {
|
||||
|
@ -275,9 +311,9 @@ save(LV2_Handle instance,
|
|||
apath,
|
||||
strlen(apath) + 1,
|
||||
map_uri(plugin, LV2_ATOM__Path),
|
||||
LV2_STATE_IS_PORTABLE);
|
||||
free(apath);
|
||||
free(spath);
|
||||
LV2_STATE_IS_POD);
|
||||
free_path(apath);
|
||||
free_path(spath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +354,11 @@ restore(LV2_Handle instance,
|
|||
map_uri(plugin, "http://example.org/extfile"),
|
||||
&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) {
|
||||
char* path = map_path->absolute_path(map_path->handle, apath);
|
||||
FILE* f = fopen(path, "r");
|
||||
|
@ -328,7 +369,7 @@ restore(LV2_Handle instance,
|
|||
fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n",
|
||||
str);
|
||||
}
|
||||
free(path);
|
||||
free_path(path);
|
||||
}
|
||||
|
||||
apath = (char*)retrieve(
|
||||
|
@ -343,7 +384,7 @@ restore(LV2_Handle instance,
|
|||
} else {
|
||||
fclose(sfile);
|
||||
}
|
||||
free(spath);
|
||||
free_path(spath);
|
||||
} else {
|
||||
fprintf(stderr, "error: Failed to restore save file.\n");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
# 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
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -37,4 +37,10 @@
|
|||
lv2:index 1 ;
|
||||
lv2:symbol "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
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,10 +21,10 @@
|
|||
#ifndef BENCH_H
|
||||
#define BENCH_H
|
||||
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
static inline double
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lilv/lilv.h"
|
||||
|
||||
#include "lilv_config.h"
|
||||
|
||||
int
|
||||
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