diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/lv2.h | 305 | ||||
-rw-r--r-- | include/lv2.ttl | 326 |
3 files changed, 634 insertions, 0 deletions
diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..a8d9fe0 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,3 @@ +lv2includedir = $(includedir) + +lv2include_HEADERS = lv2.h diff --git a/include/lv2.h b/include/lv2.h new file mode 100644 index 0000000..7c3cec7 --- /dev/null +++ b/include/lv2.h @@ -0,0 +1,305 @@ +/* LV2 - LADSPA (Linux Audio Developer's Simple Plugin API) Version 2.0 + * *** PROVISIONAL *** + * + * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, Stefan + * Westerfeld + * Copyright (C) 2006 Steve Harris, Dave Robillard. + * + * This header is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, + * or (at your option) any later version. + * + * This header is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA. + */ + +#ifndef LV2_INCLUDED +#define LV2_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ************************************************************************* */ + +/* Overview: + * + * There are a large number of open source and free software synthesis + * packages in use or development at this time. This API ('LV2') + * attempts to give programmers the ability to write simple 'plugin' + * audio processors in C/C++ and link them dynamically ('plug') into + * a range of these packages ('hosts'). It should be possible for any + * host and any plugin to communicate completely through this interface. + * + * This API is deliberately as short and simple as possible. + * The information required to use a plugin is in a companion data + * (RDF) file. The shared library portion of the API (defined in this + * header) does not contain enough information to make use of the plugin + * possible - the data file is mandatory. + * + * Plugins are expected to distinguish between control rate and audio + * rate data. Plugins have 'ports' that are inputs or outputs for audio + * or control data and each plugin is 'run' for a 'block' corresponding + * to a short time interval measured in samples. Audio rate data is + * communicated using arrays with one element per sample processed, + * allowing a block of audio to be processed by the plugin in a single + * pass. Control rate data is communicated using single values. Control + * rate data has a single value at the start of a call to the 'run()' + * function, and may be considered to remain this value for its duration. + * Thus the 'control rate' is determined by the block size, controlled + * by the host. The plugin may assume that all its input and output + * ports have been connected to the relevant data location (see the + * 'connect_port()' function below) before it is asked to run. + * + * Plugins will reside in shared object files suitable for dynamic linking + * by dlopen() and family. The file will provide a number of 'plugin + * types' that can be used to instantiate actual plugins (sometimes known + * as 'plugin instances') that can be connected together to perform tasks. + * + * This API contains very limited error-handling. + */ + +/* ************************************************************************* */ + + +/** Plugin Handle. + * + * This plugin handle indicates a particular instance of the plugin + * concerned. It is valid to compare this to NULL (0 for C++) but + * otherwise the host MUST not attempt to interpret it. The plugin + * may use it to reference internal instance data. */ +typedef void * LV2_Handle; + + +/* ************************************************************************* */ + +/** Host feature. + * + * These are passed to a plugin's instantiate method to represent a special + * feature the host has which the plugin may depend on. This is to allow + * extensions to the LV2 specification without causing any breakage. The base + * LV2 specification does not define any host features; hosts are not required + * to use this facility. + */ +typedef struct _LV2_Host_Feature { + /** A globally unique, case-sensitive identifier for this feature. + * + * This MUST be defined in the specification of any LV2 extension which + * defines a host feature. + */ + const char * URI; + + /** Pointer to arbitrary data. + * + * This is to allow hosts to pass data to a plugin (simple values, data + * structures, function pointers, etc) as part of a 'feature'. The LV2 + * specification makes no restrictions on the contents of this data. + * The data here MUST be cleary defined by the LV2 extension which defines + * this feature. + * If no data is required, this may be set to NULL. + */ + void * data; +} LV2_Host_Feature; + + +/* ************************************************************************* */ + + +/** Descriptor for a Type of Plugin. + * + * This structure is used to describe a plugin type. It provides a number + * of functions to instantiate it, link it to buffers and run it. */ +typedef struct _LV2_Descriptor { + + /** A globally unique, case-sensitive identifier for this plugin type. + * + * All plugins with the same URI MUST be compatible in terms of 'port + * signature', meaning they have the same number of ports, same port + * shortnames, and roughly the same functionality. URIs should + * probably contain a version number (or similar) for this reason. + * + * Rationale: When serializing session/patch/etc files, hosts MUST + * refer to a loaded plugin by the plugin URI only. In the future + * loading a plugin with this URI MUST yield a plugin with the + * same ports (etc) which is 100% compatible. */ + const char * URI; + + /** Function pointer that instantiates a plugin. + * + * A handle is returned indicating the new plugin instance. The + * instantiation function accepts a sample rate as a parameter as well + * as the plugin descriptor from which this instantiate function was + * found. This function must return NULL if instantiation fails. + * + * BundlePath is a string of the path to the plugin's .lv2 bundle + * directory, it MUST not include the trailing /. + * + * HostFeatures is a NULL terminated array of the URIs of the LV2 + * features that the host supports. Plugins may refuse to instantiate + * if required features are not found here (however hosts SHOULD NOT use + * this as a discovery mechanism, instead reading the data file before + * attempting to instantiate the plugin). + * + * Note that instance initialisation should generally occur in + * activate() rather than here. If a host calls instantiate, it MUST + * call cleanup() at some point in the future. */ + LV2_Handle (*instantiate)(const struct _LV2_Descriptor * Descriptor, + unsigned long SampleRate, + const char * BundlePath, + const LV2_Host_Feature** HostFeatures); + + /** Function pointer that connects a port on a plugin instance to a memory + * location where the block of data for the port will be read/written. + * + * The data location is expected to be an array of void * (typically + * float *) for audio ports or a single void * value for control + * ports. Memory issues are managed by the host. The plugin must + * read/write the data at these locations every time run() is called + * and the data present at the time of this connection call MUST NOT + * be considered meaningful. + * + * connect_port() may be called more than once for a plugin instance + * to allow the host to change the buffers that the plugin is reading + * or writing. These calls may be made before or after activate() + * or deactivate() calls. + * + * connect_port() must be called at least once for each port before + * run() is called. The plugin must pay careful attention to the block + * size passed to the run function as the block allocated may only just + * be large enough to contain the block of data (typically samples), and + * is not guaranteed to be constant. + * + * Plugin writers should be aware that the host may elect to use the + * same buffer for more than one port and even use the same buffer for + * both input and output (see LV2_PROPERTY_INPLACE_BROKEN (FIXME)). + * However, overlapped buffers or use of a single buffer for both + * audio and control data may result in unexpected behaviour. */ + void (*connect_port)(LV2_Handle Instance, + unsigned long Port, + void * DataLocation); + + /** Function pointer that initialises a plugin instance and activates + * it for use. + * + * This is separated from instantiate() to aid real-time support and so + * that hosts can reinitialise a plugin instance by calling deactivate() + * and then activate(). In this case the plugin instance must reset all + * state information dependent on the history of the plugin instance + * except for any data locations provided by connect_port(). If there + * is nothing for activate() to do then the plugin writer may provide + * a NULL rather than an empty function. + * + * When present, hosts MUST call this function once before run() + * is called for the first time. This call SHOULD be made as close + * to the run() call as possible and indicates to real-time plugins + * that they are now live, however plugins MUST NOT rely on a prompt + * call to run() after activate(). activate() may not be called again + * unless deactivate() is called first (after which activate() may be + * called again, followed by deactivate, etc. etc.). If a host calls + * activate, it MUST call deactivate at some point in the future. + * + * Note that connect_port() may be called before or after a call to + * activate(). */ + void (*activate)(LV2_Handle Instance); + + /** Function pointer that runs a plugin instance for a block. + * + * Two parameters are required: the first is a handle to the particular + * instance to be run and the second indicates the block size (in + * samples) for which the plugin instance may run. + * + * Note that if an activate() function exists then it must be called + * before run(). If deactivate() is called for a plugin instance then + * the plugin instance may not be reused until activate() has been + * called again. + * + * If the plugin has the property LV2_PROPERTY_HARD_RT_CAPABLE then + * there are various things that the plugin MUST NOT do within the run() + * function (see above). */ + void (*run)(LV2_Handle Instance, + unsigned long SampleCount); + + /** This is the counterpart to activate() (see above). If there is + * nothing for deactivate() to do then the plugin writer may provide + * a NULL rather than an empty function. + * + * Hosts must deactivate all activated units after they have been run() + * for the last time. This call SHOULD be made as close to the last + * run() call as possible and indicates to real-time plugins that + * they are no longer live, however plugins MUST NOT rely on prompt + * deactivation. Note that connect_port() may be called before or + * after a call to deactivate(). + * + * Note that deactivation is not similar to pausing as the plugin + * instance will be reinitialised when activate() is called to reuse it. + * Hosts MUST NOT call deactivate() unless activate() was previously + * called. */ + void (*deactivate)(LV2_Handle Instance); + + /** This is the counterpart to instantiate() (see above). Once an instance + * of a plugin has been finished with it can be deleted using this + * function. The instance handle passed ceases to be valid after + * this call. + * + * If activate() was called for a plugin instance then a corresponding + * call to deactivate() MUST be made before cleanup() is called. + * Hosts MUST NOT call cleanup() unless instantiate() was previously + * called. */ + void (*cleanup)(LV2_Handle Instance); + +} LV2_Descriptor; + + +/* ****************************************************************** */ + + +/** Accessing a Plugin: + * + * The exact mechanism by which plugins are loaded is host-dependent, + * however all most hosts will need to know is the URI of the plugin they + * wish to load. The environment variable LV2_PATH, if present, should + * contain a colon-separated path indicating directories (containing + * plugin bundle subdirectories) that should be searched (in order) + * for plugins. It is expected that hosts will use a library to provide + * this functionality. + * + * A plugin programmer must include a function called "lv2_descriptor" + * with the following function prototype within the shared object + * file. This function will have C-style linkage (if you are using + * C++ this is taken care of by the 'extern "C"' clause at the top of + * the file). + * + * A host will find the plugin shared object file by one means or another, + * find the lv2_descriptor() function, call it, and proceed from there. + * + * Plugin types are accessed by index (not ID) using values from 0 + * upwards. Out of range indexes must result in this function returning + * NULL, so the plugin count can be determined by checking for the least + * index that results in NULL being returned. Index has no meaning, + * hosts MUST NOT depend on it remaining constant (ie when serialising) + * in any way. */ +const LV2_Descriptor * lv2_descriptor(unsigned long Index); + + +/** Datatype corresponding to the lv2_descriptor() function. */ +typedef const LV2_Descriptor * +(*LV2_Descriptor_Function)(unsigned long Index); + + +/* ******************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LV2_INCLUDED */ diff --git a/include/lv2.ttl b/include/lv2.ttl new file mode 100644 index 0000000..47b21ae --- /dev/null +++ b/include/lv2.ttl @@ -0,0 +1,326 @@ +# RDF Schema file for LV2 plugins +# *** PROVISIONAL *** +# +# This document describes the classes and properties that are defined by the +# core LV2 specification. + +@prefix : <http://lv2plug.in/ontology#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . + +<> dc:creator "Steve Harris" ; + dc:date "2006-04-26" . + +# +# Classes +# + +:Plugin a rdfs:Class ; + rdfs:label "Plugin" ; + rdfs:comment """ +This is the class that represents an LV2 plugin. + +In order for it to be used by a host it must have at least one occurance of the +following properties: + rdf:type (with object :Plugin) + doap:name (one without language tag) + doap:licence + lv2:port + +This can be determined by the following SPARQL query: + +PREFIX : <http://lv2plug.in/ontology#> +PREFIX doap: <http://usefulinc.com/ns/doap#> +SELECT DISTINCT ?uri WHERE { + ?uri a :Plugin ; + doap:name ?name ; + doap:licence ?rights ; + :port ?port . + FILTER( LANG(?name) = "" ) +} +""" . + +:Port a rdfs:Class ; + rdfs:label "Port" ; + rdfs:comment """ +This is the class that represents an LV2 port + +In order for it to be used by a host it must have at least the following +properties: + rdf:type (where object is exactly one of :InputControlRatePort, + :OutputControlRatePort, :InputAudioRatePort or :OututAudioRatePort) + :datatype + :index + :symbol + :name +""" . + +:InputPort a rdfs:Class ; + rdfs:subClassOf :Port . + +:OutputPort a rdfs:Class ; + rdfs:subClassOf :Port . + +:ControlRatePort a rdfs:Class ; + rdfs:subClassOf :Port . + +:AudioRatePort a rdfs:Class ; + rdfs:subClassOf :Port . + +:InputControlRatePort a rdfs:Class ; + rdfs:label "Input control port" ; + rdfs:subClassOf :ControlRatePort ; + rdfs:subClassOf :InputPort ; + rdfs:comment """ +Ports of this type will be connected to a pointer to a single value of the type +defined by the :datatype property. + +Plugins will read values from this pointer during thier run method. +""" . + +:OutputControlRatePort a rdfs:Class ; + rdfs:label "Output control port" ; + rdfs:subClassOf :ControlRatePort ; + rdfs:subClassOf :OutputPort ; + rdfs:comment """ +Ports of this type will be connected to a pointer to a single value of the type +defined by the :datatype property. + +Plugins will write values to this pointer during thier run method. +""" . + +:InputAudioRatePort a rdfs:Class ; + rdfs:label "Input audio port" ; + rdfs:subClassOf :AudioRatePort ; + rdfs:subClassOf :InputPort ; + rdfs:comment """ +Ports of this type will be connected to a an array of values of length +SampleCount and of the type defined by the :datatype property. + +Plugins will read values from this array during their run method. +""" . + +:OutputAudioRatePort a rdfs:Class ; + rdfs:label "Output audio port" ; + rdfs:subClassOf :AudioRatePort ; + rdfs:subClassOf :OutputPort ; + rdfs:comment """ +Ports of this type will be connected to a an array of values of length +SampleCount and of the type defined by the :datatype property. + +Plugins will write values to this array during their run method. +""" . + +:ScalePoint a rdfs:Class ; + rdfs:label "Scale point" ; + rdfs:comment """ +Used to describe interesting values in a Port's range. + +It has two properties neccesary for use, :label and :value. +""" . + +:Property a rdfs:Class ; + rdfs:label "Property" ; + rdfs:comment """ +Used to inform the host of the capabilities of the Plugin. +""" . + +:Hint a rdfs:Class ; + rdfs:label "Hint" ; + rdfs:comment """ +Used to hint to the host various things which can make interacting with the +Port more natural. +""" . + +:HostFeature a rdfs:Class ; + rdfs:label "Host feature" ; + rdfs:comment """ +Used to describe a host feature which plugin may use or require. +""" . + + +# +# Properties +# + +:property a rdf:Property ; + rdfs:domain :Plugin ; + rdfs:range :Property ; + rdfs:label "property" ; + rdfs:comment "Relates Plugins to Properties." . + +:requiredHostFeature a rdf:Property ; + rdfs:domain :Plugin ; + rdfs:range :HostFeature ; + rdfs:label "Required host feature" ; + rdfs:comment """ +Signifies that plugin requires a certain host feature to function. +The plugin will fail to instantiate if a required host feature is not present; +hosts SHOULD always check this before attempting to instantiate a plugin. +""" . + +:hint a rdf:Property ; + rdfs:domain :Port ; + rdfs:range :Hint ; + rdfs:label "hint" ; + rdfs:comment "Relates Ports to Hints." . + +:datatype a rdf:Property ; + rdfs:domain :Port ; + rdfs:range :Datatype ; + rdfs:label "datatype" ; + rdfs:comment """ +Relates a Port to the datatype(s) is can accept. Currently the only specified +datatype is :float, which specfies IEEE-754 32bit floating point values. + +Hosts that do not support a specfied datatype MUST NOT instantiate the plugin. + +If multiple datatypes are specfied the plugin must have some way to distinguish +the values. +""" . + +# FIXME: rdfs:range = xsd:nonNegativeInteger? +:index a rdf:Property ; + rdfs:domain :Port ; + rdfs:label "index" ; + rdfs:comment """ +Specifies the index of the port, passed as an argument to the connect port +function. This number uniqely identifies the port within the plugin. +""" . + +# FIXME: rdfs:range = xsd:NCName? Closest thing xsd: has.. +:symbol a rdf:Property ; + rdfs:domain :Port ; + rdfs:label "symbol" ; + rdfs:comment """ +A short name used to identify the port in an easily machine and human readable way. + +The first character must be one of _, a-z or A-Z and subsequenct characters can +be from _, a-z, A-Z and 0-9. + +No language tag should be used on this property. +""" . + +:name a rdf:Property ; + rdfs:domain :Port ; + rdfs:label "name" ; + rdfs:comment """ +A display name for labeling the Port in a user interface. + +This property is required for Ports, but should not be used by the host for +port identification. The plugin author may change the values of this +property without changing the Plugin URI. +""" . + +:default a rdf:Property ; + rdfs:domain :ControlRatePort ; + rdfs:label "default" ; + rdfs:comment """ +The default value that the host SHOULD set this port to when there is not other +information available. Only meaningful for Ports with a :datatype of :float. +""" . + +:minimum a rdf:Property ; + rdfs:domain :Port ; + rdfs:label "minimum" ; + rdfs:comment """ +A hint to the host for the minimum useful value that the port will use. The +plugin is required to accept all values in the range of :float. +""" . + +:minimum a rdf:Property ; + rdfs:domain :Port ; + rdfs:label "maximum" ; + rdfs:comment """ +A hint to the host for the maximum useful value that the port will use. The +plugin is required to accept all values in the range of :float. +""" . + +:scalePoint a rdf:Property ; + rdfs:domain :Port ; + rdfs:range :ScalePoint ; + rdfs:label "scale point" ; + rdfs:comment "Relates a Port to its ScalePoints." . + + +# +# Instances +# + +:toggled a :Hint ; + rdfs:label "toggled" ; + rdfs:comment """ +Indicates that the data item should be considered a Boolean toggle. Data less +than or equal to zero should be considered `off' or `false,' and data above +zero should be considered `on' or `true.' +""" . + +:sampleRate a :Hint ; + rdfs:label "sample rate" ; + rdfs:comment """ +Indicates that any bounds specified should be interpreted as multiples of the +sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency +(half the sample rate) could be requested by this hint in conjunction with +:minimum 0.0 and :maximum 0.5. Hosts that support bounds at all must support +this hint to retain meaning. +""" . + +:integer a :Hint ; + rdfs:label "integer" ; + rdfs:comment """ +Indicates that a user interface would probably wish to provide a stepped +control taking only integer values. +""" . + +:realtime a :Property ; + rdfs:label "realtime" ; + rdfs:comment """ +Indicates that the plugin has a real-time dependency (e.g. listens to a MIDI +device) and so its output must not be cached or subject to significant latency. +""" . + +:inplaceBroken a :Property ; + rdfs:label "in-place broken" ; + rdfs:comment """ +Indicates that the plugin may cease to work correctly if the host elects to use +the same data location for both input and output (see connect_port()). This +should be avoided as enabling this flag makes it impossible for hosts to use +the plugin to process audio `in-place.' +""" . + +:hardRtCapable a :Property ; + rdfs:label "hard realtime capable" ; + rdfs:comment """ +Indicates that the plugin is capable of running not only in a conventional host +but also in a `hard real-time' environment. To qualify for this the plugin must +satisfy all of the following: + + (1) The plugin must not use malloc(), free() or other heap memory + management within its run() or run_adding() functions. All new + memory used in run() must be managed via the stack. These + restrictions only apply to the run() function. + + (2) The plugin will not attempt to make use of any library + functions with the exceptions of functions in the ANSI standard C + and C maths libraries, which the host is expected to provide. + + (3) The plugin will not access files, devices, pipes, sockets, IPC + or any other mechanism that might result in process or thread + blocking. + + (4) The plugin will take an amount of time to execute a run() or + run_adding() call approximately of form (A+B*SampleCount) where A + and B depend on the machine and host in use. This amount of time + may not depend on input signals or plugin state. The host is left + the responsibility to perform timings to estimate upper bounds for + A and B. +""" . + +# FIXME: = xsd:float? +:float a :Datatype ; + rdfs:label "float" ; + rdfs:comment """ +Represents values conforming to the 32bit IEEE-754 floating point specification. +""" . + |