aboutsummaryrefslogtreecommitdiffstats
path: root/lv2/ns/ext/atom
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-11-21 01:36:00 +0000
committerDavid Robillard <d@drobilla.net>2011-11-21 01:36:00 +0000
commiteb43c8896480114b224755e824fae2e2f7485256 (patch)
tree26e91bd8dc6421d2296a33991e90f7dcb546b079 /lv2/ns/ext/atom
parentdf79255ccef7fb5d091e9d4e52f3c46545b53282 (diff)
downloadlv2-eb43c8896480114b224755e824fae2e2f7485256.tar.xz
Move ns to lv2/ns so repository top level can be used as an include dir directly.
Diffstat (limited to 'lv2/ns/ext/atom')
-rw-r--r--lv2/ns/ext/atom/atom-buffer.h163
-rw-r--r--lv2/ns/ext/atom/atom-helpers.h174
-rw-r--r--lv2/ns/ext/atom/atom.h248
-rw-r--r--lv2/ns/ext/atom/atom.ttl435
l---------lv2/ns/ext/atom/ext.pc.in1
-rw-r--r--lv2/ns/ext/atom/forge.h75
-rw-r--r--lv2/ns/ext/atom/manifest.ttl9
l---------lv2/ns/ext/atom/waf1
l---------lv2/ns/ext/atom/wscript1
9 files changed, 1107 insertions, 0 deletions
diff --git a/lv2/ns/ext/atom/atom-buffer.h b/lv2/ns/ext/atom/atom-buffer.h
new file mode 100644
index 0000000..f4b90dd
--- /dev/null
+++ b/lv2/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/lv2/ns/ext/atom/atom-helpers.h b/lv2/ns/ext/atom/atom-helpers.h
new file mode 100644
index 0000000..4e51c89
--- /dev/null
+++ b/lv2/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/lv2/ns/ext/atom/atom.h b/lv2/ns/ext/atom/atom.h
new file mode 100644
index 0000000..39d721c
--- /dev/null
+++ b/lv2/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/lv2/ns/ext/atom/atom.ttl b/lv2/ns/ext/atom/atom.ttl
new file mode 100644
index 0000000..1b2e265
--- /dev/null
+++ b/lv2/ns/ext/atom/atom.ttl
@@ -0,0 +1,435 @@
+# 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
+properties. 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 a URID.</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/lv2/ns/ext/atom/ext.pc.in b/lv2/ns/ext/atom/ext.pc.in
new file mode 120000
index 0000000..82b50df
--- /dev/null
+++ b/lv2/ns/ext/atom/ext.pc.in
@@ -0,0 +1 @@
+../../../../ext.pc.in \ No newline at end of file
diff --git a/lv2/ns/ext/atom/forge.h b/lv2/ns/ext/atom/forge.h
new file mode 100644
index 0000000..e8f5d40
--- /dev/null
+++ b/lv2/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/lv2/ns/ext/atom/manifest.ttl b/lv2/ns/ext/atom/manifest.ttl
new file mode 100644
index 0000000..adb10e5
--- /dev/null
+++ b/lv2/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/lv2/ns/ext/atom/waf b/lv2/ns/ext/atom/waf
new file mode 120000
index 0000000..b955110
--- /dev/null
+++ b/lv2/ns/ext/atom/waf
@@ -0,0 +1 @@
+../../../../waf \ No newline at end of file
diff --git a/lv2/ns/ext/atom/wscript b/lv2/ns/ext/atom/wscript
new file mode 120000
index 0000000..ec20a77
--- /dev/null
+++ b/lv2/ns/ext/atom/wscript
@@ -0,0 +1 @@
+../../../../ext.wscript \ No newline at end of file