aboutsummaryrefslogtreecommitdiffstats
path: root/ns/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ns/ext')
-rw-r--r--ns/ext/atom/atom-buffer.h163
-rw-r--r--ns/ext/atom/atom-helpers.h174
-rw-r--r--ns/ext/atom/atom.h248
-rw-r--r--ns/ext/atom/atom.ttl436
l---------ns/ext/atom/ext.pc.in1
-rw-r--r--ns/ext/atom/forge.h75
-rw-r--r--ns/ext/atom/manifest.ttl9
l---------ns/ext/atom/waf1
l---------ns/ext/atom/wscript1
-rw-r--r--ns/ext/contexts/contexts.h82
-rw-r--r--ns/ext/contexts/contexts.ttl134
l---------ns/ext/contexts/ext.pc.in1
-rw-r--r--ns/ext/contexts/manifest.ttl9
-rw-r--r--ns/ext/contexts/test.c67
l---------ns/ext/contexts/waf1
l---------ns/ext/contexts/wscript1
-rw-r--r--ns/ext/cv-port/cv-port.ttl77
l---------ns/ext/cv-port/ext.pc.in1
-rw-r--r--ns/ext/cv-port/manifest.ttl9
l---------ns/ext/cv-port/waf1
l---------ns/ext/cv-port/wscript1
-rw-r--r--ns/ext/data-access/data-access.h56
-rw-r--r--ns/ext/data-access/data-access.ttl82
l---------ns/ext/data-access/ext.pc.in1
-rw-r--r--ns/ext/data-access/manifest.ttl9
l---------ns/ext/data-access/waf1
l---------ns/ext/data-access/wscript1
-rw-r--r--ns/ext/dynmanifest/dynmanifest.h144
-rw-r--r--ns/ext/dynmanifest/dynmanifest.ttl122
l---------ns/ext/dynmanifest/ext.pc.in1
-rw-r--r--ns/ext/dynmanifest/lv2-dynmanifest.doap.ttl43
-rw-r--r--ns/ext/dynmanifest/manifest.ttl9
l---------ns/ext/dynmanifest/waf1
l---------ns/ext/dynmanifest/wscript1
-rw-r--r--ns/ext/event/event-helpers.h246
-rw-r--r--ns/ext/event/event.h281
-rw-r--r--ns/ext/event/event.ttl194
l---------ns/ext/event/ext.pc.in1
-rw-r--r--ns/ext/event/manifest.ttl9
l---------ns/ext/event/waf1
l---------ns/ext/event/wscript1
l---------ns/ext/files/ext.pc.in1
-rw-r--r--ns/ext/files/files.h134
-rw-r--r--ns/ext/files/files.ttl115
-rw-r--r--ns/ext/files/manifest.ttl9
l---------ns/ext/files/waf1
l---------ns/ext/files/wscript1
l---------ns/ext/host-info/ext.pc.in1
-rw-r--r--ns/ext/host-info/host-info.ttl118
-rw-r--r--ns/ext/host-info/manifest.ttl9
l---------ns/ext/host-info/waf1
l---------ns/ext/host-info/wscript1
l---------ns/ext/instance-access/ext.pc.in1
-rw-r--r--ns/ext/instance-access/instance-access.h38
-rw-r--r--ns/ext/instance-access/instance-access.ttl80
-rw-r--r--ns/ext/instance-access/manifest.ttl9
l---------ns/ext/instance-access/waf1
l---------ns/ext/instance-access/wscript1
l---------ns/ext/midi/ext.pc.in1
-rw-r--r--ns/ext/midi/manifest.ttl9
-rw-r--r--ns/ext/midi/midi.ttl115
l---------ns/ext/midi/waf1
l---------ns/ext/midi/wscript1
l---------ns/ext/osc/ext.pc.in1
-rw-r--r--ns/ext/osc/lv2_osc.c238
-rw-r--r--ns/ext/osc/lv2_osc_print.c66
-rw-r--r--ns/ext/osc/lv2_osc_test.c55
-rw-r--r--ns/ext/osc/manifest.ttl9
-rw-r--r--ns/ext/osc/osc-print.h42
-rw-r--r--ns/ext/osc/osc.h119
-rw-r--r--ns/ext/osc/osc.ttl39
l---------ns/ext/osc/waf1
l---------ns/ext/osc/wscript1
l---------ns/ext/parameter/ext.pc.in1
-rw-r--r--ns/ext/parameter/manifest.ttl9
-rw-r--r--ns/ext/parameter/parameter.ttl111
l---------ns/ext/parameter/waf1
l---------ns/ext/parameter/wscript1
l---------ns/ext/port-groups/ext.pc.in1
-rw-r--r--ns/ext/port-groups/manifest.ttl9
-rw-r--r--ns/ext/port-groups/port-groups.ttl490
l---------ns/ext/port-groups/waf1
l---------ns/ext/port-groups/wscript1
l---------ns/ext/port-props/ext.pc.in1
-rw-r--r--ns/ext/port-props/manifest.ttl8
-rw-r--r--ns/ext/port-props/port-props.ttl217
l---------ns/ext/port-props/waf1
l---------ns/ext/port-props/wscript1
l---------ns/ext/presets/ext.pc.in1
-rw-r--r--ns/ext/presets/manifest.ttl9
-rw-r--r--ns/ext/presets/presets.ttl113
l---------ns/ext/presets/waf1
l---------ns/ext/presets/wscript1
l---------ns/ext/pui/ext.pc.in1
-rw-r--r--ns/ext/pui/manifest.ttl8
-rw-r--r--ns/ext/pui/pui.h374
-rw-r--r--ns/ext/pui/pui.ttl282
l---------ns/ext/pui/waf1
l---------ns/ext/pui/wscript1
l---------ns/ext/reference/ext.pc.in1
-rw-r--r--ns/ext/reference/manifest.ttl9
-rw-r--r--ns/ext/reference/reference.h161
-rw-r--r--ns/ext/reference/reference.ttl82
l---------ns/ext/reference/waf1
l---------ns/ext/reference/wscript1
l---------ns/ext/resize-port/ext.pc.in1
-rw-r--r--ns/ext/resize-port/manifest.ttl9
-rw-r--r--ns/ext/resize-port/resize-port.h57
-rw-r--r--ns/ext/resize-port/resize-port.ttl80
l---------ns/ext/resize-port/waf1
l---------ns/ext/resize-port/wscript1
l---------ns/ext/state/ext.pc.in1
-rw-r--r--ns/ext/state/manifest.ttl9
-rw-r--r--ns/ext/state/state.h258
-rw-r--r--ns/ext/state/state.ttl231
l---------ns/ext/state/waf1
l---------ns/ext/state/wscript1
l---------ns/ext/string-port/ext.pc.in1
-rw-r--r--ns/ext/string-port/manifest.ttl8
-rw-r--r--ns/ext/string-port/string-port.h58
-rw-r--r--ns/ext/string-port/string-port.ttl105
l---------ns/ext/string-port/waf1
l---------ns/ext/string-port/wscript1
l---------ns/ext/time/ext.pc.in1
-rw-r--r--ns/ext/time/manifest.ttl9
-rw-r--r--ns/ext/time/time.h131
-rw-r--r--ns/ext/time/time.ttl57
l---------ns/ext/time/waf1
l---------ns/ext/time/wscript1
l---------ns/ext/ui-resize/ext.pc.in1
-rw-r--r--ns/ext/ui-resize/manifest.ttl9
-rw-r--r--ns/ext/ui-resize/ui-resize.h58
-rw-r--r--ns/ext/ui-resize/ui-resize.ttl43
l---------ns/ext/ui-resize/waf1
l---------ns/ext/ui-resize/wscript1
l---------ns/ext/uri-map/ext.pc.in1
-rw-r--r--ns/ext/uri-map/manifest.ttl8
-rw-r--r--ns/ext/uri-map/uri-map.h92
-rw-r--r--ns/ext/uri-map/uri-map.ttl57
l---------ns/ext/uri-map/waf1
l---------ns/ext/uri-map/wscript1
l---------ns/ext/uri-unmap/ext.pc.in1
-rw-r--r--ns/ext/uri-unmap/manifest.ttl8
-rw-r--r--ns/ext/uri-unmap/uri-unmap.h81
-rw-r--r--ns/ext/uri-unmap/uri-unmap.ttl46
l---------ns/ext/uri-unmap/waf1
l---------ns/ext/uri-unmap/wscript1
l---------ns/ext/urid/ext.pc.in1
-rw-r--r--ns/ext/urid/manifest.ttl9
-rw-r--r--ns/ext/urid/urid.h113
-rw-r--r--ns/ext/urid/urid.ttl67
l---------ns/ext/urid/waf1
l---------ns/ext/urid/wscript1
153 files changed, 7442 insertions, 0 deletions
diff --git a/ns/ext/atom/atom-buffer.h b/ns/ext/atom/atom-buffer.h
new file mode 100644
index 0000000..f4b90dd
--- /dev/null
+++ b/ns/ext/atom/atom-buffer.h
@@ -0,0 +1,163 @@
+/*
+ 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 atom-event-buffer.h Helper functions for atom:EventBuffer.
+
+ Note that these functions are all static inline which basically means:
+ do not take the address of these functions.
+*/
+
+#ifndef LV2_ATOM_EVENT_BUFFER_H
+#define LV2_ATOM_EVENT_BUFFER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+
+/**
+ Initialize an existing atom buffer.
+ All fields of @c buf are reset, except capacity which is unmodified.
+*/
+static inline void
+lv2_atom_buffer_reset(LV2_Atom_Buffer* buf)
+{
+ buf->event_count = 0;
+ buf->size = 0;
+}
+
+/**
+ Allocate a new, empty atom buffer.
+*/
+static inline LV2_Atom_Buffer*
+lv2_atom_buffer_new(uint32_t capacity)
+{
+ const uint32_t size = sizeof(LV2_Atom_Buffer) + capacity;
+ LV2_Atom_Buffer* buf = (LV2_Atom_Buffer*)malloc(size);
+ if (buf) {
+ buf->data = (uint8_t*)(buf + 1);
+ buf->capacity = capacity;
+ lv2_atom_buffer_reset(buf);
+ }
+ return buf;
+}
+
+/**
+ Free an atom buffer allocated with lv2_atom_buffer_new().
+*/
+static inline void
+lv2_atom_buffer_free(LV2_Atom_Buffer* buf)
+{
+ free(buf);
+}
+
+/**
+ An iterator over an LV2_Atom_Buffer.
+*/
+typedef struct {
+ LV2_Atom_Buffer* buf;
+ uint32_t offset;
+} LV2_Atom_Buffer_Iterator;
+
+/**
+ Return an iterator to the beginning of @c buf.
+*/
+static inline LV2_Atom_Buffer_Iterator
+lv2_atom_buffer_begin(LV2_Atom_Buffer* buf)
+{
+ const LV2_Atom_Buffer_Iterator i = { buf, 0 };
+ return i;
+}
+
+/**
+ Return true iff @c i points to a valid atom.
+*/
+static inline bool
+lv2_atom_buffer_is_valid(LV2_Atom_Buffer_Iterator i)
+{
+ return i.offset < i.buf->size;
+}
+
+/**
+ Return the iterator to the next element after @c i.
+ @param i A valid iterator to an atom in a buffer.
+*/
+static inline LV2_Atom_Buffer_Iterator
+lv2_atom_buffer_next(LV2_Atom_Buffer_Iterator i)
+{
+ if (!lv2_atom_buffer_is_valid(i)) {
+ return i;
+ }
+ const LV2_Atom_Event* const ev = (LV2_Atom_Event*)(i.buf->data + i.offset);
+ i.offset += lv2_atom_pad_size(sizeof(LV2_Atom_Event) + ev->body.size);
+ return i;
+}
+
+/**
+ Return a pointer to the atom currently pointed to by @c i.
+*/
+static inline LV2_Atom_Event*
+lv2_atom_buffer_get(LV2_Atom_Buffer_Iterator i)
+{
+ if (!lv2_atom_buffer_is_valid(i)) {
+ return NULL;
+ }
+ return (LV2_Atom_Event*)(i.buf->data + i.offset);
+}
+
+/**
+ Write an atom to a buffer.
+
+ The atom will be written at the location pointed to by @c i, which will be
+ incremented to point to the location where the next atom should be written
+ (which is likely now garbage). Thus, this function can be called repeatedly
+ with a single @c i to write a sequence of atoms to the buffer.
+
+ @return True if atom was written, otherwise false (buffer is full).
+*/
+static inline bool
+lv2_atom_buffer_write(LV2_Atom_Buffer_Iterator* i,
+ uint32_t frames,
+ uint32_t subframes,
+ uint32_t type,
+ uint32_t size,
+ const uint8_t* data)
+{
+ const uint32_t free_space = i->buf->capacity - i->buf->size;
+ if (free_space < sizeof(LV2_Atom_Event) + size) {
+ return false;
+ }
+
+ LV2_Atom_Event* const ev = (LV2_Atom_Event*)(i->buf->data + i->offset);
+
+ ev->frames = frames;
+ ev->subframes = subframes;
+ ev->body.type = type;
+ ev->body.size = size;
+ memcpy((uint8_t*)ev + sizeof(LV2_Atom_Event), data, size);
+ ++i->buf->event_count;
+
+ size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + size);
+ i->buf->size += size;
+ i->offset += size;
+
+ return true;
+}
+
+#endif /* LV2_ATOM_EVENT_BUFFER_H */
diff --git a/ns/ext/atom/atom-helpers.h b/ns/ext/atom/atom-helpers.h
new file mode 100644
index 0000000..4e51c89
--- /dev/null
+++ b/ns/ext/atom/atom-helpers.h
@@ -0,0 +1,174 @@
+/*
+ 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 atom-helpers.h Helper functions for the LV2 Atom extension.
+
+ These functions are provided for convenience only, use of them is not
+ required for supporting atoms.
+
+ Note that these functions are all static inline which basically means:
+ do not take the address of these functions.
+*/
+
+#ifndef LV2_ATOM_HELPERS_H
+#define LV2_ATOM_HELPERS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+
+typedef LV2_Atom_Property* LV2_Thing_Iter;
+
+/** Get an iterator pointing to @c prop in some LV2_Thing */
+static inline LV2_Thing_Iter
+lv2_thing_begin(const LV2_Thing* obj)
+{
+ return (LV2_Thing_Iter)(obj->properties);
+}
+
+/** Return true iff @c iter has reached the end of @c thing */
+static inline bool
+lv2_thing_iter_is_end(const LV2_Thing* obj, LV2_Thing_Iter iter)
+{
+ return (uint8_t*)iter >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->size);
+}
+
+/** Return true iff @c l points to the same property as @c r */
+static inline bool
+lv2_thing_iter_equals(const LV2_Thing_Iter l, const LV2_Thing_Iter r)
+{
+ return l == r;
+}
+
+/** Return an iterator to the property following @c iter */
+static inline LV2_Thing_Iter
+lv2_thing_iter_next(const LV2_Thing_Iter iter)
+{
+ return (LV2_Thing_Iter)((uint8_t*)iter
+ + sizeof(LV2_Atom_Property)
+ + lv2_atom_pad_size(iter->value.size));
+}
+
+/** Return the property pointed to by @c iter */
+static inline LV2_Atom_Property*
+lv2_thing_iter_get(LV2_Thing_Iter iter)
+{
+ return (LV2_Atom_Property*)iter;
+}
+
+/**
+ A macro for iterating over all properties of an Thing.
+ @param thing The thing 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.:
+ <pre>
+ LV2_THING_FOREACH(thing, i) {
+ LV2_Atom_Property* prop = lv2_thing_iter_get(i);
+ // Do things with prop here...
+ }
+ </pre>
+*/
+#define LV2_THING_FOREACH(thing, iter) \
+ for (LV2_Thing_Iter (iter) = lv2_thing_begin(thing); \
+ !lv2_thing_iter_is_end(thing, (iter)); \
+ (iter) = lv2_thing_iter_next(iter))
+
+/**
+ Append a Property body to an Atom that contains properties (e.g. atom:Thing).
+ @param thing Pointer to the atom that contains the property to add. thing.size
+ must be valid, but thing.type is ignored.
+ @param key The key of the new property
+ @param value_type The type of the new value
+ @param value_size The size of the new value
+ @param value_body Pointer to the new value's data
+ @return a pointer to the new LV2_Atom_Property in @c body.
+
+ This function will write the property body (not including an LV2_Thing
+ header) at lv2_atom_pad_size(body + size). Thus, it can be used with any
+ Atom type that contains headerless 32-bit aligned properties.
+*/
+static inline LV2_Atom_Property*
+lv2_thing_append(LV2_Thing* thing,
+ uint32_t key,
+ uint32_t value_type,
+ uint32_t value_size,
+ const void* value_body)
+{
+ thing->size = lv2_atom_pad_size(thing->size);
+ LV2_Atom_Property* prop = (LV2_Atom_Property*)(
+ (uint8_t*)thing + sizeof(LV2_Atom) + thing->size);
+ prop->key = key;
+ prop->value.type = value_type;
+ prop->value.size = value_size;
+ memcpy(prop->value.body, value_body, value_size);
+ thing->size += sizeof(LV2_Atom_Property) + value_size;
+ return prop;
+}
+
+/** Return true iff @c atom is NULL */
+static inline bool
+lv2_atom_is_null(LV2_Atom* atom)
+{
+ return !atom || (atom->type == 0 && atom->size == 0);
+}
+
+/** A single entry in an Thing 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_Thing_Query;
+
+static const LV2_Thing_Query LV2_THING_QUERY_END = { 0, NULL };
+
+/**
+ "Query" an thing, getting a pointer to the values for various keys.
+
+ The value pointer of each item in @c query will be set to the location of
+ the corresponding value in @c thing. Every value pointer in @c query MUST
+ be initialised to NULL. This function reads @c thing in a single linear
+ sweep. By allocating @c query on the stack, things can be "queried"
+ quickly without allocating any memory. This function is realtime safe.
+*/
+static inline int
+lv2_thing_query(const LV2_Thing* thing, LV2_Thing_Query* query)
+{
+ int matches = 0;
+ int n_queries = 0;
+
+ /* Count number of query keys so we can short-circuit when done */
+ for (LV2_Thing_Query* q = query; q->key; ++q)
+ ++n_queries;
+
+ LV2_THING_FOREACH(thing, o) {
+ const LV2_Atom_Property* prop = lv2_thing_iter_get(o);
+ for (LV2_Thing_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;
+}
+
+#endif /* LV2_ATOM_HELPERS_H */
diff --git a/ns/ext/atom/atom.h b/ns/ext/atom/atom.h
new file mode 100644
index 0000000..39d721c
--- /dev/null
+++ b/ns/ext/atom/atom.h
@@ -0,0 +1,248 @@
+/*
+ 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 atom.h C header for the LV2 Atom extension
+ <http://lv2plug.in/ns/ext/atom>.
+
+ This header describes the binary layout of various types defined in the
+ atom extension.
+*/
+
+#ifndef LV2_ATOM_H
+#define LV2_ATOM_H
+
+#define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom"
+
+#define LV2_ATOM_REFERENCE_TYPE 0
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ An LV2 Atom.
+
+ An "Atom" is a generic chunk of memory with a given type and size.
+ The type field defines how to interpret an atom.
+
+ All atoms are by definition Plain Old Data (POD) and may be safely copied
+ (e.g. with memcpy) using the size field, except atoms with type 0. An atom
+ with type 0 is a reference, and may only be used via the functions provided
+ in LV2_Blob_Support (e.g. it MUST NOT be manually copied).
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint8_t body[]; /**< Body of length @ref size bytes. */
+} LV2_Atom;
+
+/**
+ An atom:String.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding. */
+} LV2_Atom_String;
+
+/**
+ An atom:Literal.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t datatype; /**< The ID of the datatype of this literal. */
+ uint32_t lang; /**< The ID of the language of this literal. */
+ uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding. */
+} LV2_Atom_Literal;
+
+/**
+ An atom:URID or atom:BlankID.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t id; /**< URID (integer mapped URI) or blank node ID. */
+} LV2_Atom_ID;
+
+/**
+ An atom:Vector.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t elem_count; /**< The number of elements in the vector */
+ uint32_t elem_type; /**< The type of each element in the vector */
+ uint8_t elems[]; /**< Sequence of element bodies */
+} LV2_Atom_Vector;
+
+/**
+ The body of an atom:Property.
+ Note this type is not an LV2_Atom.
+*/
+typedef struct _LV2_Atom_Property {
+ uint32_t key; /**< Key (predicate) (mapped URI). */
+ LV2_Atom value; /**< Value (object) */
+} LV2_Atom_Property;
+
+/**
+ An atom:Thing (Resource, Blank, or Message).
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t context; /**< ID of context graph, or 0 for default */
+ uint32_t id; /**< URID (for Resource) or blank ID (for Blank) */
+ uint8_t properties[]; /**< Sequence of LV2_Atom_Property */
+} LV2_Thing;
+
+/**
+ An atom:Event, a timestamped Atom.
+ Note this type is not an LV2_Atom, but contains an Atom as payload.
+*/
+typedef struct {
+ uint32_t frames; /**< Time in frames relative to this block. */
+ uint32_t subframes; /**< Fractional time in 1/(2^32)ths of a frame. */
+ LV2_Atom body; /**< Event body. */
+} LV2_Atom_Event;
+
+/**
+ An atom:Int32, a signed 32-bit integer.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type;
+ uint32_t size;
+ int32_t value;
+} LV2_Atom_Int32;
+
+/**
+ An atom:Int64, a signed 64-bit integer.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type;
+ uint32_t size;
+ int64_t value;
+} LV2_Atom_Int64;
+
+/**
+ An atom:Float, a 32-bit IEEE-754 floating point number.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type;
+ uint32_t size;
+ float value;
+} LV2_Atom_Float;
+
+/**
+ An atom:Double, a 64-bit IEEE-754 floating point number.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type;
+ uint32_t size;
+ double value;
+} LV2_Atom_Double;
+
+/**
+ A buffer of events (the contents of an atom:EventPort).
+
+ The host MAY elect to allocate buffers as a single chunk of POD by using
+ this struct as a header much like LV2_Atom, or it may choose to point to
+ a fragment of a buffer elsewhere. In either case, @ref data points to the
+ start of the data contained in this buffer.
+
+ The buffer at @ref data contains a sequence of LV2_Atom_Event padded such
+ that the start of each event is aligned to 64 bits, e.g.:
+ <pre>
+ | Event 1 (size 6) | Event 2
+ | | | | | | | | |
+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ |FRAMES |SUBFRMS|TYPE |SIZE |DATADATADATAPAD|FRAMES |SUBFRMS|...
+ </pre>
+*/
+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 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 capacity 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_Atom_Buffer;
+
+/**
+ Pad a size to 64 bits.
+*/
+static inline uint32_t
+lv2_atom_pad_size(uint32_t size)
+{
+ return (size + 7) & (~7);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_ATOM_H */
diff --git a/ns/ext/atom/atom.ttl b/ns/ext/atom/atom.ttl
new file mode 100644
index 0000000..0ef3b34
--- /dev/null
+++ b/ns/ext/atom/atom.ttl
@@ -0,0 +1,436 @@
+# LV2 Atom Extension
+# Copyright 2007-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+
+<http://lv2plug.in/ns/ext/atom>
+ a lv2:Specification ;
+ doap:name "LV2 Atom" ;
+ doap:shortdesc "A generic value container and several data types." ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ rdfs:seeAlso <atom-buffer.h> ;
+ doap:release [
+ doap:revision "0.2" ;
+ doap:created "2011-11-05"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension defines a generic format for a typed piece of data, called an
+lv2:Atom (e.g. integers, strings, buffers, data structures,
+etc). Atoms allow LV2 plugins and hosts to communicate, process, serialise,
+and store values of any type via a generic mechanism (e.g. LV2 ports, events,
+disk, shared memory, network). Atoms are, with one exception, Plain
+Old Data (POD) and may be safely copied (e.g. with a simple call to
+<code>memcpy</code>).</p>
+
+<p>Since Atom communication can be implemented generically, plugins that
+understand some type can be used together in a host that does not understand
+that type, and plugins (e.g. routers, delays) can process atoms of unknown
+type.</p>
+
+<p>An Atom can be trivially constructed in-place from an
+<a href="http://lv2plug.in/ns/ext/event#Event">Event</a> as defined by the
+<a href="http://lv2plug.in/ns/ext/event">LV2 Event</a> extension. In other
+words, an Event is simply an Atom with a time stamp header. Atoms SHOULD
+be used anywhere a "value" needs to be stored or communicated, to allow
+implementations to be polymorphic and extensible.</p>
+
+<p>Atoms (the start of the LV2_Atom header) MUST be 32-bit aligned.</p>
+
+<p>Atoms can be communicated in many ways. Since an Atom is the payload of an
+Event, an <a href="http://lv2plug.in/ns/ext/event#EventPort">EventPort</a> can
+be used for communicating Atoms in realtime with sub-sample time stamp
+accuracy. This extension also defines two port types for connecting directly
+to a single Atom: atom:ValuePort and atom:MessagePort, which both have the same
+buffer format but different semantics (with respect to how the run() callback
+interprets the Atom).</p>
+
+<p>Implementing this extension requires a facility for mapping URIs to
+integers, such as the <a href="http://lv2plug.in/ns/ext/urid">LV2 URID</a>
+extension.</p>
+""" .
+
+atom:Atom
+ a rdfs:Class ;
+ rdfs:label "Atom" ;
+ atom:cType "LV2_Atom" ;
+ lv2:documentation """
+<p>Abstract base class for all atoms. An LV2_Atom has a 32-bit
+<code>type</code> and <code>size</code> followed by a <code>body</code> of
+<code>size</code> bytes.</p>
+
+<p>All concrete Atom types (subclasses of this class) MUST define a precise
+binary layout for <code>body</code>.</p>
+
+<p>The <code>type</code> field is the URI of a subclass of Atom mapped to an
+integer using the <a href="http://lv2plug.in/ns/ext/uri-map">URI Map</a>
+extension's LV2_URI_Map_Feature::uri_to_id() with
+<code>map = "http://lv2plug.in/ns/ext/event"</code>. If a plugin or host
+does not understand <code>type</code>, that atom SHOULD be gracefully ignored
+(or copied if it does not have type 0).</p>
+
+<p>All atoms are POD by definition except references, which as a special case
+have <code>type = 0</code>. An Atom MUST NOT contain a Reference. It is safe
+to copy any non-reference Atom with a simple <code>memcpy</code>, even if the
+implementation does not understand <code>type</code>. Though this extension reserves
+the type 0 for references, actual specification of how references are used is left
+to another extension.</p>
+""" .
+
+atom:String
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "String" ;
+ atom:cType "LV2_Atom_String" ;
+ lv2:documentation """
+<p>A UTF-8 encoded string.</p>
+
+<p>The body of an LV2_Atom_String is a C string in UTF-8 encoding, i.e. an
+array of bytes (<code>uint8_t</code>) terminated with a NULL byte
+(<code>'\\0'</code>).</p>
+
+<p>This type can be used for free-form strings, but in most cases it is better to
+use atom:Literal since this supports a language tag or datatype. Implementations
+SHOULD NOT use atom:String unless translating the string does not make sense and
+the string has no meaningful datatype.</p>
+""" .
+
+atom:Literal
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "String Literal" ;
+ atom:cType "LV2_Atom_Literal" ;
+ lv2:documentation """
+<p>A UTF-8 encoded string literal, with an optional datatype or language.</p>
+
+<p>This type is compatible with rdf:Literal and is capable of expressing a
+string in any language, or a value of any type. A Literal has a
+<code>datatype</code> and <code>lang</code> followed by string data in UTF-8
+encoding. The length of the string data in bytes is <code>size -
+sizeof(LV2_Atom_Literal)</code>, including the terminating NULL character. The
+<code>lang</code> field SHOULD be a URI of the form
+&lt;http://lexvo.org/id/term/LANG&gt; where LANG is an <a
+href="http://www.loc.gov/standards/iso639-2/">ISO 693-2</a> or <a
+href="http://www.loc.gov/standards/iso639-2/">ISO 693-3</a> language code.</p>
+
+<p>For compatibility, a Literal MUST have either a <code>datatype</code>
+or a <code>lang</code>, but never both.</p>
+
+<p>For example, a Literal can be "Hello" in English:</p>
+<pre class="c-code">
+void set_to_hello_in_english(LV2_Atom_Literal* lit) {
+ lit->type = map(expand("atom:Literal"));
+ lit->size = 14;
+ lit->datatype = 0;
+ lit->lang = map("http://lexvo.org/id/term/en");
+ memcpy(lit->str, "Hello", sizeof("Hello")); // Assumes enough space
+}
+</pre>
+
+<p>or a Turtle string:</p>
+<pre class="c-code">
+void set_to_turtle_string(LV2_Atom_Literal* lit, const char* ttl) {
+ lit->type = map(expand("atom:Literal"));
+ lit->size = 64;
+ lit->datatype = map("http://www.w3.org/2008/turtle#turtle");
+ lit->lang = 0;
+ memcpy(lit->str, ttl, strlen(ttl) + 1); // Assumes enough space
+}
+</pre>
+""" .
+
+atom:URID
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Integer ID mapped from a URI" ;
+ atom:cType "LV2_Atom_ID" ;
+ lv2:documentation """
+<p>An unsigned 32-bit integer mapped from a URI using the <a
+href="http://lv2plug.in/ns/ext/uri-map">URI Map</a> extension's
+LV2_URI_Map_Feature::uri_to_id() with <code>map = NULL</code>.</p>
+""" .
+
+atom:BlankID
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Integer ID for a blank node" ;
+ atom:cType "LV2_Atom_ID" ;
+ lv2:documentation """
+<p>An unsigned 32-bit integer identifier for a blank node. A BlankID is only
+meaningful within a limited scope (e.g. the Atom in which it appears), and
+MUST NOT be used as a global identifier. In particular, a BlankID is NOT a
+URID, and can not be mapped to/from a URI.</p>
+""" .
+
+atom:Vector
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Vector" ;
+ atom:cType "LV2_Atom_Vector" ;
+ lv2:documentation """
+<p>A homogeneous sequence of atoms with equivalent type and size.</p>
+
+<p>An LV2_Atom_Vector is a 32-bit <code>elem_count</code> and
+<code>elem_type</code> followed by <code>elem_count</code> atom bodies of type
+<code>elem_type</code>. The element type must be a fixed size atom:Atom type,
+i.e. the size of each element is the vector's <code>size /
+elem_count</code>.</p>
+
+<p>For example, an atom:Vector containing 42 elements of type atom:Float:</p>
+<pre class="c-code">
+struct VectorOf42Floats {
+ uint32_t type; // map(expand("atom:Vector"))
+ uint32_t size; // sizeof(LV2_Atom_Vector) + (42 * sizeof(float);
+ uint32_t elem_count; // 42
+ uint32_t elem_type; // map(expand("atom:Float"))
+ float elems[32];
+};
+</pre>
+
+<p>Note that it is possible to construct a valid Atom for each element
+of the vector, even by an implementation which does not understand
+<code>elem_type</code>.</p>
+""" .
+
+atom:Tuple
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Tuple" ;
+ lv2:documentation """
+<p>A sequence of lv2:Atom with varying <code>type</code>
+and <code>size</code>.</p>
+
+<p>The body of a Tuple is simply a sequence of complete atoms, each aligned to
+32 bits.</p>
+""" .
+
+atom:Thing
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Thing" ;
+ atom:cType "LV2_Thing" ;
+ lv2:documentation """
+<p>Abstract base class for a "Thing", i.e. an atom:Atom with a
+number of <a href="#Property">properties</a>. An LV2_Object is an unsigned
+32-bit integer <code>context</code> and <code>id</code> followed by a sequence
+of LV2_Atom_Property .</p>
+
+<p>The <code>context</code> is mapped using the <a
+href="http://lv2plug.in/ns/ext/uri-map">URI Map</a> extension's
+LV2_URI_Map_Feature::uri_to_id() with <code>map = NULL</code>, and may be 0
+(the default context).</p>
+
+<p>Note this is an abstract class, i.e. no Atom can exist with <code>type =
+uri_to_id(atom:Thing)</code>. An Object is either an atom:Resource or an
+atom:Blank, but the <code>body</code> always has the same binary format,
+LV2_Object. Thus, both named and anonymous objects can be handled with common
+code using only a 64-bit header for both.</p>
+""" .
+
+atom:Resource
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Thing ;
+ atom:cType "LV2_Thing" ;
+ lv2:documentation """
+<p>An atom:Thing where <code>id</code> is the URI of the resource mapped to an
+atom:URID.</p>
+""" .
+
+atom:Blank
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Thing ;
+ atom:cType "LV2_Thing" ;
+ lv2:documentation """
+<p>An atom:Thing where <code>id</code> is the blank node ID of the object,
+which is only meaningful within a certain limited scope (e.g. the container of
+the Blank) and MUST NOT be used as a global ID. In particular, <code>id</code>
+is NOT an <a href="ID">ID</a>.</p>
+""" .
+
+atom:Message
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Thing ;
+ atom:cType "LV2_Thing" ;
+ lv2:documentation """
+<p>A atom:Thing where <code>id</code> is a message type ID. Conceptually, a
+Message is identical to a Blank, but is a distinct type with a single type
+field to allow simple and fast dispatch by handling code.</p>
+
+<p>A Message may be serialised as a Blank by adding an rdf:type property with
+the value <code>id</code> unmapped to a URI.</p>
+""" .
+
+atom:Event
+ a rdfs:Class ;
+ rdfs:label "Event" ;
+ atom:cType "LV2_Atom_Event" ;
+ lv2:documentation """
+<p>An atom with a time stamp header prepended, typically for sample accurate
+transmission via LV2 ports. See struct LV2_Atom_Event.</p>
+""" .
+
+atom:Bang
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Bang (activity) (size = 0)" .
+
+atom:Number
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Number (abstract class)." .
+
+atom:Int32
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Number ;
+ rdfs:label "Signed 32-bit integer" ;
+ atom:cType "LV2_Atom_Int32" .
+
+atom:Int64
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Number ;
+ rdfs:label "Signed 64-bit integer" ;
+ atom:cType "LV2_Atom_Int64" .
+
+atom:Bool
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "An atom:Int32 where 0 is false and all other values true" ;
+ atom:cType "LV2_Atom_Int32" .
+
+atom:Float
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Number ;
+ rdfs:label "32-bit IEEE-754 floating point number" ;
+ atom:cType "LV2_Atom_Float" .
+
+atom:Double
+ a rdfs:Class ;
+ rdfs:subClassOf atom:Number ;
+ rdfs:label "64-bit IEEE-754 floating point number" ;
+ atom:cType "LV2_Atom_Double" .
+
+atom:blobSupport
+ a lv2:Feature ;
+ rdfs:label "Blob support" ;
+ lv2:documentation """
+<p>Support for dynamically allocated blobs. If a host supports this feature,
+it MUST pass a LV2_Feature with <code>URI</code>
+http://lv2plug.in/ns/ext/atom#blobSupport and <code>data</code> pointing to a
+LV2_Blob_Support.</p>
+""" .
+
+atom:AtomPort
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:Port ;
+ rdfs:label "Atom Port" ;
+ lv2:documentation """
+<p>A port which contains an lv2:Atom. Ports of this type will
+be connected to a 32-bit aligned LV2_Atom immediately followed by
+<code>size</code> bytes of data.</p>
+
+<p>This is an abstract port type, i.e. a port MUST NOT only be an AtomPort,
+but must be a more descriptive type that is a subclass of AtomPort which
+defines the port's semantics (typically atom:ValuePort or atom:MessagePort).
+</p>
+
+<p>Before calling a method on the plugin that writes to an AtomPort output,
+the host MUST set the size of the Atom in that output to the amount of
+available memory immediately following the Atom header. The plugin MUST
+write a valid Atom to that port (leaving it untouched is illegal). If there
+is no reasonable value to write to the port, the plugin MUST write NULL
+(the Atom with both <code>type = 0</code> and <code>size = 0</code>).</p>
+""" .
+
+atom:ValuePort
+ a rdfs:Class ;
+ rdfs:subClassOf atom:AtomPort ;
+ rdfs:label "Value Port" ;
+ lv2:documentation """
+<p>An AtomPort that interprets its data as a persistent and time-independent
+"value".</p>
+<ul>
+<li>If a plugin has fixed input values for all ports, all ValuePort outputs
+are also fixed regardless of the number of times the plugin is run.</li>
+<li>If a plugin has fixed input values for all ports except a ValuePort,
+each value V of that ValuePort corresponds to a single set of outputs
+for all ports.</li>
+<li>If a ValuePort contains a reference then the blob it refers to is
+constant; plugin MUST NOT modify the blob in any way.</li>
+</ul>
+<p>Value ports can be thought of as purely functional ports: if a plugin
+callback has only value ports, then the plugin callback is a pure function.</p>
+""" .
+
+atom:MessagePort
+ a rdfs:Class ;
+ rdfs:subClassOf atom:AtomPort ;
+ rdfs:label "Message Port" ;
+ rdfs:comment """
+An AtomPort that "receives", "consumes", "executes", or "sends" its value.
+The Atom contained in a MessagePort is considered transient and/or
+time-dependent, and is only valid for a single run invocation. Unlike a
+ValuePort, a MessagePort may be used to manipulate internal plugin state.
+
+Intuitively, a MessagePort contains a "message" or "command" or "event"
+which is reacted to, NOT a "value" or "signal" (which is computed with).
+""" .
+
+atom:cType
+ a rdf:Property ,
+ owl:DatatypeProperty ;
+ rdfs:label "C type" ;
+ rdfs:domain rdfs:Class ;
+ rdfs:range xsd:string ;
+ rdfs:comment """
+The identifier for a C type describing the in-memory representation of
+an instance of this class.
+""" .
+
+atom:EventPort
+ a rdfs:Class ;
+ rdfs:label "Event port" ;
+ rdfs:subClassOf lv2:Port ;
+ lv2:documentation """
+<p>A port used for communicating time-stamped atoms in the audio context.
+Ports of this type are connected to an LV2_Atom_Buffer, which contains a flat
+time-stamped sequence of atom:Event.</p>
+
+<p>This port type is intended as a simpler and atom compatible successor to <a
+href="http://lv2plug.in/ns/ext/event#EventPort">ev:EventPort</a>.</p>
+""" .
+
+atom:supports
+ a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range atom:Atom ;
+ rdfs:label "supports" ;
+ lv2:documentation """
+<p>Indicates that a Port supports a certain atom:Atom type. This is distinct from
+the port type - e.g. the port type ValuePort can hold atoms with many different
+types. This property is used to describe which Atom types a Port expects to
+receive or send.</p>
+""" .
diff --git a/ns/ext/atom/ext.pc.in b/ns/ext/atom/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/atom/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/atom/forge.h b/ns/ext/atom/forge.h
new file mode 100644
index 0000000..e8f5d40
--- /dev/null
+++ b/ns/ext/atom/forge.h
@@ -0,0 +1,75 @@
+/*
+ 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 forge.h Helper constructor functions for LV2 atoms.
+*/
+
+#ifndef LV2_ATOM_FORGE_H
+#define LV2_ATOM_FORGE_H
+
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t ID;
+ uint32_t Message;
+ uint32_t Property;
+} LV2_Atom_Forge;
+
+static inline LV2_Atom_Forge*
+lv2_atom_forge_new(LV2_URID_Map* map)
+{
+ LV2_Atom_Forge* forge = (LV2_Atom_Forge*)malloc(sizeof(LV2_Atom_Forge));
+ forge->ID = map->map(map->handle, LV2_ATOM_URI "#ID");
+ forge->Message = map->map(map->handle, LV2_ATOM_URI "#Message");
+ forge->Property = map->map(map->handle, LV2_ATOM_URI "#Property");
+ return forge;
+}
+
+static inline void
+lv2_atom_forge_free(LV2_Atom_Forge* forge)
+{
+ free(forge);
+}
+
+static inline LV2_Atom_ID
+lv2_atom_forge_make_id(LV2_Atom_Forge* forge, uint32_t id)
+{
+ const LV2_Atom_ID atom = { forge->ID, sizeof(uint32_t), id };
+ return atom;
+}
+
+static inline void
+lv2_atom_forge_set_message(LV2_Atom_Forge* forge,
+ LV2_Thing* msg,
+ uint32_t id)
+{
+ msg->type = forge->Message;
+ msg->size = sizeof(LV2_Thing) - sizeof(LV2_Atom);
+ msg->context = 0;
+ msg->id = id;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_ATOM_FORGE_H */
diff --git a/ns/ext/atom/manifest.ttl b/ns/ext/atom/manifest.ttl
new file mode 100644
index 0000000..adb10e5
--- /dev/null
+++ b/ns/ext/atom/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/atom>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <atom.ttl> .
+
diff --git a/ns/ext/atom/waf b/ns/ext/atom/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/atom/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/atom/wscript b/ns/ext/atom/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/atom/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/contexts/contexts.h b/ns/ext/contexts/contexts.h
new file mode 100644
index 0000000..f49b474
--- /dev/null
+++ b/ns/ext/contexts/contexts.h
@@ -0,0 +1,82 @@
+/* LV2 Contexts Extension
+ * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/** @file
+ * C header for the LV2 Contexts extension
+ * <http://lv2plug.in/ns/ext/contexts>.
+ */
+
+#ifndef LV2_CONTEXTS_H
+#define LV2_CONTEXTS_H
+
+#include <stdint.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define LV2_CONTEXTS_URI "http://lv2plug.in/ns/ext/contexts"
+
+static inline void
+lv2_contexts_set_port_valid(void* flags, uint32_t index) {
+ ((uint8_t*)flags)[index / 8] |= 1 << (index % 8);
+}
+
+static inline void
+lv2_contexts_unset_port_valid(void* flags, uint32_t index) {
+ ((uint8_t*)flags)[index / 8] &= ~(1 << (index % 8));
+}
+
+static inline int
+lv2_contexts_port_is_valid(const void* flags, uint32_t index) {
+ return (((uint8_t*)flags)[index / 8] & (1 << (index % 8))) != 0;
+}
+
+typedef struct {
+
+ /** The message run function. This is called once to process a set of
+ * inputs and produce a set of outputs.
+ *
+ * Before calling the host MUST set valid_inputs such that the bit
+ * corresponding to each input port is 1 iff data is present. The plugin
+ * MUST only inspect bits corresponding to ports in the message thread.
+ *
+ * Similarly, before returning the plugin MUST set valid_outputs such that
+ * the bit corresponding to each output port of the message context is 1
+ * iff the value at that port has changed.
+ * The plugin must return 1 if outputs have been written, 0 otherwise.
+ */
+ uint32_t (*run)(LV2_Handle instance,
+ const void* valid_inputs,
+ void* valid_outputs);
+
+} LV2_Contexts_MessageContext;
+
+typedef void* LV2_Contexts_Request_Run_Data;
+
+typedef struct {
+
+ /** Pointer to opaque host data (to be passed to request_run) */
+ LV2_Contexts_Request_Run_Data data;
+
+ /** Request the host execute the context with the given URI */
+ void (*request_run)(LV2_Contexts_Request_Run_Data host_handle,
+ uint32_t context_uri);
+
+} LV2_Contexts_Request_Run_Feature;
+
+#endif /* LV2_CONTEXTS_H */
+
diff --git a/ns/ext/contexts/contexts.ttl b/ns/ext/contexts/contexts.ttl
new file mode 100644
index 0000000..c56c649
--- /dev/null
+++ b/ns/ext/contexts/contexts.ttl
@@ -0,0 +1,134 @@
+# LV2 Contexts Extension
+#
+# Allows for an LV2 plugin to have several independent contexts, each with its
+# own run callback and associated ports.
+#
+# Copyright (C) 2007-2010 David Robillard
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix ctx: <http://lv2plug.in/ns/ext/contexts#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/contexts>
+ a lv2:Specification , lv2:Feature ;
+ doap:name "LV2 Contexts" ;
+ doap:shortdesc "Support for plugins with several execution contexts." ;
+ lv2:documentation """
+<p>An extension for LV2 plugins which have several execution contexts.</p>
+
+<p>Contexts allow plugins to run tasks and/or process input/output in
+multiple threads. Contexts can be used to add non-realtime functionality
+to a plugin while still keeping the audio run() method realtime safe.</p>
+
+<p>A context is an LV2 feature, so the usual LV2 feature mechanism is used
+to determine whether a plugin has a given context, and whether or not it is
+mandatory.</p>
+
+<p>Unless otherwise stated, each context (defined by some URI) adds a new
+threading class similar to the Audio class defined by LV2. Each context has a
+run callback and a connect_port callback both in the same class (i.e. can't be
+called concurrently), but may be called concurrently with functions for other
+contexts (excluding the Instantiation class). Context properties such as
+ctx:hardRTCapable apply to both functions.
+The host MUST only call the correct connect_port function associated with the
+context for that port, i.e. it is an error to use the main LV2 connect_port
+function on a port with a context other than the main LV2 run function.</p>
+""" .
+
+
+##########################
+## Context Base Classes ##
+##########################
+
+ctx:Context a rdfs:Class ;
+ rdfs:label "LV2 Context" ;
+ lv2:documentation """
+<p>A potentially concurrent context (callback) on a plugin.</p>
+
+<p>Ports are always associated with a context. If a port has no explicit context
+property, then its context is ctx:audioContext (the default LV2 run() context).</p>
+
+<p>A plugin indicates support for a context by supporting an LV2 Feature with
+that context's URI. If a plugin optionally supports a context (e.g.
+<code>&lt;plugin&gt; lv2:optionalFeature ctx:idleContext .</code>), then
+all ports associated with that context MUST be lv2:connectionOptional. Thus,
+hosts that do not support contexts will connect such ports to NULL and the
+plugin can run with only a standard LV2 run() context.</p>
+
+<p>Any plugin that supports any context (optionally or mandatorily) MUST adhere
+to the following additional threading rules for LV2_Descriptor.connect_port:</p>
+<ul>
+<li>connect_port MUST only be called for a given port from the context
+associated with that port</li>
+<li>connect_port MAY be called concurrently for ports with different
+contexts (but MUST NOT be called concurrently for multiple ports in the
+same context)</li>
+</ul>
+<p>Note this implies that any shared data access in connect_port may be
+accessed concurrently. The plugin is responsible for any synchronisation
+or locking necessary to make this possible.</p>
+""" .
+
+ctx:audioContext a ctx:Context , lv2:Feature ;
+ rdfs:comment """The context of LV2_Descriptor.run().""" .
+
+ctx:messageContext a ctx:Context , lv2:Feature ;
+ lv2:documentation """
+<p>A non-realtime context for plugin control via message passing. This context
+has a run method which takes a bitset of flags for parameters specifying which
+input and output ports are valid before and after the run method has executed,
+respectively (see <code>LV2_Contexts_MessageContext</code>).</p>
+""" .
+
+ctx:idleContext a ctx:Context , lv2:Feature ;
+ rdfs:comment """
+A non-realtime idle context, periodically run by the host roughly every second.
+This context never has any ports.
+""" .
+
+ctx:requestRunFeature a lv2:Feature ;
+ lv2:documentation """
+<p>A feature allowing the plugin to request the execution of a particular
+context at an arbitrary time. To support this feature, the host MUST pass an
+LV2_Feature to <code>instantiate</code> with <code>data</code> pointing to a
+LV2_Contexts_Request_Run_Feature.</p>
+
+<p>The plugin MAY call <code>request_run</code> with the given
+<code>data</code> from any non-realtime context to demand soon-as-possible execution
+of the specified context.</p>
+""" .
+
+ctx:context a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range ctx:Context ;
+ rdfs:label "is used in context" ;
+ rdfs:comment """
+The context a particular port is associated with; the port will only be
+connected/read/written by that context.
+
+If no context is specified, the port is considered part of the default LV2
+audio context.""" .
+
+
diff --git a/ns/ext/contexts/ext.pc.in b/ns/ext/contexts/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/contexts/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/contexts/manifest.ttl b/ns/ext/contexts/manifest.ttl
new file mode 100644
index 0000000..d2cc036
--- /dev/null
+++ b/ns/ext/contexts/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/contexts>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <contexts.ttl> .
+
diff --git a/ns/ext/contexts/test.c b/ns/ext/contexts/test.c
new file mode 100644
index 0000000..ca41a10
--- /dev/null
+++ b/ns/ext/contexts/test.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <assert.h>
+#include <unistd.h>
+#include "contexts.h"
+
+#define TEST_ASSERT(check) do {\
+ if (!(check)) {\
+ fprintf(stderr, "Failure at line %d: %s\n", __LINE__, #check);\
+ assert(false);\
+ _exit(1);\
+ }\
+} while (0)
+
+#define NUM_PORTS 64
+
+void
+print_flags(void* flags)
+{
+ for (int i = NUM_PORTS; i >= 0; --i)
+ printf((lv2_contexts_port_is_valid(flags, i)) ? "1" : "0");
+ printf("\n");
+}
+
+
+int
+main()
+{
+ uint64_t flags = 0;
+ print_flags(&flags);
+
+ lv2_contexts_set_port_valid(&flags, 16);
+ print_flags(&flags);
+ for (int i = 0; i < NUM_PORTS; ++i) {
+ if (i == 16) {
+ TEST_ASSERT(lv2_contexts_port_is_valid(&flags, i));
+ } else {
+ TEST_ASSERT(!lv2_contexts_port_is_valid(&flags, i));
+ }
+ }
+
+ lv2_contexts_set_port_valid(&flags, 46);
+ lv2_contexts_set_port_valid(&flags, 0);
+ print_flags(&flags);
+ for (int i = 0; i < NUM_PORTS; ++i) {
+ if (i == 0 || i == 16 || i == 46) {
+ TEST_ASSERT(lv2_contexts_port_is_valid(&flags, i));
+ } else {
+ TEST_ASSERT(!lv2_contexts_port_is_valid(&flags, i));
+ }
+ }
+
+ lv2_contexts_unset_port_valid(&flags, 16);
+ print_flags(&flags);
+ for (int i = 0; i < NUM_PORTS; ++i) {
+ if (i == 0 || i == 46) {
+ TEST_ASSERT(lv2_contexts_port_is_valid(&flags, i));
+ } else {
+ TEST_ASSERT(!lv2_contexts_port_is_valid(&flags, i));
+ }
+ }
+
+ return 0;
+}
+
diff --git a/ns/ext/contexts/waf b/ns/ext/contexts/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/contexts/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/contexts/wscript b/ns/ext/contexts/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/contexts/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/cv-port/cv-port.ttl b/ns/ext/cv-port/cv-port.ttl
new file mode 100644
index 0000000..f49024b
--- /dev/null
+++ b/ns/ext/cv-port/cv-port.ttl
@@ -0,0 +1,77 @@
+# LV2 CV Port Extension
+# Copyright 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.
+
+@prefix cv: <http://lv2plug.in/ns/ext/cv-port#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/cv-port>
+ a lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 CV Port" ;
+ doap:shortdesc "Control Voltage ports for LV2 plugins." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension defines Control Voltage (CV) ports, which are audio-rate
+control ports like those used on classical voltage-controlled synthesizers.
+These ports serve as control ports like <a
+href="http://lv2plug.in/ns/lv2core#ControlPort">lv2:ControlPort</a> but can
+also be used for audio-rate modulation of control signals. This enables many
+types of processing and synthesis which are not possible with a lower control
+rate.</p>
+""" .
+
+cv:CVPort
+ a rdfs:Class ;
+ rdfs:label "CV Port" ;
+ rdfs:subClassOf lv2:Port ;
+ lv2:documentation """
+
+<p>Ports of this type have identical semantics to <a
+href="http://lv2plug.in/ns/lv2core#AudioPort">lv2:AudioPort</a> in terms of
+buffer format and connection/input/output logistics. However, rather than the
+buffer representing audio, the buffer represents audio-rate control data. A
+CVPort SHOULD have the same properties a <a
+href="http://lv2plug.in/ns/lv2core#ControlPort">lv2:ControlPort</a> typically
+has to describe appropriate control values (e.g. <a
+href="http://lv2plug.in/ns/lv2core#minimum">lv2:minimum</a>, <a
+href="http://lv2plug.in/ns/lv2core#maximum">lv2:maximum</a>, <a
+href="http://lv2plug.in/ns/lv2core#default">lv2:default</a>)</p>
+
+<p>Hosts SHOULD take care to prevent data from a CVPort port from being used as
+audio except in cases where this is known to be safe.</p>
+
+<p>Example:</p>
+<pre class="turtle-code">
+&lt;http://example.org/some-plugin&gt;
+ lv2:port [
+ a cv:CVPort, lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:minimum -1.0 ;
+ lv2:maximum 1.0 ;
+ lv2:default 0.0 ;
+ lv2:symbol "modulation" ;
+ lv2:name "Modulation" ;
+ ] .
+</pre>
+""" .
diff --git a/ns/ext/cv-port/ext.pc.in b/ns/ext/cv-port/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/cv-port/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/cv-port/manifest.ttl b/ns/ext/cv-port/manifest.ttl
new file mode 100644
index 0000000..e5fa145
--- /dev/null
+++ b/ns/ext/cv-port/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/cv-port>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <cv-port.ttl> .
+
diff --git a/ns/ext/cv-port/waf b/ns/ext/cv-port/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/cv-port/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/cv-port/wscript b/ns/ext/cv-port/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/cv-port/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/data-access/data-access.h b/ns/ext/data-access/data-access.h
new file mode 100644
index 0000000..fac6974
--- /dev/null
+++ b/ns/ext/data-access/data-access.h
@@ -0,0 +1,56 @@
+/*
+ LV2 Data Access Extension
+ 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 data-access.h
+ C header for the LV2 Extension Data extension
+ <http://lv2plug.in/ns/ext/data-access>.
+
+ This extension defines a method for (e.g.) plugin UIs to have (possibly
+ marshalled) access to the extension_data function on a plugin instance.
+*/
+
+#ifndef LV2_DATA_ACCESS_H
+#define LV2_DATA_ACCESS_H
+
+#define LV2_DATA_ACCESS_URI "http://lv2plug.in/ns/ext/data-access"
+
+/**
+ The data field of the LV2_Feature for this extension.
+
+ To support this feature the host must pass an LV2_Feature struct to the
+ instantiate method with URI "http://lv2plug.in/ns/ext/data-access"
+ and data pointed to an instance of this struct.
+*/
+typedef struct {
+ /**
+ A pointer to a method the UI can call to get data (of a type specified
+ by some other extension) from the plugin.
+
+ This call never is never guaranteed to return anything, UIs should
+ degrade gracefully if direct access to the plugin data is not possible
+ (in which case this function will return NULL).
+
+ This is for access to large data that can only possibly work if the UI
+ and plugin are running in the same process. For all other things, use
+ the normal LV2 UI communication system.
+ */
+ const void* (*data_access)(const char* uri);
+
+} LV2_Extension_Data_Feature;
+
+#endif /* LV2_DATA_ACCESS_H */
diff --git a/ns/ext/data-access/data-access.ttl b/ns/ext/data-access/data-access.ttl
new file mode 100644
index 0000000..1f2ec04
--- /dev/null
+++ b/ns/ext/data-access/data-access.ttl
@@ -0,0 +1,82 @@
+# LV2 Data Access Extension
+# Copyright 2008-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix da: <http://lv2plug.in/ns/ext/data-access#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+<http://lv2plug.in/ns/ext/data-access>
+ a lv2:Specification ,
+ doap:Project ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 Data Access" ;
+ doap:shortdesc "Provides access to LV2_Descriptor::extension_data()." ;
+ doap:developer <http://drobilla.net/drobilla#me> ;
+ doap:release [
+ doap:revision "1.4" ;
+ doap:created "2011-11-14" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-data-access-1.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Update packaging."
+ ] , [
+ rdfs:label "Improve documentation."
+ ]
+ ]
+ ] , [
+ doap:revision "1.2" ;
+ doap:created "2011-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-data-access-1.2.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Add build system for installation."
+ ] , [
+ rdfs:label "Switch to ISC license."
+ ]
+ ]
+ ] , [
+ doap:revision "1.0" ;
+ doap:created "2010-10-04" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-data-access-1.0.tar.gz> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Initial release."
+ ]
+ ]
+ ] ;
+ lv2:documentation """
+<p>This extension defines a feature, LV2_Extension_Data_Feature, which provides
+access to LV2_Descriptor::extension_data() for plugin UIs or other potentially
+remote users of a plugin.</p>
+
+<p>To support this feature the host must pass an LV2_Feature struct to the
+instantiate method with URI "http://lv2plug.in/ns/ext/data-access" and data
+pointed to an instance of LV2_Extension_Data_Feature.</p>
+""" . \ No newline at end of file
diff --git a/ns/ext/data-access/ext.pc.in b/ns/ext/data-access/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/data-access/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/data-access/manifest.ttl b/ns/ext/data-access/manifest.ttl
new file mode 100644
index 0000000..f7ccd9d
--- /dev/null
+++ b/ns/ext/data-access/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/data-access>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 4 ;
+ rdfs:seeAlso <data-access.ttl> .
+
diff --git a/ns/ext/data-access/waf b/ns/ext/data-access/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/data-access/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/data-access/wscript b/ns/ext/data-access/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/data-access/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/dynmanifest/dynmanifest.h b/ns/ext/dynmanifest/dynmanifest.h
new file mode 100644
index 0000000..56d829e
--- /dev/null
+++ b/ns/ext/dynmanifest/dynmanifest.h
@@ -0,0 +1,144 @@
+/*
+ Dynamic manifest specification for LV2
+ Copyright 2008-2011 Stefano D'Angelo <zanga.mail@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 dynmanifest.h
+ C header for the LV2 Dynamic Manifest extension
+ <http://lv2plug.in/ns/ext/dynmanifest>.
+ Revision: 1.1
+*/
+
+#ifndef LV2_DYN_MANIFEST_H_INCLUDED
+#define LV2_DYN_MANIFEST_H_INCLUDED
+
+#include <stdio.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define LV2_DYN_MANIFEST_URI "http://lv2plug.in/ns/ext/dynmanifest"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ Dynamic manifest generator handle.
+
+ This handle indicates a particular status of a dynamic manifest generator.
+ The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is
+ NOT even valid to compare this to NULL. The dynamic manifest generator MAY
+ use it to reference internal data.
+*/
+typedef void * LV2_Dyn_Manifest_Handle;
+
+/**
+ Generate the dynamic manifest.
+
+ @param handle Pointer to an uninitialized dynamic manifest generator handle.
+
+ @param features NULL terminated array of LV2_Feature structs which represent
+ the features the host supports. The dynamic manifest generator may refuse to
+ (re)generate the dynamic manifest if required features are not found here
+ (however hosts SHOULD NOT use this as a discovery mechanism, instead of
+ reading the static manifest file). This array must always exist; if a host
+ has no features, it MUST pass a single element array containing NULL.
+
+ @return 0 on success, otherwise a non-zero error code. The host SHOULD
+ evaluate the result of the operation by examining the returned value and
+ MUST NOT try to interpret the value of handle.
+*/
+int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle * handle,
+ const LV2_Feature *const * features);
+
+/**
+ Fetch a "list" of subject URIs described in the dynamic manifest.
+
+ The dynamic manifest generator has to fill the resource only with the needed
+ triples to make the host aware of the "objects" it wants to expose. For
+ example, if the plugin library exposes a regular LV2 plugin, it should
+ output only a triple like the following:
+
+ <http://www.example.com/plugin/uri> a lv2:Plugin .
+
+ The objects that are elegible for exposure are those that would need to be
+ represented by a subject node in a static manifest.
+
+ @param handle Dynamic manifest generator handle.
+
+ @param fp FILE * identifying the resource the host has to set up for the
+ dynamic manifest generator. The host MUST pass a writable, empty resource to
+ this function, and the dynamic manifest generator MUST ONLY perform write
+ operations on it at the end of the stream (e.g., using only fprintf(),
+ fwrite() and similar).
+
+ @return 0 on success, otherwise a non-zero error code.
+*/
+int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
+ FILE * fp);
+
+/**
+ Function that fetches data related to a specific URI.
+
+ The dynamic manifest generator has to fill the resource with data related to
+ object represented by the given URI. For example, if the library exposes a
+ regular LV2 plugin whose URI, as retrieved by the host using
+ lv2_dyn_manifest_get_subjects() is http://www.example.com/plugin/uri, it
+ should output something like:
+
+ <pre>
+ <http://www.example.com/plugin/uri>
+ a lv2:Plugin ;
+ doap:name "My Plugin" ;
+ lv2:binary <mylib.so> ;
+ etc:etc "..." .
+ </pre>
+
+ @param handle Dynamic manifest generator handle.
+
+ @param fp FILE * identifying the resource the host has to set up for the
+ dynamic manifest generator. The host MUST pass a writable resource to this
+ function, and the dynamic manifest generator MUST ONLY perform write
+ operations on it at the current position of the stream (e.g. using only
+ fprintf(), fwrite() and similar).
+
+ @param uri URI to get data about (in the "plain" form, i.e., absolute URI
+ without Turtle prefixes).
+
+ @return 0 on success, otherwise a non-zero error code.
+*/
+int lv2_dyn_manifest_get_data(LV2_Dyn_Manifest_Handle handle,
+ FILE * fp,
+ const char * uri);
+
+/**
+ Function that ends the operations on the dynamic manifest generator.
+
+ This function SHOULD be used by the dynamic manifest generator to perform
+ cleanup operations, etc.
+
+ Once this function is called, referring to handle will cause undefined
+ behavior.
+
+ @param handle Dynamic manifest generator handle.
+*/
+void lv2_dyn_manifest_close(LV2_Dyn_Manifest_Handle handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LV2_DYN_MANIFEST_H_INCLUDED */
diff --git a/ns/ext/dynmanifest/dynmanifest.ttl b/ns/ext/dynmanifest/dynmanifest.ttl
new file mode 100644
index 0000000..591cb11
--- /dev/null
+++ b/ns/ext/dynmanifest/dynmanifest.ttl
@@ -0,0 +1,122 @@
+# LV2 Dynamic Manifest Extension
+# Copyright 2008-2011 Stefano D'Angelo <zanga.mail@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.
+
+@prefix dman: <http://lv2plug.in/ns/ext/dynmanifest#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/dynmanifest>
+ a doap:Project ,
+ lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 Dynamic Manifest" ;
+ doap:homepage <http://naspro.atheme.org> ;
+ doap:created "2009-06-13" ;
+ doap:shortdesc "An LV2-based specification for dynamic data generation." ;
+ doap:programming-language "C" ;
+ doap:release [
+ doap:revision "1.1" ;
+ doap:created "2011-11-17"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "Stefano D'Angelo"
+ ] ;
+ lv2:documentation """
+<p>The LV2 API, on its own, cannot be used to write plugin libraries where data
+is dynamically generated at runtime (e.g. API wrappers), since LV2 requires
+needed information to be provided in one or more static data (RDF) files. This
+API addresses this limitation by extending the LV2 API.</p>
+
+<p>To detect that a plugin library implements a dynamic manifest generator,
+the host checks its static manifest for a description like:</p>
+
+<pre class="turtle-code">
+&lt;http://example.org/my-dynamic-manifest&gt;
+ a dman:DynManifest ;
+ lv2:binary &lt;mydynmanifest.so&gt; .
+</pre>
+
+<p>To load the data, the host loads the library
+(e.g. <code>mydynmanifest.so</code>) as usual and fetches the dynamic Turtle
+data from it using this API.</p>
+
+<p>The host is allowed to request regeneration of the dynamic manifest multiple
+times, and the plugin library is expected to provide updated data if/when
+possible. All data and references provided via this API before the last
+regeneration of the dynamic manifest is to be considered invalid by the host,
+including plugin descriptors whose URIs were discovered using this API.</p>
+
+<h3>Accessing Data</h3>
+
+<p>Whenever a host wants to access data using this API, it could:</p>
+
+<ol>
+<li>Call lv2_dyn_manifest_open().</li>
+<li>Create a FILE for functions to write data to (e.g. using tmpfile()).</li>
+<li>Get a <q>list</q> of exposed subject URIs using
+ lv2_dyn_manifest_get_subjects().</li>
+<li>Call lv2_dyn_manifest_get_data() for each URI of interest to
+ get the data related to that URI (which can be written to any FILE).</li>
+<li>Call lv2_dyn_manifest_close().</li>
+<li>Parse the content of the FILE(s).</li>
+<li>Free/delete/unlink the FILE(s).</li>
+</ol>
+
+<p>Each call to the above mentioned dynamic manifest functions MUST write a
+complete, valid Turtle document (including all needed prefix definitions) to
+the output FILE.</p>
+
+<p>Each call to lv2_dyn_manifest_open() causes the (re)generation of the
+dynamic manifest data, and invalidates all data fetched before the call.</p>
+
+<p>In case the plugin library uses this same API to access other dynamic
+manifests, it MUST implement some mechanism to avoid potentially endless loops
+(such as A loads B, B loads A, etc.) and, in case such a loop is detected, the
+operation MUST fail. For this purpose, use of a static boolean flag is
+suggested.</p>
+
+<h3>Threading Rules</h3>
+
+<p>All of the functions defined by this specification belong to the Discovery
+class.</p>
+""" .
+
+dman:DynManifest
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:Resource ;
+ rdfs:label "Dynamic manifest generator" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ owl:onProperty lv2:binary ;
+ owl:minCardinality 1 ;
+ rdfs:comment """A DynManifest has at least 1 lv2:binary.
+The binary must be a library with at least the functions described in
+lv2_dyn_manifest.h implemented.
+"""
+ ] ;
+ rdfs:comment """
+The class which represents a dynamic manifest generator.
+
+There MUST NOT be any instances of :DynManifest in the generated manifest.
+
+All relative URIs in the generated data MUST be relative to the base path
+that would be used to parse a normal LV2 manifest (the bundle path).
+""" .
diff --git a/ns/ext/dynmanifest/ext.pc.in b/ns/ext/dynmanifest/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/dynmanifest/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/dynmanifest/lv2-dynmanifest.doap.ttl b/ns/ext/dynmanifest/lv2-dynmanifest.doap.ttl
new file mode 100644
index 0000000..f47c381
--- /dev/null
+++ b/ns/ext/dynmanifest/lv2-dynmanifest.doap.ttl
@@ -0,0 +1,43 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+<http://lv2plug.in/ns/ext/dynmanifest>
+ a doap:Project ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 Dynamic Manifest" ;
+ doap:homepage <http://naspro.atheme.org> ;
+ doap:created "2009-06-13" ;
+ doap:shortdesc "An LV2-based specification for dynamic data generation." ;
+ doap:programming-language "C" ;
+ doap:developer [
+ a foaf:Person ;
+ foaf:name "Stefano D'Angelo"
+ ] ;
+ doap:release [
+ doap:revision "1.1" ;
+ doap:created "2011-11-17" ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Improve documentation."
+ ]
+ ]
+ ] , [
+ doap:revision "1.0" ;
+ doap:created "2010-04-10" ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Initial release."
+ ]
+ ]
+ ] .
diff --git a/ns/ext/dynmanifest/manifest.ttl b/ns/ext/dynmanifest/manifest.ttl
new file mode 100644
index 0000000..6718092
--- /dev/null
+++ b/ns/ext/dynmanifest/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/dynmanifest>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <dynmanifest.ttl> ,
+ <lv2-dynmanifest.doap.ttl> .
diff --git a/ns/ext/dynmanifest/waf b/ns/ext/dynmanifest/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/dynmanifest/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/dynmanifest/wscript b/ns/ext/dynmanifest/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/dynmanifest/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/event/event-helpers.h b/ns/ext/event/event-helpers.h
new file mode 100644
index 0000000..75ba14b
--- /dev/null
+++ b/ns/ext/event/event-helpers.h
@@ -0,0 +1,246 @@
+/* lv2_event_helpers.h - Helper functions for the LV2 events extension.
+ *
+ * Copyright (C) 2008-2009 David Robillard <http://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
+ * Helper functions for the LV2 Event extension
+ * <http://lv2plug.in/ns/ext/event>.
+ *
+ * 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)
+{
+ const size_t size = sizeof(LV2_Event_Buffer) + capacity;
+ LV2_Event_Buffer* buf = (LV2_Event_Buffer*)malloc(size);
+ 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 @a 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 @a 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 */
+
diff --git a/ns/ext/event/event.h b/ns/ext/event/event.h
new file mode 100644
index 0000000..2c340ba
--- /dev/null
+++ b/ns/ext/event/event.h
@@ -0,0 +1,281 @@
+/*
+ LV2 Event Extension
+ Copyright 2008-2011 David Robillard <http://drobilla.net>
+ Copyright 2006-2007 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.
+*/
+
+#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 event.h
+ C API for the LV2 Event extension <http://lv2plug.in/ns/ext/event>.
+
+ 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 timestamps.
+ 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;
+
+
+/**
+ Non-POD events feature.
+
+ 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. Note this feature
+ is not mandatory to support the event extension.
+*/
+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 */
diff --git a/ns/ext/event/event.ttl b/ns/ext/event/event.ttl
new file mode 100644
index 0000000..d207a7a
--- /dev/null
+++ b/ns/ext/event/event.ttl
@@ -0,0 +1,194 @@
+# LV2 Event Extension
+# 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.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/event>
+ a lv2:Specification ;
+ owl:deprecated true ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 Event" ;
+ doap:shortdesc "A port-based real-time generic event interface." ;
+ rdfs:seeAlso <event-helpers.h> ;
+ doap:release [
+ doap:revision "1.3" ;
+ doap:created "2011-11-23"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.xrdf>
+ ] , [
+ a foaf:Person ;
+ foaf:name "Lars Luthman" ;
+ ] ;
+ lv2:documentation """
+<p><span class="warning">This extension is deprecated.</span> New
+implementations should use <a href="http://lv2plug.in/ns/ext/atom">LV2 Atom</a>
+instead.</p>
+
+<p>This extension defines a generic time-stamped event port type, which can be
+used to create plugins that read and write real-time events, such as MIDI,
+OSC, or any other type of event payload. The type(s) of event supported by
+a port is defined in the data file for a plugin, for example:</p>
+<pre class="turtle-code">
+&lt;http://example.org/some-plugin&gt;
+ lv2:port [
+ a ev:EventPort, lv2:InputPort ;
+ lv2:index 0 ;
+ ev:supportsEvent &lt;http://lv2plug.in/ns/ext/midi#MidiEvent&gt; ;
+ lv2:symbol "midi_input" ;
+ lv2:name "MIDI input" ;
+ ] .
+</pre>
+""" .
+
+ev:EventPort a rdfs:Class ;
+ rdfs:label "Event port" ;
+ rdfs:subClassOf lv2:Port ;
+ rdfs:comment """
+Ports of this type will be connected to a struct of type LV2_Event_Buffer,
+defined in event.h. These ports contain a sequence of generic events
+(possibly several types mixed in a single stream), the specific types of
+which are defined by some URI in another LV2 extension.
+""" .
+
+
+ev:Event a rdfs:Class ;
+ rdfs:label "LV2 event" ;
+ rdfs:comment """
+A single generic time-stamped event.
+
+An lv2ev:EventPort contains an LV2_Event_Buffer which contains a sequence
+of these events. The binary format of LV2 events is defined by the
+LV2_Event struct in event.h.
+
+Specific event types (e.g. MIDI, OSC) are defined by extensions, and should
+be rdfs:subClassOf this class.
+""" .
+
+
+ev:TimeStamp a rdfs:Class ;
+ rdfs:label "LV2 event time stamp" ;
+ rdfs:comment """
+The time stamp of an Event.
+
+This defines the meaning of the 'frames' and 'subframes' fields of an
+LV2_Event (both unsigned 32-bit integers).
+""" .
+
+
+ev:FrameStamp a rdfs:Class ;
+ rdfs:subClassOf ev:TimeStamp ;
+ rdfs:label "Audio frame time stamp" ;
+ rdfs:comment """
+The default time stamp unit for an LV2 event: the frames field represents
+audio frames (in the sample rate passed to intantiate), and the subframes
+field is 1/UINT32_MAX of a frame.
+""" .
+
+
+ev:generic a lv2:PortProperty ;
+ rdfs:label "Generic event port" ;
+ rdfs:comment """
+Indicates that this port does something meaningful for any event type
+(e.g. event mixers, delays, serialisers, etc). If this property is set, hosts
+should consider the port suitable for any type of event. Otherwise, hosts
+should consider the port 'appropriate' only for the specific event types
+listed with :supportsEvent. Note that plugins must gracefully handle unknown
+event types whether or not this property is present.
+""" .
+
+
+ev:supportsEvent a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range ev:Event ;
+ rdfs:label "Supports event type" ;
+ rdfs:comment """
+Indicates that this port supports or "understands" a certain event type.
+For input ports, this means the plugin understands and does something useful
+with events of this type. For output ports, this means the plugin may generate
+events of this type. If the plugin never actually generates events of this type,
+but might pass them through from an input, this property should not be set (use
+ev:inheritsEvent for that).
+Plugins with event input ports must always gracefully handle any type of event,
+even if it does not 'support' it. This property should always be set for
+event types the plugin understands/generates so hosts can discover plugins
+appropriate for a given scenario (e.g. plugins with a MIDI input).
+Hosts are not expected to consider event ports suitable for some type of
+event if the relevant :supportsEvent property is not set, unless the
+lv2ev:generic property for that port is also set.
+""" .
+
+
+ev:inheritsEvent a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range lv2:Port ;
+ rdfs:label "Inherits event type" ;
+ rdfs:comment """
+Indicates that this output port might pass through events that arrived at some
+other input port (or generate an event of the same type as events arriving at
+that input). The host must always check the stamp type of all outputs when
+connecting an input, but this property should be set whenever it applies.
+""" .
+
+
+ev:supportsTimeStamp a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range ev:TimeStamp ;
+ rdfs:label "Supports time stamp type" ;
+ rdfs:comment """
+Indicates that this port supports or "understands" a certain time stamp type.
+Meaningful only for input ports, the host must never connect a port to an
+event buffer with a time stamp type that isn't supported by the port.
+""" .
+
+
+ev:generatesTimeStamp a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range ev:TimeStamp ;
+ rdfs:label "Outputs time stamp type" ;
+ rdfs:comment """
+Indicates that this port may output a certain time stamp type, regardless of
+the time stamp type of any input ports. If the port outputs stamps based on
+what type inputs are connected to, this property should not be set (use the
+ev:inheritsTimeStamp property for that). Hosts MUST check the time_stamp value
+of any output port buffers after a call to connect_port on ANY event input
+port on the plugin. If the plugin changes the stamp_type field of an output
+event buffer during a call to run(), the plugin must call the
+stamp_type_changed function provided by the host in the LV2_Event_Feature
+struct, if it is non-NULL.
+""" .
+
+
+ev:inheritsTimeStamp a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range lv2:Port ;
+ rdfs:label "Inherits time stamp type" ;
+ rdfs:comment """
+Indicates that this port follows the time stamp type of an input port.
+This property is not necessary, but it should be set for outputs that
+base their output type on an input port so the host can make more sense
+of the plugin and provide a more sensible interface.
+""" .
+
diff --git a/ns/ext/event/ext.pc.in b/ns/ext/event/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/event/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/event/manifest.ttl b/ns/ext/event/manifest.ttl
new file mode 100644
index 0000000..2b1ff43
--- /dev/null
+++ b/ns/ext/event/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/event>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 3 ;
+ rdfs:seeAlso <event.ttl> .
+
diff --git a/ns/ext/event/waf b/ns/ext/event/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/event/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/event/wscript b/ns/ext/event/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/event/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/files/ext.pc.in b/ns/ext/files/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/files/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/files/files.h b/ns/ext/files/files.h
new file mode 100644
index 0000000..623587a
--- /dev/null
+++ b/ns/ext/files/files.h
@@ -0,0 +1,134 @@
+/*
+ Copyright 2010-2011 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/**
+ @file files.h
+ C API for the LV2 Files extension <http://lv2plug.in/ns/ext/files>.
+*/
+
+#ifndef LV2_FILES_H
+#define LV2_FILES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LV2_FILES_URI "http://lv2plug.in/ns/ext/files"
+#define LV2_FILES_PATH_SUPPORT_URI LV2_FILES_URI "#pathSupport"
+#define LV2_FILES_NEW_FILE_SUPPORT_URI LV2_FILES_URI "#newFileSupport"
+
+typedef void* LV2_Files_Host_Data;
+
+/**
+ files:pathSupport feature struct.
+
+ To support this feature, the host MUST pass an LV2_Feature struct with @a
+ URI @ref LV2_FILES_PATH_SUPPORT_URI and @a data pointed to an instance of
+ this struct.
+*/
+typedef struct {
+
+ /**
+ Opaque host data.
+ */
+ LV2_Files_Host_Data host_data;
+
+ /**
+ Map an absolute path to an abstract path for use in plugin state.
+ @param host_data MUST be the @a host_data 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.
+
+ Hosts MAY map paths in any way (e.g. by creating symbolic links within
+ the plugin's state directory or storing a list of referenced files for
+ later export). Plugins MUST NOT make any assumptions about abstract
+ paths except that they can be mapped to an absolute path using @ref
+ absolute_path. Particularly when restoring from state, this absolute
+ path MAY not be the same as the original absolute path, but the host
+ MUST guarantee it refers to a file with contents equivalent to the
+ original.
+
+ This function may only be called within the context of
+ LV2_Persist.save() or LV2_Persist.restore(). The caller is responsible
+ for freeing the returned value.
+ */
+ char* (*abstract_path)(LV2_Files_Host_Data host_data,
+ const char* absolute_path);
+
+ /**
+ Map an abstract path from plugin state to an absolute path.
+ @param host_data MUST be the @a host_data member of this struct.
+ @param abstract_path An abstract path (e.g. a path from plugin state).
+ @return An absolute file system path.
+
+ Since abstract paths are not necessarily actual file paths (or at least
+ not necessarily absolute paths), this function MUST be used in order to
+ actually open or otherwise use the file referred to by an abstract path.
+
+ This function may only be called within the context of
+ LV2_Persist.save() or LV2_Persist.restore(). The caller is responsible
+ for freeing the returned value.
+ */
+ char* (*absolute_path)(LV2_Files_Host_Data host_data,
+ const char* abstract_path);
+
+} LV2_Files_Path_Support;
+
+/**
+ files:newFileSupport feature struct.
+
+ To support this feature, the host MUST pass an LV2_Feature struct with @a
+ URI @ref LV2_FILES_NEW_FILE_SUPPORT_URI and @a data pointed to an instance
+ of this struct.
+*/
+typedef struct {
+
+ /**
+ Opaque host data.
+ */
+ LV2_Files_Host_Data host_data;
+
+ /**
+ Return an absolute path the plugin may use to create a new file.
+ @param host_data MUST be the @a host_data member of this struct.
+ @param relative_path The relative path of the file.
+ @return The absolute path to use for the new file.
+
+ The plugin can assume @a relative_path is relative to a namespace
+ dedicated to that plugin instance; hosts MUST ensure this, e.g. by
+ giving each plugin instance its own state directory. The returned path
+ is absolute and thus suitable for creating and using a file, but NOT
+ suitable for storing in plugin state (it MUST be mapped to an abstract
+ path using @ref LV2_Files_Path_Support::abstract_path to do so).
+
+ This function may be called from any non-realtime context. The caller
+ is responsible for freeing the returned value.
+ */
+ char* (*new_file_path)(LV2_Files_Host_Data host_data,
+ const char* relative_path);
+
+} LV2_Files_New_File_Support;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_FILES_H */
diff --git a/ns/ext/files/files.ttl b/ns/ext/files/files.ttl
new file mode 100644
index 0000000..d3ff8a5
--- /dev/null
+++ b/ns/ext/files/files.ttl
@@ -0,0 +1,115 @@
+# LV2 Files Extension
+# Copyright 2010-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix files: <http://lv2plug.in/ns/ext/files#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/files>
+ a lv2:Specification ;
+ doap:name "LV2 Files" ;
+ doap:shortdesc "A standard for referring to files in plugin state." ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:release [
+ doap:revision "0.2" ;
+ doap:created "2011-04-05"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension provides a mechanism for plugins to portably refer to files
+in persistent plugin state (using the <a
+href="http://lv2plug.in/ns/ext/persist">LV2 Persist</a> extension), and create
+instance-local files in host-defined locations (e.g. for recording).</p>
+
+<p>The motivating idea behind this extension is that all details of file
+management MUST be handled by the host since different hosts may have very
+different requirements. Plugins MUST NOT make any assumption about file system
+locations beyond what is explicitly guaranteed by this extension.</p>
+
+<p>This extension defines two features: files:newFileSupport allows plugins to
+create new files within an instance-specific namespace at any time (except in
+realtime contexts); while files:pathSupport allows plugins to refer to file
+paths in plugin state in a way transparent to the host.</p>
+
+<p>To create a new file, the plugin MUST request a path from the host using
+LV2_Files_New_File_Support::new_file_path(). Thus, the host may choose an
+appropriate location for the file (e.g. a writable path on the appropriate disk
+volume or a path within a session directory) using information not available to
+the plugin.</p>
+
+<p>To store a path in persistent state, the plugin MUST map it to an
+<q>abstract path</q> using LV2_Files_Path_Support::abstract_path(). To use a
+path loaded from persistent state, the plugin MUST map the (abstract) path to
+an absolute path using LV2_Files_Path_Support::absolute_path(). Thus, the host
+can manage all paths used in a session and support exporting sessions to a
+portable self-contained format for archival or distribution.</p> """ .
+
+files:pathSupport a lv2:Feature ;
+ rdfs:label "Support for storing file paths in plugin state" ;
+ lv2:documentation """
+<p>This feature allows plugins to refer to pre-existing or newly created files
+in persistent plugin state in a portable way. To support this feature a host
+MUST pass a LV2_Files_Path_Support structure to the plugin's
+LV2_Descriptor::instantiate() method as an LV2_Feature with LV2_Feature::URI =
+LV2_FILES_PATH_SUPPORT_URI and LV2_Feature::data pointed to an instance of
+LV2_Files_Path_Support.</p>
+
+<p>Plugins MUST use the functions provided by this feature to handle
+<em>all</em> paths saved to, or restored from, persistent plugin state;
+otherwise broken and/or non-portable state will silently be created resulting
+in a broken user experience.</p>
+""" .
+
+files:newFileSupport a lv2:Feature ;
+ rdfs:label "Support for creating new files" ;
+ lv2:documentation """
+<p>This feature allows plugins to create new files local to that plugin
+instance. To support this feature a host MUST pass a
+LV2_Files_New_File_Support structure to the plugin's
+LV2_Descriptor::instantiate() method as an LV2_Feature with LV2_Feature::URI =
+LV2_FILES_NEW_FILE_SUPPORT_URI and LV2_Feature::data pointed to an instance of
+LV2_Files_New_File_Support.</p>
+""" .
+
+files:AbstractPath a rdfs:Class ;
+ rdfs:label "File Path" ;
+ lv2:documentation """
+<p>An abstract path to a file in persistent plugin state.</p>
+
+<p>The format of a files:AbstractPath is a C string escaped or otherwise
+restricted in a system-specific manner. This URI,
+<q>http://lv2plug.in/ns/ext/files#AbstractPath</q>, mapped to an integer,
+should be used as the <code>type</code> parameter to a
+LV2_Persist_Store_Function; and will likewise be returned by the corresponding
+call to a LV2_Persist_Retrieve_Function.</p>
+
+<p>Abstract paths reside in a namespace specific to a plugin instance.
+Typical hosts are expected to implement this by giving each plugin instance its
+own state directory.</p>
+
+<p>When storing and retrieving an abstract path, the plugin MUST NOT assume the
+same path will be restored. However, the restored path will refer to a file
+with equivalent contents to the original.</p>
+""" .
diff --git a/ns/ext/files/manifest.ttl b/ns/ext/files/manifest.ttl
new file mode 100644
index 0000000..d0233c4
--- /dev/null
+++ b/ns/ext/files/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/files>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <files.ttl> .
+
diff --git a/ns/ext/files/waf b/ns/ext/files/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/files/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/files/wscript b/ns/ext/files/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/files/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/host-info/ext.pc.in b/ns/ext/host-info/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/host-info/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/host-info/host-info.ttl b/ns/ext/host-info/host-info.ttl
new file mode 100644
index 0000000..127f4cc
--- /dev/null
+++ b/ns/ext/host-info/host-info.ttl
@@ -0,0 +1,118 @@
+# LV2 Host Info Extension
+# PROVISIONAL
+# Copyright (C) 2009 David Robillard <d@drobilla.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix hi: <http://lv2plug.in/ns/ext/host-info#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix amb: <http://ambisonics.ch/standards/channels/> .
+
+<http://lv2plug.in/ns/ext/host-info> a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 Host Info" ;
+ doap:shortdesc "A format for describing LV2 hosts." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This specification defines various properties to represent useful information
+about LV2 hosts. Currently, the primary use of this specification is to describe which
+extensions are supported by a given host.</p>
+
+<p>The extensions supported by a host can be described like this:</p>
+<pre class="turtle-code">
+@prefix hi: &lt;http://lv2plug.in/ns/ext/host-info#&gt; .
+
+&lt;http://example.org/some-host&gt;
+ a hi:Host ;
+ doap:name "Foo Rack" ;
+ hi:supportsExtension [
+ hi:extension &lt;http://example.org/some-extension&gt; ;
+ hi:sinceVersion "1.2.0"
+ ] .
+</pre>
+""" .
+
+
+## Core Classes / Properties
+
+hi:Host a rdfs:Class ;
+ rdfs:label "LV2 Host" ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty doap:name ;
+ owl:someValuesFrom xsd:string ;
+ owl:minCardinality 1 ;
+ rdfs:comment "A hi:Host MUST have at least one string doap:name"
+ ] ;
+ rdfs:comment """
+An application that supports loading LV2 plugins, or performs other
+LV2 related functionality.
+""" .
+
+hi:supportsExtension a rdf:Property ;
+ rdfs:domain hi:Host ;
+ rdfs:range hi:ExtensionSupport ;
+ rdfs:label "supports extension" ;
+ rdfs:comment "Relates a Host to its ExtensionSupport" .
+
+hi:ExtensionSupport a rdfs:Class ;
+ rdfs:label "Extension Support" ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty hi:sinceVersion ;
+ owl:someValuesFrom xsd:string ;
+ owl:minCardinality 1 ;
+ rdfs:comment """
+A hi:ExtensionSupport MUST have at least one string hi:sinceVersion
+""" ] ;
+ rdfs:comment "A description of the support for an extension by a Host" .
+
+hi:extension a rdf:Property ;
+ rdfs:domain hi:ExtensionSupport ;
+ rdfs:range lv2:Specification ;
+ rdfs:label "extension" ;
+ rdfs:comment "Indicates the extension supported by a host." .
+
+hi:sinceVersion a rdf:Property ;
+ rdfs:domain hi:ExtensionSupport ;
+ rdfs:range xsd:string ;
+ rdfs:label "since version" ;
+ rdfs:comment """
+The initial version of a host which supported an extension.
+This property MUST always be given
+""" .
+
+hi:untilVersion a rdf:Property ;
+ rdfs:domain hi:ExtensionSupport ;
+ rdfs:range xsd:string ;
+ rdfs:label "until version" ;
+ rdfs:comment """
+The final version of a host which supported an extension. This property can
+be used if support for an extension was discontinued in a host for some reason.
+""" .
+
diff --git a/ns/ext/host-info/manifest.ttl b/ns/ext/host-info/manifest.ttl
new file mode 100644
index 0000000..ae1e097
--- /dev/null
+++ b/ns/ext/host-info/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/host-info>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <host-info.ttl> .
+
diff --git a/ns/ext/host-info/waf b/ns/ext/host-info/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/host-info/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/host-info/wscript b/ns/ext/host-info/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/host-info/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/instance-access/ext.pc.in b/ns/ext/instance-access/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/instance-access/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/instance-access/instance-access.h b/ns/ext/instance-access/instance-access.h
new file mode 100644
index 0000000..7e18ee4
--- /dev/null
+++ b/ns/ext/instance-access/instance-access.h
@@ -0,0 +1,38 @@
+/*
+ LV2 Instance Access Extension
+ 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.
+*/
+
+#ifndef LV2_INSTANCE_ACCESS_H
+#define LV2_INSTANCE_ACCESS_H
+
+#define LV2_INSTANCE_ACCESS_URI "http://lv2plug.in/ns/ext/instance-access"
+
+
+/** @file
+ * C header for the LV2 Instance Access extension
+ * <http://lv2plug.in/ns/ext/instance-access>.
+ *
+ * This extension defines a method for (e.g.) plugin UIs to get a direct
+ * handle to an LV2 plugin instance (LV2_Handle), if possible.
+ *
+ * To support this feature the host must pass an LV2_Feature struct to the
+ * UI instantiate method with URI "http://lv2plug.in/ns/ext/instance-access"
+ * and data pointed directly to the LV2_Handle of the plugin instance.
+ */
+
+
+#endif /* LV2_INSTANCE_ACCESS_H */
+
diff --git a/ns/ext/instance-access/instance-access.ttl b/ns/ext/instance-access/instance-access.ttl
new file mode 100644
index 0000000..f3d1a42
--- /dev/null
+++ b/ns/ext/instance-access/instance-access.ttl
@@ -0,0 +1,80 @@
+# LV2 Instance Access Extension
+# Copyright 2008-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix ia: <http://lv2plug.in/ns/ext/instance-access#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+<http://lv2plug.in/ns/ext/instance-access>
+ a lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 Instance Access" ;
+ doap:shortdesc "Provides access to the LV2_Handle of a plugin." ;
+ doap:developer <http://drobilla.net/drobilla#me> ;
+ doap:release [
+ doap:revision "1.4" ;
+ doap:created "2011-11-14" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-instance-access-1.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Update packaging."
+ ] , [
+ rdfs:label "Improve documentation."
+ ]
+ ]
+ ] , [
+ doap:revision "1.2" ;
+ doap:created "2011-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-instance-access-1.2.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Add build system for installation."
+ ] , [
+ rdfs:label "Switch to ISC license."
+ ]
+ ]
+ ] , [
+ doap:revision "1.0" ;
+ doap:created "2010-10-04" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-instance-access-1.0.tar.gz> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Initial release."
+ ]
+ ]
+ ] ;
+ lv2:documentation """
+<p>This extension defines a feature which allows plugin UIs to get a direct
+handle to an LV2 plugin instance (LV2_Handle), if possible.</p>
+
+<p>To support this feature the host must pass an LV2_Feature struct to the UI
+instantiate method with URI "http://lv2plug.in/ns/ext/instance-access" and data
+pointed directly to the LV2_Handle of the plugin instance.</p>
+""" .
diff --git a/ns/ext/instance-access/manifest.ttl b/ns/ext/instance-access/manifest.ttl
new file mode 100644
index 0000000..d6412c5
--- /dev/null
+++ b/ns/ext/instance-access/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/instance-access>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 4 ;
+ rdfs:seeAlso <instance-access.ttl> .
+
diff --git a/ns/ext/instance-access/waf b/ns/ext/instance-access/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/instance-access/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/instance-access/wscript b/ns/ext/instance-access/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/instance-access/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/midi/ext.pc.in b/ns/ext/midi/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/midi/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/midi/manifest.ttl b/ns/ext/midi/manifest.ttl
new file mode 100644
index 0000000..a8e194e
--- /dev/null
+++ b/ns/ext/midi/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/midi>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 4 ;
+ rdfs:seeAlso <midi.ttl> .
+
diff --git a/ns/ext/midi/midi.ttl b/ns/ext/midi/midi.ttl
new file mode 100644
index 0000000..0b66f42
--- /dev/null
+++ b/ns/ext/midi/midi.ttl
@@ -0,0 +1,115 @@
+# LV2 MIDI Extension
+# Copyright 2008-2011 David Robillard <d@drobilla.net>
+# Copyright 2006 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.
+
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+_:larsl
+ a foaf:Person ;
+ foaf:name "Lars Luthman" ;
+ foaf:mbox <mailto:lars.luthman@gmail.com> .
+
+<http://lv2plug.in/ns/ext/midi>
+ a lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 MIDI" ;
+ doap:shortdesc "A data type for raw MIDI." ;
+ doap:maintainer <http://drobilla.net/drobilla#me> ;
+ doap:developer _:larsl ;
+ doap:release [
+ doap:revision "1.4" ;
+ doap:created "2011-11-14" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-midi-1.4.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Update packaging."
+ ] , [
+ rdfs:label "Improve documentation."
+ ]
+ ]
+ ] , [
+ doap:revision "1.2" ;
+ doap:created "2011-05-26" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-midi-1.2.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Add build system for installation."
+ ] , [
+ rdfs:label "Switch to ISC license."
+ ]
+ ]
+ ] , [
+ doap:revision "1.0" ;
+ doap:created "2010-10-04" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-midi-1.0.tar.gz> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Initial release."
+ ]
+ ]
+ ] ;
+ lv2:documentation """
+<p>This extension defines a data type for a MIDI message, midi:MidiEvent, which
+is normalized for fast and convenient processing by plugins. It is
+particularly useful as the payload of an <a
+href="http://lv2plug.in/ns/ext/atom#Atom">Atom</a> or <a
+href="http://lv2plug.in/ns/ext/event#Event">Event</a>.</p>
+""" .
+
+midi:MidiEvent
+ a rdfs:Class ;
+ rdfs:label "LV2 MIDI message." ;
+ rdfs:subClassOf ev:Event ,
+ atom:Atom ;
+ lv2:documentation """
+<p>A single raw MIDI message (i.e. a sequence of bytes).</p>
+
+<p>This is equivalent to a standard MIDI messages, except with the following
+restrictions to simplify handling:</p>
+<ul>
+ <li>Running status is not allowed, every message must have its own status
+ byte.</li>
+
+ <li>Note On messages with velocity 0 are not allowed. These messages are
+ equivalent to Note Off in standard MIDI streams, but here only proper Note
+ Off messages are allowed.</li>
+
+ <li>"Realtime messages" (status bytes 0xF8 to 0xFF) are allowed, but may
+ not occur inside other messages like they can in standard MIDI streams.</li>
+
+ <li>All messages are complete valid MIDI messages. This means, for example,
+ that only the first byte in each event (the status byte) may have the eighth
+ bit set, that Note On and Note Off events are always 3 bytes long, etc.
+ Where messages are communicated, the writer is responsible for writing valid
+ messages, and the reader may assume that all events are valid.</li>
+</ul>
+""" .
diff --git a/ns/ext/midi/waf b/ns/ext/midi/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/midi/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/midi/wscript b/ns/ext/midi/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/midi/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/osc/ext.pc.in b/ns/ext/osc/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/osc/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/osc/lv2_osc.c b/ns/ext/osc/lv2_osc.c
new file mode 100644
index 0000000..afea2c9
--- /dev/null
+++ b/ns/ext/osc/lv2_osc.c
@@ -0,0 +1,238 @@
+/* LV2 OSC Messages Extension
+ * Copyright (C) 2007-2009 David Robillard
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "lv2_osc.h"
+#include "lv2_osc_print.h"
+
+/*#ifndef BIG_ENDIAN
+ #ifndef LITTLE_ENDIAN
+ #warning This code requires BIG_ENDIAN or LITTLE_ENDIAN to be defined
+ #warning Assuming little endian. THIS MAY BREAK HORRIBLY!
+ #endif
+#endif*/
+
+#define lv2_osc_swap32(x) \
+({ \
+ uint32_t __x = (x); \
+ ((uint32_t)( \
+ (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
+ (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
+})
+
+#define lv2_osc_swap64(x) \
+({ \
+ uint64_t __x = (x); \
+ ((uint64_t)( \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
+})
+
+
+/** Pad a size to a multiple of 32 bits */
+inline static uint32_t
+lv2_osc_pad_size(uint32_t size)
+{
+ return size + 3 - ((size-1) % 4);
+}
+
+
+inline static uint32_t
+lv2_osc_string_size(const char *s)
+{
+ return lv2_osc_pad_size((uint32_t)strlen(s) + 1);
+}
+
+
+static inline uint32_t
+lv2_osc_blob_size(const void* blob)
+{
+ return sizeof(uint32_t) + lv2_osc_pad_size(*((uint32_t*)blob));
+}
+
+
+uint32_t
+lv2_osc_arg_size(char type, const LV2_OSC_Argument* arg)
+{
+ switch (type) {
+ case 'c':
+ case 'i':
+ case 'f':
+ case 'S': // Symbol (URI-mapped integer)
+ return 4;
+
+ case 'h':
+ case 'd':
+ return 8;
+
+ case 's':
+ return lv2_osc_string_size(&arg->s);
+
+ case 'b':
+ return lv2_osc_blob_size(&arg->b);
+
+ default:
+ fprintf(stderr, "Warning: unknown OSC type '%c'.", type);
+ return 0;
+ }
+}
+
+
+void
+lv2_osc_argument_swap_byte_order(char type, LV2_OSC_Argument* arg)
+{
+ switch (type) {
+ case 'i':
+ case 'f':
+ case 'b':
+ case 'c':
+ *(int32_t*)arg = lv2_osc_swap32(*(int32_t*)arg);
+ break;
+
+ case 'h':
+ case 'd':
+ *(int64_t*)arg = lv2_osc_swap64(*(int64_t*)arg);
+ break;
+ }
+}
+
+
+/** Convert a message from network byte order to host byte order. */
+void
+lv2_osc_message_swap_byte_order(LV2_OSC_Event* msg)
+{
+ const char* const types = lv2_osc_get_types(msg);
+
+ for (uint32_t i=0; i < msg->argument_count; ++i)
+ lv2_osc_argument_swap_byte_order(types[i], lv2_osc_get_argument(msg, i));
+}
+
+
+/** Not realtime safe, returned value must be free()'d by caller. */
+LV2_OSC_Event*
+lv2_osc_message_new(const char* path, const char* types, ...)
+{
+ /* FIXME: path only */
+
+ LV2_OSC_Event* result = malloc(sizeof(LV2_OSC_Event)
+ + 4 + lv2_osc_string_size(path));
+
+ const uint32_t path_size = lv2_osc_string_size(path);
+ result->data_size = path_size + 4; // 4 for types
+ result->argument_count = 0;
+ result->types_offset = lv2_osc_string_size(path) + 1;
+ (&result->data)[result->types_offset - 1] = ',';
+ (&result->data)[result->types_offset] = '\0';
+
+ memcpy(&result->data, path, strlen(path) + 1);
+
+ return result;
+}
+
+
+/** Create a new LV2_OSC_Event from a raw OSC message.
+ *
+ * If \a out_buf is NULL, new memory will be allocated. Otherwise the returned
+ * value will be equal to buf, unless there is insufficient space in which
+ * case NULL is returned.
+ */
+LV2_OSC_Event*
+lv2_osc_message_from_raw(uint32_t out_buf_size,
+ void* out_buf,
+ uint32_t raw_msg_size,
+ void* raw_msg)
+{
+ const uint32_t message_header_size = (sizeof(uint32_t) * 4);
+
+ const uint32_t path_size = lv2_osc_string_size((char*)raw_msg);
+ const uint32_t types_len = strlen((char*)(raw_msg + path_size + 1));
+ uint32_t index_size = types_len * sizeof(uint32_t);
+
+ if (out_buf == NULL) {
+ out_buf_size = message_header_size + index_size + raw_msg_size;
+ out_buf = malloc((size_t)out_buf_size);
+ } else if (out_buf && out_buf_size < message_header_size + raw_msg_size) {
+ return NULL;
+ }
+
+ LV2_OSC_Event* write_loc = (LV2_OSC_Event*)(out_buf);
+ write_loc->argument_count = types_len;
+ write_loc->data_size = index_size + raw_msg_size;
+
+ // Copy raw message
+ memcpy(&write_loc->data + index_size, raw_msg, raw_msg_size);
+
+ write_loc->types_offset = index_size + path_size + 1;
+ const char* const types = lv2_osc_get_types(write_loc);
+
+ // Calculate/Write index
+ uint32_t args_base_offset = write_loc->types_offset + lv2_osc_string_size(types) - 1;
+ uint32_t arg_offset = 0;
+
+ for (uint32_t i=0; i < write_loc->argument_count; ++i) {
+ ((uint32_t*)&write_loc->data)[i] = args_base_offset + arg_offset;
+ const LV2_OSC_Argument* const arg = (LV2_OSC_Argument*)(&write_loc->data + args_base_offset + arg_offset);
+ // Special case because size is still big-endian
+#ifndef BIG_ENDIAN
+ if (types[i] == 'b') // special case because size is still big-endian
+ arg_offset += lv2_osc_swap32(*((int32_t*)arg));
+ else
+#endif
+ arg_offset += lv2_osc_arg_size(types[i], arg);
+ }
+
+ /*printf("Index:\n");
+ for (uint32_t i=0; i < write_loc->argument_count; ++i) {
+ printf("%u ", ((uint32_t*)&write_loc->data)[i]);
+ }
+ printf("\n");
+
+ printf("Data:\n");
+ for (uint32_t i=0; i < (write_loc->argument_count * 4) + size; ++i) {
+ printf("%3u", i % 10);
+ }
+ printf("\n");
+ for (uint32_t i=0; i < (write_loc->argument_count * 4) + size; ++i) {
+ char c = *(((char*)&write_loc->data) + i);
+ if (c >= 32 && c <= 126)
+ printf("%3c", c);
+ else
+ printf("%3d", (int)c);
+ }
+ printf("\n");*/
+
+ // Swap to host byte order if necessary
+#ifndef BIG_ENDIAN
+ lv2_osc_message_swap_byte_order(write_loc);
+#endif
+
+ printf("Created message:\n");
+ lv2_osc_message_print(write_loc);
+
+ return write_loc;
+}
diff --git a/ns/ext/osc/lv2_osc_print.c b/ns/ext/osc/lv2_osc_print.c
new file mode 100644
index 0000000..5282d46
--- /dev/null
+++ b/ns/ext/osc/lv2_osc_print.c
@@ -0,0 +1,66 @@
+/* LV2 OSC Messages Extension - Pretty printing methods
+ * Copyright (C) 2007-2009 David Robillard
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include "lv2_osc_print.h"
+
+void
+lv2_osc_argument_print(char type, const LV2_OSC_Argument* arg)
+{
+ int32_t blob_size;
+
+ switch (type) {
+ case 'c':
+ printf("%c", arg->c); break;
+ case 'i':
+ printf("%d", arg->i); break;
+ case 'f':
+ printf("%f", arg->f); break;
+ case 'h':
+ printf("%ld", arg->h); break;
+ case 'd':
+ printf("%f", arg->d); break;
+ case 's':
+ printf("\"%s\"", &arg->s); break;
+ /*case 'S':
+ printf("\"%s\"", &arg->S); break;*/
+ case 'b':
+ blob_size = *((int32_t*)arg);
+ printf("{ ");
+ for (int32_t i=0; i < blob_size; ++i)
+ printf("%X, ", (&arg->b)[i+4]);
+ printf(" }");
+ break;
+ default:
+ printf("?");
+ }
+}
+
+
+void
+lv2_osc_print(const LV2_OSC_Event* msg)
+{
+ const char* const types = lv2_osc_get_types(msg);
+
+ printf("%s (%s) ", lv2_osc_get_path(msg), types);
+ for (uint32_t i=0; i < msg->argument_count; ++i) {
+ lv2_osc_argument_print(types[i], lv2_osc_get_argument(msg, i));
+ printf(" ");
+ }
+ printf("\n");
+}
+
diff --git a/ns/ext/osc/lv2_osc_test.c b/ns/ext/osc/lv2_osc_test.c
new file mode 100644
index 0000000..3f76d41
--- /dev/null
+++ b/ns/ext/osc/lv2_osc_test.c
@@ -0,0 +1,55 @@
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <lo/lo.h>
+#include "lv2_osc.h"
+#include "lv2_osc_print.h"
+
+int
+main()
+{
+ lo_message lo_msg = lo_message_new();
+ //lo_message_add_symbol(lo_msg, "a_sym");
+ lo_message_add_string(lo_msg, "Hello World");
+ lo_message_add_char(lo_msg, 'a');
+ lo_message_add_int32(lo_msg, 1234);
+ lo_message_add_float(lo_msg, 0.1234);
+ lo_message_add_int64(lo_msg, 5678);
+ lo_message_add_double(lo_msg, 0.5678);
+
+
+ /*unsigned char blob_data[] = { 0,1,2,3,4,5,6,7,8,9 };
+ lo_blob blob = lo_blob_new(10, blob_data);
+ lo_message_add_blob(lo_msg, blob);*/
+
+ /* Leaks like a sieve */
+
+ size_t raw_msg_size = 0;
+ void* raw_msg = lo_message_serialise(lo_msg, "/foo/bar", NULL, &raw_msg_size);
+
+ LV2Message* msg = lv2_osc_message_from_raw(0.0, 0, NULL, raw_msg_size, raw_msg);
+ assert(msg);
+
+ LV2OSCBuffer* buf = lv2_osc_buffer_new(1024);
+
+ int ret = lv2_osc_buffer_append_message(buf, msg);
+ if (ret)
+ fprintf(stderr, "Message append failed: %s", strerror(ret));
+
+ lo_message lo_msg_2 = lo_message_new();
+ lo_message_add_string(lo_msg_2, "Another message");
+
+ raw_msg = lo_message_serialise(lo_msg_2, "/baz", NULL, &raw_msg_size);
+
+ msg = lv2_osc_message_from_raw(0.0, 0, NULL, raw_msg_size, raw_msg);
+ assert(msg);
+
+ ret = lv2_osc_buffer_append_message(buf, msg);
+ if (ret)
+ fprintf(stderr, "Message append failed: %s", strerror(ret));
+
+ printf("\nBuffer contents:\n\n");
+ lv2_osc_buffer_print(buf);
+
+ return 0;
+}
diff --git a/ns/ext/osc/manifest.ttl b/ns/ext/osc/manifest.ttl
new file mode 100644
index 0000000..7209b05
--- /dev/null
+++ b/ns/ext/osc/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/osc>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <osc.ttl> .
+
diff --git a/ns/ext/osc/osc-print.h b/ns/ext/osc/osc-print.h
new file mode 100644
index 0000000..ceebbf7
--- /dev/null
+++ b/ns/ext/osc/osc-print.h
@@ -0,0 +1,42 @@
+/* LV2 OSC Messages Extension - Pretty printing methods
+ * Copyright (C) 2007-2009 David Robillard
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Helper functions for printing LV2 OSC messages as defined by the
+ * LV2 OSC extension <http://lv2plug.in/ns/ext/osc>.
+ */
+
+#ifndef LV2_OSC_PRINT_H
+#define LV2_OSC_PRINT_H
+
+#include "lv2/lv2plug.in/ns/ext/osc/osc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+lv2_osc_argument_print(char type, const LV2_OSC_Argument* arg);
+
+void
+lv2_osc_message_print(const LV2_OSC_Event* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LV2_OSC_PRINT_H */
diff --git a/ns/ext/osc/osc.h b/ns/ext/osc/osc.h
new file mode 100644
index 0000000..05e39cc
--- /dev/null
+++ b/ns/ext/osc/osc.h
@@ -0,0 +1,119 @@
+/* LV2 OSC Messages Extension
+ * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LV2_OSC_H
+#define LV2_OSC_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ * C header for the LV2 OSC extension <http://lv2plug.in/ns/ext/osc>.
+ * This extension defines a format for (raw) OSC messages/events.
+ */
+
+
+/** Argument (in a message).
+ *
+ * The name of the element in this union directly corresponds to the OSC
+ * type tag character in LV2_Event::types.
+ */
+typedef union {
+ /* Standard OSC types */
+ int32_t i; /**< 32 bit signed integer */
+ float f; /**< 32 bit IEEE-754 floating point number ("float") */
+ char s; /**< Standard C, NULL terminated string */
+ uint8_t b; /**< Blob (int32 size then size bytes padded to 32 bits) */
+
+ /* "Nonstandard" OSC types (defined in the OSC standard) */
+ int64_t h; /* 64 bit signed integer */
+ // t /* OSC-timetag */
+ double d; /* 64 bit IEEE 754 floating point number ("double") */
+ // S /* Symbol, represented as an OSC-string */
+ int32_t c; /* Character, represented as a 32-bit integer */
+ // r /* 32 bit RGBA color */
+ // m /* 4 byte MIDI message. Bytes from MSB to LSB are: port id, status byte, data1, data2 */
+ // T /* True. No bytes are allocated in the argument data. */
+ // F /* False. No bytes are allocated in the argument data. */
+ // N /* Nil. No bytes are allocated in the argument data. */
+ // I /* Infinitum. No bytes are allocated in the argument data. */
+ // [ /* The beginning of an array. */
+ // ] /* The end of an array. */
+} LV2_OSC_Argument;
+
+
+
+/** Message.
+ *
+ * This is an OSC message at heart, but with some additional cache information
+ * to allow fast access to parameters. This is the payload of an LV2_Event,
+ * time stamp and size (being generic) are in the containing header.
+ */
+typedef struct {
+ uint32_t data_size; /**< Total size of data, in bytes */
+ uint32_t argument_count; /**< Number of arguments in data */
+ uint32_t types_offset; /**< Offset of types string in data */
+
+ /** Take the address of this member to get a pointer to the remaining data.
+ *
+ * Contents are an argument index:
+ * uint32_t argument_index[argument_count]
+ *
+ * followed by a standard OSC message:
+ * char path[path_length] (padded OSC string)
+ * char types[argument_count] (padded OSC string)
+ * void data[data_size]
+ */
+ char data;
+
+} LV2_OSC_Event;
+
+LV2_OSC_Event* lv2_osc_event_new(const char* path, const char* types, ...);
+
+LV2_OSC_Event* lv2_osc_event_from_raw(uint32_t out_buf_size, void* out_buf,
+ uint32_t raw_msg_size, void* raw_msg);
+
+static inline uint32_t lv2_osc_get_osc_message_size(const LV2_OSC_Event* msg)
+ { return (msg->argument_count * sizeof(char) + 1) + msg->data_size; }
+
+static inline const void* lv2_osc_get_osc_message(const LV2_OSC_Event* msg)
+ { return (const void*)(&msg->data + (sizeof(uint32_t) * msg->argument_count)); }
+
+static inline const char* lv2_osc_get_path(const LV2_OSC_Event* msg)
+ { return (const char*)(&msg->data + (sizeof(uint32_t) * msg->argument_count)); }
+
+static inline const char* lv2_osc_get_types(const LV2_OSC_Event* msg)
+ { return (const char*)(&msg->data + msg->types_offset); }
+
+static inline LV2_OSC_Argument* lv2_osc_get_argument(const LV2_OSC_Event* msg, uint32_t i)
+ { return (LV2_OSC_Argument*)(&msg->data + ((uint32_t*)&msg->data)[i]); }
+
+/*
+int lv2_osc_buffer_append_message(LV2_Event_Buffer* buf, LV2_Event* msg);
+int lv2_osc_buffer_append(LV2_Event_Buffer* buf, double time, const char* path, const char* types, ...);
+void lv2_osc_buffer_compact(LV2_Event_Buffer* buf);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LV2_OSC_H */
diff --git a/ns/ext/osc/osc.ttl b/ns/ext/osc/osc.ttl
new file mode 100644
index 0000000..c83a69d
--- /dev/null
+++ b/ns/ext/osc/osc.ttl
@@ -0,0 +1,39 @@
+# LV2 OSC Messages Extension
+# Copyright (C) 2007 David Robillard <d@drobilla.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix osc: <http://lv2plug.in/ns/ext/osc#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/osc> a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 OSC Events" ;
+ doap:shortdesc "A data type for raw OSC." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.xrdf>
+ ] .
diff --git a/ns/ext/osc/waf b/ns/ext/osc/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/osc/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/osc/wscript b/ns/ext/osc/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/osc/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/parameter/ext.pc.in b/ns/ext/parameter/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/parameter/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/parameter/manifest.ttl b/ns/ext/parameter/manifest.ttl
new file mode 100644
index 0000000..d7af7ff
--- /dev/null
+++ b/ns/ext/parameter/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/parameter>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <parameter.ttl> .
+
diff --git a/ns/ext/parameter/parameter.ttl b/ns/ext/parameter/parameter.ttl
new file mode 100644
index 0000000..191aa81
--- /dev/null
+++ b/ns/ext/parameter/parameter.ttl
@@ -0,0 +1,111 @@
+# LV2 Parameter Extension
+# Copyright (C) 2010 David Robillard <d@drobilla.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix param: <http://lv2plug.in/ns/ext/parameter#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/parameter>
+ a lv2:Specification ;
+ doap:name "LV2 Parameter" ;
+ doap:shortdesc "Dynamic message-controlled LV2 plugin parameters." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ rdfs:comment """
+""" .
+
+
+param:Parameter a rdfs:Class ; a lv2:Resource ;
+ rdfs:label "Parameter" ;
+ lv2:documentation """
+<p>A parameter on an LV2 plugin. Parameters can be manipulated to alter
+the behaviour or output of a plugin. Unlike lv2:ControlPort:</p>
+<ul>
+<li>A parameter may have any data type</li>
+<li>Parameters can be dynamically added or removed</li>
+<li>Parameter values can be manipulated by the plugin</li>
+</ul>
+
+<p>Note that plugins are not required to support this potential functionality,
+parameters can be used to provide a basic LADSPA-like set of floating point
+parameters in a more extensible manner.</p>
+
+<p>Parameters are essentially controls that are not 1:1 associated with ports
+(manipulation of parameters can be accomplished by e.g. sending messages
+to a command port).</p>
+""" .
+
+
+param:supportsType a rdf:Property ;
+ rdfs:domain param:Parameter ;
+ rdfs:range atom:AtomType ;
+ rdfs:label "supports type" ;
+ lv2:documentation """
+<p>Indicates that a Parameter has values of a particular type. A Parameter may
+support many types. Parameter values are always LV2 Atoms as defined by the <a
+href="http://lv2plug.in/ns/ext/atom">LV2 Atom</a> Extension Any type of LV2
+Atom may be used as a parameter value.</p>
+""" .
+
+
+param:value a rdf:Property ;
+ rdfs:domain param:Parameter ;
+ rdfs:label "value" ;
+ rdfs:comment """
+Indicates that a Parameter has a certain value. A Parameter has at most
+one value at any given time. The type of the value specified must be
+one of the types specified by param:supportsType. When used in a plugin
+data file this property specifies the default value of a parameter.
+""" .
+
+
+param:minimum a rdf:Property ;
+ rdfs:domain param:Parameter ;
+ rdfs:label "minimum" ;
+ rdfs:comment """
+Specifies the minimum value of a Parameter (for Parameters with comparable
+types for which this makes sense). The type of the minimum must be one of
+the types specified by param:supportsType. The host MAY attempt to set a
+parameter to any value (of a legal type), i.e. the plugin MUST NOT assume
+attempts to change a parameter are within range and SHOULD clamp accordingly.
+""" .
+
+
+param:maximum a rdf:Property ;
+ rdfs:domain param:Parameter ;
+ rdfs:label "maximum" ;
+ rdfs:comment """
+Specifies the maximum value of a Parameter (for Parameters with comparable
+types for which this makes sense). The type of the maximum must be one of
+the types specified by param:supportsType. The host MAY attempt to set a
+parameter to any value (of a legal type), i.e. the plugin MUST NOT assume
+attempts to change a parameter are within range and SHOULD clamp accordingly.
+""" .
+
diff --git a/ns/ext/parameter/waf b/ns/ext/parameter/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/parameter/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/parameter/wscript b/ns/ext/parameter/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/parameter/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/port-groups/ext.pc.in b/ns/ext/port-groups/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/port-groups/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/port-groups/manifest.ttl b/ns/ext/port-groups/manifest.ttl
new file mode 100644
index 0000000..ff4205b
--- /dev/null
+++ b/ns/ext/port-groups/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/port-groups>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <port-groups.ttl> .
+
diff --git a/ns/ext/port-groups/port-groups.ttl b/ns/ext/port-groups/port-groups.ttl
new file mode 100644
index 0000000..b584a25
--- /dev/null
+++ b/ns/ext/port-groups/port-groups.ttl
@@ -0,0 +1,490 @@
+# LV2 Port Groups Extension
+# PROVISIONAL
+# Copyright (C) 2009 David Robillard <d@drobilla.net>
+# Copyright (C) 2008-2009 Lars Luthman <lars.luthman@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix amb: <http://ambisonics.ch/standards/channels/> .
+
+<http://lv2plug.in/ns/ext/port-groups> a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 Port Groups" ;
+ doap:shortdesc "Multi-channel groups of LV2 ports." ;
+ rdfs:comment "Defines semantic groupings of LV2 ports" ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "Lars Luthman" ;
+ foaf:mbox <mailto:lars.luthman@gmail.com>
+ ] , [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] .
+
+
+## Core Classes / Properties
+
+pg:Group a rdfs:Class ;
+ rdfs:label "LV2 Port Group" ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty lv2:symbol ;
+ owl:someValuesFrom xsd:string ;
+ owl:cardinality 1 ;
+ rdfs:comment """
+A pg:Group MUST have exactly one string lv2:symbol. This symbol must be
+unique according to the same rules as the lv2:symbol for an lv2:Port, where
+group symbols and port symbols reside in the same namespace. In other words,
+a group on a plugin MUST NOT have the same symbol as another group or a port
+on that plugin. Rationale: Hosts or bindings may find it useful to construct
+an identifier to refer to groups for the same reasons this is useful for ports.
+"""
+ ] ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty pg:hasRole ;
+ owl:someValuesFrom pg:RoleAssignment ;
+ owl:minCardinality 1 ;
+ rdfs:comment "A Group MUST have at least one role assignment"
+ ] ;
+ rdfs:comment """
+A grouping of ports that can be logically considered a single "stream", e.g.
+two audio ports in a group may form a stereo stream. The pg:source predicate
+can also be used to describe this correspondence between separate ports/groups.
+""" .
+
+pg:index a rdf:Property ;
+ rdfs:domain pg:RoleAssignment ;
+ rdfs:range xsd:nonNegativeInteger ;
+ rdfs:label "index" ;
+ rdfs:comment "Index of a role within some group" .
+
+pg:RoleAssignment a rdfs:Class ;
+ rdfs:label "Role Assignment" ;
+ rdfs:comment "A numbered role within some Group." ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty pg:index ;
+ owl:cardinality 1 ;
+ rdfs:comment """
+A RoleAssignment MUST have exactly one index.
+""" ] ;
+ rdfs:subClassOf [ a owl:Restriction ;
+ owl:onProperty pg:role ;
+ owl:cardinality 1 ;
+ rdfs:comment """
+A RoleAssignment MUST have exactly one role.
+""" ] ;
+ rdfs:comment """
+All group definitions MUST define the order of channels. Note that this
+does not have anything to do with port indices, this information is only
+defined here for use by other extensions. For simply assigning groups
+and roles to a basic LV2 plugin, index is irrelevant.
+""" .
+
+pg:hasChannel a rdf:Property ;
+ rdfs:domain pg:Group ;
+ rdfs:range pg:Channel ;
+ rdfs:label "Has port with role" ;
+ rdfs:comment """
+Indicates that a group always has a port with a particular role.
+""" .
+
+pg:sideChainOf a rdf:Property ;
+ rdfs:domain pg:Group , lv2:Port ;
+ rdfs:range pg:Group , lv2:Port ;
+ rdfs:label "Side-chain of" ;
+ rdfs:comment """
+Indicates that this port or group should be considered a "side chain" of
+some other port or group. The precise definition of "side chain" depends
+on the plugin, but in general this group should be considered a modifier to
+some other group, rather than an independent input itself.
+""" .
+
+pg:subGroupOf a rdf:Property ;
+ rdfs:domain pg:Group ;
+ rdfs:range pg:Group ;
+ rdfs:label "Sub-group of" ;
+ rdfs:comment """
+Indicates that this group is a child of another group. This property has
+no meaning with respect to plugin execution, but the host may find this
+information useful (e.g. to provide a compact user interface). Note that
+all groups on a plugin MUST have a unique symbol with respect to the plugin
+as documented for pg:Group, i.e. sub-groups must have a unique symbol among
+all groups and ports on the plugin.
+""" .
+
+pg:source a rdf:Property ;
+ rdfs:domain pg:Group , lv2:Port ;
+ rdfs:range pg:Group , lv2:Port ;
+ rdfs:label "Source group" ;
+ rdfs:comment """
+Indicates that this port or group should be considered the "result" of
+some other port or group. This property only makes sense on groups with
+outputs when the source is a group with inputs. This can be used to convey
+a relationship between corresponding input and output groups with different
+types, e.g. a mono->stereo plugin.
+""" .
+
+pg:mainGroup a rdf:Property ;
+ rdfs:domain lv2:Plugin ;
+ rdfs:range pg:Group ;
+ rdfs:label "Main port group" ;
+ rdfs:comment """
+Indicates that this group should be considered the "main" inputs/outputs of
+the plugin, e.g. it probably makes sense to just connect main groups and set
+some controls. A plugin MUST NOT have more than one :mainGroup property.
+High-level hosts that simply want to insert an plugin in a given stream
+should use this property to determine where the plugin 'fits'.
+""" .
+
+pg:inGroup a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range pg:Group ;
+ rdfs:label "In port group" ;
+ rdfs:comment """
+Indicates that this port is a part of a group of ports on the plugin.
+Ports that have a meaningful "role" that may be useful to hosts SHOULD also
+have a :role property, otherwise ports in the group have no meaningful order.
+""" .
+
+pg:Role a rdfs:Class ;
+ rdfs:label "Port role" ;
+ rdfs:comment """
+The role of a port with respect to its plugin or group. If the port is a
+member of a group (has an :inGroup property) the role is relevant with respect
+to that group. Otherwise the role is relevant with respect to the plugin.
+""" .
+
+pg:role a rdf:Property ;
+ rdfs:domain pg:Port , pg:RoleAssignment;
+ rdfs:range pg:Role ;
+ rdfs:label "Role" ;
+ rdfs:comment """
+Indicates that this port has a particular role with respect to its enclosing
+plugin or group (whichever is smaller). A port may have several roles if it
+makes sense to do so (though some Role or Group definition may forbid this).
+""" .
+
+
+# Discrete
+
+pg:DiscreteGroup a rdfs:Class ;
+ rdfs:subClassOf pg:Group ;
+ rdfs:comment """
+"Discrete" channel configurations. These groups are divided into channels
+where each represents a particular speaker location. The position of sound
+in one of these groups depends on a particular speaker configuration.
+""" .
+
+pg:leftChannel a pg:Role ; rdfs:label "Left" .
+pg:rightChannel a pg:Role ; rdfs:label "Right" .
+pg:centerChannel a pg:Role ; rdfs:label "Center" .
+pg:sideChannel a pg:Role ; rdfs:label "Side" .
+pg:centerLeftChannel a pg:Role ; rdfs:label "Center Left" .
+pg:centerRightChannel a pg:Role ; rdfs:label "Center Right" .
+pg:sideLeftChannel a pg:Role ; rdfs:label "Side Left" .
+pg:sideRightChannel a pg:Role ; rdfs:label "Side Right" .
+pg:rearLeftChannel a pg:Role ; rdfs:label "Rear Left" .
+pg:rearRightChannel a pg:Role ; rdfs:label "Rear Right" .
+pg:rearCenterChannel a pg:Role ; rdfs:label "Rear Center" .
+pg:lfeChannel a pg:Role ; rdfs:label "Sub (LFE)" .
+
+pg:MonoGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "Mono" ;
+ pg:hasRole [ pg:index 0; pg:role pg:centerChannel ] .
+
+pg:StereoGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "Stereo" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:rightChannel ] .
+
+pg:MidSideGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "Mid-Side Stereo" ;
+ pg:hasRole [ pg:index 0; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:sideChannel ] .
+
+pg:ThreePointZeroGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "3.0 Surround" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rearCenterChannel ] .
+
+pg:FourPointZeroGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "4.0 Surround (Quadraphonic)" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:rearCenterChannel ] .
+
+pg:FivePointZeroGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "5.0 Surround (3-2 stereo)" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:rearLeftChannel ] ;
+ pg:hasRole [ pg:index 4; pg:role pg:rearRightChannel ] .
+
+pg:FivePointOneGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "5.1 Surround (3-2 stereo)" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:rearLeftChannel ] ;
+ pg:hasRole [ pg:index 4; pg:role pg:rearRightChannel ] ;
+ pg:hasRole [ pg:index 5; pg:role pg:lfeChannel ] .
+
+pg:SixPointOneGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "6.1 Surround" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:sideLeftChannel ] ;
+ pg:hasRole [ pg:index 4; pg:role pg:sideRightChannel ] ;
+ pg:hasRole [ pg:index 5; pg:role pg:rearCenterChannel ] ;
+ pg:hasRole [ pg:index 6; pg:role pg:lfeChannel ] .
+
+pg:SevenPointOneGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "7.1 Surround" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:sideLeftChannel ] ;
+ pg:hasRole [ pg:index 4; pg:role pg:sideRightChannel ] ;
+ pg:hasRole [ pg:index 5; pg:role pg:rearLeftChannel ] ;
+ pg:hasRole [ pg:index 6; pg:role pg:rearRightChannel ] ;
+ pg:hasRole [ pg:index 7; pg:role pg:lfeChannel ] .
+
+pg:SevenPointOneWideGroup a rdfs:Class ;
+ rdfs:subClassOf pg:DiscreteGroup ;
+ rdfs:label "7.1 Surround (Wide)" ;
+ pg:hasRole [ pg:index 0; pg:role pg:leftChannel ] ;
+ pg:hasRole [ pg:index 1; pg:role pg:centerLeftChannel ] ;
+ pg:hasRole [ pg:index 2; pg:role pg:centerChannel ] ;
+ pg:hasRole [ pg:index 3; pg:role pg:centerRightChannel ] ;
+ pg:hasRole [ pg:index 4; pg:role pg:rightChannel ] ;
+ pg:hasRole [ pg:index 5; pg:role pg:leftRearChannel ] ;
+ pg:hasRole [ pg:index 6; pg:role pg:rightRearChannel ] ;
+ pg:hasRole [ pg:index 7; pg:role pg:lfeChannel ] .
+
+
+# Ambisonic
+
+pg:AmbisonicGroup a rdfs:Class ;
+ rdfs:subClassOf pg:Group ;
+ rdfs:comment """
+"Ambisonic" channel configurations. These groups are divided into channels
+which together represent a position in an abstract n-dimensional space.
+The position of sound in one of these groups does not depend on a particular
+speaker configuration; a decoder can be used to convert an ambisonic stream
+for any speaker configuration.
+""" .
+
+#amb:ACN0 a pg:Role ; rdfs:label "ACN 0 (W)" .
+#amb:ACN1 a pg:Role ; rdfs:label "ACN 1 (Y)" .
+#amb:ACN2 a pg:Role ; rdfs:label "ACN 2 (Z)" .
+#amb:ACN3 a pg:Role ; rdfs:label "ACN 3 (X)" .
+#amb:ACN4 a pg:Role ; rdfs:label "ACN 4 (V)" .
+#amb:ACN5 a pg:Role ; rdfs:label "ACN 5 (T)" .
+#amb:ACN6 a pg:Role ; rdfs:label "ACN 6 (R)" .
+#amb:ACN7 a pg:Role ; rdfs:label "ACN 7 (S)" .
+#amb:ACN8 a pg:Role ; rdfs:label "ACN 8 (U)" .
+#amb:ACN9 a pg:Role ; rdfs:label "ACN 9 (Q)" .
+#amb:ACN10 a pg:Role ; rdfs:label "ACN 10 (O)" .
+#amb:ACN11 a pg:Role ; rdfs:label "ACN 11 (M)" .
+#amb:ACN12 a pg:Role ; rdfs:label "ACN 12 (K)" .
+#amb:ACN13 a pg:Role ; rdfs:label "ACN 13 (L)" .
+#amb:ACN14 a pg:Role ; rdfs:label "ACN 14 (N)" .
+#amb:ACN15 a pg:Role ; rdfs:label "ACN 15 (P)" .
+
+pg:AmbisonicBH1P0Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 1 and peripheral order 0." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN3 ] .
+
+pg:AmbisonicBH1P1Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 1 and peripheral order 1." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] .
+
+pg:AmbisonicBH2P0Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 0." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN8 ] .
+
+pg:AmbisonicBH2P1Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 1." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN8 ] .
+
+pg:AmbisonicBH2P2Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 2." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN5 ] ;
+ pg:hasRole [ pg:index 6; pg:role amb:ACN6 ] ;
+ pg:hasRole [ pg:index 7; pg:role amb:ACN7 ] ;
+ pg:hasRole [ pg:index 8; pg:role amb:ACN8 ] .
+
+pg:AmbisonicBH3P0Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 0." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN8 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN9 ] ;
+ pg:hasRole [ pg:index 6; pg:role amb:ACN15 ] .
+
+pg:AmbisonicBH3P1Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 1." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN8 ] ;
+ pg:hasRole [ pg:index 6; pg:role amb:ACN9 ] ;
+ pg:hasRole [ pg:index 7; pg:role amb:ACN15 ] .
+
+pg:AmbisonicBH3P2Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 2." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN5 ] ;
+ pg:hasRole [ pg:index 6; pg:role amb:ACN6 ] ;
+ pg:hasRole [ pg:index 7; pg:role amb:ACN7 ] ;
+ pg:hasRole [ pg:index 8; pg:role amb:ACN8 ] ;
+ pg:hasRole [ pg:index 9; pg:role amb:ACN9 ] ;
+ pg:hasRole [ pg:index 10; pg:role amb:ACN15 ] .
+
+pg:AmbisonicBH3P3Group a rdfs:Class ;
+ rdfs:subClassOf pg:AmbisonicGroup ;
+ rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 3." ;
+ pg:hasRole [ pg:index 0; pg:role amb:ACN0 ] ;
+ pg:hasRole [ pg:index 1; pg:role amb:ACN1 ] ;
+ pg:hasRole [ pg:index 2; pg:role amb:ACN2 ] ;
+ pg:hasRole [ pg:index 3; pg:role amb:ACN3 ] ;
+ pg:hasRole [ pg:index 4; pg:role amb:ACN4 ] ;
+ pg:hasRole [ pg:index 5; pg:role amb:ACN5 ] ;
+ pg:hasRole [ pg:index 6; pg:role amb:ACN6 ] ;
+ pg:hasRole [ pg:index 7; pg:role amb:ACN7 ] ;
+ pg:hasRole [ pg:index 8; pg:role amb:ACN8 ] ;
+ pg:hasRole [ pg:index 9; pg:role amb:ACN9 ] ;
+ pg:hasRole [ pg:index 10; pg:role amb:ACN10 ] ;
+ pg:hasRole [ pg:index 11; pg:role amb:ACN11 ] ;
+ pg:hasRole [ pg:index 12; pg:role amb:ACN12 ] ;
+ pg:hasRole [ pg:index 13; pg:role amb:ACN13 ] ;
+ pg:hasRole [ pg:index 14; pg:role amb:ACN14 ] ;
+ pg:hasRole [ pg:index 15; pg:role amb:ACN15 ] .
+
+
+# Controls
+
+pg:ControlGroup a rdfs:Class ;
+ rdfs:subClassOf pg:Group ;
+ rdfs:comment """
+A group representing a set of associated controls.
+""" .
+
+pg:amplitude a pg:Role ; rdfs:label "Amplitude" .
+pg:attack a pg:Role ; rdfs:label "Attack" .
+pg:cutoffFrequency a pg:Role ; rdfs:label "Cutoff Frequency" .
+pg:decay a pg:Role ; rdfs:label "Decay" .
+pg:delay a pg:Role ; rdfs:label "Delay" .
+pg:frequency a pg:Role ; rdfs:label "Frequency" .
+pg:hold a pg:Role ; rdfs:label "Hold" .
+pg:pulseWidth a pg:Role ; rdfs:label "Pulse Width" .
+pg:ratio a pg:Role ; rdfs:label "Ratio" .
+pg:release a pg:Role ; rdfs:label "Release" .
+pg:resonance a pg:Role ; rdfs:label "Resonance" .
+pg:sustain a pg:Role ; rdfs:label "Sustain" .
+pg:threshold a pg:Role ; rdfs:label "Threshold" .
+pg:waveform a pg:Role ; rdfs:label "Waveform" .
+
+pg:EnvelopeControlGroup a rdfs:Class ;
+ rdfs:subClassOf pg:ControlGroup ;
+ rdfs:label "Controls for a DAHDSR envelope." ;
+ pg:mayHavePort pg:delay ;
+ pg:mayHavePort pg:attack ;
+ pg:mayHavePort pg:hold ;
+ pg:mayHavePort pg:decay ;
+ pg:mayHavePort pg:sustain ;
+ pg:mayHavePort pg:release .
+
+pg:OscillatorControlGroup a rdfs:Class ;
+ rdfs:subClassOf pg:ControlGroup ;
+ rdfs:label "Controls for an oscillator." ;
+ pg:mayHavePort pg:frequency ;
+ pg:mayHavePort pg:amplitude ;
+ pg:mayHavePort pg:waveform ;
+ pg:mayHavePort pg:pulseWidth .
+
+pg:FilterControlGroup a rdfs:Class ;
+ rdfs:subClassOf pg:ControlGroup ;
+ rdfs:label "Controls for a filter." ;
+ pg:mayHavePort pg:cutoffFrequency ;
+ pg:mayHavePort pg:resonance .
+
+pg:CompressorControlGroup a rdfs:Class ;
+ rdfs:subClassOf pg:ControlGroup ;
+ rdfs:label "Controls for a compressor." ;
+ pg:mayHavePort pg:threshold ;
+ pg:mayHavePort pg:ratio .
+
diff --git a/ns/ext/port-groups/waf b/ns/ext/port-groups/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/port-groups/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/port-groups/wscript b/ns/ext/port-groups/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/port-groups/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/port-props/ext.pc.in b/ns/ext/port-props/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/port-props/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/port-props/manifest.ttl b/ns/ext/port-props/manifest.ttl
new file mode 100644
index 0000000..b4afe2f
--- /dev/null
+++ b/ns/ext/port-props/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/port-props>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <port-props.ttl> .
diff --git a/ns/ext/port-props/port-props.ttl b/ns/ext/port-props/port-props.ttl
new file mode 100644
index 0000000..d811959
--- /dev/null
+++ b/ns/ext/port-props/port-props.ttl
@@ -0,0 +1,217 @@
+@prefix pprops: <http://lv2plug.in/ns/ext/port-props#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/port-props>
+ a lv2:Specification ;
+ doap:name "LV2 Port Properties" ;
+ doap:release [
+ doap:revision "0.1" ;
+ doap:created "2011-11-01"
+ ] ;
+ doap:created "2009-01-01" ;
+ doap:shortdesc "Additional properties for LV2 plugin ports." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "Krzysztof Foltman"
+ ] , [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension defines several useful properties for LV2 plugin ports, which
+can be used in plugin descriptions to better describe ports. Using this
+metadata, hosts can build better UIs for plugins, and provide more advanced
+automatic functionality.</p>
+""" .
+
+pprops:trigger
+ a lv2:PortProperty ;
+ rdfs:label "Trigger" ;
+ rdfs:comment """
+Indicates that the data item corresponds to a momentary event that has been
+detected (control output ports) or is to be triggered (control input ports).
+For input ports, the port needs to be reset to lv2:default value after run()
+function of the plugin has returned. If the control port is assigned a GUI
+widget by the host, the widget should be of auto-off (momentary, one-shot) type
+- for example, a push button if the port is also declared as lv2:toggled, or a
+series of push button or auto-clear input box with a "Send" button if the port
+is also lv2:integer.
+""" .
+
+pprops:supportsStrictBounds
+ a lv2:Feature ;
+ rdfs:label "Supports strict bounds" ;
+ rdfs:comment """
+Indicates use of host support for pprops:hasStrictBounds port property. A
+plugin that specifies it as optional feature can omit value clamping for
+hasStrictBounds ports, if the feature is supported by the host. When specified
+as required feature, it indicates that the plugin does not do any clamping for
+input ports that have a pprops:hasStrictBounds property.
+""" .
+
+pprops:hasStrictBounds
+ a lv2:PortProperty ;
+ rdfs:label "Has strict bounds" ;
+ rdfs:comment """
+For hosts that support pprops:supportsStrictBounds, this indicates that the
+value of the port should never exceed the port's minimum and maximum control
+points. For input ports, it moves the responsibility for limiting the range of
+values to host, if it supports pprops:supportsStrictBounds. For output ports,
+it indicates that values within specified range are to be expected, and
+breaking that should be considered by the host as error in plugin
+implementation.
+""" .
+
+pprops:expensive
+ a lv2:PortProperty ;
+ rdfs:label "Changes trigger expensive calculation" ;
+ rdfs:comment """
+Input ports only. Indicates that any changes to the port value may trigger
+expensive background calculation (e.g. regenerate some lookup tables in a
+background thread). Any value changes may have not have immediate effect, or
+may cause silence or diminished-quality version of the output until background
+processing is finished. Ports having this property are typically not well
+suited for connection to outputs of other plugins, and should not be offered as
+connection targets or for automation by default.
+""" .
+
+pprops:causesArtifacts
+ a lv2:PortProperty ;
+ rdfs:label "May cause audio artifacts when changed" ;
+ rdfs:comment """
+Input ports only. Indicates that any changes to the port value may produce
+slight artifacts to produced audio signals (zipper noise and other results of
+signal discontinuities). Connecting ports of this type to continuous signals
+is not recommended, and when presenting a list of automation targets, those
+ports may be marked as artifact-producing.
+""" .
+
+pprops:continuousCV
+ a lv2:PortProperty ;
+ rdfs:label "Carries a smooth modulation signal" ;
+ rdfs:comment """
+Indicates that the port carries a "smooth" modulation signal. Control input
+ports of this type are well-suited for being connected to sources of smooth
+signals (knobs with smoothing, modulation rate oscillators, output ports with
+continuousCV type, etc.). Typically, the plugin with ports which have this
+property will implement appropriate smoothing to avoid audio artifacts. For
+output ports, this property suggests the value of the port is likely to change
+frequently, and describes a smooth signal (e.g. successive values may be
+considered points along a curve).
+""" .
+
+pprops:discreteCV
+ a lv2:PortProperty ;
+ rdfs:label "Carries a discrete modulation signal" ;
+ rdfs:comment """
+Indicates that the port carries a "discrete" modulation signal. Input ports of
+this type are well-suited for being connected to sources of discrete signals
+(switches, buttons, classifiers, event detectors, etc.). May be combined with
+pprops:trigger property. For output ports, this property suggests the value of
+the port describe discrete values that should be interpreted as steps (and not
+points along a curve).
+""" .
+
+pprops:reportsBpm
+ a lv2:PortProperty ;
+ rdfs:label "Carries the current tempo expressed in BPM" ;
+ rdfs:comment """
+Indicates that the port is used to pass the current tempo in context of the
+plugin (which may be current song tempo, or tempo of a particular subset of the
+song, or the subgraph the plugin resides in). For input ports, the host may
+automatically feed the port with current tempo and hide the port from the user,
+unless the user or other factors encourage different behaviour.
+""" .
+
+pprops:reportsBeatsPerBar
+ a lv2:PortProperty ;
+ rdfs:label "Carries the current number of beats in a bar" ;
+ rdfs:comment """
+Indicates that the port may be used to pass the current number of beats in a
+bar. """ .
+
+pprops:reportsBeatUnit
+ a lv2:PortProperty ;
+ rdfs:label "Carries the current beat size" ;
+ rdfs:comment """
+Indicates that the port may be used to pass the current size of a beat (4 for a
+crochet/quarter note, 8 for a quaver/eighth note, etc.).
+""" .
+
+pprops:logarithmic
+ a lv2:PortProperty ;
+ rdfs:label "Port value uses a logarithmic scale" ;
+ rdfs:comment """
+Indicates that port value behaviour within specified range (bounds) is a value
+using logarithmic scale. The lower and upper bounds must be specified, and
+must be of the same sign.
+""" .
+
+pprops:notAutomatic
+ a lv2:PortProperty ;
+ rdfs:label "Port is not intended as a CV input" ;
+ rdfs:comment """
+Indicates that the port is not primarily intended to be fed with modulation
+signals from external sources (other plugins, etc.). It is merely a UI hint
+and hosts may allow the user to override it.
+""" .
+
+pprops:notOnGUI
+ a lv2:PortProperty ;
+ rdfs:label "Port is not to be displayed on a GUI or equivalent" ;
+ rdfs:comment """
+Indicates that the port is not primarily intended to be represented by a
+separate control in the user interface window (or any similar mechanism used
+for direct, immediate control of control ports). It is merely a UI hint and
+hosts may allow the user to override it.
+""" .
+
+pprops:priority
+ a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range xsd:float ;
+ rdfs:label "Relative usefulness of a port" ;
+ rdfs:comment """
+Indicates how (typically) useful is the port comparing to other ports with that
+property (higher value = more important). The values do not need to be unique,
+and ports can be grouped based on their priorities.
+""" .
+
+pprops:rangeSteps
+ a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range xsd:nonNegativeInteger ;
+ rdfs:label "Number of value quantization steps" ;
+ lv2:documentation """
+<p>This value indicates into how many evenly-divided points the (control) port
+range shoujld be divided for step-wise control. This may be used for changing
+the value with step-based controllers like arrow keys, mouse wheel, rotary
+encoders, etc.</p>
+
+<p>Note that when used with a pprops:logarithmic port, the steps are
+logarithmic too, and port value can be calculated as:</p>
+
+<pre class="c-code">
+value = lower * pow(upper / lower, step / (steps - 1))
+</pre>
+
+<p>and the step from value is:</p>
+
+<pre class="c-code">
+step = (steps - 1) * log(value / lower) / log(upper / lower)
+</pre>
+
+<p>where:</p>
+<ul>
+<li><code>value</code> is the port value</li>
+<li><code>step</code> is the step number (0..steps)</li>
+<li><code>steps</code> is the number of steps (= value of :rangeSteps property)</li>
+<li><code>lower</code> and <code>upper</code> are the bounds</li>
+</ul>
+""" .
diff --git a/ns/ext/port-props/waf b/ns/ext/port-props/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/port-props/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/port-props/wscript b/ns/ext/port-props/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/port-props/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/presets/ext.pc.in b/ns/ext/presets/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/presets/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/presets/manifest.ttl b/ns/ext/presets/manifest.ttl
new file mode 100644
index 0000000..51985ab
--- /dev/null
+++ b/ns/ext/presets/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/presets>
+ a lv2:Specification ;
+ lv2:minorVersion 2 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <presets.ttl> .
+
diff --git a/ns/ext/presets/presets.ttl b/ns/ext/presets/presets.ttl
new file mode 100644
index 0000000..ebe6d0f
--- /dev/null
+++ b/ns/ext/presets/presets.ttl
@@ -0,0 +1,113 @@
+# LV2 Presets Extension
+# Copyright 2009-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix pset: <http://lv2plug.in/ns/ext/presets#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+<http://lv2plug.in/ns/ext/presets>
+ a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 Presets" ;
+ doap:shortdesc "Presets for LV2 plugins. " ;
+ doap:maintainer <http://drobilla.net/drobilla#me> ;
+ doap:release [
+ doap:revision "2.2" ;
+ doap:created "2011-11-14" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-presets-2.2.tar.bz2> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Update packaging."
+ ] , [
+ rdfs:label "Improve documentation."
+ ]
+ ]
+ ] , [
+ doap:revision "2.0" ;
+ doap:created "2010-10-04" ;
+ doap:file-release <http://lv2plug.in/spec/lv2-presets-2.0.tar.gz> ;
+ dcs:blame <http://drobilla.net/drobilla#me> ;
+ dcs:changeset [
+ dcs:item [
+ rdfs:label "Initial release."
+ ]
+ ]
+ ] ;
+ rdfs:comment """
+Defines presets (e.g. named sets of control values) for LV2 plugins.
+""" .
+
+pset:Preset
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:PluginBase ;
+ rdfs:label "LV2 Preset" ;
+ rdfs:subClassOf [
+ a owl:Restriction ;
+ owl:onProperty rdfs:label ;
+ owl:someValuesFrom xsd:string ;
+ rdfs:comment "A Preset MUST have at least one string rdfs:label."
+ ] ;
+ rdfs:comment """
+A Preset for an LV2 Plugin. A preset can be considered an "overlay" on a
+Plugin. Rather than attempting to define all valid predicates for a Preset
+(which is not possible since presets may need to specify values for things
+defined in other extensions), the presets extension simply provides this
+class which can be augmented with any data in the exact same fashion as the
+definition of a Plugin.
+
+A Preset SHOULD have at least one pset:appliesTo property.
+Each Port on a Preset MUST have at least a lv2:symbol property and a
+pset:value property.
+""" .
+
+pset:appliesTo
+ a rdf:Property ;
+ rdfs:domain pset:Preset ;
+ rdfs:range lv2:Plugin ;
+ rdfs:label "Applies to" ;
+ rdfs:comment """
+Specifies the Plugin(s) a Preset may be applied to. When a Preset applies
+to a Plugin, that Preset SHOULD have ports for every control port on that
+plugin, each of which SHOULD have a pset:value property. If the Preset is
+missing ports, or refers to ports which do not exist on the Plugin, then
+the host SHOULD apply all the values in the preset that do match the Plugin.
+
+The Preset MAY have any other values that should be applied to the Plugin
+in some way. The host SHOULD simply ignore any values on a Preset it does
+not understand.
+""" .
+
+pset:value
+ a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:label "Has value" ;
+ rdfs:comment """
+Specifies the value of a Port on some Preset. This property is used
+in a similar way to e.g. lv2:default.
+""" .
diff --git a/ns/ext/presets/waf b/ns/ext/presets/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/presets/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/presets/wscript b/ns/ext/presets/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/presets/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/pui/ext.pc.in b/ns/ext/pui/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/pui/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/pui/manifest.ttl b/ns/ext/pui/manifest.ttl
new file mode 100644
index 0000000..1229118
--- /dev/null
+++ b/ns/ext/pui/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
+
+<http://lv2plug.in/ns/ext/pui>
+ a lv2:Specification;
+ lv2:minorVersion 0;
+ lv2:microVersion 1;
+ rdfs:seeAlso <pui.ttl>.
diff --git a/ns/ext/pui/pui.h b/ns/ext/pui/pui.h
new file mode 100644
index 0000000..caa7deb
--- /dev/null
+++ b/ns/ext/pui/pui.h
@@ -0,0 +1,374 @@
+/************************************************************************
+ *
+ * Plugin UI extension for LV2
+ *
+ * Copyright (C) 2006-2011 Lars Luthman <mail@larsluthman.net>
+ *
+ * Based on lv2.h, which was
+ *
+ * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
+ * Stefan Westerfeld
+ * Copyright (C) 2006 Steve Harris, David Robillard.
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License,
+ * or (at your option) any later version.
+ *
+ * This header is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ *
+ ***********************************************************************/
+
+/**
+ @file pui.h C API for the LV2 UI extension <http://lv2plug.in/ns/ext/pui>.
+
+ This file specifies a C API for communication between an LV2 host and an
+ LV2 UI. The interface is similar to the one used for actual LV2 plugins.
+
+ The entry point is the function lv2ui_descriptor().
+*/
+
+#ifndef LV2_PUI_H
+#define LV2_PUI_H
+
+#include <lv2.h>
+
+/** The URI of this extension (note this is not the same as the prefix). */
+#define LV2_PUI_URI "http://lv2plug.in/ns/ext/pui"
+
+/** The numerical ID returned by LV2_PUI_Host_Descriptor::port_index() for
+ invalid port symbols. */
+#define LV2_PUI_INVALID_PORT_INDEX ((uint32_t)-1)
+
+/** The full URI for the pui:floatControl PortProtocol. */
+#define LV2_PUI_FLOAT_CONTROL_URI "http://lv2plug.in/ns/ext/pui#floatControl"
+
+/** The full URI for the pui:floatPeakRMS PortProtocol. */
+#define LV2_PUI_FLOAT_PEAK_RMS_URI "http://lv2plug.in/ns/ext/pui#floatPeakRMS"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ A data type that is used to pass peak and RMS values for a period of
+ audio data at an input or output port to an UI, using port_event. See the
+ documentation for pui:floatPeakRMS for details about how and when this
+ should be done.
+*/
+typedef struct _LV2_PUI_Peak_RMS_Data {
+
+ /**
+ The start of the measurement period. This is just a running counter that
+ must not be interpreted as any sort of global frame position. It should
+ only be interpreted relative to the starts of other measurement periods
+ in port_event() calls to the same plugin instance.
+
+ This counter is allowed to overflow, in which case it should just wrap
+ around.
+ */
+ 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;
+
+ /**
+ The RMS value for the measurement period. This should be the root mean
+ square value of the samples in the period, equivalent to
+ sqrt((pow(sample1, 2) + pow(sample2, 2) + ... + pow(sampleN, 2)) / N)
+ where N is period_size.
+ */
+ float rms;
+
+} LV2_PUI_Peak_RMS_Data;
+
+/**
+ A pointer to a widget or other type of UI.
+ The actual type is defined by the type of the UI defined in the RDF data.
+ All the functionality provided by this extension is toolkit independent, the
+ host only needs to pass the necessary callbacks and display the widget, if
+ possible. Plugins may have several UIs, in various toolkits.
+*/
+typedef void* LV2_PUI_Widget;
+
+/**
+ Handle for a particular 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 may use it to reference internal
+ instance data.
+*/
+typedef void* LV2_PUI_Handle;
+
+/**
+ Handle for host functions and data provided to a UI.
+ An object of this type is passed to the UI's instantiate() function, and the
+ UI must in turn pass it as the first parameter to the callbacks in
+ LV2_PUI_Host_Descriptor. The host may use it to reference internal data, such
+ as the plugin instance that the UI is associated with. The UI MUST NOT
+ interpret the value of an LV2_PUI_Host_Handle in any way.
+*/
+typedef void* LV2_PUI_Host_Handle;
+
+/**
+ Host-provided functions that the UI can use to control the plugin instance.
+
+ A pointer to an object of this type is passed to the lv2ui_descriptor()
+ function.
+
+ The host MUST provide non-NULL values for all the function pointers.
+*/
+typedef struct _LV2_PUI_Host_Descriptor {
+
+ /**
+ Send data to one of the plugin's input ports.
+
+ The @c buffer parameter MUST point to a block of data @c buffer_size
+ bytes large. The contents of this buffer and what the host should do
+ with it depends on the value of the @c port_protocol parameter.
+
+ The @c port_protocol parameter MUST be a numeric ID for a
+ pui:PortProtocol. Numeric IDs for PortProtocols are retrieved using the
+ port_protocol_id() function.
+
+ The @c buffer is only valid during the time of this function call, so if
+ the host wants to keep it for later use it has to copy the contents to an
+ internal buffer.
+
+ @param host_handle The @c host_handle that was passed to the UI's
+ instantiate() function.
+ @param port_index The index of the port that the data should be written
+ to, as returned by port_index().
+ @param buffer_size The size of the data pointed to by @c buffer, in
+ bytes.
+ @param port_protocol The numeric ID of the Port Protocol to use,
+ as returned by port_protocol_id().
+ */
+ void (*write_port)(LV2_PUI_Host_Handle host_handle,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t port_protocol,
+ void const* buffer);
+
+ /**
+ Return the numerical index for a port.
+ This index is used when writing data to ports using write_port() and whe
+ receiving data using port_event(). If @c port_symbol is not a valid port
+ symbol for @c plugin the host it MUST return
+ LV2_PUI_INVALID_PORT_INDEX. For performance reasons it may be a good idea
+ to cache port indices in the UI at instantiation time.
+
+ @param host_handle The LV2_PUI_Host_Handle that was passed to the UI's
+ instantiate() function.
+ @param port_symbol The port's symbol, as defined in the RDF data for
+ the plugin.
+ */
+ uint32_t (*port_index)(LV2_PUI_Host_Handle host_handle,
+ char const* port_symbol);
+
+ /**
+ 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 the PortProtocol).
+
+ Calling this function with the same @c port_index and @c port_protocol
+ as an already active subscription has no effect.
+
+ @param host_handle The @c host_handle that was passed to the UI's
+ instantiate() function.
+ @param port_index The index of the port, as returned by port_index().
+ @param port_protocol The numeric ID of the PortProtocol, as
+ returned by port_protocol_id().
+ */
+ void (*subscribe_to_port)(LV2_PUI_Host_Handle host_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 host_handle The @c host_handle that was passed to the UI's
+ instantiate() function.
+ @param port_index The index of the port, as returned by port_index().
+ @param port_protocol The numeric ID of the PortProtocol, as
+ returned by port_protocol_id().
+ */
+ void (*unsubscribe_from_port)(LV2_PUI_Host_Handle host_handle,
+ uint32_t port_index,
+ uint32_t port_protocol,
+ const LV2_Feature* const* features);
+
+
+} LV2_PUI_Host_Descriptor;
+
+/**
+ This struct contains the implementation of an UI. A pointer to an
+ object of this type is returned by the lv2ui_descriptor() function.
+*/
+typedef struct _LV2_PUI_Descriptor {
+
+ /**
+ The URI for this UI (not for the plugin it controls).
+ */
+ char const* 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 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 that
+ references this shared object file, with trailing separator (e.g. '/').
+
+ @param host_descriptor A pointer to an object that contains function
+ pointers that the UI instance should use to control the plugin
+ instance. This pointer MUST be valid until cleanup() is called for this
+ UI instance.
+
+ @param host_handle A handle that the host may use to reference internal
+ data. It MUST be passed as the first parameter to the function
+ pointers in @c host_descriptor, and MUST NOT be interpreted in any other
+ way by the UI.
+
+ @param features A NULL-terminated 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; @c features will probably not be the same array as the one the
+ plugin host passes to a plugin.
+ */
+ LV2_PUI_Handle (*instantiate)(
+ struct _LV2_PUI_Descriptor const* descriptor,
+ char const* plugin_uri,
+ char const* bundle_path,
+ LV2_PUI_Host_Descriptor const* host_descriptor,
+ LV2_PUI_Host_Handle host_handle,
+ LV2_Feature const* const* features);
+
+ /**
+ Return the widget pointer for the UI object.
+ This MUST return the same value during the entire lifetime of the UI
+ object.
+ */
+ LV2_PUI_Widget (*get_widget)(LV2_PUI_Handle ui);
+
+ /**
+ Destroy the UI object and the associated widget.
+ The host must not try to access the widget after calling this function.
+ */
+ void (*cleanup)(LV2_PUI_Handle ui);
+
+ /**
+ Notify the UI that something has happened to a subscribed port.
+
+ This is called by the host when something happens at a plugin port that
+ has been subscribed to using
+ LV2_PUI_Host_Descriptor::add_port_subscription().
+
+ 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.
+
+ @param ui A handle for the UI object.
+ @param port_index The index of the port that has changed, as returned by
+ LV2_PUI_Host_Descriptor::port_index().
+ @param buffer_size The size of the data buffer in bytes.
+ @param port_protocol The format of the data buffer, as returned by
+ LV2_PUI_Host_Descriptor::port_protocol_id().
+ @param buffer A pointer to the data buffer.
+ */
+ void (*port_event)(LV2_PUI_Handle ui,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t port_protocol,
+ void const* buffer);
+
+ /**
+ Return a data structure associated with an extension URI.
+
+ This facility can be used by extensions to extend the LV2_PUI_Descriptor
+ API. This function adheres to the same rules as
+ LV2_Descriptor::extension_data, except it applies to UIs rather than
+ plugins.
+ */
+ void const* (*extension_data)(char const* uri);
+
+} LV2_PUI_Descriptor;
+
+typedef void* LV2_PUI_Lib_Data;
+
+/**
+ Descriptor for a plugin UI library.
+
+ Each plugin UI shared library has exactly one of these objects, accessed
+ via the lv2_pui_lib_descriptor() function in that library.
+*/
+typedef struct {
+ /**
+ Opaque library data which must be passed as the first parameter to
+ all the methods of this struct.
+ */
+ LV2_PUI_Lib_Data lib_data;
+
+ void (*cleanup)(LV2_PUI_Lib_Data lib_data);
+
+ /**
+ Prototype for UI accessor function.
+
+ This function follows the same rules as lv2_descriptor(), except it
+ applies to UIs rather than plugins.
+ */
+ LV2_PUI_Descriptor const* (*pui_descriptor)(LV2_PUI_Lib_Data lib_data,
+ uint32_t index);
+
+} LV2_PUI_Lib_Descriptor;
+
+/**
+ Prototype for UI library accessor function.
+
+ This is the entry point for a plugin UI library. Hosts load this symbol
+ from the library and call this function to obtain a library descriptor which
+ can be used to access all the UIs contained in this library. The returned
+ object must not be destroyed (with LV2_PUI_Lib_Descriptor::cleanup()) until
+ all UIs loaded from that library have been destroyed.
+*/
+LV2_PUI_Lib_Descriptor const* lv2_pui_lib_descriptor(
+ const char* bundle_path,
+ LV2_Feature const* const* features);
+
+/**
+ Type of the lv2_pui_lib_descriptor() function in a UI library.
+*/
+typedef LV2_PUI_Lib_Descriptor const* (*LV2_PUI_Lib_Descriptor_Func)(
+ const char* bundle_path,
+ LV2_Feature const* const* features);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LV2_PUI_H */
diff --git a/ns/ext/pui/pui.ttl b/ns/ext/pui/pui.ttl
new file mode 100644
index 0000000..c035e56
--- /dev/null
+++ b/ns/ext/pui/pui.ttl
@@ -0,0 +1,282 @@
+# LV2 Plugin UI Extension
+# Copyright (C) 2010-2011 Lars Luthman <mail@larsluthman.net>
+#
+# Based on lv2.ttl, which is
+# Copyright (C) 2006-2008 Steve Harris, David Robillard
+#
+# This extension should be considered a replacement for the earlier
+# in-process UI extension with the URI <http://lv2plug.in/ns/extensions/ui>.
+# Hosts and plugins that used that extension should use this one instead.
+# The earlier in-process UI extension is not compatible with LV2 revision 3
+# and later and may break in subtle ways.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
+@prefix pui: <http://lv2plug.in/ns/ext/pui#>.
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/pui>
+ a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 UI" ;
+ doap:shortdesc "Generic UI interface for LV2 plugins." ;
+ doap:release [
+ doap:revision "0.1" ;
+ doap:created "2011-03-26"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "Lars Luthman" ;
+ foaf:mbox <mailto:mail@larsluthman.net>
+ ] ;
+ lv2:documentation """
+<p>This extension defines an interface that can be used to create UIs for
+plugins. The UIs are code that reside in shared object files in an LV2
+bundle and are referenced in the RDF data using the triples:</p>
+<pre class="turtle-code">
+@prefix pui: &lt;http://lv2plug.in/ns/ext/pui#&gt; .
+&lt;http://example.org/my-ui&gt; a pui:Gtk2UI ;
+ lv2:appliesTo &lt;http://example.org/my-plugin&gt; ;
+ pui:binary &lt;my-ui.so&gt; .
+</pre>
+<p>... where <code>http://example.org/my-plugin</code> is the URI of the plugin,
+<code>http://example.org/my-ui</code> is the URI of the plugin UI and
+<code>my-ui.so</code> is the relative URI to the shared object file. While it
+is possible to have the plugin UI and the plugin in the same shared object file
+it is probably a good idea to keep them separate so that hosts that don't want
+UIs don't have to load the UI code.</p>
+
+<p>A UI MUST specify its class in the RDF data and the class MUST be a proper
+subclass of pui:UI, in this case pui:Gtk2UI. The class defines what type the
+UI is, e.g. what graphics toolkit it uses. There are no UI classes defined in
+this extension, those are specified separately (and anyone can define their
+own).</p>
+
+<p>It's entirely possible to have multiple UIs for the same plugin, or to have
+the UI for a plugin in a different bundle from the actual plugin - this way
+people other than the plugin author can write plugin UIs independently without
+editing the original plugin bundle. It is also possible to have one UI that
+works with several different plugins.</p>
+
+<p>UIs should also be written in such a way that the host may load several
+instances of an UI, or different UIs, and use them with the same plugin
+instance.</p>
+
+<p>Note that the process that loads the shared object file containing the UI
+code and the process that loads the shared object file containing the actual
+plugin implementation do not have to be the same. There are many valid reasons
+for having the plugin and the UI in different processes, or even on different
+machines. This means that you can <strong>not</strong> use singletons and
+global variables and expect them to refer to the same objects in the UI and the
+actual plugin. The function callback interface defined in the header pui.h is
+all you can expect to work.</p>
+""" .
+
+pui:UI
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:Feature ;
+ rdfs:label "UI" ;
+ lv2:documentation """
+<p>The class which represents an LV2 plugin UI.
+</p>
+
+<p>To be used by a host a UI MUST have at least the following properties:</p>
+<ul>
+<li>rdf:type (with object a proper subclass of pui:UI)</li>
+<li>doap:name (one without language tag)</li>
+<li>lv2:binary (with a shared object file as object)</li>
+<li>lv2:appliesTo (with a LV2 plugin as object)</li>
+</ul>
+
+<p>The rdf:type of an UI is used by the host to decide whether it supports the
+UI and how to handle the LV2_PUI_Widget object that is returned by the UIs
+get_widget() function. For example, a type of pui:Gtk2UI might tell the
+host that LV2_PUI_Widget is a pointer to an object of a type defined in the
+Gtk+ library. No UI types are defined in this extension, that is intentionally
+left for other extensions.</p>
+
+<p>The doap:name property should be at most a few words in length using title
+capitalization, e.g. "Flashy Mixer GUI". Use lv2:documentation for more
+detailed descriptions.</p>
+
+<p>UIs may have optional or required features, specified using lv2:optionalFeature
+or lv2:requiredFeature. The same rules apply here as for plugins; a host MUST
+pass the LV2_Feature objects for all features it supports to the UI's
+instantiate() function, a host SHOULD NOT try to instantiate an UI if it
+doesn't support all of its required features, and an UI MUST fail to
+instantiate if the host doesn't pass all required features to instantiate().
+</p>
+
+<p>For details about the C API used to load UIs, see the file pui.h.
+</p>
+""" .
+
+pui:PortProtocol
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:Feature ;
+ rdfs:label "Port protocol" ;
+ lv2:documentation """
+<p>A PortProtocol defines a certain way of communicating port data between UI
+and plugin. PortProtocols can be specified in additional extensions, and
+those extensions MUST specify:
+</p>
+
+<ol>
+<li>Which plugin port types the buffer type is valid for</li>
+<li>When the host should call port_event() in LV2_PUI_Descriptor</li>
+<li>The format of the data in the buffer passed to port_event()</li>
+<li>The format of the data in the buffer passed to write_port()</li>
+<li>What happens when the UI calls write_port() in LV2_PUI_Host_Descriptor</li>
+<li>What data (if any) should be passed in the LV2_Feature data pointer. </li>
+</ol>
+
+<p>For an example, see pui:floatControl or pui:floatPeakRMS.
+</p>
+
+<p>PortProtocol is a subclass of lv2:Feature, so UIs use lv2:optionalFeature and
+lv2:requiredFeature to specify which PortProtocols they want to use.
+</p>
+""" .
+
+pui:floatControl
+ a pui:PortProtocol ;
+ rdfs:label "Floating point value" ;
+ lv2:documentation """
+<p>The rules (see pui:PortProtocol) for this port protocol are:</p>
+<ol>
+<li>This PortProtocol is valid for ports with the type lv2:ControlPort.</li>
+<li>The host SHOULD call port_event() as soon as possible when the port value
+ has changed, but the plugin MUST NOT depend on a call for every change or
+ the timing of the calls. However, the host MUST do the calls in the same
+ order that the value changes occur in.</li>
+<li>The format of the data in the buffer passed to port_event() is a single
+ float, and the buffer size is sizeof(float).</li>
+<li>Same as 3.</li>
+<li>The host SHOULD change the port value as soon as possible when write_port()
+ is called, but the UI MUST NOT depend on a change for every call or the
+ timing of the changes. However, the host MUST do the changes in the same
+ order that the function calls occur in.</li>
+<li>The data pointer in the LV2_Feature object for this feature should be
+ NULL.</li>
+</ol>
+""" .
+
+pui:floatPeakRMS
+ a pui:PortProtocol ;
+ rdfs:label "Peak and RMS for a period of audio data" ;
+ lv2:documentation """
+<p>This port protocol defines a way for the host to send continuous peak
+and RMS measurements of the audio signal at a certain port to the UI. The
+intended use is visualisation, e.g. an animated meter widget that shows
+the level of the audio input or output.</p>
+
+<p>A contiguous sequence of audio samples for which a single peak value
+and a single RMS value have been computed is called a <em>measurement
+period</em>.</p>
+
+<p>The rules (see pui:PortProtocol) for this port protocol are:</p>
+<ol>
+<li>This PortProtocol is valid for ports with the type lv2:AudioPort.</li>
+<li>The host SHOULD call port_event() at regular intervals. The measurement
+ periods used for calls to port_event() for the same port SHOULD be
+ contiguous (i.e. the measurement period for one call should begin right
+ after the end of the measurement period for the previous call ends) unless
+ the UI has removed and re-added the port subscription between those calls.
+ However, UIs MUST NOT depend on either the regularity of the calls or the
+ contiguity of the measurement periods; hosts may change the call rate
+ or skip calls for performance or other reasons. Measurement periods for
+ different calls to port_event() for the same port MUST NOT overlap.</li>
+<li>The format of the data in the buffer passed to port_event() is a single
+ LV2_PUI_Peak_RMS_Data object, and the buffer size is
+ sizeof(LV2_PUI_Peak_RMS_Data).</li>
+<li>The UI MUST NOT call write_port() with the ID for this port protocol as
+ the port_protocol parameter.</li>
+<li>The host MUST ignore any write_port() calls with the ID for this port
+ protocol as the port_protocol parameter.</li>
+<li>The data pointer in the LV2_Feature object for this feature should be
+ NULL.</li>
+</ol>
+""" .
+
+pui:events
+ a pui:PortProtocol ;
+ rdfs:label "Event buffer" ;
+ lv2:documentation """
+<ol>
+<li>This PortProtocol is valid for ports with the type ev:EventPort.</li>
+<li>The host MUST call port_event() whenever there is an event in an input port
+ prior to the plugin instance's run() function is called, and whenever there
+ is an event in an output port after run() has been called. The UI MUST NOT
+ depend on the timing of the calls. However, the host MUST do the calls in
+ the same order that the events occur in. The host is allowed and encouraged
+ to bundle multiple events into a single port_event() call if it improves
+ performance.</li>
+<li>The data buffer passed to port_event() is an LV2_Event_Buffer, as specified
+ in the Event extension. The stamp_type MUST be ignored. The frames and
+ subframes fields of every event in the buffer MUST be ignored. Events with
+ type 0 (reference counted events) MUST be ignored.</li>
+<li>The data buffer passed to write_event() is an LV2_Event_Buffer, as
+ specified in the Event extension. The stamp_type MUST be ignored. The
+ frames and subframes fields of every event in the buffer MUST be
+ ignored. The host MUST NOT pass events with type 0 (references) unless the
+ UI supports the feature "http://lv2plug.in/ns/ext/event".</li>
+<li>The host MUST pass all the events in the buffer to the plugin instance's
+ event port in the same order, but the plugin and the UI MUST NOT depend on
+ the timing of the events, or on whether they are all sent to the plugin in
+ the same run() call or distributed over multiple calls.</li>
+<li>The data pointer in the LV2_Feature object for this feature should be
+ NULL.</li>
+</ol>
+""" .
+
+pui:Gtk2UI
+ a rdfs:Class ;
+ rdfs:subClassOf pui:UI ;
+ rdfs:label "Gtk+ UI" ;
+ lv2:documentation """
+<p>The class which represents a Gtk+ UI. For a successfully created instance of
+an UI of this class, the get_widget() function MUST return a pointer to a valid
+GtkWidget object compatible with Gtk+ version 2.0. The host MUST ensure that
+the Gtk+ library has been initialised and that the Glib main loop is running
+before an UI of this type is instantiated.</p>
+
+<p>Unless otherwise specified by extensions, all function pointers in
+LV2_PUI_Descriptor may only be called from the thread that runs the Glib main
+loop.</p>
+""" .
+
+pui:noHostResize
+ a lv2:Feature ;
+ rdfs:label "No host resize" ;
+ lv2:documentation """
+<p>This Feature should only be used with UIs.</p>
+
+<p>When this Feature is active the host SHOULD NOT resize the UI widget to any
+other size than its natural size, which the host should be able to determine
+via the API of whatever toolkit the UI is implemented in. However, the UI MUST
+NOT break if the widget is resized to another size. This Feature can be used
+for example when the widget uses a fixed-size pixmap interface.</p>
+
+<p>The data pointer in the LV2_Feature object for this Feature should be set to
+NULL.</p>
+""" .
diff --git a/ns/ext/pui/waf b/ns/ext/pui/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/pui/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/pui/wscript b/ns/ext/pui/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/pui/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/reference/ext.pc.in b/ns/ext/reference/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/reference/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/reference/manifest.ttl b/ns/ext/reference/manifest.ttl
new file mode 100644
index 0000000..e25c54d
--- /dev/null
+++ b/ns/ext/reference/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/reference>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <reference.ttl> .
+
diff --git a/ns/ext/reference/reference.h b/ns/ext/reference/reference.h
new file mode 100644
index 0000000..26ef4c3
--- /dev/null
+++ b/ns/ext/reference/reference.h
@@ -0,0 +1,161 @@
+/*
+ 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 reference.h C header for the LV2 Reference extension
+ <http://lv2plug.in/ns/ext/reference>.
+*/
+
+#ifndef LV2_REFERENCE_H
+#define LV2_REFERENCE_H
+
+#define LV2_REFERENCE_URI "http://lv2plug.in/ns/ext/reference"
+#define LV2_REFERENCE_BLOB_SUPPORT_URI LV2_REFERENCE_URI "#blobSupport"
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+
+/**
+ Dynamically Allocated Data.
+
+ This is an opaque piece of data of any type, dynamically allocated in memory.
+ Unlike an "atom", a "blob" is not necessarily POD. Non-POD data is referred
+ to by a "reference (a special case of atom with type 0).
+
+ This is a pointer to host data which is opaque to the plugin. Plugins MUST
+ NOT interpret this data in any way, except via host-provided functions in
+ LV2_Blob_Support.
+*/
+typedef void* LV2_Blob;
+
+typedef LV2_Atom LV2_Reference;
+
+typedef void* LV2_Blob_Support_Data;
+
+typedef void (*LV2_Blob_Destroy)(LV2_Blob* blob);
+
+/**
+ The data field of the LV2_Feature for reference:blobSupport.
+
+ A host which supports blobs must pass an LV2_Feature to the plugin's
+ instantiate method with 'URI' = "http://lv2plug.in/ns/ext/reference#blobSupport"
+ and 'data' pointing to an instance of this struct. All fields of this struct
+ MUST be set to non-NULL values by the host, except possibly 'data'.
+*/
+typedef struct {
+
+ /**
+ Pointer to opaque host data.
+
+ The plugin MUST pass this to any call to functions in this struct.
+ Otherwise, the plugin MUST NOT interpret this value in any way.
+ */
+ LV2_Blob_Support_Data data;
+
+ /**
+ The size of a reference, in bytes.
+
+ This value is provided by the host so plugins can allocate large enough
+ chunks of memory to store references. Note a reference is an LV2_Reference
+ with type reference:Reference, hence ref_size is a uint16, like
+ LV2_Reference.size.
+ */
+ uint16_t ref_size;
+
+ /**
+ Return the Blob referred to by @a ref.
+
+ The returned value MUST NOT be used in any way other than by calling
+ methods defined in LV2_Blob_Support (e.g. it MUST NOT be directly
+ accessed, copied, or destroyed). The actual payload of the blob can
+ be accessed with LV2_Blob_Support.blob_get.
+ */
+ LV2_Blob (*ref_get)(LV2_Blob_Support_Data data,
+ LV2_Reference* ref);
+
+ /**
+ Copy a reference.
+ This copies a reference but not the blob it refers to,
+ i.e. after this call @a dst and @a src refer to the same LV2_Blob.
+ */
+ void (*ref_copy)(LV2_Blob_Support_Data data,
+ LV2_Reference* dst,
+ LV2_Reference* src);
+
+ /**
+ Reset (release) a reference.
+ After this call, @a ref is invalid. Implementations must be sure to
+ call this function when necessary, or memory leaks will result. The
+ specific times this is necessary MUST be defined by any extensions that
+ define a mechanism for transporting references. The standard semantics are:
+ <ul><li>Whenever passed a Reference (e.g. via a Port) and run, the
+ plugin owns that reference.</li>
+ <li>The plugin owns any reference it creates (e.g. by using blob_new or
+ ref_copy).</li>
+ <li>For any reference it owns, the plugin MUST either:
+ <ul><li>Copy the reference and store it (to be used in future runs and
+ released later).</li>
+ <li>Copy the reference to an output port exactly once.</li>
+ <li>Release it with ref_reset.</li></ul></li>
+ </ul>
+ */
+ void (*ref_reset)(LV2_Blob_Support_Data data,
+ LV2_Reference* ref);
+
+ /**
+ Initialize a reference to point to a newly allocated Blob.
+
+ @param data Must be the data member of this struct.
+ @param ref Pointer to an area of memory at least as large as
+ the ref_size field of this struct. On return, this will
+ be the unique reference to the new blob, which is owned by the
+ caller. Assumed to be uninitialised, i.e. the caller MUST NOT
+ pass a valid reference since this could cause a memory leak.
+ @param destroy Function to destroy this blob. This function
+ MUST clean up any resources contained in the blob, but MUST NOT
+ attempt to free the memory pointed to by its LV2_Blob* parameter
+ (since this is allocated by the host).
+ @param type ID of type of blob to allocate.
+ @param size Size of blob to allocate in bytes.
+ */
+ void (*blob_new)(LV2_Blob_Support_Data data,
+ LV2_Reference* ref,
+ LV2_Blob_Destroy destroy,
+ uint32_t type,
+ size_t size);
+
+ /**
+ Get blob's type as an ID.
+
+ The return value may be any type URI, mapped to an integer with the
+ URI Map extension with <code>context = NULL</code>.
+ */
+ uint32_t (*blob_type)(LV2_Blob blob);
+
+ /**
+ Get blob's body.
+
+ Returns a pointer to the start of the blob data. The format of this
+ data is defined by the return value of the type method. It MUST NOT
+ be used in any way by code which does not understand that type.
+ */
+ void* (*blob_data)(LV2_Blob blob);
+
+} LV2_Blob_Support;
+
+#endif /* LV2_REFERENCE_H */
diff --git a/ns/ext/reference/reference.ttl b/ns/ext/reference/reference.ttl
new file mode 100644
index 0000000..1e030ee
--- /dev/null
+++ b/ns/ext/reference/reference.ttl
@@ -0,0 +1,82 @@
+# LV2 Reference Extension
+# Copyright 2007-2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix reference: <http://lv2plug.in/ns/ext/reference#> .
+
+<http://lv2plug.in/ns/ext/reference>
+ a lv2:Specification ;
+ doap:name "LV2 Reference" ;
+ doap:shortdesc "A reference data type for using non-POD data." ;
+ doap:release [
+ doap:revision "0.1" ;
+ doap:created "2011-07-22"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension defines a mechanism for working with generic/opaque
+dynamically allocated memory, called a <a href="#Blob">"Blob"</a>, which is
+(unlike an Atom) not necessarily POD. Blobs are accessed via a
+reference:Reference, which is a special case of <a
+href="http://lv2plug.in/ns/ext/ext#Atom">Atom</a> that always has <code>type =
+0</code>, is not POD, and can only be copied using host provided functions.
+This allows plugins and hosts to work with data of any type at all.</p>
+""" .
+
+reference:Reference a rdfs:Class ;
+ rdfs:subClassOf atom:Atom ;
+ rdfs:label "Reference" ;
+ lv2:documentation """
+<p>Reference to an lv2:Blob. The actual contents of a Reference are opaque and
+host specific, and must not be copied, serialized, or otherwise interpreted by
+a plugin, except via functions provided by the host in LV2_Blob_Support.</p>
+
+<p>A Reference is a special case of Atom with <code>type = 0</code>.
+"Null" is the unique Atom with <code>type = 0</code> and
+<code>size = 0</code>.</p>
+""" .
+
+reference:blobSupport a lv2:Feature ;
+ rdfs:label "Blob support" ;
+ lv2:documentation """
+<p>Support for dynamically allocated blobs. If a host supports this feature,
+it MUST pass a LV2_Feature with <code>URI</code>
+http://lv2plug.in/ns/ext/atom#blobSupport and <code>data</code> pointing to a
+LV2_Blob_Support.</p>
+""" .
+
+reference:Blob a rdfs:Class ;
+ rdfs:label "Blob" ;
+ lv2:documentation """
+<p>Base class for all dynamically allocated blobs. An LV2_Blob is an opaque
+pointer to host data. The type and data of a blob can be accessed via
+host-provided functions in LV2_Blob_Support. The type of a blob can be any URI
+that describes a data format. Blobs are always allocated by the host, and
+unlike atoms are not necessarily POD.</p>
+
+<p>Blob data MUST NOT be used in any way by an implementation that does not
+understand that blob type (unlike Atoms, meaningful type-oblivious use
+of a Blob is impossible).</p>
+""" .
diff --git a/ns/ext/reference/waf b/ns/ext/reference/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/reference/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/reference/wscript b/ns/ext/reference/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/reference/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/resize-port/ext.pc.in b/ns/ext/resize-port/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/resize-port/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/resize-port/manifest.ttl b/ns/ext/resize-port/manifest.ttl
new file mode 100644
index 0000000..37d1b42
--- /dev/null
+++ b/ns/ext/resize-port/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/resize-port>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <resize-port.ttl> .
+
diff --git a/ns/ext/resize-port/resize-port.h b/ns/ext/resize-port/resize-port.h
new file mode 100644
index 0000000..7f014a3
--- /dev/null
+++ b/ns/ext/resize-port/resize-port.h
@@ -0,0 +1,57 @@
+/* LV2 Resize Port Extension
+ * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LV2_RESIZE_PORT_H
+#define LV2_RESIZE_PORT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define LV2_RESIZE_PORT_URI "http://lv2plug.in/ns/ext/resize-port"
+
+typedef void* LV2_Resize_Port_Feature_Data;
+
+typedef struct {
+
+ LV2_Resize_Port_Feature_Data data;
+
+ /** Resize a port buffer to at least @a size bytes.
+ *
+ * This function MAY return false, in which case the port buffer was
+ * not resized and the port is still connected to the same location.
+ * Plugins MUST gracefully handle this situation.
+ *
+ * This function MUST NOT be called from any context other than
+ * the context associated with the port of the given index.
+ *
+ * The host MUST preserve the contents of the port buffer when
+ * resizing.
+ *
+ * Plugins MAY resize a port many times in a single run callback.
+ * Hosts SHOULD make this an inexpensive as possible (i.e. plugins
+ * can liberally use this function in a similar way to realloc).
+ */
+ bool (*resize_port)(LV2_Resize_Port_Feature_Data data,
+ uint32_t index,
+ size_t size);
+
+} LV2_Resize_Port_Feature;
+
+#endif /* LV2_RESIZE_PORT_H */
+
diff --git a/ns/ext/resize-port/resize-port.ttl b/ns/ext/resize-port/resize-port.ttl
new file mode 100644
index 0000000..baa1f7f
--- /dev/null
+++ b/ns/ext/resize-port/resize-port.ttl
@@ -0,0 +1,80 @@
+# LV2 Contexts Extension
+#
+# Allows for an LV2 plugin to have several independent contexts, each with its
+# own run callback and associated ports.
+#
+# Copyright (C) 2007 David Robillard
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix rsz: <http://lv2plug.in/ns/ext/resize-port#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/resize-port>
+ a lv2:Specification ;
+ a lv2:Feature ;
+ doap:name "LV2 Resize Port Extension" ;
+ doap:shortdesc "Dynamically sized LV2 port buffers." ;
+ lv2:documentation """
+<p>An extension that allows LV2 plugins to request a resize of an output port.</p>
+
+<p>Any host which supports this extension must pass an LV2_Feature to
+the plugin's instantiate method with URI http://lv2plug.in/ns/ext/resize-port
+and a pointer to a LV2_Resize_Port_Feature structure (see
+<a href="resize-port.h">resize-port.h</a> for details). This structure
+provides a resize_port function which plugins may use to resize output
+port buffers as necessary.</p>
+
+<p>This extension also defines several predicates useful for describing the
+amount of space required for a particular port buffer.</p>
+""" .
+
+rsz:asLargeAs a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range lv2:Symbol ;
+ rdfs:label "as large as" ;
+ rdfs:comment """
+Indicates that a port requires at least as much buffer space as the port
+with the given symbol on the same plugin instance. This may be used for
+any ports, but is generally most useful to indicate an output port must
+be at least as large as some input port (because it will copy from it).
+If a port is asLargeAs several ports, it is asLargeAs the largest such port
+(not the sum of those ports' sizes).
+
+The host guarantees that whenever an ObjectPort's run method is called,
+any output O that is obj:asLargeAs an input I is connected to a buffer large
+enough to copy I, or NULL if the port is lv2:connectionOptional.
+""" .
+
+rsz:minimumSize a rdf:Property ;
+ rdfs:domain lv2:Port ;
+ rdfs:range lv2:Symbol ;
+ rdfs:label "minimum size" ;
+ rdfs:comment """
+Indicates that a port requires a buffer at least this large, in bytes.
+Any host that supports the resize-port feature MUST connect any port with a
+minimumSize specified to a buffer at least as large as the value given for
+this property. Any host, especially those that do NOT support dynamic port
+resizing, SHOULD do so or reduced functionality may result.
+""" .
diff --git a/ns/ext/resize-port/waf b/ns/ext/resize-port/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/resize-port/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/resize-port/wscript b/ns/ext/resize-port/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/resize-port/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/state/ext.pc.in b/ns/ext/state/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/state/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/state/manifest.ttl b/ns/ext/state/manifest.ttl
new file mode 100644
index 0000000..7894a22
--- /dev/null
+++ b/ns/ext/state/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/state>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <state.ttl> .
+
diff --git a/ns/ext/state/state.h b/ns/ext/state/state.h
new file mode 100644
index 0000000..4e1c28a
--- /dev/null
+++ b/ns/ext/state/state.h
@@ -0,0 +1,258 @@
+/*
+ Copyright 2010-2011 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
+ C API for the LV2 State extension <http://lv2plug.in/ns/ext/state>.
+*/
+
+#ifndef LV2_STATE_H
+#define LV2_STATE_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LV2_STATE_URI "http://lv2plug.in/ns/ext/state"
+
+#define LV2_STATE_INTERFACE_URI LV2_STATE_URI "#Interface"
+
+typedef void* LV2_State_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 references to non-stateent or
+ non-global resources (e.g. pointers, handles, local paths, etc.). It is
+ safe to copy POD values with a simple memcpy and store them for use at
+ any time in the future on a machine with a compatible architecture
+ (e.g. the same endianness and alignment).
+
+ 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, i.e. if the value is saved on one machine it can safely be
+ restored on another machine regardless of endianness, alignment, etc.
+ */
+ 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 host-provided function to store a property.
+ @param handle Must be the handle passed to LV2_State_Interface.save().
+ @param key The key (predicate) to store @c value under (URI mapped integer).
+ @param value Pointer to the value (object) to be stored.
+ @param size The size of the data at @c value in bytes.
+ @param type The type of @c value (URI).
+ @param flags LV2_State_Flags for @c 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 within LV2_State_Interface.save() to store all
+ the statements that describe its current state.
+
+ The host MAY fail to store a property if the type is not understood and is
+ not LV2_STATE_IS_POD and/or LV2_STATE_IS_PORTABLE. Implementations are
+ encouraged to use POD and portable values (e.g. string literals) wherever
+ possible, and use common types (e.g. types from
+ http://lv2plug.in/ns/ext/atom) regardless, since hosts are likely to already
+ contain the necessary implementation.
+
+ Note that @c size MUST be > 0, and @c value MUST point to a valid region of
+ memory @c 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 int (*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 (predicate) of the property to retrieve (URI).
+ @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 LV2_State_Flags for
+ the returned value.
+ @return A pointer to the restored value (object), or NULL if no value
+ has been stored under @c key.
+
+ A callback of this type is passed by the host to
+ LV2_State_Interface.restore(). This callback is called repeatedly by the
+ plugin within LV2_State_Interface.restore() 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. Returned values
+ MAY be copied for later use if necessary, assuming the plugin knows how to
+ do so correctly (e.g. the value is POD, or the plugin understands the type).
+*/
+typedef const void* (*LV2_State_Retrieve_Function)(LV2_State_Handle handle,
+ uint32_t key,
+ size_t* size,
+ uint32_t* type,
+ uint32_t* flags);
+
+/**
+ State Extension Data.
+
+ When the plugin's extension_data is called with argument LV2_STATE_URI,
+ the plugin MUST return an LV2_State 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
+ for the given function are met).
+
+ The typical use case is to save the plugin's state when a project is saved,
+ and to restore the state when a project has been loaded. Other uses are
+ possible (e.g. cloning plugin instances or taking a snapshot of plugin
+ state).
+
+ 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 compatibility issues in the future.
+*/
+typedef struct _LV2_State_Interface {
+
+ /**
+ Save plugin state using a host-provided @c 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, e.g. the map or
+ file where the values are to be stored. If @c store is called, this MUST
+ be passed as its handle parameter.
+ @param flags Flags describing desires properties of this save. The
+ plugin SHOULD use these values to determine the most appropriate and/or
+ efficient serialisation, but is not required to do so.
+ @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 (possibly much later, in a different process, on
+ a completely different machine, etc.)
+
+ The @c handle pointer and @c 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.
+ */
+ void (*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 @c 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, e.g. the map or
+ file from which the values are to be restored. If @c retrieve is
+ called, this MUST be passed as its handle parameter.
+ @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 @c handle pointer and @c 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.
+ */
+ void (*restore)(LV2_Handle instance,
+ LV2_State_Retrieve_Function retrieve,
+ LV2_State_Handle handle,
+ uint32_t flags,
+ const LV2_Feature *const * features);
+
+} LV2_State_Interface;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_STATE_H */
diff --git a/ns/ext/state/state.ttl b/ns/ext/state/state.ttl
new file mode 100644
index 0000000..c79188e
--- /dev/null
+++ b/ns/ext/state/state.ttl
@@ -0,0 +1,231 @@
+# LV2 State Extension
+# Copyright 2010-2011 David Robillard <d@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.
+
+@prefix state: <http://lv2plug.in/ns/ext/state#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/state>
+ a lv2:Specification ;
+ doap:name "LV2 State" ;
+ doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:release [
+ doap:revision "0.2" ;
+ doap:created "2011-11-14"
+ ] ;
+ doap:developer [
+ a foaf:Person ;
+ foaf:name "Leonard Ritter" ;
+ foaf:homepage <http://paniq.org> ;
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension provides a mechanism for plugins to save and restore state
+across instances, allowing hosts to save, restore, clone, or take a snapshot of
+a plugin instance's state at any point in time. The intention is for a plugin
+instance's state to be <em>completely</em> described by port values (as with all
+LV2 plugins) and a simple dictionary.</p>
+
+<p>The <q>state</q> described by this extension is conceptually a single
+key/value dictionary, where keys are URIDs and values are type-tagged blobs of
+any type. The plugin provides an LV2_State_Interface for working with this
+state. To save or restore, the host calls LV2_State_Interface::save() or
+LV2_State_Interface::restore(), passing a callback to be used for handling a
+single key/value pair. The host is free to implement saving and restoring in
+any way; the actual mechanism is completely abstract from the plugin's
+perspective.</p>
+
+<p>Because state is a simple dictionary, hosts and plugins can work with it
+easily from many languages and protocols. Keys are URIDs for performance
+reasons as well as RDF compatibility, which makes it simple to serialise state
+in many formats (e.g. any RDF syntax, JSON, XML, key/value databases such as
+BDB, etc.). In particular, state can be elegantly described in a plugin's
+Turtle description, which is useful for e.g. presets or default state.
+Specific keys may be described in Turtle on the fly or in extensions,
+allowing plugins to use common well-defined keys.</p>
+
+<p>This extension defines a conceptual model of state and a mechanism for
+saving and restoring it, but no interface for manipulating it dynamically.
+While no such mechanism is defined here, dynamic control of plugins SHOULD be
+achieved by generic manipulations of the same conceptual state dictionary used
+by this extension (e.g. <code>plugin->set(key, value)</code>). Accordingly,
+plugins SHOULD use meaningful and well-defined keys wherever possible.</p>
+
+<p>In pseudo code, a typical use case in a plugin is:</p>
+<pre class="c-code">
+#define NS_EG "http://example.org/"
+#define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
+
+LV2_Handle my_instantiate(...)
+{
+ MyPlugin* plugin = ...;
+ plugin->uris.atom_String = map_uri(NS_ATOM "String");
+ plugin->uris.eg_greeting = map_uri(NS_EG "greeting");
+ plugin->state.greeting = strdup("Hello");
+ return plugin;
+}
+
+void my_save(LV2_Handle instance,
+ LV2_State_Store_Function store,
+ void* handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
+
+{
+ MyPlugin* plugin = (MyPlugin*)instance;
+ const char* greeting = plugin->state.greeting;
+
+ store(handle,
+ plugin->uris.eg_greeting,
+ greeting,
+ strlen(greeting) + 1,
+ plugin->uris.atom_String,
+ LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
+}
+
+void my_restore(LV2_Handle instance,
+ LV2_State_Retrieve_Function retrieve,
+ void* handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
+{
+ MyPlugin* plugin = (MyPlugin*)instance;
+
+ size_t size;
+ uint32_t type;
+ uint32_t flags;
+ const char* greeting = retrieve(handle,
+ plugin->uris.eg_greeting,
+ &amp;size,
+ &amp;type,
+ &amp;flags);
+
+ if (greeting) {
+ free(plugin->state->greeting);
+ plugin->state->greeting = strdup(greeting);
+ } else {
+ plugin->state->greeting = strdup("Hello");
+ }
+}
+
+const void* my_extension_data(const char* uri)
+{
+ static const LV2_State_Interface state_iface = { my_save, my_restore };
+ if (!strcmp(uri, LV2_STATE_INTERFACE_URI)) {
+ return &amp;state_iface;
+ }
+}
+</pre>
+
+<p>Similarly, a typical use case in a host is:</p>
+<pre class="c-code">
+int store_callback(void* handle,
+ uint32_t key,
+ const void* value,
+ size_t size,
+ uint32_t type,
+ uint32_t flags)
+{
+ if ((flags &amp; LV2_STATE_IS_POD)) {
+ /* We only care about POD since we're keeping state in memory only.
+ If this was for disk or network storage/transmission,
+ LV2_STATE_IS_PORTABLE would have to be checked as well.
+ */
+ Map* state_map = (Map*)handle;
+ state_map->insert(key, Value(copy(value), size, type, pod));
+ return 0;
+ } else {
+ return 1; /* Non-POD events are unsupported. */
+ }
+}
+
+Map get_plugin_state(LV2_Handle instance)
+{
+ LV2_State* state = instance.extension_data("http://lv2plug.in/ns/ext/state");
+ Map state_map;
+ /** Request a fast/native/POD save, since we're just copying in memory */
+ state.save(instance, store_callback, &amp;state_map,
+ LV2_STATE_IS_POD|LV2_STATE_IS_NATIVE);
+ return state_map;
+}
+</pre>
+""" .
+
+state:Interface
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:ExtensionData ;
+ lv2:documentation """
+<p>A structure (LV2_State_Interface) which contains functions to be called by
+the host to save and restore state. In order to support this extension, the
+plugin must return a valid LV2_State_Interface from
+LV2_Descriptor::extension_data() when it is called with
+LV2_STATE_INTERFACE_URI.</p>
+
+<p>The plugin data file should describe this like so:</p>
+<pre class="turtle-code">
+@prefix state: &lt;http://lv2plug.in/ns/ext/state#&gt; .
+
+&lt;plugin&gt;
+ a lv2:Plugin ;
+ lv2:extensionData state:Interface .
+</pre>
+""" .
+
+state:InstanceState
+ a rdfs:Class ;
+ rdfs:label "Plugin Instance State" ;
+ rdfs:comment """
+This class is used to express a plugin instance's state in RDF. The key/value
+properties of the instance form the predicate/object (respectively) of triples
+with a state:InstanceState as the subject (see state:instanceState for an
+example). This may be used wherever it is useful to express a plugin instance's
+state in RDF (e.g. for serialisation, storing in a model, or transmitting over
+a network). Note that this class is provided because it may be useful for
+hosts, plugins, or extensions that work with instance state, but its use is not
+required to support the LV2 State extension.
+""" .
+
+state:instanceState
+ a rdf:Property ;
+ rdfs:range state:InstanceState ;
+ lv2:documentation """
+<p>Predicate to relate a plugin instance to an InstanceState. This may be used
+wherever the state of a particular plugin instance needs to be represented.
+Note that the domain of this property is unspecified, since LV2 does not define
+any RDF class for plugin instance. This predicate may be used wherever it makes
+sense to do so, e.g.:</p>
+<pre class="turtle-code">
+@prefix eg: &lt;http://example.org/&gt; .
+
+&lt;plugininstance&gt; state:instanceState [
+ eg:somekey "some value" ;
+ eg:someotherkey "some other value" ;
+ eg:favourite-number 2
+] .
+</pre>
+<p>Note that this property is provided because it may be useful for hosts,
+plugins, or extensions that work with instance state, but its use is not
+required to support the LV2 State extension.</p>
+""" .
diff --git a/ns/ext/state/waf b/ns/ext/state/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/state/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/state/wscript b/ns/ext/state/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/state/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/string-port/ext.pc.in b/ns/ext/string-port/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/string-port/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/string-port/manifest.ttl b/ns/ext/string-port/manifest.ttl
new file mode 100644
index 0000000..d0e618e
--- /dev/null
+++ b/ns/ext/string-port/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/string-port>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <string-port.ttl> .
diff --git a/ns/ext/string-port/string-port.h b/ns/ext/string-port/string-port.h
new file mode 100644
index 0000000..e7fc8c7
--- /dev/null
+++ b/ns/ext/string-port/string-port.h
@@ -0,0 +1,58 @@
+/* lv2_string_port.h - C header file for LV2 string port extension.
+ * Draft Revision 3
+ * Copyright (C) 2008 Krzysztof Foltman <wdev@foltman.com>
+ *
+ * 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
+ */
+
+/** @file
+ * C header for the LV2 String Port extension
+ * <http://lv2plug.in/ns/ext/string-port#StringTransfer>.
+ */
+
+#ifndef LV2_STRING_PORT_H
+#define LV2_STRING_PORT_H
+
+#include <stdint.h>
+
+/** URI for the string port transfer mechanism feature */
+#define LV2_STRING_PORT_URI "http://lv2plug.in/ns/ext/string-port#StringTransfer"
+
+/** Flag: port data has been updated; for input ports, this flag is set by
+the host. For output ports, this flag is set by the plugin. */
+#define LV2_STRING_DATA_CHANGED_FLAG 1
+
+/** structure for string port data */
+typedef struct
+{
+ /** Buffer for UTF-8 encoded zero-terminated string value; host-allocated */
+ char *data;
+
+ /** Length in bytes (not characters), not including zero byte */
+ size_t len;
+
+ /** Output ports: storage space in bytes; must be >= RDF-specified requirements */
+ size_t storage;
+
+ /** Flags defined above */
+ uint32_t flags;
+
+ /** Undefined (pad to 8 bytes) */
+ uint32_t pad;
+
+} LV2_String_Data;
+
+#endif
+
diff --git a/ns/ext/string-port/string-port.ttl b/ns/ext/string-port/string-port.ttl
new file mode 100644
index 0000000..f36fa7a
--- /dev/null
+++ b/ns/ext/string-port/string-port.ttl
@@ -0,0 +1,105 @@
+# LV2 String Port Extension.
+# Draft Revision 3
+# Copyright (C) 2008 Krzysztof Foltman
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix sp: <http://lv2plug.in/ns/ext/string-port#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/string-port> a lv2:Specification ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 String Ports" ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "Krzysztof Foltman" ;
+ ] ;
+ lv2:documentation """
+<p>Defines ports which contain string data.</p>
+
+<h4>UI issues</h4>
+<p>When using port_event / write_port (and possible other communication
+mechanisms), the format parameter should contain the numeric value of URI
+LV2_STRING_PORT_URI (mapped with http://lv2plug.in/ns/extensions/ui specified
+as map URI).</p>
+
+<p>It's probably possible to use ports belonging to message context
+&lt;http://lv2plug.in/ns/ext/contexts#MessageContext&gt; for transfer. However,
+contexts mechanism does not offer any way to notify the message recipient about
+which ports have been changed. To remedy that, this extension defines a flag
+LV2_STRING_DATA_CHANGED_FLAG that carries that information inside a port value
+structure.</p>
+
+<h4>Storage</h4>
+<p>The value of string port are assumed to be "persistent": if a host saves and
+restores a state of a plugin (e.g. control port values), the values of input
+string ports should also be assumed to belong to that state. This also applies
+to message context: if a session is being restored, the host MUST resend the
+last value that was sent to the port before session has been saved. In other
+words, string port values "stick" to message ports.</p>
+""" .
+
+sp:StringTransfer a lv2:Feature ;
+ rdfs:label "String data transfer via LV2_String_Data" .
+
+sp:StringPort a lv2:Port ;
+ rdfs:label "String port" ;
+ lv2:documentation """
+<p>Indicates that the port data points to a LV2_String_Data structure
+as defined in accompanying header file.</p>
+
+<h4>Input Port Semantics</h4>
+<p>If the port does not have a context specified (it runs in the default,
+realtime audio processing context), the values in the structure and the actual
+string data MUST remain unchanged for the time a run() function of a plugin
+is executed. However, if the port belongs to a different context, the same
+data MUST remain unchanged only for the time a run() or message_process()
+function of a given context is executed.</p>
+
+<h4>Output Port Semantics</h4>
+<p>The plugin may only change the string or length in a run() function (if
+the port belongs to default context) or in context-defined counterparts
+(if the port belongs to another context). Because of that, using default
+context output string ports is contraindicated for longer strings.</p>
+""" .
+
+sp:default a rdf:Property ;
+ rdfs:label "Default value" ;
+ rdfs:domain sp:StringPort ;
+ rdfs:range xsd:string ;
+ rdfs:comment """
+Gives a default value for a string port.
+""" .
+
+sp:requiredSpace a rdf:Property ;
+ rdfs:label "Required storage space in bytes" ;
+ rdfs:domain sp:StringPort ;
+ rdfs:range xsd:nonNegativeInteger ;
+ rdfs:comment """
+Specifies required buffer space for output string ports and those of
+input string ports that are meant to be GUI-controlled. The host MUST
+allocate a buffer of at least required size to accommodate for all values
+that can be produced by the plugin.
+""" .
+
diff --git a/ns/ext/string-port/waf b/ns/ext/string-port/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/string-port/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/string-port/wscript b/ns/ext/string-port/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/string-port/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/time/ext.pc.in b/ns/ext/time/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/time/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/time/manifest.ttl b/ns/ext/time/manifest.ttl
new file mode 100644
index 0000000..2657388
--- /dev/null
+++ b/ns/ext/time/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/time>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <time.ttl> .
+
diff --git a/ns/ext/time/time.h b/ns/ext/time/time.h
new file mode 100644
index 0000000..f3b2e77
--- /dev/null
+++ b/ns/ext/time/time.h
@@ -0,0 +1,131 @@
+/*
+ Copyright 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 time.h C header for the LV2 Time extension
+ <http://lv2plug.in/ns/ext/time>.
+*/
+
+#ifndef LV2_TIME_H
+#define LV2_TIME_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ Time states.
+*/
+typedef enum {
+ LV2_TIME_STOPPED = 0, /**< Transport halted */
+ LV2_TIME_ROLLING = 1, /**< Transport playing */
+} LV2_Time_State;
+
+/**
+ Bits indicating properties of an LV2_Time_Position.
+*/
+typedef enum {
+ LV2_TIME_HAS_BBT = 1 /**< Has Bar, Beat, Tick */
+} LV2_Time_Flags;
+
+/**
+ Description of a position and/or tempo.
+
+ This struct is used as the payload of an event to notify the plugin about
+ time state, such as position and tempo.
+*/
+typedef struct {
+ /**
+ @{
+ @name Mandatory Fields
+ */
+
+ /**
+ Frame number on the timeline.
+ */
+ uint64_t frame;
+
+ /**
+ Bit field of LV2_Time_Flags values indicating which fields
+ of this struct are valid.
+ */
+ uint32_t flags;
+
+ /**
+ Transport state.
+ */
+ LV2_Time_State state;
+
+ /**
+ @}
+ @{
+ @name LV2_TIME_BBT fields
+ These fields are valid iff the LV2_TIME_BBT bit is set in @ref flags.
+ */
+
+ /**
+ Current bar.
+ The first bar is number 0 (but should be represented in a UI as bar 1).
+ */
+ int64_t bar;
+
+ /**
+ Beat within the current bar.
+ The first beat is number 0.
+ Always <= @ref beats_per_bar.
+ */
+ int32_t beat;
+
+ /**
+ Tick within the current beat.
+ The first tick is number 0.
+ Always <= @ref ticks_per_beat.
+ */
+ int32_t tick;
+
+ /**
+ Number of beats per bar (top of time signature).
+ */
+ int32_t beats_per_bar;
+
+ /**
+ Type of note that counts as one beat (bottom of time signature).
+ */
+ int32_t beat_type;
+
+ /**
+ Number of ticks per beat.
+ Typically this is a large integer with many even divisors.
+ */
+ int32_t ticks_per_beat;
+
+ /**
+ Current tempo, in beats per minute.
+ */
+ double beats_per_minute;
+
+ /**
+ @}
+ */
+} LV2_Time_Position;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_TIME_H */
diff --git a/ns/ext/time/time.ttl b/ns/ext/time/time.ttl
new file mode 100644
index 0000000..40bfdbb
--- /dev/null
+++ b/ns/ext/time/time.ttl
@@ -0,0 +1,57 @@
+# LV2 Time Extension
+# Copyright 2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix time: <http://lv2plug.in/ns/ext/time#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/ext/time>
+ a lv2:Specification ;
+ doap:name "LV2 Time" ;
+ doap:shortdesc "A data type for transport speed and position." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.rdf>
+ ] ;
+ lv2:documentation """
+<p>This extension defines a structure type, LV2_Time_Position, which
+describes a tempo and position along a timeline. This can be used as
+an event payload by the host to notify plugins about the current
+tempo and position.</p>
+""" .
+
+time:Position
+ a rdfs:Class ;
+ rdfs:label "LV2 time position" ;
+ lv2:documentation """
+<p>Type for an LV2_Time_Position struct. This can be mapped to an integer and
+used as the type field of an event to indicate that the event payload is an
+LV2_Time_Positon struct. Plugins SHOULD indicate that a port supports time
+information using the ev:supports predicate, e.g.:</p>
+<pre class="turtle-code">
+&lt;plugin&gt; lv2:port [
+ a lv2:InputPort , ev:EventPort ;
+ lv2:name "control" ;
+ lv2:index 0 ;
+ ev:supportsEvent time:Position
+] .
+</pre>
+""" .
diff --git a/ns/ext/time/waf b/ns/ext/time/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/time/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/time/wscript b/ns/ext/time/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/time/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/ui-resize/ext.pc.in b/ns/ext/ui-resize/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/ui-resize/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/ui-resize/manifest.ttl b/ns/ext/ui-resize/manifest.ttl
new file mode 100644
index 0000000..ca5cdf9
--- /dev/null
+++ b/ns/ext/ui-resize/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/ui-resize>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <ui-resize.ttl> .
+
diff --git a/ns/ext/ui-resize/ui-resize.h b/ns/ext/ui-resize/ui-resize.h
new file mode 100644
index 0000000..cf5ccc6
--- /dev/null
+++ b/ns/ext/ui-resize/ui-resize.h
@@ -0,0 +1,58 @@
+/*
+ Copyright 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.
+*/
+
+#ifndef LV2_UI_RESIZE_H
+#define LV2_UI_RESIZE_H
+
+#define LV2_UI_RESIZE_URI "http://lv2plug.in/ns/ext/ui-resize"
+
+typedef void* LV2_UI_Resize_Feature_Data;
+
+/**
+ UI Resize Feature.
+
+ This structure may be used in two ways: as a feature passed by the host
+ (e.g. via the features parameter of LV2UI_Descriptor::instantiate()) or
+ as a feature exposed by a UI (e.g. via LV2UI_Descriptor::extension_data()).
+
+ In both cases, the URI to be used is
+ http://lv2plug.in/ns/ext/ui-resize#UIResize
+*/
+typedef struct {
+
+ LV2_UI_Resize_Feature_Data data;
+
+ /**
+ Request or notify a size change.
+
+ When this struct is provided by the host, the UI may call this
+ function to notify the host that a size change is desired, or notify
+ the host of the initial size of the UI.
+
+ When this struct is provided by the plugin, the host may call this
+ function in the UI thread to notify the UI that it should change its
+ size to the given dimensions.
+
+ @return 0 on success.
+ */
+ int (*ui_resize)(LV2_UI_Resize_Feature_Data data,
+ int width,
+ int height);
+
+} LV2_UI_Resize_Feature;
+
+#endif /* LV2_UI_RESIZE_H */
+
diff --git a/ns/ext/ui-resize/ui-resize.ttl b/ns/ext/ui-resize/ui-resize.ttl
new file mode 100644
index 0000000..5e2a5a8
--- /dev/null
+++ b/ns/ext/ui-resize/ui-resize.ttl
@@ -0,0 +1,43 @@
+# LV2 UI Resize Extension
+# Copyright 2011 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix uirsz: <http://lv2plug.in/ns/ext/ui-resize#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/ui-resize>
+ a lv2:Specification ;
+ doap:name "LV2 UI Resize Extension" ;
+ doap:shortdesc "A feature for self-resizing plugin UIs." ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ lv2:documentation """
+<p>An extension that allows LV2 plugin UIs to notify the host about size
+changes, or for the host to notify plugin UIs about size changes.</p>
+""" .
+
+uirsz:UIResize
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature that allows the UI to notify the host about its current size, or
+request a size change. This feature corresponds to the LV2_UI_Resize_Feature
+struct, which should be passed with the feature URI
+<code>http://lv2plug.in/ns/ext/ui-resize#UIResize</code>. This struct may also
+be provided by the UI as extension data using the same URI, in which case it
+is used by the host to request that the UI change its size.</p>
+""" .
diff --git a/ns/ext/ui-resize/waf b/ns/ext/ui-resize/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/ui-resize/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/ui-resize/wscript b/ns/ext/ui-resize/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/ui-resize/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/uri-map/ext.pc.in b/ns/ext/uri-map/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/uri-map/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/uri-map/manifest.ttl b/ns/ext/uri-map/manifest.ttl
new file mode 100644
index 0000000..eb78686
--- /dev/null
+++ b/ns/ext/uri-map/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/uri-map>
+ a lv2:Specification ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <uri-map.ttl> .
diff --git a/ns/ext/uri-map/uri-map.h b/ns/ext/uri-map/uri-map.h
new file mode 100644
index 0000000..6767cd1
--- /dev/null
+++ b/ns/ext/uri-map/uri-map.h
@@ -0,0 +1,92 @@
+/*
+ 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 URI Map extension <http://lv2plug.in/ns/ext/uri-map>.
+
+ 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).
+*/
+
+#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>
+
+/**
+ Opaque pointer to host data.
+*/
+typedef void* LV2_URI_Map_Callback_Data;
+
+/**
+ URI Map Feature.
+
+ 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. Extensions SHOULD NOT define a context
+ unless there is a specific need to do so, e.g. to restrict the range of
+ the returned value.
+ @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 indicates that an ID for that URI
+ could not be created for whatever reason. Extensions MAY define more
+ precisely what this means in a certain context, but in general plugins
+ SHOULD handle this situation as gracefully as possible. However, hosts
+ SHOULD NOT return 0 from this function in non-exceptional circumstances
+ (e.g. the URI map SHOULD be dynamic). Hosts that statically support only
+ a fixed set of URIs should not expect plugins to function correctly.
+ */
+ 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 */
diff --git a/ns/ext/uri-map/uri-map.ttl b/ns/ext/uri-map/uri-map.ttl
new file mode 100644
index 0000000..b0a5399
--- /dev/null
+++ b/ns/ext/uri-map/uri-map.ttl
@@ -0,0 +1,57 @@
+# LV2 URI Map Extension
+# 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.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix umap: <http://lv2plug.in/ns/ext/uri-map#> .
+
+<http://lv2plug.in/ns/ext/uri-map>
+ a lv2:Specification ,
+ lv2:Feature ;
+ owl:deprecated true ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 URI Map" ;
+ doap:shortdesc "A feature for mapping URIs to integers." ;
+ doap:release [
+ doap:revision "1.2" ;
+ doap:created "2011-05-26"
+ ] ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.xrdf>
+ ] , [
+ a foaf:Person ;
+ foaf:name "Lars Luthman"
+ ] ;
+ lv2:documentation """
+<p><span class="warning">This extension is deprecated.</span> New
+implementations should use <a href="http://lv2plug.in/ns/ext/urid">LV2 URID</a>
+instead.</p>
+
+<p>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).</p>
+""" .
diff --git a/ns/ext/uri-map/waf b/ns/ext/uri-map/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/uri-map/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/uri-map/wscript b/ns/ext/uri-map/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/uri-map/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/uri-unmap/ext.pc.in b/ns/ext/uri-unmap/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/uri-unmap/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/uri-unmap/manifest.ttl b/ns/ext/uri-unmap/manifest.ttl
new file mode 100644
index 0000000..217e7b6
--- /dev/null
+++ b/ns/ext/uri-unmap/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/uri-unmap>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 1 ;
+ rdfs:seeAlso <uri-unmap.ttl> .
diff --git a/ns/ext/uri-unmap/uri-unmap.h b/ns/ext/uri-unmap/uri-unmap.h
new file mode 100644
index 0000000..d6cb900
--- /dev/null
+++ b/ns/ext/uri-unmap/uri-unmap.h
@@ -0,0 +1,81 @@
+/* lv2_uri_unmap.h - C header file for the LV2 URI Unmap extension.
+ *
+ * Copyright (C) 2010 David Robillard <http://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
+ */
+
+/** @file
+ * C header for the LV2 URI Map extension <http://lv2plug.in/ns/ext/uri-unmap>.
+ */
+
+#ifndef LV2_URI_UNMAP_H
+#define LV2_URI_UNMAP_H
+
+#define LV2_URI_UNMAP_URI "http://lv2plug.in/ns/ext/uri-unmap"
+
+#include <stdint.h>
+
+
+/** Opaque pointer to host data. */
+typedef void* LV2_URI_Unmap_Callback_Data;
+
+
+/** The data field of the LV2_Feature for the URI Unmap extension.
+ *
+ * To support this extension the host must pass an LV2_Feature struct to the
+ * plugin's instantiate method with URI "http://lv2plug.in/ns/ext/uri-unmap"
+ * 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_Unmap_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' used to map this URI.
+ * @param id The URI ID to unmap.
+ * @return The string form of @a id, or NULL on error.
+ *
+ * The @a id MUST be a value previously returned from
+ * LV2_Uri_Map_Feature.uri_to_id.
+ *
+ * The returned string is owned by the host and MUST NOT be freed by
+ * the plugin or stored for a long period of time (e.g. across run
+ * invocations) without copying.
+ *
+ * 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 ID may return different values
+ * with a different map parameter).
+ *
+ * This function may be called from any non-realtime thread, possibly
+ * concurrently (hosts may simply use a mutex to meet these requirements).
+ */
+ const char* (*id_to_uri)(LV2_URI_Unmap_Callback_Data callback_data,
+ const char* map,
+ uint32_t id);
+
+} LV2_URI_Unmap_Feature;
+
+
+#endif /* LV2_URI_UNMAP_H */
+
diff --git a/ns/ext/uri-unmap/uri-unmap.ttl b/ns/ext/uri-unmap/uri-unmap.ttl
new file mode 100644
index 0000000..053bb37
--- /dev/null
+++ b/ns/ext/uri-unmap/uri-unmap.ttl
@@ -0,0 +1,46 @@
+# LV2 URI Unmap Extension
+# Copyright (C) 2010 David Robillard <d@drobilla.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+@prefix unmap: <http://lv2plug.in/ns/ext/uri-unmap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+<http://lv2plug.in/ns/ext/uri-unmap> a lv2:Specification , lv2:Feature ;
+ doap:license <http://usefulinc.com/doap/licenses/mit> ;
+ doap:name "LV2 URI Unmap" ;
+ doap:shortdesc "A feature for unmapping URIs from integers." ;
+ doap:maintainer [
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:homepage <http://drobilla.net/> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla.xrdf>
+ ] ;
+ lv2:documentation """
+<p>This extension is the opposite of the <a
+href="http://lv2plug.in/ns/ext/uri-map" >LV2 URI Map</a> extension. It allows
+the host to pass an id_to_uri function to the plugin which can be used for
+unmapping an integer (previously mapped using the URI map extension's
+uri_to_id) back to a string.</p>""" .
+
diff --git a/ns/ext/uri-unmap/waf b/ns/ext/uri-unmap/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/uri-unmap/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/uri-unmap/wscript b/ns/ext/uri-unmap/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/uri-unmap/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file
diff --git a/ns/ext/urid/ext.pc.in b/ns/ext/urid/ext.pc.in
new file mode 120000
index 0000000..1cdad2a
--- /dev/null
+++ b/ns/ext/urid/ext.pc.in
@@ -0,0 +1 @@
+../../../ext.pc.in \ No newline at end of file
diff --git a/ns/ext/urid/manifest.ttl b/ns/ext/urid/manifest.ttl
new file mode 100644
index 0000000..c77aff6
--- /dev/null
+++ b/ns/ext/urid/manifest.ttl
@@ -0,0 +1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+<http://lv2plug.in/ns/ext/urid>
+ a lv2:Specification ;
+ lv2:minorVersion 0 ;
+ lv2:microVersion 2 ;
+ rdfs:seeAlso <urid.ttl> .
diff --git a/ns/ext/urid/urid.h b/ns/ext/urid/urid.h
new file mode 100644
index 0000000..d36d0dd
--- /dev/null
+++ b/ns/ext/urid/urid.h
@@ -0,0 +1,113 @@
+/*
+ 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"
+
+#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 */
diff --git a/ns/ext/urid/urid.ttl b/ns/ext/urid/urid.ttl
new file mode 100644
index 0000000..a87b368
--- /dev/null
+++ b/ns/ext/urid/urid.ttl
@@ -0,0 +1,67 @@
+# LV2 URID Extension
+# 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.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+<http://lv2plug.in/ns/ext/urid>
+ a lv2:Specification ;
+ doap:license <http://opensource.org/licenses/isc-license> ;
+ doap:name "LV2 URID" ;
+ doap:shortdesc "Features for mapping URIs to and from integers." ;
+ doap:release [
+ doap:revision "0.2" ;
+ doap:created "2011-01-04"
+ ] ;
+ doap:developer [
+ a foaf:Person ;
+ foaf:name "Gabriel M. Beddingfield" ;
+ foaf:homepage <http://gabe.is-a-geek.org/>
+ ] ;
+ lv2:documentation """
+<p>This extension defines a simple mechanism for plugins to map URIs to and
+from integers, usually for performance reasons (e.g. processing events typed by
+URIs in real time). Typically, plugins 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 for the extensibility
+of RDF but with the performance of integers.</p>
+
+<p>This extension is intended as an improved and simpler replacement for the <a
+href="http://lv2plug.in/ns/ext/uri-map">uri-map</a> extension, since the
+<q>map</q> context parameter has been found problematic.</p>
+""" .
+
+urid:map
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature which is used to map URIs to integers. To support this feature,
+the host must pass an LV2_Feature to LV2_Descriptor::instantiate() with
+<em>URI</em> <q>http://lv2plug.in/ns/ext/urid#map</q> and <em>data</em> pointed
+to an instance of LV2_URID_Map.</p>
+""" .
+
+urid:unmap
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature which is used to unmap URIs previously mapped to integers by
+urid:map. To support this feature, the host must pass an LV2_Feature to
+LV2_Descriptor::instantiate() with <em>URI</em>
+<q>http://lv2plug.in/ns/ext/urid#unmap</q> and <em>data</em> pointed to an
+instance of LV2_URID_Unmap.</p>
+""" .
diff --git a/ns/ext/urid/waf b/ns/ext/urid/waf
new file mode 120000
index 0000000..917d5c5
--- /dev/null
+++ b/ns/ext/urid/waf
@@ -0,0 +1 @@
+../../../waf \ No newline at end of file
diff --git a/ns/ext/urid/wscript b/ns/ext/urid/wscript
new file mode 120000
index 0000000..cf8cbae
--- /dev/null
+++ b/ns/ext/urid/wscript
@@ -0,0 +1 @@
+../../../ext.wscript \ No newline at end of file