From 725d4a404b838da6b67d9da66228a1125bddef57 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 20 Nov 2011 23:08:57 +0000 Subject: Lay out repository structure to match include and URI structure. Treat lv2core like all the other specifications in gendoc.py. --- ns/ext/atom/atom-buffer.h | 163 +++++++++++++++++ ns/ext/atom/atom-helpers.h | 174 ++++++++++++++++++ ns/ext/atom/atom.h | 248 ++++++++++++++++++++++++++ ns/ext/atom/atom.ttl | 436 +++++++++++++++++++++++++++++++++++++++++++++ ns/ext/atom/ext.pc.in | 1 + ns/ext/atom/forge.h | 75 ++++++++ ns/ext/atom/manifest.ttl | 9 + ns/ext/atom/waf | 1 + ns/ext/atom/wscript | 1 + 9 files changed, 1108 insertions(+) create mode 100644 ns/ext/atom/atom-buffer.h create mode 100644 ns/ext/atom/atom-helpers.h create mode 100644 ns/ext/atom/atom.h create mode 100644 ns/ext/atom/atom.ttl create mode 120000 ns/ext/atom/ext.pc.in create mode 100644 ns/ext/atom/forge.h create mode 100644 ns/ext/atom/manifest.ttl create mode 120000 ns/ext/atom/waf create mode 120000 ns/ext/atom/wscript (limited to 'ns/ext/atom') 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 + + 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 +#include +#include +#include + +#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 + + 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 +#include +#include +#include + +#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.: +
+   LV2_THING_FOREACH(thing, i) {
+   LV2_Atom_Property* prop = lv2_thing_iter_get(i);
+   // Do things with prop here...
+   }
+   
+*/ +#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 + + 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 + . + + 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 +#include + +#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.: +
+   | Event 1 (size 6)                              | Event 2
+   |       |       |       |       |       |       |       |       |
+   | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+   |FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|...
+   
+*/ +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 +# +# 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: . +@prefix doap: . +@prefix foaf: . +@prefix lv2: . +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . +@prefix owl: . + + + a lv2:Specification ; + doap:name "LV2 Atom" ; + doap:shortdesc "A generic value container and several data types." ; + doap:license ; + rdfs:seeAlso ; + doap:release [ + doap:revision "0.2" ; + doap:created "2011-11-05" + ] ; + doap:maintainer [ + a foaf:Person ; + foaf:name "David Robillard" ; + foaf:homepage ; + rdfs:seeAlso + ] ; + lv2:documentation """ +

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 +memcpy).

+ +

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.

+ +

An Atom can be trivially constructed in-place from an +Event as defined by the +LV2 Event 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.

+ +

Atoms (the start of the LV2_Atom header) MUST be 32-bit aligned.

+ +

Atoms can be communicated in many ways. Since an Atom is the payload of an +Event, an EventPort 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).

+ +

Implementing this extension requires a facility for mapping URIs to +integers, such as the LV2 URID +extension.

+""" . + +atom:Atom + a rdfs:Class ; + rdfs:label "Atom" ; + atom:cType "LV2_Atom" ; + lv2:documentation """ +

Abstract base class for all atoms. An LV2_Atom has a 32-bit +type and size followed by a body of +size bytes.

+ +

All concrete Atom types (subclasses of this class) MUST define a precise +binary layout for body.

+ +

The type field is the URI of a subclass of Atom mapped to an +integer using the URI Map +extension's LV2_URI_Map_Feature::uri_to_id() with +map = "http://lv2plug.in/ns/ext/event". If a plugin or host +does not understand type, that atom SHOULD be gracefully ignored +(or copied if it does not have type 0).

+ +

All atoms are POD by definition except references, which as a special case +have type = 0. An Atom MUST NOT contain a Reference. It is safe +to copy any non-reference Atom with a simple memcpy, even if the +implementation does not understand type. Though this extension reserves +the type 0 for references, actual specification of how references are used is left +to another extension.

+""" . + +atom:String + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "String" ; + atom:cType "LV2_Atom_String" ; + lv2:documentation """ +

A UTF-8 encoded string.

+ +

The body of an LV2_Atom_String is a C string in UTF-8 encoding, i.e. an +array of bytes (uint8_t) terminated with a NULL byte +('\\0').

+ +

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.

+""" . + +atom:Literal + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "String Literal" ; + atom:cType "LV2_Atom_Literal" ; + lv2:documentation """ +

A UTF-8 encoded string literal, with an optional datatype or language.

+ +

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 +datatype and lang followed by string data in UTF-8 +encoding. The length of the string data in bytes is size - +sizeof(LV2_Atom_Literal), including the terminating NULL character. The +lang field SHOULD be a URI of the form +<http://lexvo.org/id/term/LANG> where LANG is an ISO 693-2 or ISO 693-3 language code.

+ +

For compatibility, a Literal MUST have either a datatype +or a lang, but never both.

+ +

For example, a Literal can be "Hello" in English:

+
+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
+}
+
+ +

or a Turtle string:

+
+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
+}
+
+""" . + +atom:URID + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "Integer ID mapped from a URI" ; + atom:cType "LV2_Atom_ID" ; + lv2:documentation """ +

An unsigned 32-bit integer mapped from a URI using the URI Map extension's +LV2_URI_Map_Feature::uri_to_id() with map = NULL.

+""" . + +atom:BlankID + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "Integer ID for a blank node" ; + atom:cType "LV2_Atom_ID" ; + lv2:documentation """ +

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.

+""" . + +atom:Vector + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "Vector" ; + atom:cType "LV2_Atom_Vector" ; + lv2:documentation """ +

A homogeneous sequence of atoms with equivalent type and size.

+ +

An LV2_Atom_Vector is a 32-bit elem_count and +elem_type followed by elem_count atom bodies of type +elem_type. The element type must be a fixed size atom:Atom type, +i.e. the size of each element is the vector's size / +elem_count.

+ +

For example, an atom:Vector containing 42 elements of type atom:Float:

+
+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];
+};
+
+ +

Note that it is possible to construct a valid Atom for each element +of the vector, even by an implementation which does not understand +elem_type.

+""" . + +atom:Tuple + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "Tuple" ; + lv2:documentation """ +

A sequence of lv2:Atom with varying type +and size.

+ +

The body of a Tuple is simply a sequence of complete atoms, each aligned to +32 bits.

+""" . + +atom:Thing + a rdfs:Class ; + rdfs:subClassOf atom:Atom ; + rdfs:label "Thing" ; + atom:cType "LV2_Thing" ; + lv2:documentation """ +

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 context and id followed by a sequence +of LV2_Atom_Property .

+ +

The context is mapped using the URI Map extension's +LV2_URI_Map_Feature::uri_to_id() with map = NULL, and may be 0 +(the default context).

+ +

Note this is an abstract class, i.e. no Atom can exist with type = +uri_to_id(atom:Thing). An Object is either an atom:Resource or an +atom:Blank, but the body 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.

+""" . + +atom:Resource + a rdfs:Class ; + rdfs:subClassOf atom:Thing ; + atom:cType "LV2_Thing" ; + lv2:documentation """ +

An atom:Thing where id is the URI of the resource mapped to an +atom:URID.

+""" . + +atom:Blank + a rdfs:Class ; + rdfs:subClassOf atom:Thing ; + atom:cType "LV2_Thing" ; + lv2:documentation """ +

An atom:Thing where id 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, id +is NOT an ID.

+""" . + +atom:Message + a rdfs:Class ; + rdfs:subClassOf atom:Thing ; + atom:cType "LV2_Thing" ; + lv2:documentation """ +

A atom:Thing where id 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.

+ +

A Message may be serialised as a Blank by adding an rdf:type property with +the value id unmapped to a URI.

+""" . + +atom:Event + a rdfs:Class ; + rdfs:label "Event" ; + atom:cType "LV2_Atom_Event" ; + lv2:documentation """ +

An atom with a time stamp header prepended, typically for sample accurate +transmission via LV2 ports. See struct LV2_Atom_Event.

+""" . + +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 """ +

Support for dynamically allocated blobs. If a host supports this feature, +it MUST pass a LV2_Feature with URI +http://lv2plug.in/ns/ext/atom#blobSupport and data pointing to a +LV2_Blob_Support.

+""" . + +atom:AtomPort + a rdfs:Class ; + rdfs:subClassOf lv2:Port ; + rdfs:label "Atom Port" ; + lv2:documentation """ +

A port which contains an lv2:Atom. Ports of this type will +be connected to a 32-bit aligned LV2_Atom immediately followed by +size bytes of data.

+ +

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). +

+ +

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 type = 0 and size = 0).

+""" . + +atom:ValuePort + a rdfs:Class ; + rdfs:subClassOf atom:AtomPort ; + rdfs:label "Value Port" ; + lv2:documentation """ +

An AtomPort that interprets its data as a persistent and time-independent +"value".

+
    +
  • 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.
  • +
  • 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.
  • +
  • If a ValuePort contains a reference then the blob it refers to is +constant; plugin MUST NOT modify the blob in any way.
  • +
+

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.

+""" . + +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 """ +

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.

+ +

This port type is intended as a simpler and atom compatible successor to ev:EventPort.

+""" . + +atom:supports + a rdf:Property ; + rdfs:domain lv2:Port ; + rdfs:range atom:Atom ; + rdfs:label "supports" ; + lv2:documentation """ +

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.

+""" . 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 + + 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: . +@prefix rdfs: . + + + a lv2:Specification ; + lv2:minorVersion 0 ; + lv2:microVersion 2 ; + rdfs:seeAlso . + 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 -- cgit v1.2.1