Remove support for old and/or experimental LV2 stuff.

Ardour 3 now simply depends on the latest version of Lilv, which depends on the LV2 package (which contains all the LV2 headers).

git-svn-id: svn://localhost/ardour2/branches/3.0@12041 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2012-04-20 01:00:45 +00:00
parent cfbc2e2438
commit 6e2dd99a04
14 changed files with 3 additions and 2906 deletions

View File

@ -26,7 +26,7 @@
#include "gui_thread.h"
#include "lv2_plugin_ui.h"
#include "lv2_ui.h"
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
#include <lilv/lilv.h>
#include <suil/suil.h>
@ -223,9 +223,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
ui_host = suil_host_new(LV2PluginUI::write_from_ui,
LV2PluginUI::port_index,
NULL, NULL);
#ifdef HAVE_NEW_SUIL
suil_host_set_touch_func(ui_host, LV2PluginUI::touch);
#endif
}
const char* container_type = (is_external_ui)
? NS_UI "external"

View File

@ -1,382 +0,0 @@
/*
LV2 UI Extension
Copyright 2009-2012 David Robillard <d@drobilla.net>
Copyright 2006-2011 Lars Luthman <lars.luthman@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.
*/
/**
@file ui.h
C header for the LV2 UI extension <http://lv2plug.in/ns/extensions/ui>.
*/
#ifndef LV2_UI_H
#define LV2_UI_H
#include <stdint.h>
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui"
#define LV2_UI_PREFIX LV2_UI_URI "#"
#define LV2_UI__GtkUI LV2_UI_PREFIX "GtkUI"
#define LV2_UI__PortNotification LV2_UI_PREFIX "PortNotification"
#define LV2_UI__Qt4UI LV2_UI_PREFIX "Qt4UI"
#define LV2_UI__UI LV2_UI_PREFIX "UI"
#define LV2_UI__X11UI LV2_UI_PREFIX "X11UI"
#define LV2_UI__fixedSize LV2_UI_PREFIX "fixedSize"
#define LV2_UI__noUserResize LV2_UI_PREFIX "noUserResize"
#define LV2_UI__notifyType LV2_UI_PREFIX "notifyType"
#define LV2_UI__parent LV2_UI_PREFIX "parent"
#define LV2_UI__plugin LV2_UI_PREFIX "plugin"
#define LV2_UI__portIndex LV2_UI_PREFIX "portIndex"
#define LV2_UI__portMap LV2_UI_PREFIX "portMap"
#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"
#define LV2_UI__portSubscribe LV2_UI_PREFIX "portSubscribe"
#define LV2_UI__resize LV2_UI_PREFIX "resize"
#define LV2_UI__touch LV2_UI_PREFIX "touch"
/**
The index returned by LV2_UI_Port_Port::port_index() for unknown ports.
*/
#define LV2UI_INVALID_PORT_INDEX ((uint32_t)-1)
#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif
/**
A pointer to some widget or other type of UI handle.
The actual type is defined by the type of the UI.
*/
typedef void* LV2UI_Widget;
/**
A pointer to an instance of a UI.
It is valid to compare this to NULL (0 for C++) but otherwise the host MUST
not attempt to interpret it. The UI plugin may use it to reference internal
instance data.
*/
typedef void* LV2UI_Handle;
/**
A pointer to a controller provided by the host.
It is valid to compare this to NULL (0 for C++) but otherwise the UI plugin
MUST NOT attempt to interpret it. The host may use it to reference internal
instance data.
*/
typedef void* LV2UI_Controller;
/**
A pointer to opaque data for a feature.
*/
typedef void* LV2UI_Feature_Handle;
/**
The type of the host-provided function that the UI can use to
send data to a plugin's input ports.
The @c buffer parameter must point to a block of data, @c buffer_size bytes
large. The format of this data and how the host should use it is defined by
the @c port_protocol. This buffer is owned by the UI and is only valid for
the duration of this call.
The @c port_protocol parameter should either be 0 or the URID for a
ui:PortProtocol. If it is 0, the protocol is implicitly ui:floatProtocol,
the port must be an lv2:ControlPort input, @c buffer must point to a single
float value, and @c buffer_size must be sizeof(float).
The UI SHOULD NOT use a PortProtocol not supported by the host (i.e. one not
passed by the host as a feature), but the host MUST gracefully ignore any
port_protocol it does not understand.
*/
typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
uint32_t port_index,
uint32_t buffer_size,
uint32_t port_protocol,
const void* buffer);
/**
The implementation of a UI.
A pointer to an object of this type is returned by the lv2ui_descriptor()
function.
*/
typedef struct _LV2UI_Descriptor {
/**
The URI for this UI (not for the plugin it controls).
*/
const char* URI;
/**
Create a new UI object and return a handle to it. This function works
similarly to the instantiate() member in LV2_Descriptor.
@param descriptor The descriptor for the UI that you want to instantiate.
@param plugin_uri The URI of the plugin that this UI will control.
@param bundle_path The path to the bundle containing the RDF data file
that references this shared object file, including the trailing '/'.
@param write_function A function provided by the host that the UI can use
to send data to the plugin's input ports.
@param controller A handle for the plugin instance that should be passed
as the first parameter of @c write_function.
@param widget A pointer to an LV2UI_Widget. The UI will write a widget
pointer to this location (what type of widget depends on the RDF class of
the UI) that will be the main UI widget.
@param features An array of LV2_Feature pointers. The host must pass all
feature URIs that it and the UI supports and any additional data, just
like in the LV2 plugin instantiate() function. Note that UI features and
plugin features are NOT necessarily the same, they just share the same
data structure - this will probably not be the same array as the one the
plugin host passes to a plugin.
*/
LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
const char* plugin_uri,
const char* bundle_path,
LV2UI_Write_Function write_function,
LV2UI_Controller controller,
LV2UI_Widget* widget,
const LV2_Feature* const* features);
/**
Destroy the UI object and the associated widget. The host must not try
to access the widget after calling this function.
*/
void (*cleanup)(LV2UI_Handle ui);
/**
Tell the UI that something interesting has happened at a plugin port.
What is interesting and how it is written to the buffer passed to this
function is defined by the @c format parameter, which has the same
meaning as in LV2UI_Write_Function. The only exception is ports of the
class lv2:ControlPort, for which this function should be called when the
port value changes (it does not have to be called for every single change
if the host's UI thread has problems keeping up with the thread the
plugin is running in), @c buffer_size should be 4, the buffer should
contain a single IEEE-754 float, and @c format should be 0.
By default, the host should only call this function for input ports of
the lv2:ControlPort class. However, this can be modified by using
ui:portNotification in the UI data, or the ui:portSubscribe feature.
The @c buffer is only valid during the time of this function call, so if
the UI wants to keep it for later use it has to copy the contents to an
internal buffer.
This member may be set to NULL if the UI is not interested in any
port events.
*/
void (*port_event)(LV2UI_Handle ui,
uint32_t port_index,
uint32_t buffer_size,
uint32_t format,
const void* buffer);
/**
Return a data structure associated with an extension URI, for example
a struct containing additional function pointers.
Avoid returning function pointers directly since standard C/C++ has no
valid way of casting a void* to a function pointer. This member may be set
to NULL if the UI is not interested in supporting any extensions. This is
similar to the extension_data() member in LV2_Descriptor.
*/
const void* (*extension_data)(const char* uri);
} LV2UI_Descriptor;
/**
UI Resize Feature (LV2_UI__resize)
This structure may be used in two ways: as a feature passed by the host via
LV2UI_Descriptor::instantiate(), or as extension data provided by a UI via
LV2UI_Descriptor::extension_data()).
*/
typedef struct _LV2UI_Resize {
/**
Pointer to opaque data which must be passed to ui_resize().
*/
LV2UI_Feature_Handle handle;
/**
Request or advertise a size change.
When this struct is provided by the host, the UI may call this
function to inform the host about the size of the UI.
When this struct is provided by the UI, the host may call this
function to notify the UI that it should change its size accordingly.
@return 0 on success.
*/
int (*ui_resize)(LV2UI_Feature_Handle handle, int width, int height);
} LV2UI_Resize;
/**
Port Map Feature (LV2_UI__portMap).
This feature can be used by the UI to get the index for a port with the
given symbol. This makes it possible to implement and distribute a UI
separately from the plugin (since symbol is a guaranteed stable port
identifier while index is not).
*/
typedef struct _LV2UI_Port_Map {
/**
Pointer to opaque data which must be passed to ui_resize().
*/
LV2UI_Feature_Handle handle;
/**
Get the index for the port with the given @p symbol.
@return The index of the port, or LV2_UI_INVALID_PORT_INDEX if no such
port is found.
*/
uint32_t (*port_index)(LV2UI_Feature_Handle handle, const char* symbol);
} LV2UI_Port_Map;
/**
Port subscription feature (LV2_UI__portSubscribe);
*/
typedef struct _LV2UI_Port_Subscribe {
/**
Pointer to opaque data which must be passed to ui_resize().
*/
LV2UI_Feature_Handle handle;
/**
Subscribe to updates for a port.
This means that the host will call the UI's port_event() function when
the port value changes (as defined by protocol).
Calling this function with the same @c port_index and @c port_protocol
as an already active subscription has no effect.
@param handle The handle field of this struct.
@param port_index The index of the port.
@param port_protocol The URID of the ui:PortProtocol.
@param features Features for this subscription.
@return 0 on success.
*/
uint32_t (*subscribe)(LV2UI_Feature_Handle handle,
uint32_t port_index,
uint32_t port_protocol,
const LV2_Feature* const* features);
/**
Unsubscribe from updates for a port.
This means that the host will cease calling calling port_event() when
the port value changes.
Calling this function with a @c port_index and @c port_protocol that
does not refer to an active port subscription has no effect.
@param handle The handle field of this struct.
@param port_index The index of the port.
@param port_protocol The URID of the ui:PortProtocol.
@param features Features for this subscription.
@return 0 on success.
*/
uint32_t (*unsubscribe)(LV2UI_Feature_Handle handle,
uint32_t port_index,
uint32_t port_protocol,
const LV2_Feature* const* features);
} LV2UI_Port_Subscribe;
/**
A feature to notify the host the user has grabbed a UI control.
*/
typedef struct _LV2UI_Touch {
/**
Pointer to opaque data which must be passed to ui_resize().
*/
LV2UI_Feature_Handle handle;
/**
Notify the host that a control has been grabbed or released.
@param handle The handle field of this struct.
@param port_index The index of the port associated with the control.
@param grabbed If true, the control has been grabbed, otherwise the
control has been released.
*/
void (*touch)(LV2UI_Feature_Handle handle,
uint32_t port_index,
bool grabbed);
} LV2UI_Touch;
/**
Peak data for a slice of time, the update format for ui:peakProtocol.
*/
typedef struct _LV2UI_Peak_Data {
/**
The start of the measurement period. This is just a running counter
that is only meaningful in comparison to previous values and must not be
interpreted as an absolute time.
*/
uint32_t period_start;
/**
The size of the measurement period, in the same units as period_start.
*/
uint32_t period_size;
/**
The peak value for the measurement period. This should be the maximal
value for abs(sample) over all the samples in the period.
*/
float peak;
} LV2UI_Peak_Data;
/**
A plugin UI programmer must include a function called "lv2ui_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). This function is
loaded from the library by the UI host and called to get a
LV2UI_Descriptor for the wanted plugin.
Just like lv2_descriptor(), this function takes an index parameter. The
index should only be used for enumeration and not as any sort of ID number -
the host should just iterate from 0 and upwards until the function returns
NULL or a descriptor with an URI matching the one the host is looking for.
*/
const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
/**
The type of the lv2ui_descriptor() function.
*/
typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index);
#ifdef __cplusplus
}
#endif
#endif /* LV2_UI_H */

View File

@ -1,238 +0,0 @@
/*
Copyright 2008-2012 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.
*/
/**
@file atom.h C header for the LV2 Atom extension
<http://lv2plug.in/ns/ext/atom>.
*/
#ifndef LV2_ATOM_H
#define LV2_ATOM_H
#include <stdint.h>
#include <stddef.h>
#define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom"
#define LV2_ATOM_PREFIX LV2_ATOM_URI "#"
#define LV2_ATOM__Atom LV2_ATOM_PREFIX "Atom"
#define LV2_ATOM__AtomPort LV2_ATOM_PREFIX "AtomPort"
#define LV2_ATOM__AudioFrames LV2_ATOM_PREFIX "AudioFrames"
#define LV2_ATOM__Beats LV2_ATOM_PREFIX "Beats"
#define LV2_ATOM__Blank LV2_ATOM_PREFIX "Blank"
#define LV2_ATOM__Bool LV2_ATOM_PREFIX "Bool"
#define LV2_ATOM__Chunk LV2_ATOM_PREFIX "Chunk"
#define LV2_ATOM__Double LV2_ATOM_PREFIX "Double"
#define LV2_ATOM__Event LV2_ATOM_PREFIX "Event"
#define LV2_ATOM__Float LV2_ATOM_PREFIX "Float"
#define LV2_ATOM__Int LV2_ATOM_PREFIX "Int"
#define LV2_ATOM__Long LV2_ATOM_PREFIX "Long"
#define LV2_ATOM__Literal LV2_ATOM_PREFIX "Literal"
#define LV2_ATOM__Number LV2_ATOM_PREFIX "Number"
#define LV2_ATOM__Object LV2_ATOM_PREFIX "Object"
#define LV2_ATOM__Path LV2_ATOM_PREFIX "Path"
#define LV2_ATOM__Property LV2_ATOM_PREFIX "Property"
#define LV2_ATOM__Resource LV2_ATOM_PREFIX "Resource"
#define LV2_ATOM__Sequence LV2_ATOM_PREFIX "Sequence"
#define LV2_ATOM__Sound LV2_ATOM_PREFIX "Sound"
#define LV2_ATOM__String LV2_ATOM_PREFIX "String"
#define LV2_ATOM__TimeUnit LV2_ATOM_PREFIX "TimeUnit"
#define LV2_ATOM__Tuple LV2_ATOM_PREFIX "Tuple"
#define LV2_ATOM__URI LV2_ATOM_PREFIX "URI"
#define LV2_ATOM__URID LV2_ATOM_PREFIX "URID"
#define LV2_ATOM__Vector LV2_ATOM_PREFIX "Vector"
#define LV2_ATOM__beatTime LV2_ATOM_PREFIX "beatTime"
#define LV2_ATOM__bufferType LV2_ATOM_PREFIX "bufferType"
#define LV2_ATOM__childType LV2_ATOM_PREFIX "childType"
#define LV2_ATOM__eventTransfer LV2_ATOM_PREFIX "eventTransfer"
#define LV2_ATOM__frameTime LV2_ATOM_PREFIX "frameTime"
#define LV2_ATOM__supports LV2_ATOM_PREFIX "supports"
#define LV2_ATOM__timeUnit LV2_ATOM_PREFIX "timeUnit"
#define LV2_ATOM_REFERENCE_TYPE 0
#ifdef __cplusplus
extern "C" {
#endif
/** This expression will fail to compile if double does not fit in 64 bits. */
typedef char lv2_atom_assert_double_fits_in_64_bits[
((sizeof(double) <= sizeof(uint64_t)) * 2) - 1];
/**
Return a pointer to the contents of an Atom. The "contents" of an atom
is the data past the complete type-specific header.
@param type The type of the atom, e.g. LV2_Atom_String.
@param atom A variable-sized atom.
*/
#define LV2_ATOM_CONTENTS(type, atom) \
((void*)((uint8_t*)(atom) + sizeof(type)))
/**
Return a pointer to the body of an Atom. The "body" of an atom is the
data just past the LV2_Atom head (i.e. the same offset for all types).
*/
#define LV2_ATOM_BODY(atom) LV2_ATOM_CONTENTS(LV2_Atom, atom)
/** The header of an atom:Atom. */
typedef struct {
uint32_t size; /**< Size in bytes, not including type and size. */
uint32_t type; /**< Type of this atom (mapped URI). */
} LV2_Atom;
/** An atom:Int or atom:Bool. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
int32_t body; /**< Integer value. */
} LV2_Atom_Int;
/** An atom:Long. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
int64_t body; /**< Integer value. */
} LV2_Atom_Long;
/** An atom:Float. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
float body; /**< Floating point value. */
} LV2_Atom_Float;
/** An atom:Double. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
double body; /**< Floating point value. */
} LV2_Atom_Double;
/** An atom:Bool. May be cast to LV2_Atom. */
typedef LV2_Atom_Int LV2_Atom_Bool;
/** An atom:URID. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
uint32_t body; /**< URID. */
} LV2_Atom_URID;
/** An atom:String. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
/* Contents (a null-terminated UTF-8 string) follow here. */
} LV2_Atom_String;
/** The body of an atom:Literal. */
typedef struct {
uint32_t datatype; /**< Datatype URID. */
uint32_t lang; /**< Language URID. */
/* Contents (a null-terminated UTF-8 string) follow here. */
} LV2_Atom_Literal_Body;
/** An atom:Literal. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Literal_Body body; /**< Body. */
} LV2_Atom_Literal;
/** An atom:Tuple. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
/* Contents (a series of complete atoms) follow here. */
} LV2_Atom_Tuple;
/** The body of an atom:Vector. */
typedef struct {
uint32_t child_size; /**< The size of each element in the vector. */
uint32_t child_type; /**< The type of each element in the vector. */
/* Contents (a series of packed atom bodies) follow here. */
} LV2_Atom_Vector_Body;
/** An atom:Vector. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Vector_Body body; /**< Body. */
} LV2_Atom_Vector;
/** The body of an atom:Property (e.g. in an atom:Object). */
typedef struct {
uint32_t key; /**< Key (predicate) (mapped URI). */
uint32_t context; /**< Context URID (may be, and generally is, 0). */
LV2_Atom value; /**< Value atom header. */
/* Value atom body follows here. */
} LV2_Atom_Property_Body;
/** An atom:Property. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Property_Body body; /**< Body. */
} LV2_Atom_Property;
/** The body of an atom:Object. May be cast to LV2_Atom. */
typedef struct {
uint32_t id; /**< URID (atom:Resource) or blank ID (atom:Blank). */
uint32_t otype; /**< Type URID (same as rdf:type, for fast dispatch). */
/* Contents (a series of property bodies) follow here. */
} LV2_Atom_Object_Body;
/** An atom:Object. May be cast to LV2_Atom. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Object_Body body; /**< Body. */
} LV2_Atom_Object;
/** The header of an atom:Event. Note this type is NOT an LV2_Atom. */
typedef struct {
/** Time stamp. Which type is valid is determined by context. */
union {
int64_t frames; /**< Time in audio frames. */
double beats; /**< Time in beats. */
} time;
LV2_Atom body; /**< Event body atom header. */
/* Body atom contents follow here. */
} LV2_Atom_Event;
/**
The body of an atom:Sequence (a sequence of events).
The unit field is either a URID that described an appropriate time stamp
type, or may be 0 where a default stamp type is known. For
LV2_Descriptor::run(), the default stamp type is atom:AudioFrames, i.e.
LV2_Atom_Audio_Time.
The contents of a sequence is a series of LV2_Atom_Event, each aligned
to 64-bits, e.g.:
<pre>
| Event 1 (size 6) | Event 2
| | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|FRAMES |SUBFRMS|TYPE |SIZE |DATADATADATAPAD|FRAMES |SUBFRMS|...
</pre>
*/
typedef struct {
uint32_t unit; /**< URID of unit of event time stamps. */
uint32_t pad; /**< Currently unused. */
/* Contents (a series of events) follow here. */
} LV2_Atom_Sequence_Body;
/** An atom:Sequence. */
typedef struct {
LV2_Atom atom; /**< Atom header. */
LV2_Atom_Sequence_Body body; /**< Body. */
} LV2_Atom_Sequence;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV2_ATOM_H */

View File

@ -1,618 +0,0 @@
/*
Copyright 2008-2012 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.
*/
/**
@file forge.h An API for constructing LV2 atoms.
This file provides an API for constructing Atoms which makes it relatively
simple to build nested atoms of arbitrary complexity without requiring
dynamic memory allocation.
The API is based on successively appending the appropriate pieces to build a
complete Atom. The size of containers is automatically updated. Functions
that begin a container return (via their frame argument) a stack frame which
must be popped when the container is finished.
All output is written to a user-provided buffer or sink function. This
makes it popssible to create create atoms on the stack, on the heap, in LV2
port buffers, in a ringbuffer, or elsewhere, all using the same API.
This entire API is realtime safe if used with a buffer or a realtime safe
sink, except lv2_atom_forge_init() which is only realtime safe if the URI
map function is.
Note these functions are all static inline, do not take their address.
This header is non-normative, it is provided for convenience.
*/
#ifndef LV2_ATOM_FORGE_H
#define LV2_ATOM_FORGE_H
#include <assert.h>
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif
/** Handle for LV2_Atom_Forge_Sink. */
typedef void* LV2_Atom_Forge_Sink_Handle;
/** A reference to a chunk of written output. */
typedef intptr_t LV2_Atom_Forge_Ref;
/** Sink function for writing output. See lv2_atom_forge_set_sink(). */
typedef LV2_Atom_Forge_Ref
(*LV2_Atom_Forge_Sink)(LV2_Atom_Forge_Sink_Handle handle,
const void* buf,
uint32_t size);
/** Function for resolving a reference. See lv2_atom_forge_set_sink(). */
typedef LV2_Atom*
(*LV2_Atom_Forge_Deref_Func)(LV2_Atom_Forge_Sink_Handle handle,
LV2_Atom_Forge_Ref ref);
/** A stack frame used for keeping track of nested Atom containers. */
typedef struct _LV2_Atom_Forge_Frame {
struct _LV2_Atom_Forge_Frame* parent;
LV2_Atom_Forge_Ref ref;
} LV2_Atom_Forge_Frame;
/** A "forge" for creating atoms by appending to a buffer. */
typedef struct {
uint8_t* buf;
uint32_t offset;
uint32_t size;
LV2_Atom_Forge_Sink sink;
LV2_Atom_Forge_Deref_Func deref;
LV2_Atom_Forge_Sink_Handle handle;
LV2_Atom_Forge_Frame* stack;
LV2_URID Blank;
LV2_URID Bool;
LV2_URID Double;
LV2_URID Float;
LV2_URID Int;
LV2_URID Long;
LV2_URID Literal;
LV2_URID Path;
LV2_URID Property;
LV2_URID Resource;
LV2_URID Sequence;
LV2_URID String;
LV2_URID Tuple;
LV2_URID URI;
LV2_URID URID;
LV2_URID Vector;
} LV2_Atom_Forge;
static inline void
lv2_atom_forge_set_buffer(LV2_Atom_Forge* forge, uint8_t* buf, size_t size);
/**
Initialise @p forge.
URIs will be mapped using @p map and stored, a reference to @p map itself is
not held.
*/
static inline void
lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)
{
lv2_atom_forge_set_buffer(forge, NULL, 0);
forge->Blank = map->map(map->handle, LV2_ATOM__Blank);
forge->Bool = map->map(map->handle, LV2_ATOM__Bool);
forge->Double = map->map(map->handle, LV2_ATOM__Double);
forge->Float = map->map(map->handle, LV2_ATOM__Float);
forge->Int = map->map(map->handle, LV2_ATOM__Int);
forge->Long = map->map(map->handle, LV2_ATOM__Long);
forge->Literal = map->map(map->handle, LV2_ATOM__Literal);
forge->Path = map->map(map->handle, LV2_ATOM__Path);
forge->Property = map->map(map->handle, LV2_ATOM__Property);
forge->Resource = map->map(map->handle, LV2_ATOM__Resource);
forge->Sequence = map->map(map->handle, LV2_ATOM__Sequence);
forge->String = map->map(map->handle, LV2_ATOM__String);
forge->Tuple = map->map(map->handle, LV2_ATOM__Tuple);
forge->URI = map->map(map->handle, LV2_ATOM__URI);
forge->URID = map->map(map->handle, LV2_ATOM__URID);
forge->Vector = map->map(map->handle, LV2_ATOM__Vector);
}
static inline LV2_Atom*
lv2_atom_forge_deref(LV2_Atom_Forge* forge, LV2_Atom_Forge_Ref ref)
{
if (forge->buf) {
return (LV2_Atom*)ref;
} else {
return forge->deref(forge->handle, ref);
}
}
/**
@name Object Stack
@{
*/
/**
Push a stack frame.
This is done automatically by container functions (which take a stack frame
pointer), but may be called by the user to push the top level container when
writing to an existing Atom.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_push(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
LV2_Atom_Forge_Ref ref)
{
frame->parent = forge->stack;
frame->ref = ref;
forge->stack = frame;
return ref;
}
/** Pop a stack frame. This must be called when a container is finished. */
static inline void
lv2_atom_forge_pop(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
{
assert(frame == forge->stack);
forge->stack = frame->parent;
}
/** Return true iff the top of the stack has the given type. */
static inline bool
lv2_atom_forge_top_is(LV2_Atom_Forge* forge, uint32_t type)
{
return forge->stack &&
lv2_atom_forge_deref(forge, forge->stack->ref)->type == type;
}
/**
@}
@name Output Configuration
@{
*/
/** Set the output buffer where @p forge will write atoms. */
static inline void
lv2_atom_forge_set_buffer(LV2_Atom_Forge* forge, uint8_t* buf, size_t size)
{
forge->buf = buf;
forge->size = size;
forge->offset = 0;
forge->deref = NULL;
forge->sink = NULL;
forge->handle = NULL;
forge->stack = NULL;
}
/**
Set the sink function where @p forge will write output.
The return value of forge functions is an LV2_Atom_Forge_Ref which is an
integer type safe to use as a pointer but is otherwise opaque. The sink
function must return a ref that can be dereferenced to access as least
sizeof(LV2_Atom) bytes of the written data, so sizes can be updated. For
ringbuffers, this should be possible as long as the size of the buffer is a
multiple of sizeof(LV2_Atom), since atoms are always aligned.
Note that 0 is an invalid reference, so if you are using a buffer offset be
sure to offset it such that 0 is never a valid reference. You will get
confusing errors otherwise.
*/
static inline void
lv2_atom_forge_set_sink(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Sink sink,
LV2_Atom_Forge_Deref_Func deref,
LV2_Atom_Forge_Sink_Handle handle)
{
forge->buf = NULL;
forge->size = forge->offset = 0;
forge->deref = deref;
forge->sink = sink;
forge->handle = handle;
forge->stack = NULL;
}
/**
@}
@name Low Level Output
@{
*/
/**
Write raw output. This is used internally, but is also useful for writing
atom types not explicitly supported by the forge API. Note the caller is
responsible for ensuring the output is approriately padded.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_raw(LV2_Atom_Forge* forge, const void* data, uint32_t size)
{
LV2_Atom_Forge_Ref out = 0;
if (forge->sink) {
out = forge->sink(forge->handle, data, size);
} else {
out = (LV2_Atom_Forge_Ref)forge->buf + forge->offset;
uint8_t* mem = forge->buf + forge->offset;
if (forge->offset + size > forge->size) {
return 0;
}
forge->offset += size;
memcpy(mem, data, size);
}
for (LV2_Atom_Forge_Frame* f = forge->stack; f; f = f->parent) {
lv2_atom_forge_deref(forge, f->ref)->size += size;
}
return out;
}
/** Pad output accordingly so next write is 64-bit aligned. */
static inline void
lv2_atom_forge_pad(LV2_Atom_Forge* forge, uint32_t written)
{
const uint64_t pad = 0;
const uint32_t pad_size = lv2_atom_pad_size(written) - written;
lv2_atom_forge_raw(forge, &pad, pad_size);
}
/** Write raw output, padding to 64-bits as necessary. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_write(LV2_Atom_Forge* forge, const void* data, uint32_t size)
{
LV2_Atom_Forge_Ref out = lv2_atom_forge_raw(forge, data, size);
if (out) {
lv2_atom_forge_pad(forge, size);
}
return out;
}
/** Write a null-terminated string body. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_string_body(LV2_Atom_Forge* forge,
const char* str,
uint32_t len)
{
LV2_Atom_Forge_Ref out = lv2_atom_forge_raw(forge, str, len);
if (out && (out = lv2_atom_forge_raw(forge, "", 1))) {
lv2_atom_forge_pad(forge, len + 1);
}
return out;
}
/**
@}
@name Atom Output
@{
*/
/** Write an atom:Atom header. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_atom(LV2_Atom_Forge* forge, uint32_t size, uint32_t type)
{
const LV2_Atom a = { size, type };
return lv2_atom_forge_raw(forge, &a, sizeof(a));
}
/** Write a primitive (fixed-size) atom. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_primitive(LV2_Atom_Forge* forge, const LV2_Atom* a)
{
if (lv2_atom_forge_top_is(forge, forge->Vector)) {
return lv2_atom_forge_raw(forge, LV2_ATOM_BODY(a), a->size);
} else {
return lv2_atom_forge_write(forge, a, sizeof(LV2_Atom) + a->size);
}
}
/** Write an atom:Int. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_int(LV2_Atom_Forge* forge, int32_t val)
{
const LV2_Atom_Int a = { { sizeof(val), forge->Int }, val };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom:Long. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_long(LV2_Atom_Forge* forge, int64_t val)
{
const LV2_Atom_Long a = { { sizeof(val), forge->Long }, val };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom:Float. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_float(LV2_Atom_Forge* forge, float val)
{
const LV2_Atom_Float a = { { sizeof(val), forge->Float }, val };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom:Double. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_double(LV2_Atom_Forge* forge, double val)
{
const LV2_Atom_Double a = { { sizeof(val), forge->Double }, val };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom:Bool. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_bool(LV2_Atom_Forge* forge, bool val)
{
const LV2_Atom_Bool a = { { sizeof(int32_t), forge->Bool }, val ? 1 : 0 };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom:URID. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_urid(LV2_Atom_Forge* forge, LV2_URID id)
{
const LV2_Atom_URID a = { { sizeof(id), forge->URID }, id };
return lv2_atom_forge_primitive(forge, &a.atom);
}
/** Write an atom compatible with atom:String. Used internally. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_typed_string(LV2_Atom_Forge* forge,
uint32_t type,
const char* str,
uint32_t len)
{
const LV2_Atom_String a = { { len + 1, type } };
LV2_Atom_Forge_Ref out = lv2_atom_forge_raw(forge, &a, sizeof(a));
if (out) {
if (!lv2_atom_forge_string_body(forge, str, len)) {
LV2_Atom* atom = lv2_atom_forge_deref(forge, out);
atom->size = atom->type = 0;
out = 0;
}
}
return out;
}
/** Write an atom:String. Note that @p str need not be NULL terminated. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_string(LV2_Atom_Forge* forge, const char* str, uint32_t len)
{
return lv2_atom_forge_typed_string(forge, forge->String, str, len);
}
/**
Write an atom:URI. Note that @p uri need not be NULL terminated.
This does not map the URI, but writes the complete URI string. To write
a mapped URI, use lv2_atom_forge_urid().
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_uri(LV2_Atom_Forge* forge, const char* uri, uint32_t len)
{
return lv2_atom_forge_typed_string(forge, forge->URI, uri, len);
}
/** Write an atom:Path. Note that @p path need not be NULL terminated. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_path(LV2_Atom_Forge* forge, const char* path, uint32_t len)
{
return lv2_atom_forge_typed_string(forge, forge->Path, path, len);
}
/** Write an atom:Literal. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_literal(LV2_Atom_Forge* forge,
const char* str,
uint32_t len,
uint32_t datatype,
uint32_t lang)
{
const LV2_Atom_Literal a = {
{ sizeof(LV2_Atom_Literal) - sizeof(LV2_Atom) + len + 1,
forge->Literal },
{ datatype,
lang }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_raw(forge, &a, sizeof(a));
if (out) {
if (!lv2_atom_forge_string_body(forge, str, len)) {
LV2_Atom* atom = lv2_atom_forge_deref(forge, out);
atom->size = atom->type = 0;
out = 0;
}
}
return out;
}
/** Start an atom:Vector. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_vector_head(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
uint32_t child_size,
uint32_t child_type)
{
const LV2_Atom_Vector a = {
{ sizeof(LV2_Atom_Vector_Body), forge->Vector },
{ child_size, child_type }
};
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
}
/** Write a complete atom:Vector. */
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_vector(LV2_Atom_Forge* forge,
uint32_t child_size,
uint32_t child_type,
uint32_t n_elems,
const void* elems)
{
const LV2_Atom_Vector a = {
{ sizeof(LV2_Atom_Vector_Body) + n_elems * child_size, forge->Vector },
{ child_size, child_type }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
if (out) {
lv2_atom_forge_write(forge, elems, child_size * n_elems);
}
return out;
}
/**
Write the header of an atom:Tuple.
The passed frame will be initialised to represent this tuple. To complete
the tuple, write a sequence of atoms, then pop the frame with
lv2_atom_forge_pop().
For example:
@code
// Write tuple (1, 2.0)
LV2_Atom_Forge_Frame frame;
LV2_Atom* tup = (LV2_Atom*)lv2_atom_forge_tuple(forge, &frame);
lv2_atom_forge_int32(forge, 1);
lv2_atom_forge_float(forge, 2.0);
lv2_atom_forge_pop(forge, &frame);
@endcode
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_tuple(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
{
const LV2_Atom_Tuple a = { { 0, forge->Tuple } };
return lv2_atom_forge_push(
forge, frame, lv2_atom_forge_write(forge, &a, sizeof(a)));
}
/**
Write the header of an atom:Resource.
The passed frame will be initialised to represent this object. To complete
the object, write a sequence of properties, then pop the frame with
lv2_atom_forge_pop().
For example:
@code
LV2_URID eg_Cat = map("http://example.org/Cat");
LV2_URID eg_name = map("http://example.org/name");
// Write object header
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_resource(forge, &frame, 1, eg_Cat);
// Write property: eg:name = "Hobbes"
lv2_atom_forge_property_head(forge, eg_name, 0);
lv2_atom_forge_string(forge, "Hobbes", strlen("Hobbes"));
// Finish object
lv2_atom_forge_pop(forge, &frame);
@endcode
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_resource(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
LV2_URID id,
LV2_URID otype)
{
const LV2_Atom_Object a = {
{ sizeof(LV2_Atom_Object) - sizeof(LV2_Atom), forge->Resource },
{ id, otype }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
}
/**
The same as lv2_atom_forge_resource(), but for object:Blank.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_blank(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
uint32_t id,
LV2_URID otype)
{
const LV2_Atom_Object a = {
{ sizeof(LV2_Atom_Object) - sizeof(LV2_Atom), forge->Blank },
{ id, otype }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
}
/**
Write the header for a property body (likely in an Object).
See lv2_atom_forge_object() documentation for an example.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_property_head(LV2_Atom_Forge* forge,
LV2_URID key,
LV2_URID context)
{
const LV2_Atom_Property_Body a = { key, context, { 0, 0 } };
return lv2_atom_forge_write(forge, &a, 2 * sizeof(uint32_t));
}
/**
Write the header for a Sequence.
The size of the returned sequence will be 0, so passing it as the parent
parameter to other forge methods will do the right thing.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_sequence_head(LV2_Atom_Forge* forge,
LV2_Atom_Forge_Frame* frame,
uint32_t unit)
{
const LV2_Atom_Sequence a = {
{ sizeof(LV2_Atom_Sequence) - sizeof(LV2_Atom), forge->Sequence },
{ unit, 0 }
};
LV2_Atom_Forge_Ref out = lv2_atom_forge_write(forge, &a, sizeof(a));
return lv2_atom_forge_push(forge, frame, out);
}
/**
Write the time stamp header of an Event (in a Sequence) in audio frames.
After this, call the appropriate forge method(s) to write the body, passing
the same @p parent parameter. Note the returned LV2_Event is NOT an Atom.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_frame_time(LV2_Atom_Forge* forge, int64_t frames)
{
return lv2_atom_forge_write(forge, &frames, sizeof(frames));
}
/**
Write the time stamp header of an Event (in a Sequence) in beats.
After this, call the appropriate forge method(s) to write the body, passing
the same @p parent parameter. Note the returned LV2_Event is NOT an Atom.
*/
static inline LV2_Atom_Forge_Ref
lv2_atom_forge_beat_time(LV2_Atom_Forge* forge, double beats)
{
return lv2_atom_forge_write(forge, &beats, sizeof(beats));
}
/**
@}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV2_ATOM_FORGE_H */

View File

@ -1,424 +0,0 @@
/*
Copyright 2008-2012 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.
*/
/**
@file util.h Helper functions for the LV2 Atom extension.
Note these functions are all static inline, do not take their address.
This header is non-normative, it is provided for convenience.
*/
#ifndef LV2_ATOM_UTIL_H
#define LV2_ATOM_UTIL_H
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif
/** Pad a size to 64 bits. */
static inline uint32_t
lv2_atom_pad_size(uint32_t size)
{
return (size + 7) & (~7);
}
/** Return the total size of @p atom, including the header. */
static inline uint32_t
lv2_atom_total_size(const LV2_Atom* atom)
{
return sizeof(LV2_Atom) + atom->size;
}
/** Return true iff @p atom is null. */
static inline bool
lv2_atom_is_null(const LV2_Atom* atom)
{
return !atom || (atom->type == 0 && atom->size == 0);
}
/** Return true iff @p a is equal to @p b. */
static inline bool
lv2_atom_equals(const LV2_Atom* a, const LV2_Atom* b)
{
return (a == b) || ((a->type == b->type) &&
(a->size == b->size) &&
!memcmp(a + 1, b + 1, a->size));
}
/**
@name Sequence Iterator
@{
*/
/** An iterator over the elements of an LV2_Atom_Sequence. */
typedef LV2_Atom_Event* LV2_Atom_Sequence_Iter;
/** Get an iterator pointing to the first element in a Sequence body. */
static inline LV2_Atom_Sequence_Iter
lv2_sequence_body_begin(const LV2_Atom_Sequence_Body* body)
{
return (LV2_Atom_Sequence_Iter)(body + 1);
}
/** Get an iterator pointing to the first element in a Sequence. */
static inline LV2_Atom_Sequence_Iter
lv2_sequence_begin(const LV2_Atom_Sequence* seq)
{
return (LV2_Atom_Sequence_Iter)(seq + 1);
}
/** Return true iff @p i has reached the end of @p body. */
static inline bool
lv2_sequence_body_is_end(const LV2_Atom_Sequence_Body* body,
uint32_t size,
LV2_Atom_Sequence_Iter i)
{
return (uint8_t*)i >= ((uint8_t*)body + size);
}
/** Return true iff @p i has reached the end of @p seq. */
static inline bool
lv2_sequence_is_end(const LV2_Atom_Sequence* seq, LV2_Atom_Sequence_Iter i)
{
return (uint8_t*)i >= ((uint8_t*)seq + sizeof(LV2_Atom) + seq->atom.size);
}
/** Return an iterator to the element following @p i. */
static inline LV2_Atom_Sequence_Iter
lv2_sequence_iter_next(const LV2_Atom_Sequence_Iter i)
{
return (LV2_Atom_Sequence_Iter)((uint8_t*)i
+ sizeof(LV2_Atom_Event)
+ lv2_atom_pad_size(i->body.size));
}
/** Return the element pointed to by @p i. */
static inline LV2_Atom_Event*
lv2_sequence_iter_get(LV2_Atom_Sequence_Iter i)
{
return (LV2_Atom_Event*)i;
}
/**
A macro for iterating over all events in a Sequence.
@param sequence The sequence to iterate over
@param iter The name of the iterator
This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_SEQUENCE_FOREACH(sequence, i) {
LV2_Atom_Event* ev = lv2_sequence_iter_get(i);
// Do something with ev here...
}
@endcode
*/
#define LV2_SEQUENCE_FOREACH(sequence, iter) \
for (LV2_Atom_Sequence_Iter (iter) = lv2_sequence_begin(sequence); \
!lv2_sequence_is_end(sequence, (iter)); \
(iter) = lv2_sequence_iter_next(iter))
/** A version of LV2_SEQUENCE_FOREACH for when only the body is available. */
#define LV2_SEQUENCE_BODY_FOREACH(body, size, iter) \
for (LV2_Atom_Sequence_Iter (iter) = lv2_sequence_body_begin(body); \
!lv2_sequence_body_is_end(body, size, (iter)); \
(iter) = lv2_sequence_iter_next(iter))
/**
@}
@name Tuple Iterator
@{
*/
/** An iterator over the elements of an LV2_Atom_Tuple. */
typedef LV2_Atom* LV2_Atom_Tuple_Iter;
/** Get an iterator pointing to the first element in @p tup. */
static inline LV2_Atom_Tuple_Iter
lv2_tuple_begin(const LV2_Atom_Tuple* tup)
{
return (LV2_Atom_Tuple_Iter)(LV2_ATOM_BODY(tup));
}
/** Return true iff @p i has reached the end of @p body. */
static inline bool
lv2_atom_tuple_body_is_end(const void* body,
uint32_t size,
LV2_Atom_Tuple_Iter i)
{
return (uint8_t*)i >= ((uint8_t*)body + size);
}
/** Return true iff @p i has reached the end of @p tup. */
static inline bool
lv2_tuple_is_end(const LV2_Atom_Tuple* tup, LV2_Atom_Tuple_Iter i)
{
return lv2_atom_tuple_body_is_end(LV2_ATOM_BODY(tup), tup->atom.size, i);
}
/** Return an iterator to the element following @p i. */
static inline LV2_Atom_Tuple_Iter
lv2_tuple_iter_next(const LV2_Atom_Tuple_Iter i)
{
return (LV2_Atom_Tuple_Iter)(
(uint8_t*)i + sizeof(LV2_Atom) + lv2_atom_pad_size(i->size));
}
/** Return the element pointed to by @p i. */
static inline LV2_Atom*
lv2_tuple_iter_get(LV2_Atom_Tuple_Iter i)
{
return (LV2_Atom*)i;
}
/**
A macro for iterating over all properties of a Tuple.
@param tuple The tuple to iterate over
@param iter The name of the iterator
This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_TUPLE_FOREACH(tuple, i) {
LV2_Atom* elem = lv2_tuple_iter_get(i);
// Do something with elem here...
}
@endcode
*/
#define LV2_TUPLE_FOREACH(tuple, iter) \
for (LV2_Atom_Tuple_Iter (iter) = lv2_tuple_begin(tuple); \
!lv2_tuple_is_end(tuple, (iter)); \
(iter) = lv2_tuple_iter_next(iter))
/** A version of LV2_TUPLE_FOREACH for when only the body is available. */
#define LV2_TUPLE_BODY_FOREACH(body, size, iter) \
for (LV2_Atom_Tuple_Iter (iter) = (LV2_Atom_Tuple_Iter)body; \
!lv2_atom_tuple_body_is_end(body, size, (iter)); \
(iter) = lv2_tuple_iter_next(iter))
/**
@}
@name Object Iterator
@{
*/
/** An iterator over the properties of an LV2_Atom_Object. */
typedef LV2_Atom_Property_Body* LV2_Atom_Object_Iter;
static inline LV2_Atom_Object_Iter
lv2_object_body_begin(const LV2_Atom_Object_Body* body)
{
return (LV2_Atom_Object_Iter)(body + 1);
}
/** Get an iterator pointing to the first property in @p obj. */
static inline LV2_Atom_Object_Iter
lv2_object_begin(const LV2_Atom_Object* obj)
{
return (LV2_Atom_Object_Iter)(obj + 1);
}
static inline bool
lv2_atom_object_body_is_end(const LV2_Atom_Object_Body* body,
uint32_t size,
LV2_Atom_Object_Iter i)
{
return (uint8_t*)i >= ((uint8_t*)body + size);
}
/** Return true iff @p i has reached the end of @p obj. */
static inline bool
lv2_object_is_end(const LV2_Atom_Object* obj, LV2_Atom_Object_Iter i)
{
return (uint8_t*)i >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->atom.size);
}
/** Return an iterator to the property following @p i. */
static inline LV2_Atom_Object_Iter
lv2_object_iter_next(const LV2_Atom_Object_Iter i)
{
const LV2_Atom* const value = (LV2_Atom*)((uint8_t*)i + sizeof(i));
return (LV2_Atom_Object_Iter)((uint8_t*)i
+ sizeof(LV2_Atom_Property_Body)
+ lv2_atom_pad_size(value->size));
}
/** Return the property pointed to by @p i. */
static inline LV2_Atom_Property_Body*
lv2_object_iter_get(LV2_Atom_Object_Iter i)
{
return (LV2_Atom_Property_Body*)i;
}
/**
A macro for iterating over all properties of an Object.
@param object The object to iterate over
@param iter The name of the iterator
This macro is used similarly to a for loop (which it expands to), e.g.:
@code
LV2_OBJECT_FOREACH(object, i) {
LV2_Atom_Property_Body* prop = lv2_object_iter_get(i);
// Do something with prop here...
}
@endcode
*/
#define LV2_OBJECT_FOREACH(object, iter) \
for (LV2_Atom_Object_Iter (iter) = lv2_object_begin(object); \
!lv2_object_is_end(object, (iter)); \
(iter) = lv2_object_iter_next(iter))
/** A version of LV2_OBJECT_FOREACH for when only the body is available. */
#define LV2_OBJECT_BODY_FOREACH(body, size, iter) \
for (LV2_Atom_Object_Iter (iter) = lv2_object_body_begin(body); \
!lv2_atom_object_body_is_end(body, size, (iter)); \
(iter) = lv2_object_iter_next(iter))
/**
@}
@name Object Query
@{
*/
/** A single entry in an Object query. */
typedef struct {
uint32_t key; /**< Key to query (input set by user) */
const LV2_Atom** value; /**< Found value (output set by query function) */
} LV2_Atom_Object_Query;
static const LV2_Atom_Object_Query LV2_OBJECT_QUERY_END = { 0, NULL };
/**
Get an object's values for various keys.
The value pointer of each item in @p query will be set to the location of
the corresponding value in @p object. Every value pointer in @p query MUST
be initialised to NULL. This function reads @p object in a single linear
sweep. By allocating @p query on the stack, objects can be "queried"
quickly without allocating any memory. This function is realtime safe.
This function can only do "flat" queries, it is not smart enough to match
variables in nested objects.
For example:
@code
const LV2_Atom* name = NULL;
const LV2_Atom* age = NULL;
LV2_Atom_Object_Query q[] = {
{ urids.eg_name, &name },
{ urids.eg_age, &age },
LV2_OBJECT_QUERY_END
};
lv2_object_query(obj, q);
// name and age are now set to the appropriate values in obj, or NULL.
@endcode
*/
static inline int
lv2_object_query(const LV2_Atom_Object* object, LV2_Atom_Object_Query* query)
{
int matches = 0;
int n_queries = 0;
/* Count number of query keys so we can short-circuit when done */
for (LV2_Atom_Object_Query* q = query; q->key; ++q) {
++n_queries;
}
LV2_OBJECT_FOREACH(object, o) {
const LV2_Atom_Property_Body* prop = lv2_object_iter_get(o);
for (LV2_Atom_Object_Query* q = query; q->key; ++q) {
if (q->key == prop->key && !*q->value) {
*q->value = &prop->value;
if (++matches == n_queries) {
return matches;
}
break;
}
}
}
return matches;
}
/**
Variable argument version of lv2_object_get().
This is nicer-looking in code, but a bit more error-prone since it is not
type safe and the argument list must be terminated.
The arguments should be a series of uint32_t key and const LV2_Atom** value
pairs, terminated by a zero key. The value pointers MUST be initialized to
NULL. For example:
@code
const LV2_Atom* name = NULL;
const LV2_Atom* age = NULL;
lv2_object_get(obj,
uris.name_key, &name,
uris.age_key, &age,
0);
@endcode
*/
static inline int
lv2_object_get(const LV2_Atom_Object* object, ...)
{
int matches = 0;
int n_queries = 0;
/* Count number of keys so we can short-circuit when done */
va_list args;
va_start(args, object);
for (n_queries = 0; va_arg(args, uint32_t); ++n_queries) {
if (!va_arg(args, const LV2_Atom**)) {
return -1;
}
}
va_end(args);
LV2_OBJECT_FOREACH(object, o) {
const LV2_Atom_Property_Body* prop = lv2_object_iter_get(o);
va_start(args, object);
for (int i = 0; i < n_queries; ++i) {
uint32_t qkey = va_arg(args, uint32_t);
const LV2_Atom** qval = va_arg(args, const LV2_Atom**);
if (qkey == prop->key && !*qval) {
*qval = &prop->value;
if (++matches == n_queries) {
return matches;
}
break;
}
}
va_end(args);
}
return matches;
}
/**
@}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV2_ATOM_UTIL_H */

View File

@ -1,243 +0,0 @@
/* lv2_event_helpers.h - Helper functions for the LV2 events extension.
*
* Copyright (C) 2008 David Robillard <d@drobilla.net>
*
* 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 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 header; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
*/
#ifndef LV2_EVENT_HELPERS_H
#define LV2_EVENT_HELPERS_H
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "lv2/lv2plug.in/ns/ext/event/event.h"
/** @file
* This header defines some helper functions for the the LV2 events extension
* with URI <http://lv2plug.in/ns/ext/event> ('lv2ev').
*
* These functions are provided for convenience only, use of them is not
* required for supporting lv2ev (i.e. the events extension is defined by the
* raw buffer format described in lv2_event.h and NOT by this API).
*
* Note that these functions are all static inline which basically means:
* do not take the address of these functions. */
/** Pad a size to 64 bits (for event sizes) */
static inline uint16_t
lv2_event_pad_size(uint16_t size)
{
return (size + 7) & (~7);
}
/** Initialize (empty, reset..) an existing event buffer.
* The contents of buf are ignored entirely and overwritten, except capacity
* which is unmodified. */
static inline void
lv2_event_buffer_reset(LV2_Event_Buffer* buf, uint16_t stamp_type, uint8_t *data)
{
buf->data = data;
buf->header_size = sizeof(LV2_Event_Buffer);
buf->stamp_type = stamp_type;
buf->event_count = 0;
buf->size = 0;
}
/** Allocate a new, empty event buffer. */
static inline LV2_Event_Buffer*
lv2_event_buffer_new(uint32_t capacity, uint16_t stamp_type)
{
LV2_Event_Buffer* buf = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
if (buf != NULL) {
buf->capacity = capacity;
lv2_event_buffer_reset(buf, stamp_type, (uint8_t *)(buf + 1));
return buf;
} else {
return NULL;
}
}
/** An iterator over an LV2_Event_Buffer.
*
* Multiple simultaneous read iterators over a single buffer is fine,
* but changing the buffer invalidates all iterators (e.g. RW Lock). */
typedef struct {
LV2_Event_Buffer* buf;
uint32_t offset;
} LV2_Event_Iterator;
/** Reset an iterator to point to the start of @a buf.
* @return True if @a iter is valid, otherwise false (buffer is empty) */
static inline bool
lv2_event_begin(LV2_Event_Iterator* iter,
LV2_Event_Buffer* buf)
{
iter->buf = buf;
iter->offset = 0;
return (buf->size > 0);
}
/** Check if @a iter is valid..
* @return True if @a iter is valid, otherwise false (past end of buffer) */
static inline bool
lv2_event_is_valid(LV2_Event_Iterator* iter)
{
return (iter->offset < iter->buf->size);
}
/** Advance @a iter forward one event.
* @a iter must be valid.
* @return True if @a iter is valid, otherwise false (reached end of buffer) */
static inline bool
lv2_event_increment(LV2_Event_Iterator* iter)
{
assert(lv2_event_is_valid(iter));
LV2_Event* const ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);
iter->offset += lv2_event_pad_size(sizeof(LV2_Event) + ev->size);
return true;
}
/** Dereference an event iterator (get the event currently pointed at).
* @a iter must be valid.
* @a data if non-NULL, will be set to point to the contents of the event
* returned.
* @return A Pointer to the event @a iter is currently pointing at, or NULL
* if the end of the buffer is reached (in which case @a data is
* also set to NULL). */
static inline LV2_Event*
lv2_event_get(LV2_Event_Iterator* iter,
uint8_t** data)
{
assert(lv2_event_is_valid(iter));
LV2_Event* const ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);
if (data)
*data = (uint8_t*)ev + sizeof(LV2_Event);
return ev;
}
/** Write an event at @a iter.
* The event (if any) pointed to by @iter will be overwritten, and @a iter
* incremented to point to the following event (i.e. several calls to this
* function can be done in sequence without twiddling iter in-between).
* @return True if event was written, otherwise false (buffer is full). */
static inline bool
lv2_event_write(LV2_Event_Iterator* iter,
uint32_t frames,
uint32_t subframes,
uint16_t type,
uint16_t size,
const uint8_t* data)
{
if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size)
return false;
LV2_Event* const ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);
ev->frames = frames;
ev->subframes = subframes;
ev->type = type;
ev->size = size;
memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size);
++iter->buf->event_count;
size = lv2_event_pad_size(sizeof(LV2_Event) + size);
iter->buf->size += size;
iter->offset += size;
return true;
}
/** Reserve space for an event in the buffer and return a pointer to
the memory where the caller can write the event data, or NULL if there
is not enough room in the buffer. */
static inline uint8_t*
lv2_event_reserve(LV2_Event_Iterator* iter,
uint32_t frames,
uint32_t subframes,
uint16_t type,
uint16_t size)
{
size = lv2_event_pad_size(size);
if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size)
return NULL;
LV2_Event* const ev = (LV2_Event*)((uint8_t*)iter->buf->data +
iter->offset);
ev->frames = frames;
ev->subframes = subframes;
ev->type = type;
ev->size = size;
++iter->buf->event_count;
size = lv2_event_pad_size(sizeof(LV2_Event) + size);
iter->buf->size += size;
iter->offset += size;
return (uint8_t*)ev + sizeof(LV2_Event);
}
/** Write an event at @a iter.
* The event (if any) pointed to by @iter will be overwritten, and @a iter
* incremented to point to the following event (i.e. several calls to this
* function can be done in sequence without twiddling iter in-between).
* @return True if event was written, otherwise false (buffer is full). */
static inline bool
lv2_event_write_event(LV2_Event_Iterator* iter,
const LV2_Event* ev,
const uint8_t* data)
{
if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + ev->size)
return false;
LV2_Event* const write_ev = (LV2_Event*)(
(uint8_t*)iter->buf->data + iter->offset);
*write_ev = *ev;
memcpy((uint8_t*)write_ev + sizeof(LV2_Event), data, ev->size);
++iter->buf->event_count;
const uint16_t size = lv2_event_pad_size(sizeof(LV2_Event) + ev->size);
iter->buf->size += size;
iter->offset += size;
return true;
}
#endif // LV2_EVENT_HELPERS_H

View File

@ -1,260 +0,0 @@
/* lv2_event.h - C header file for the LV2 events extension.
*
* Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
* Copyright (C) 2008 David Robillard <d@drobilla.net>
*
* 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 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 header; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
*/
#ifndef LV2_EVENT_H
#define LV2_EVENT_H
#define LV2_EVENT_URI "http://lv2plug.in/ns/ext/event"
#define LV2_EVENT_AUDIO_STAMP 0
#include <stdint.h>
/** @file
* This header defines the code portion of the LV2 events extension with URI
* <http://lv2plug.in/ns/ext/event> ('lv2ev').
*
* This extension is a generic transport mechanism for time stamped events
* of any type (e.g. MIDI, OSC, ramps, etc). Each port can transport mixed
* events of any type; the type of events and timestamps are defined by a URI
* which is mapped to an integer by the host for performance reasons.
*
* This extension requires the host to support the LV2 URI Map extension.
* Any host which supports this extension MUST guarantee that any call to
* the LV2 URI Map uri_to_id function with the URI of this extension as the
* 'map' argument returns a value within the range of uint16_t.
*/
/** The best Pulses Per Quarter Note for tempo-based uint32_t timestmaps.
* Equal to 2^12 * 5 * 7 * 9 * 11 * 13 * 17, which is evenly divisble
* by all integers from 1 through 18 inclusive, and powers of 2 up to 2^12.
*/
static const uint32_t LV2_EVENT_PPQN = 3136573440U;
/** An LV2 event (header only).
*
* LV2 events are generic time-stamped containers for any type of event.
* The type field defines the format of a given event's contents.
*
* This struct defines the header of an LV2 event. An LV2 event is a single
* chunk of POD (plain old data), usually contained in a flat buffer
* (see LV2_EventBuffer below). Unless a required feature says otherwise,
* hosts may assume a deep copy of an LV2 event can be created safely
* using a simple:
*
* memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size); (or equivalent)
*/
typedef struct {
/** The frames portion of timestamp. The units used here can optionally be
* set for a port (with the lv2ev:timeUnits property), otherwise this
* is audio frames, corresponding to the sample_count parameter of the
* LV2 run method (e.g. frame 0 is the first frame for that call to run).
*/
uint32_t frames;
/** The sub-frames portion of timestamp. The units used here can
* optionally be set for a port (with the lv2ev:timeUnits property),
* otherwise this is 1/(2^32) of an audio frame.
*/
uint32_t subframes;
/** The type of this event, as a number which represents some URI
* defining an event type. This value MUST be some value previously
* returned from a call to the uri_to_id function defined in the LV2
* URI map extension (see lv2_uri_map.h).
* There are special rules which must be followed depending on the type
* of an event. If the plugin recognizes an event type, the definition
* of that event type will describe how to interpret the event, and
* any required behaviour. Otherwise, if the type is 0, this event is a
* non-POD event and lv2_event_unref MUST be called if the event is
* 'dropped' (see above). Even if the plugin does not understand an event,
* it may pass the event through to an output by simply copying (and NOT
* calling lv2_event_unref). These rules are designed to allow for generic
* event handling plugins and large non-POD events, but with minimal hassle
* on simple plugins that "don't care" about these more advanced features.
*/
uint16_t type;
/** The size of the data portion of this event in bytes, which immediately
* follows. The header size (12 bytes) is not included in this value.
*/
uint16_t size;
/* size bytes of data follow here */
} LV2_Event;
/** A buffer of LV2 events (header only).
*
* Like events (which this contains) an event buffer is a single chunk of POD:
* the entire buffer (including contents) can be copied with a single memcpy.
* The first contained event begins sizeof(LV2_EventBuffer) bytes after
* the start of this struct.
*
* After this header, the buffer contains an event header (defined by struct
* LV2_Event), followed by that event's contents (padded to 64 bits), followed by
* another header, etc:
*
* | | | | | | |
* | | | | | | | | | | | | | | | | | | | | | | | | |
* |FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ...
*/
typedef struct {
/** The contents of the event buffer. This may or may not reside in the
* same block of memory as this header, plugins must not assume either.
* The host guarantees this points to at least capacity bytes of allocated
* memory (though only size bytes of that are valid events).
*/
uint8_t* data;
/** The size of this event header in bytes (including everything).
*
* This is to allow for extending this header in the future without
* breaking binary compatibility. Whenever this header is copied,
* it MUST be done using this field (and NOT the sizeof this struct).
*/
uint16_t header_size;
/** The type of the time stamps for events in this buffer.
* As a special exception, '0' always means audio frames and subframes
* (1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate.
* INPUTS: The host must set this field to the numeric ID of some URI
* defining the meaning of the frames/subframes fields of contained
* events (obtained by the LV2 URI Map uri_to_id function with the URI
* of this extension as the 'map' argument, see lv2_uri_map.h).
* The host must never pass a plugin a buffer which uses a stamp type
* the plugin does not 'understand'. The value of this field must
* never change, except when connect_port is called on the input
* port, at which time the host MUST have set the stamp_type field to
* the value that will be used for all subsequent run calls.
* OUTPUTS: The plugin may set this to any value that has been returned
* from uri_to_id with the URI of this extension for a 'map' argument.
* When connected to a buffer with connect_port, output ports MUST set
* this field to the type of time stamp they will be writing. On any
* call to connect_port on an event input port, the plugin may change
* this field on any output port, it is the responsibility of the host
* to check if any of these values have changed and act accordingly.
*/
uint16_t stamp_type;
/** The number of events in this buffer.
* INPUTS: The host must set this field to the number of events
* contained in the data buffer before calling run().
* The plugin must not change this field.
* OUTPUTS: The plugin must set this field to the number of events it
* has written to the buffer before returning from run().
* Any initial value should be ignored by the plugin.
*/
uint32_t event_count;
/** The size of the data buffer in bytes.
* This is set by the host and must not be changed by the plugin.
* The host is allowed to change this between run() calls.
*/
uint32_t capacity;
/** The size of the initial portion of the data buffer containing data.
* INPUTS: The host must set this field to the number of bytes used
* by all events it has written to the buffer (including headers)
* before calling the plugin's run().
* The plugin must not change this field.
* OUTPUTS: The plugin must set this field to the number of bytes
* used by all events it has written to the buffer (including headers)
* before returning from run().
* Any initial value should be ignored by the plugin.
*/
uint32_t size;
} LV2_Event_Buffer;
/** Opaque pointer to host data. */
typedef void* LV2_Event_Callback_Data;
/** The data field of the LV2_Feature for this extension.
*
* To support this feature the host must pass an LV2_Feature struct to the
* plugin's instantiate method with URI "http://lv2plug.in/ns/ext/event"
* and data pointed to an instance of this struct.
*/
typedef struct {
/** Opaque pointer to host data.
*
* The plugin MUST pass this to any call to functions in this struct.
* Otherwise, it must not be interpreted in any way.
*/
LV2_Event_Callback_Data callback_data;
/** Take a reference to a non-POD event.
*
* If a plugin receives an event with type 0, it means the event is a
* pointer to some object in memory and not a flat sequence of bytes
* in the buffer. When receiving a non-POD event, the plugin already
* has an implicit reference to the event. If the event is stored AND
* passed to an output, lv2_event_ref MUST be called on that event.
* If the event is only stored OR passed through, this is not necessary
* (as the plugin already has 1 implicit reference).
*
* @param event An event received at an input that will not be copied to
* an output or stored in any way.
* @param context The calling context. (Like event types) this is a mapped
* URI, see lv2_context.h. Simple plugin with just a run()
* method should pass 0 here (the ID of the 'standard' LV2
* run context). The host guarantees that this function is
* realtime safe iff @a context is realtime safe.
*
* PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
*/
uint32_t (*lv2_event_ref)(LV2_Event_Callback_Data callback_data,
LV2_Event* event);
/** Drop a reference to a non-POD event.
*
* If a plugin receives an event with type 0, it means the event is a
* pointer to some object in memory and not a flat sequence of bytes
* in the buffer. If the plugin does not pass the event through to
* an output or store it internally somehow, it MUST call this function
* on the event (more information on using non-POD events below).
*
* @param event An event received at an input that will not be copied to
* an output or stored in any way.
* @param context The calling context. (Like event types) this is a mapped
* URI, see lv2_context.h. Simple plugin with just a run()
* method should pass 0 here (the ID of the 'standard' LV2
* run context). The host guarantees that this function is
* realtime safe iff @a context is realtime safe.
*
* PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
*/
uint32_t (*lv2_event_unref)(LV2_Event_Callback_Data callback_data,
LV2_Event* event);
} LV2_Event_Feature;
#endif // LV2_EVENT_H

View File

@ -1,359 +0,0 @@
/*
Copyright 2010-2012 David Robillard <http://drobilla.net>
Copyright 2010 Leonard Ritter <paniq@paniq.org>
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.
*/
/**
@file state.h
C API for the LV2 State extension <http://lv2plug.in/ns/ext/state>.
*/
#ifndef LV2_STATE_H
#define LV2_STATE_H
#include <stddef.h>
#include <stdint.h>
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state"
#define LV2_STATE_PREFIX LV2_STATE_URI "#"
#define LV2_STATE__State LV2_STATE_PREFIX "State"
#define LV2_STATE__interface LV2_STATE_PREFIX "interface"
#define LV2_STATE__makePath LV2_STATE_PREFIX "makePath"
#define LV2_STATE__mapPath LV2_STATE_PREFIX "mapPath"
#define LV2_STATE__state LV2_STATE_PREFIX "state"
#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif
typedef void* LV2_State_Handle;
typedef void* LV2_State_Map_Path_Handle;
typedef void* LV2_State_Make_Path_Handle;
/**
Flags describing value characteristics.
These flags are used along with the value's type URI to determine how to
(de-)serialise the value data, or whether it is even possible to do so.
*/
typedef enum {
/**
Plain Old Data.
Values with this flag contain no pointers or references to other areas
of memory. It is safe to copy POD values with a simple memcpy and store
them for the duration of the process. A POD value is not necessarily
safe to trasmit between processes or machines (e.g. filenames are POD),
see LV2_STATE_IS_PORTABLE for details.
Implementations MUST NOT attempt to copy or serialise a non-POD value if
they do not understand its type (and thus know how to correctly do so).
*/
LV2_STATE_IS_POD = 1,
/**
Portable (architecture independent) data.
Values with this flag are in a format that is usable on any
architecture. A portable value saved on one machine can be restored on
another machine regardless of architecture. The format of portable
values MUST NOT depend on architecture-specific properties like
endianness or alignment. Portable values MUST NOT contain filenames.
*/
LV2_STATE_IS_PORTABLE = 1 << 1,
/**
Native data.
This flag is used by the host to indicate that the saved data is only
going to be used locally in the currently running process (e.g. for
instance duplication or snapshots), so the plugin should use the most
efficient representation possible and not worry about serialisation
and portability.
*/
LV2_STATE_IS_NATIVE = 1 << 2
} LV2_State_Flags;
/** A status code for state functions. */
typedef enum {
LV2_STATE_SUCCESS = 0, /**< Completed successfully. */
LV2_STATE_ERR_UNKNOWN = 1, /**< Unknown error. */
LV2_STATE_ERR_BAD_TYPE = 2, /**< Failed due to unsupported type. */
LV2_STATE_ERR_BAD_FLAGS = 3, /**< Failed due to unsupported flags. */
LV2_STATE_ERR_NO_FEATURE = 4, /**< Failed due to missing features. */
LV2_STATE_ERR_NO_PROPERTY = 5 /**< Failed due to missing property. */
} LV2_State_Status;
/**
A host-provided function to store a property.
@param handle Must be the handle passed to LV2_State_Interface.save().
@param key The key to store @p value under (URID).
@param value Pointer to the value to be stored.
@param size The size of @p value in bytes.
@param type The type of @p value (URID).
@param flags LV2_State_Flags for @p value.
@return 0 on success, otherwise a non-zero error code.
The host passes a callback of this type to LV2_State_Interface.save(). This
callback is called repeatedly by the plugin to store all the properties that
describe its current state.
DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY. Best is to use keys from
existing vocabularies. If nothing appropriate is available, use http URIs
that point to somewhere you can host documents so documentation can be made
resolvable (e.g. a child of the plugin or project URI). If this is not
possible, invent a URN scheme, e.g. urn:myproj:whatever. The plugin MUST
NOT pass an invalid URI key.
The host MAY fail to store a property for whatever reason, but SHOULD
store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE.
Implementations SHOULD use the types from the LV2 Atom extension
(http://lv2plug.in/ns/ext/atom) wherever possible. The plugin SHOULD
attempt to fall-back and avoid the error if possible.
Note that @p size MUST be > 0, and @p value MUST point to a valid region of
memory @p size bytes long (this is required to make restore unambiguous).
The plugin MUST NOT attempt to use this function outside of the
LV2_State_Interface.restore() context.
*/
typedef LV2_State_Status (*LV2_State_Store_Function)(
LV2_State_Handle handle,
uint32_t key,
const void* value,
size_t size,
uint32_t type,
uint32_t flags);
/**
A host-provided function to retrieve a property.
@param handle Must be the handle passed to LV2_State_Interface.restore().
@param key The key of the property to retrieve (URID).
@param size (Output) If non-NULL, set to the size of the restored value.
@param type (Output) If non-NULL, set to the type of the restored value.
@param flags (Output) If non-NULL, set to the flags for the restored value.
@return A pointer to the restored value (object), or NULL if no value
has been stored under @p key.
A callback of this type is passed by the host to
LV2_State_Interface.restore(). This callback is called repeatedly by the
plugin to retrieve any properties it requires to restore its state.
The returned value MUST remain valid until LV2_State_Interface.restore()
returns. The plugin MUST NOT attempt to use this function, or any value
returned from it, outside of the LV2_State_Interface.restore() context.
*/
typedef const void* (*LV2_State_Retrieve_Function)(
LV2_State_Handle handle,
uint32_t key,
size_t* size,
uint32_t* type,
uint32_t* flags);
/**
LV2 Plugin State Interface.
When the plugin's extension_data is called with argument
LV2_STATE__interface, the plugin MUST return an LV2_State_Interface
structure, which remains valid for the lifetime of the plugin.
The host can use the contained function pointers to save and restore the
state of a plugin instance at any time, provided the threading restrictions
of the functions are met.
Stored data is only guaranteed to be compatible between instances of plugins
with the same URI (i.e. if a change to a plugin would cause a fatal error
when restoring state saved by a previous version of that plugin, the plugin
URI MUST change just as it must when ports change incompatibly). Plugin
authors should consider this possibility, and always store sensible data
with meaningful types to avoid such problems in the future.
*/
typedef struct _LV2_State_Interface {
/**
Save plugin state using a host-provided @p store callback.
@param instance The instance handle of the plugin.
@param store The host-provided store callback.
@param handle An opaque pointer to host data which MUST be passed as the
handle parameter to @p store if it is called.
@param flags Flags describing desired properties of this save. These
flags may be used to determine the most appropriate values to store.
@param features Extensible parameter for passing any additional
features to be used for this save.
The plugin is expected to store everything necessary to completely
restore its state later. Plugins SHOULD store simple POD data whenever
possible, and consider the possibility of state being restored much
later on a different machine.
The @p handle pointer and @p store function MUST NOT be used
beyond the scope of save().
This function has its own special threading class: it may not be called
concurrently with any "Instantiation" function, but it may be called
concurrently with functions in any other class, unless the definition of
that class prohibits it (e.g. it may not be called concurrently with a
"Discovery" function, but it may be called concurrently with an "Audio"
function. The plugin is responsible for any locking or lock-free
techniques necessary to make this possible.
Note that in the simple case where state is only modified by restore(),
there are no synchronization issues since save() is never called
concurrently with restore() (though run() may read it during a save).
Plugins that dynamically modify state while running, however, must take
care to do so in such a way that a concurrent call to save() will save a
consistent representation of plugin state for a single instant in time.
*/
LV2_State_Status (*save)(LV2_Handle instance,
LV2_State_Store_Function store,
LV2_State_Handle handle,
uint32_t flags,
const LV2_Feature *const * features);
/**
Restore plugin state using a host-provided @p retrieve callback.
@param instance The instance handle of the plugin.
@param retrieve The host-provided retrieve callback.
@param handle An opaque pointer to host data which MUST be passed as the
handle parameter to @p retrieve if it is called.
@param flags Currently unused.
@param features Extensible parameter for passing any additional
features to be used for this restore.
The plugin MAY assume a restored value was set by a previous call to
LV2_State_Interface.save() by a plugin with the same URI.
The plugin MUST gracefully fall back to a default value when a value can
not be retrieved. This allows the host to reset the plugin state with
an empty map.
The @p handle pointer and @p store function MUST NOT be used
beyond the scope of restore().
This function is in the "Instantiation" threading class as defined by
LV2. This means it MUST NOT be called concurrently with any other
function on the same plugin instance.
*/
LV2_State_Status (*restore)(LV2_Handle instance,
LV2_State_Retrieve_Function retrieve,
LV2_State_Handle handle,
uint32_t flags,
const LV2_Feature *const * features);
} LV2_State_Interface;
/**
Feature data for state:mapPath (LV2_STATE__mapPath).
*/
typedef struct {
/**
Opaque host data.
*/
LV2_State_Map_Path_Handle handle;
/**
Map an absolute path to an abstract path for use in plugin state.
@param handle MUST be the @p handle member of this struct.
@param absolute_path The absolute path of a file.
@return An abstract path suitable for use in plugin state.
The plugin MUST use this function to map any paths that will be stored
in plugin state. The returned value is an abstract path which MAY not
be an actual file system path; @ref absolute_path() MUST be used to map
it to an actual path in order to use the file.
Plugins MUST NOT make any assumptions about abstract paths except that
they can be mapped back to the absolute path of the "same" file (though
not necessarily the same original path) using @ref absolute_path().
This function may only be called within the context of
LV2_State_Interface methods. The caller is responsible for freeing the
returned value with free().
*/
char* (*abstract_path)(LV2_State_Map_Path_Handle handle,
const char* absolute_path);
/**
Map an abstract path from plugin state to an absolute path.
@param handle MUST be the @p handle member of this struct.
@param abstract_path An abstract path (e.g. a path from plugin state).
@return An absolute file system path.
The plugin MUST use this function in order to actually open or otherwise
use any paths loaded from plugin state.
This function may only be called within the context of
LV2_State_Interface methods. The caller is responsible for freeing the
returned value with free().
*/
char* (*absolute_path)(LV2_State_Map_Path_Handle handle,
const char* abstract_path);
} LV2_State_Map_Path;
/**
Feature data for state:makePath (@ref LV2_STATE__makePath).
*/
typedef struct {
/**
Opaque host data.
*/
LV2_State_Make_Path_Handle handle;
/**
Return a path the plugin may use to create a new file.
@param handle MUST be the @p handle member of this struct.
@param path The path of the new file within a namespace unique to this
plugin instance.
@return The absolute path to use for the new file.
This function can be used by plugins to create files and directories,
either at state saving time (if this feature is passed to
LV2_State_Interface.save()) or any time (if this feature is passed to
LV2_Descriptor.instantiate()).
The host MUST do whatever is necessary for the plugin to be able to
create a file at the returned path (e.g. using fopen), including
creating any leading directories.
If this function is passed to LV2_Descriptor.instantiate(), it may be
called from any non-realtime context. If it is passed to
LV2_State_Interface.save(), it may only be called within the dynamic
scope of that function call.
The caller is responsible for freeing the returned value with free().
*/
char* (*path)(LV2_State_Make_Path_Handle handle,
const char* path);
} LV2_State_Make_Path;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV2_STATE_H */

View File

@ -1,88 +0,0 @@
/* lv2_uri_map.h - C header file for the LV2 URI Map extension.
*
* Copyright (C) 2008 David Robillard <d@drobilla.net>
*
* 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 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 header; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
*/
#ifndef LV2_URI_MAP_H
#define LV2_URI_MAP_H
#define LV2_URI_MAP_URI "http://lv2plug.in/ns/ext/uri-map"
#include <stdint.h>
/** @file
* This header defines the LV2 URI Map extension with the URI
* <http://lv2plug.in/ns/ext/uri-map> (preferred prefix 'lv2urimap').
*
* This extension defines a simple mechanism for plugins to map URIs to
* integers, usually for performance reasons (e.g. processing events
* typed by URIs in real time). The expected use case is for plugins to
* map URIs to integers for things they 'understand' at instantiation time,
* and store those values for use in the audio thread without doing any string
* comparison. This allows the extensibility of RDF with the performance of
* integers (or centrally defined enumerations).
*/
/** Opaque pointer to host data. */
typedef void* LV2_URI_Map_Callback_Data;
/** The data field of the LV2_Feature for this extension.
*
* To support this feature the host must pass an LV2_Feature struct to the
* plugin's instantiate method with URI "http://lv2plug.in/ns/ext/uri-map"
* and data pointed to an instance of this struct.
*/
typedef struct {
/** Opaque pointer to host data.
*
* The plugin MUST pass this to any call to functions in this struct.
* Otherwise, it must not be interpreted in any way.
*/
LV2_URI_Map_Callback_Data callback_data;
/** Get the numeric ID of a URI from the host.
*
* @param callback_data Must be the callback_data member of this struct.
* @param map The 'context' of this URI. Certain extensions may define a
* URI that must be passed here with certain restrictions on the
* return value (e.g. limited range). This value may be NULL if
* the plugin needs an ID for a URI in general.
* @param uri The URI to be mapped to an integer ID.
*
* This function is referentially transparent - any number of calls with
* the same arguments is guaranteed to return the same value over the life
* of a plugin instance (though the same URI may return different values
* with a different map parameter). However, this function is not
* necessarily very fast: plugins should cache any IDs they might need in
* performance critical situations.
* The return value 0 is reserved and means an ID for that URI could not
* be created for whatever reason. Extensions may define more precisely
* what this means, but in general plugins should gracefully handle 0
* and consider whatever they wanted the URI for "unsupported".
*/
uint32_t (*uri_to_id)(LV2_URI_Map_Callback_Data callback_data,
const char* map,
const char* uri);
} LV2_URI_Map_Feature;
#endif // LV2_URI_MAP_H

View File

@ -1,115 +0,0 @@
/*
Copyright 2011 Gabriel M. Beddingfield <gabrbedd@gmail.com>
Copyright 2008-2011 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.
*/
/**
@file
C header for the LV2 URID extension <http://lv2plug.in/ns/ext/urid>
*/
#ifndef LV2_URID_H
#define LV2_URID_H
#define LV2_URID_URI "http://lv2plug.in/ns/ext/urid"
#define LV2_URID_MAP_URI LV2_URID_URI "#map"
#define LV2_URID_UNMAP_URI LV2_URID_URI "#unmap"
#include <stdint.h>
/**
Opaque pointer to host data for LV2_URID_Map.
*/
typedef void* LV2_URID_Map_Handle;
/**
Opaque pointer to host data for LV2_URID_Unmap.
*/
typedef void* LV2_URID_Unmap_Handle;
/**
URI mapped to an integer.
*/
typedef uint32_t LV2_URID;
/**
URI Map (http://lv2plug.in/ns/ext/urid#map).
*/
typedef struct {
/**
Opaque pointer to host data.
This MUST be passed to map_uri() whenever it is called.
Otherwise, it must not be interpreted in any way.
*/
LV2_URID_Map_Handle handle;
/**
Get the numeric ID of a URI.
If the ID does not already exist, it will be created.
This function is referentially transparent; any number of calls with the
same arguments is guaranteed to return the same value over the life of a
plugin instance. Note, however, that several URIs MAY resolve to the
same ID if the host considers those URIs equivalent.
This function is not necessarily very fast or RT-safe: plugins SHOULD
cache any IDs they might need in performance critical situations.
The return value 0 is reserved and indicates that an ID for that URI
could not be created for whatever reason. However, hosts SHOULD NOT
return 0 from this function in non-exceptional circumstances (i.e. the
URI map SHOULD be dynamic).
@param handle Must be the callback_data member of this struct.
@param uri The URI to be mapped to an integer ID.
*/
LV2_URID (*map)(LV2_URID_Map_Handle handle,
const char* uri);
} LV2_URID_Map;
/**
URI Unmap (http://lv2plug.in/ns/ext/urid#unmap).
*/
typedef struct {
/**
Opaque pointer to host data.
This MUST be passed to unmap() whenever it is called.
Otherwise, it must not be interpreted in any way.
*/
LV2_URID_Unmap_Handle handle;
/**
Get the URI for a previously mapped numeric ID.
Returns NULL if @c urid is not yet mapped. Otherwise, the corresponding
URI is returned in a canonical form. This MAY not be the exact same
string that was originally passed to LV2_URID_Map::map(), but it MUST be
an identical URI according to the URI syntax specification (RFC3986). A
non-NULL return for a given @c urid will always be the same for the life
of the plugin. Plugins that intend to perform string comparison on
unmapped URIs SHOULD first canonicalise URI strings with a call to
map_uri() followed by a call to unmap_uri().
@param handle Must be the callback_data member of this struct.
@param urid The ID to be mapped back to the URI string.
*/
const char* (*unmap)(LV2_URID_Unmap_Handle handle,
LV2_URID urid);
} LV2_URID_Unmap;
#endif /* LV2_URID_H */

View File

@ -1,150 +0,0 @@
/*
Copyright 2012 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.
*/
/**
@file worker.h C header for the LV2 Worker extension
<http://lv2plug.in/ns/ext/worker>.
*/
#ifndef LV2_WORKER_H
#define LV2_WORKER_H
#include <stdint.h>
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#define LV2_WORKER_URI "http://lv2plug.in/ns/ext/worker"
#define LV2_WORKER_PREFIX LV2_WORKER_URI "#"
#define LV2_WORKER__interface LV2_WORKER_PREFIX "interface"
#define LV2_WORKER__schedule LV2_WORKER_PREFIX "schedule"
/**
A 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;
typedef void* LV2_Worker_Respond_Handle;
/**
A function to respond to run() from the worker method.
The @p 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);
/**
LV2 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 @p respond. The plugin MUST NOT
make any assumptions about which thread calls this method, other than
the fact that there are no real-time requirements.
@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 @p respond if it is called.
@param size The size of @p 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 @p 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;
typedef void* LV2_Worker_Schedule_Handle;
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 @p 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 @p 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;
#endif /* LV2_WORKER_H */

View File

@ -151,9 +151,7 @@ work_respond(LV2_Worker_Respond_Handle handle,
struct LV2Plugin::Impl {
Impl() : plugin(0), ui(0), ui_type(0), name(0), author(0), instance(0)
, work_iface(0)
#ifdef HAVE_NEW_LILV
, state(0)
#endif
{}
/** Find the LV2 input port with the given designation.
@ -168,9 +166,7 @@ struct LV2Plugin::Impl {
LilvNode* author;
LilvInstance* instance;
LV2_Worker_Interface* work_iface;
#ifdef HAVE_NEW_LILV
LilvState* state;
#endif
};
LV2Plugin::LV2Plugin (AudioEngine& engine,
@ -228,7 +224,6 @@ LV2Plugin::init(void* c_plugin, framecnt_t rate)
LilvPlugin* plugin = _impl->plugin;
#ifdef HAVE_NEW_LILV
LilvNode* state_iface_uri = lilv_new_uri(_world.world, LV2_STATE__interface);
LilvNode* state_uri = lilv_new_uri(_world.world, LV2_STATE_URI);
_has_state_interface =
@ -238,7 +233,6 @@ LV2Plugin::init(void* c_plugin, framecnt_t rate)
|| lilv_plugin_has_feature(plugin, state_uri);
lilv_node_free(state_uri);
lilv_node_free(state_iface_uri);
#endif
_features = (LV2_Feature**)malloc(sizeof(LV2_Feature*) * 8);
_features[0] = &_instance_access_feature;
@ -727,7 +721,6 @@ LV2Plugin::add_state(XMLNode* root) const
if (_has_state_interface) {
cout << "LV2 " << name() << " has state interface" << endl;
#ifdef HAVE_NEW_LILV
// Provisionally increment state version and create directory
const std::string new_dir = state_dir(++_state_version);
g_mkdir_with_parents(new_dir.c_str(), 0744);
@ -769,12 +762,6 @@ LV2Plugin::add_state(XMLNode* root) const
}
root->add_property("state-dir", string_compose("state%1", _state_version));
#else /* !HAVE_NEW_LILV */
warning << string_compose(
_("Plugin \"%1\" has state, but Lilv is too old to save it"),
unique_id()) << endmsg;
#endif /* HAVE_NEW_LILV */
} else {
cout << "LV2 " << name() << " has no state interface." << endl;
}
@ -790,7 +777,6 @@ get_value(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate)
void
LV2Plugin::find_presets()
{
#ifdef HAVE_NEW_LILV
LilvNode* lv2_appliesTo = lilv_new_uri(_world.world, LILV_NS_LV2 "appliesTo");
LilvNode* pset_Preset = lilv_new_uri(_world.world, NS_PSET "Preset");
LilvNode* rdfs_label = lilv_new_uri(_world.world, LILV_NS_RDFS "label");
@ -817,7 +803,6 @@ LV2Plugin::find_presets()
lilv_node_free(rdfs_label);
lilv_node_free(pset_Preset);
lilv_node_free(lv2_appliesTo);
#endif /* HAVE_NEW_LILV */
}
bool
@ -1037,7 +1022,6 @@ LV2Plugin::set_state(const XMLNode& node, int version)
set_parameter(port_id, atof(value));
}
#ifdef HAVE_NEW_LILV
_state_version = 0;
if ((prop = node.property("state-dir")) != 0) {
if (sscanf(prop->value().c_str(), "state%u", &_state_version) != 1) {
@ -1056,7 +1040,6 @@ LV2Plugin::set_state(const XMLNode& node, int version)
lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
}
#endif
latency_compute_run();
@ -1451,8 +1434,7 @@ LV2Plugin::latency_compute_run()
LilvPort*
LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** bufptr)
{
LilvPort* port = NULL;
#ifdef HAVE_NEW_LILV
LilvPort* port = NULL;
LilvNode* designation = lilv_new_uri(_world.world, uri);
port = lilv_plugin_get_port_by_designation(
plugin, _world.lv2_InputPort, designation);
@ -1460,7 +1442,6 @@ LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** buf
if (port) {
bufptrs[lilv_port_get_index(plugin, port)] = bufptr;
}
#endif
return port;
}

View File

@ -257,14 +257,10 @@ def configure(conf):
atleast_version='2.0')
if Options.options.lv2:
autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV',
atleast_version='0.0.0', mandatory=False)
autowaf.check_pkg(conf, 'lilv-0', uselib_store='NEW_LILV',
atleast_version='0.14.0', mandatory=False)
if conf.is_defined('HAVE_LILV'):
autowaf.check_pkg(conf, 'suil-0', uselib_store='SUIL',
atleast_version='0.2.0', mandatory=False)
autowaf.check_pkg(conf, 'suil-0', uselib_store='NEW_SUIL',
atleast_version='0.5.0', mandatory=False)
atleast_version='0.6.0', mandatory=False)
# autowaf.check_pkg(conf, 'soundtouch-1.0', uselib_store='SOUNDTOUCH',
# mandatory=False)

View File

@ -643,7 +643,6 @@ const char* const ardour_config_info = "\\n\\
write_config_text('JACK session support', conf.is_defined('JACK_SESSION'))
write_config_text('LV2 UI embedding', conf.is_defined('HAVE_SUIL'))
write_config_text('LV2 support', conf.is_defined('LV2_SUPPORT'))
write_config_text('LV2 state support', conf.is_defined('HAVE_NEW_LILV'))
write_config_text('LXVST support', conf.is_defined('LXVST_SUPPORT'))
write_config_text('OGG', conf.is_defined('HAVE_OGG'))
write_config_text('Phone home', conf.is_defined('PHONE_HOME'))