diff options
Diffstat (limited to 'lv2/worker')
-rw-r--r-- | lv2/worker/lv2-worker.doap.ttl | 32 | ||||
-rw-r--r-- | lv2/worker/manifest.ttl | 8 | ||||
-rw-r--r-- | lv2/worker/worker.h | 177 | ||||
-rw-r--r-- | lv2/worker/worker.ttl | 53 |
4 files changed, 270 insertions, 0 deletions
diff --git a/lv2/worker/lv2-worker.doap.ttl b/lv2/worker/lv2-worker.doap.ttl new file mode 100644 index 0000000..b01159b --- /dev/null +++ b/lv2/worker/lv2-worker.doap.ttl @@ -0,0 +1,32 @@ +@prefix dcs: <http://ontologi.es/doap-changeset#> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . + +<http://lv2plug.in/ns/ext/worker> + a doap:Project ; + doap:name "LV2 Worker" ; + doap:shortdesc "Support for a non-realtime plugin worker method." ; + doap:created "2012-03-22" ; + doap:developer <http://drobilla.net/drobilla#me> ; + doap:release [ + doap:revision "1.2" ; + doap:created "2016-07-31" ; + doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ; + dcs:blame <http://drobilla.net/drobilla#me> ; + dcs:changeset [ + dcs:item [ + rdfs:label "Improve documentation." + ] + ] + ] , [ + doap:revision "1.0" ; + doap:created "2012-04-17" ; + doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ; + dcs:blame <http://drobilla.net/drobilla#me> ; + dcs:changeset [ + dcs:item [ + rdfs:label "Initial release." + ] + ] + ] . diff --git a/lv2/worker/manifest.ttl b/lv2/worker/manifest.ttl new file mode 100644 index 0000000..28c2129 --- /dev/null +++ b/lv2/worker/manifest.ttl @@ -0,0 +1,8 @@ +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . + +<http://lv2plug.in/ns/ext/worker> + a lv2:Specification ; + lv2:minorVersion 1 ; + lv2:microVersion 2 ; + rdfs:seeAlso <worker.ttl> . diff --git a/lv2/worker/worker.h b/lv2/worker/worker.h new file mode 100644 index 0000000..6926887 --- /dev/null +++ b/lv2/worker/worker.h @@ -0,0 +1,177 @@ +/* + Copyright 2012-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 + 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. +*/ + +/** + @defgroup worker Worker + + Support for non-realtime plugin operations, see + <http://lv2plug.in/ns/ext/worker> for details. + + @{ +*/ + +#ifndef LV2_WORKER_H +#define LV2_WORKER_H + +#include <stdint.h> + +#include "lv2/core/lv2.h" + +#define LV2_WORKER_URI "http://lv2plug.in/ns/ext/worker" ///< http://lv2plug.in/ns/ext/worker +#define LV2_WORKER_PREFIX LV2_WORKER_URI "#" ///< http://lv2plug.in/ns/ext/worker# + +#define LV2_WORKER__interface LV2_WORKER_PREFIX "interface" ///< http://lv2plug.in/ns/ext/worker#interface +#define LV2_WORKER__schedule LV2_WORKER_PREFIX "schedule" ///< http://lv2plug.in/ns/ext/worker#schedule + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Status code for worker functions. +*/ +typedef enum { + LV2_WORKER_SUCCESS = 0, /**< Completed successfully. */ + LV2_WORKER_ERR_UNKNOWN = 1, /**< Unknown error. */ + LV2_WORKER_ERR_NO_SPACE = 2 /**< Failed due to lack of space. */ +} LV2_Worker_Status; + +/** Opaque handle for LV2_Worker_Interface::work(). */ +typedef void* LV2_Worker_Respond_Handle; + +/** + A function to respond to run() from the worker method. + + The `data` MUST be safe for the host to copy and later pass to + work_response(), and the host MUST guarantee that it will be eventually + passed to work_response() if this function returns LV2_WORKER_SUCCESS. +*/ +typedef LV2_Worker_Status (*LV2_Worker_Respond_Function)( + LV2_Worker_Respond_Handle handle, + uint32_t size, + const void* data); + +/** + Plugin Worker Interface. + + This is the interface provided by the plugin to implement a worker method. + The plugin's extension_data() method should return an LV2_Worker_Interface + when called with LV2_WORKER__interface as its argument. +*/ +typedef struct _LV2_Worker_Interface { + /** + The worker method. This is called by the host in a non-realtime context + as requested, possibly with an arbitrary message to handle. + + A response can be sent to run() using `respond`. The plugin MUST NOT + make any assumptions about which thread calls this method, except that + there are no real-time requirements and only one call may be executed at + a time. That is, the host MAY call this method from any non-real-time + thread, but MUST NOT make concurrent calls to this method from several + threads. + + @param instance The LV2 instance this is a method on. + @param respond A function for sending a response to run(). + @param handle Must be passed to `respond` if it is called. + @param size The size of `data`. + @param data Data from run(), or NULL. + */ + LV2_Worker_Status (*work)(LV2_Handle instance, + LV2_Worker_Respond_Function respond, + LV2_Worker_Respond_Handle handle, + uint32_t size, + const void* data); + + /** + Handle a response from the worker. This is called by the host in the + run() context when a response from the worker is ready. + + @param instance The LV2 instance this is a method on. + @param size The size of `body`. + @param body Message body, or NULL. + */ + LV2_Worker_Status (*work_response)(LV2_Handle instance, + uint32_t size, + const void* body); + + /** + Called when all responses for this cycle have been delivered. + + Since work_response() may be called after run() finished, this provides + a hook for code that must run after the cycle is completed. + + This field may be NULL if the plugin has no use for it. Otherwise, the + host MUST call it after every run(), regardless of whether or not any + responses were sent that cycle. + */ + LV2_Worker_Status (*end_run)(LV2_Handle instance); +} LV2_Worker_Interface; + +/** Opaque handle for LV2_Worker_Schedule. */ +typedef void* LV2_Worker_Schedule_Handle; + +/** + Schedule Worker Host Feature. + + The host passes this feature to provide a schedule_work() function, which + the plugin can use to schedule a worker call from run(). +*/ +typedef struct _LV2_Worker_Schedule { + /** + Opaque host data. + */ + LV2_Worker_Schedule_Handle handle; + + /** + Request from run() that the host call the worker. + + This function is in the audio threading class. It should be called from + run() to request that the host call the work() method in a non-realtime + context with the given arguments. + + This function is always safe to call from run(), but it is not + guaranteed that the worker is actually called from a different thread. + In particular, when free-wheeling (e.g. for offline rendering), the + worker may be executed immediately. This allows single-threaded + processing with sample accuracy and avoids timing problems when run() is + executing much faster or slower than real-time. + + Plugins SHOULD be written in such a way that if the worker runs + immediately, and responses from the worker are delivered immediately, + the effect of the work takes place immediately with sample accuracy. + + The `data` MUST be safe for the host to copy and later pass to work(), + and the host MUST guarantee that it will be eventually passed to work() + if this function returns LV2_WORKER_SUCCESS. + + @param handle The handle field of this struct. + @param size The size of `data`. + @param data Message to pass to work(), or NULL. + */ + LV2_Worker_Status (*schedule_work)(LV2_Worker_Schedule_Handle handle, + uint32_t size, + const void* data); +} LV2_Worker_Schedule; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV2_WORKER_H */ + +/** + @} +*/ diff --git a/lv2/worker/worker.ttl b/lv2/worker/worker.ttl new file mode 100644 index 0000000..6b32742 --- /dev/null +++ b/lv2/worker/worker.ttl @@ -0,0 +1,53 @@ +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix work: <http://lv2plug.in/ns/ext/worker#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +<http://lv2plug.in/ns/ext/worker> + a owl:Ontology ; + rdfs:seeAlso <worker.h> , + <lv2-worker.doap.ttl> ; + lv2:documentation """ +<p>This extension allows plugins to schedule work that must be performed in +another thread. Plugins can use this interface to safely perform work that is +not real-time safe, and receive the result in the run context. The details of +threading are managed by the host, allowing plugins to be simple and portable +while using resources more efficiently.</p> + +<p>This interface is designed to gracefully support single-threaded synchronous +execution, which allows the same code to work with sample accuracy for offline +rendering. For example, a sampler plugin may schedule a sample to be loaded +from disk in another thread. During live execution, the host will call the +plugin's work method from another thread, and deliver the result to the audio +thread when it is finished. However, during offline export, the +<q>scheduled</q> load would be executed immediately in the same thread. This +enables reproducible offline rendering, where any changes affect the output +immediately regardless of how long the work takes to execute.</p> +""" . + +work:interface + a lv2:ExtensionData ; + lv2:documentation """ +<p>The work interface provided by a plugin, LV2_Worker_Interface.</p> +<pre class="turtle-code"> +@prefix work: <http://lv2plug.in/ns/ext/worker#> . + +<plugin> + a lv2:Plugin ; + lv2:extensionData work:interface . +</pre> +""" . + +work:schedule + a lv2:Feature ; + lv2:documentation """ +<p>The work scheduling feature provided by a host, LV2_Worker_Schedule.</p> + +<p>If the host passes this feature to LV2_Descriptor::instantiate, the plugin +MAY use it to schedule work in the audio thread, and MUST NOT call it in any +other context. Hosts MAY pass this feature to other functions as well, in +which case the plugin MAY use it to schedule work in the calling context. The +plugin MUST NOT assume any relationship between different schedule +features.</p> """ . |