Mercurial > hg > sv-dependency-builds
changeset 110:4c576e416934
Add Vamp SDK, move serd/sord to more obvious locations
line wrap: on
line diff
--- a/osx/include/serd-0/serd/serd.h Thu May 16 16:47:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,963 +0,0 @@ -/* - Copyright 2011-2012 David Robillard <http://drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/** - @file serd.h API for Serd, a lightweight RDF syntax library. -*/ - -#ifndef SERD_SERD_H -#define SERD_SERD_H - -#include <stdarg.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> - -#ifdef SERD_SHARED -# ifdef _WIN32 -# define SERD_LIB_IMPORT __declspec(dllimport) -# define SERD_LIB_EXPORT __declspec(dllexport) -# else -# define SERD_LIB_IMPORT __attribute__((visibility("default"))) -# define SERD_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef SERD_INTERNAL -# define SERD_API SERD_LIB_EXPORT -# else -# define SERD_API SERD_LIB_IMPORT -# endif -#else -# define SERD_API -#endif - -#ifdef __cplusplus -extern "C" { -#else -# include <stdbool.h> -#endif - -/** - @defgroup serd Serd - A lightweight RDF syntax library. - @{ -*/ - -/** - Environment. - - Represents the state required to resolve a CURIE or relative URI, e.g. the - base URI and set of namespace prefixes at a particular point. -*/ -typedef struct SerdEnvImpl SerdEnv; - -/** - RDF reader. - - Parses RDF by calling user-provided sink functions as input is consumed - (much like an XML SAX parser). -*/ -typedef struct SerdReaderImpl SerdReader; - -/** - RDF writer. - - Provides a number of functions to allow writing RDF syntax out to some - stream. These functions are deliberately compatible with the sink functions - used by SerdReader, so a reader can be directly connected to a writer to - re-serialise a document with minimal overhead. -*/ -typedef struct SerdWriterImpl SerdWriter; - -/** - Return status code. -*/ -typedef enum { - SERD_SUCCESS, /**< No error */ - SERD_FAILURE, /**< Non-fatal failure */ - SERD_ERR_UNKNOWN, /**< Unknown error */ - SERD_ERR_BAD_SYNTAX, /**< Invalid syntax */ - SERD_ERR_BAD_ARG, /**< Invalid argument */ - SERD_ERR_NOT_FOUND, /**< Not found */ - SERD_ERR_ID_CLASH, /**< Encountered clashing blank node IDs */ - SERD_ERR_BAD_CURIE, /**< Invalid CURIE (e.g. prefix does not exist) */ - SERD_ERR_INTERNAL /**< Unexpected internal error (should not happen) */ -} SerdStatus; - -/** - RDF syntax type. -*/ -typedef enum { - /** - Turtle - Terse RDF Triple Language (UTF-8). - @see <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a> - */ - SERD_TURTLE = 1, - - /** - NTriples - Line-based RDF triples (ASCII). - @see <a href="http://www.w3.org/TR/rdf-testcases#ntriples">NTriples</a> - */ - SERD_NTRIPLES = 2 -} SerdSyntax; - -/** - Flags indication inline abbreviation information for a statement. -*/ -typedef enum { - SERD_EMPTY_S = 1 << 1, /**< Empty blank node subject */ - SERD_EMPTY_O = 1 << 2, /**< Empty blank node object */ - SERD_ANON_S_BEGIN = 1 << 3, /**< Start of anonymous subject */ - SERD_ANON_O_BEGIN = 1 << 4, /**< Start of anonymous object */ - SERD_ANON_CONT = 1 << 5, /**< Continuation of anonymous node */ - SERD_LIST_S_BEGIN = 1 << 6, /**< Start of list subject */ - SERD_LIST_O_BEGIN = 1 << 7, /**< Start of list object */ - SERD_LIST_CONT = 1 << 8 /**< Continuation of list */ -} SerdStatementFlag; - -/** - Bitwise OR of SerdNodeFlag values. -*/ -typedef uint32_t SerdStatementFlags; - -/** - Type of a syntactic RDF node. - - This is more precise than the type of an abstract RDF node. An abstract - node is either a resource, literal, or blank. In syntax there are two ways - to refer to a resource (by URI or CURIE) and two ways to refer to a blank - (by ID or anonymously). Anonymous (inline) blank nodes are expressed using - SerdStatementFlags rather than this type. -*/ -typedef enum { - /** - The type of a nonexistent node. - - This type is useful as a sentinel, but is never emitted by the reader. - */ - SERD_NOTHING = 0, - - /** - Literal value. - - A literal optionally has either a language, or a datatype (not both). - */ - SERD_LITERAL = 1, - - /** - URI (absolute or relative). - - Value is an unquoted URI string, which is either a relative reference - with respect to the current base URI (e.g. "foo/bar"), or an absolute - URI (e.g. "http://example.org/foo"). - @see <a href="http://tools.ietf.org/html/rfc3986">RFC3986</a>. - */ - SERD_URI = 2, - - /** - CURIE, a shortened URI. - - Value is an unquoted CURIE string relative to the current environment, - e.g. "rdf:type". - @see <a href="http://www.w3.org/TR/curie">CURIE Syntax 1.0</a> - */ - SERD_CURIE = 3, - - /** - A blank node. - - Value is a blank node ID, e.g. "id3", which is meaningful only within - this serialisation. - @see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle - <tt>nodeID</tt></a> - */ - SERD_BLANK = 4, - -} SerdType; - -/** - Flags indicating certain string properties relevant to serialisation. -*/ -typedef enum { - SERD_HAS_NEWLINE = 1, /**< Contains line breaks ('\\n' or '\\r') */ - SERD_HAS_QUOTE = 1 << 1 /**< Contains quotes ('"') */ -} SerdNodeFlag; - -/** - Bitwise OR of SerdNodeFlag values. -*/ -typedef uint32_t SerdNodeFlags; - -/** - A syntactic RDF node. -*/ -typedef struct { - const uint8_t* buf; /**< Value string */ - size_t n_bytes; /**< Size in bytes (not including null) */ - size_t n_chars; /**< Length in characters (not including null)*/ - SerdNodeFlags flags; /**< Node flags (e.g. string properties) */ - SerdType type; /**< Node type */ -} SerdNode; - -/** - An unterminated string fragment. -*/ -typedef struct { - const uint8_t* buf; /**< Start of chunk */ - size_t len; /**< Length of chunk in bytes */ -} SerdChunk; - -/** - An error description. -*/ -typedef struct { - SerdStatus status; /**< Error code */ - const uint8_t* filename; /**< File where error was encountered, or NULL */ - unsigned line; /**< Line where error was encountered, or 0 */ - unsigned col; /**< Column where error was encountered */ - const char* fmt; /**< Message format string (printf style) */ - va_list* args; /**< Arguments for fmt */ -} SerdError; - -/** - A parsed URI. - - This struct directly refers to chunks in other strings, it does not own any - memory itself. Thus, URIs can be parsed and/or resolved against a base URI - in-place without allocating memory. -*/ -typedef struct { - SerdChunk scheme; /**< Scheme */ - SerdChunk authority; /**< Authority */ - SerdChunk path_base; /**< Path prefix if relative */ - SerdChunk path; /**< Path suffix */ - SerdChunk query; /**< Query */ - SerdChunk fragment; /**< Fragment */ -} SerdURI; - -/** - Syntax style options. - - The style of the writer output can be controlled by ORing together - values from this enumeration. Note that some options are only supported - for some syntaxes (e.g. NTriples does not support abbreviation and is - always ASCII). -*/ -typedef enum { - SERD_STYLE_ABBREVIATED = 1, /**< Abbreviate triples when possible. */ - SERD_STYLE_ASCII = 1 << 1, /**< Escape all non-ASCII characters. */ - SERD_STYLE_RESOLVED = 1 << 2, /**< Resolve URIs against base URI. */ - SERD_STYLE_CURIED = 1 << 3, /**< Shorten URIs into CURIEs. */ - SERD_STYLE_BULK = 1 << 4 /**< Write output in pages. */ -} SerdStyle; - -/** - @name String Utilities - @{ -*/ - -/** - Return a string describing a status code. -*/ -SERD_API -const uint8_t* -serd_strerror(SerdStatus status); - -/** - Measure a UTF-8 string. - @return Length of @c str in characters (except NULL). - @param str A null-terminated UTF-8 string. - @param n_bytes (Output) Set to the size of @c str in bytes (except NULL). - @param flags (Output) Set to the applicable flags. -*/ -SERD_API -size_t -serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags); - -/** - Parse a string to a double. - - The API of this function is identical to the standard C strtod function, - except this function is locale-independent and always matches the lexical - format used in the Turtle grammar (the decimal point is always "."). -*/ -SERD_API -double -serd_strtod(const char* str, char** endptr); - -/** - Decode a base64 string. - This function can be used to deserialise a blob node created with - serd_node_new_blob(). - - @param str Base64 string to decode. - @param len The length of @c str. - @param size Set to the size of the returned blob in bytes. - @return A newly allocated blob which must be freed with free(). -*/ -SERD_API -void* -serd_base64_decode(const uint8_t* str, size_t len, size_t* size); - -/** - @} - @name URI - @{ -*/ - -static const SerdURI SERD_URI_NULL = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; - -/** - Return the local path for @c uri, or NULL if @c uri is not a file URI. - Note this (inappropriately named) function only removes the file scheme if - necessary, and returns @c uri unmodified if it is an absolute path. Percent - encoding and other issues are not handled, to properly convert a file URI to - a path, use serd_file_uri_parse(). -*/ -SERD_API -const uint8_t* -serd_uri_to_path(const uint8_t* uri); - -/** - Get the unescaped path and hostname from a file URI. - @param uri A file URI. - @param hostname If non-NULL, set to the hostname, if present. - @return The path component of the URI. - - Both the returned path and @c hostname (if applicable) are owned by the - caller and must be freed with free(). -*/ -SERD_API -uint8_t* -serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname); - -/** - Return true iff @c utf8 starts with a valid URI scheme. -*/ -SERD_API -bool -serd_uri_string_has_scheme(const uint8_t* utf8); - -/** - Parse @c utf8, writing result to @c out. -*/ -SERD_API -SerdStatus -serd_uri_parse(const uint8_t* utf8, SerdURI* out); - -/** - Set @c out to @c uri resolved against @c base. -*/ -SERD_API -void -serd_uri_resolve(const SerdURI* uri, const SerdURI* base, SerdURI* out); - -/** - Sink function for raw string output. -*/ -typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream); - -/** - Serialise @c uri with a series of calls to @c sink. -*/ -SERD_API -size_t -serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream); - -/** - Serialise @c uri relative to @c base with a series of calls to @c sink. - - The @c uri is written as a relative URI iff if it a child of @c base and @c - root. The optional @c root parameter must be a prefix of @c base and can be - used keep up-references ("../") within a certain namespace. -*/ -SERD_API -size_t -serd_uri_serialise_relative(const SerdURI* uri, - const SerdURI* base, - const SerdURI* root, - SerdSink sink, - void* stream); - -/** - @} - @name Node - @{ -*/ - -static const SerdNode SERD_NODE_NULL = { 0, 0, 0, 0, SERD_NOTHING }; - -/** - Make a (shallow) node from @c str. - - This measures, but does not copy, @c str. No memory is allocated. -*/ -SERD_API -SerdNode -serd_node_from_string(SerdType type, const uint8_t* str); - -/** - Make a deep copy of @c node. - - @return a node that the caller must free with @ref serd_node_free. -*/ -SERD_API -SerdNode -serd_node_copy(const SerdNode* node); - -/** - Return true iff @c a is equal to @c b. -*/ -SERD_API -bool -serd_node_equals(const SerdNode* a, const SerdNode* b); - -/** - Simple wrapper for serd_node_new_uri to resolve a URI node. -*/ -SERD_API -SerdNode -serd_node_new_uri_from_node(const SerdNode* uri_node, - const SerdURI* base, - SerdURI* out); - -/** - Simple wrapper for serd_node_new_uri to resolve a URI string. -*/ -SERD_API -SerdNode -serd_node_new_uri_from_string(const uint8_t* str, - const SerdURI* base, - SerdURI* out); - -/** - Create a new file URI node from a file system path and optional hostname. - - Backslashes in Windows paths will be converted and '%' will always be - percent encoded. If @c escape is true, all other invalid characters will be - percent encoded as well. - - If @c path is relative, @c hostname is ignored. - If @c out is not NULL, it will be set to the parsed URI. -*/ -SERD_API -SerdNode -serd_node_new_file_uri(const uint8_t* path, - const uint8_t* hostname, - SerdURI* out, - bool escape); - -/** - Create a new node by serialising @c uri into a new string. - - @param uri The URI to parse and serialise. - - @param base Base URI to resolve @c uri against (or NULL for no resolution). - - @param out Set to the parsing of the new URI (i.e. points only to - memory owned by the new returned node). -*/ -SERD_API -SerdNode -serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out); - -/** - Create a new node by serialising @c d into an xsd:decimal string. - - The resulting node will always contain a `.', start with a digit, and end - with a digit (i.e. will have a leading and/or trailing `0' if necessary). - It will never be in scientific notation. A maximum of @c frac_digits digits - will be written after the decimal point, but trailing zeros will - automatically be omitted (except one if @c d is a round integer). - - Note that about 16 and 8 fractional digits are required to precisely - represent a double and float, respectively. - - @param d The value for the new node. - @param frac_digits The maximum number of digits after the decimal place. -*/ -SERD_API -SerdNode -serd_node_new_decimal(double d, unsigned frac_digits); - -/** - Create a new node by serialising @c i into an xsd:integer string. -*/ -SERD_API -SerdNode -serd_node_new_integer(int64_t i); - -/** - Create a node by serialising @c buf into an xsd:base64Binary string. - This function can be used to make a serialisable node out of arbitrary - binary data, which can be decoded using serd_base64_decode(). - - @param buf Raw binary input data. - @param size Size of @c buf. - @param wrap_lines Wrap lines at 76 characters to conform to RFC 2045. -*/ -SERD_API -SerdNode -serd_node_new_blob(const void* buf, size_t size, bool wrap_lines); - -/** - Free any data owned by @c node. - - Note that if @c node is itself dynamically allocated (which is not the case - for nodes created internally by serd), it will not be freed. -*/ -SERD_API -void -serd_node_free(SerdNode* node); - -/** - @} - @name Event Handlers - @{ -*/ - -/** - Sink (callback) for errors. - - @param handle Handle for user data. - @param error Error description. -*/ -typedef SerdStatus (*SerdErrorSink)(void* handle, - const SerdError* error); - -/** - Sink (callback) for base URI changes. - - Called whenever the base URI of the serialisation changes. -*/ -typedef SerdStatus (*SerdBaseSink)(void* handle, - const SerdNode* uri); - -/** - Sink (callback) for namespace definitions. - - Called whenever a prefix is defined in the serialisation. -*/ -typedef SerdStatus (*SerdPrefixSink)(void* handle, - const SerdNode* name, - const SerdNode* uri); - -/** - Sink (callback) for statements. - - Called for every RDF statement in the serialisation. -*/ -typedef SerdStatus (*SerdStatementSink)(void* handle, - SerdStatementFlags flags, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang); - -/** - Sink (callback) for anonymous node end markers. - - This is called to indicate that the anonymous node with the given - @c value will no longer be referred to by any future statements - (i.e. the anonymous serialisation of the node is finished). -*/ -typedef SerdStatus (*SerdEndSink)(void* handle, - const SerdNode* node); - -/** - @} - @name Environment - @{ -*/ - -/** - Create a new environment. -*/ -SERD_API -SerdEnv* -serd_env_new(const SerdNode* base_uri); - -/** - Free @c ns. -*/ -SERD_API -void -serd_env_free(SerdEnv* env); - -/** - Get the current base URI. -*/ -SERD_API -const SerdNode* -serd_env_get_base_uri(const SerdEnv* env, - SerdURI* out); - -/** - Set the current base URI. -*/ -SERD_API -SerdStatus -serd_env_set_base_uri(SerdEnv* env, - const SerdNode* uri); - -/** - Set a namespace prefix. -*/ -SERD_API -SerdStatus -serd_env_set_prefix(SerdEnv* env, - const SerdNode* name, - const SerdNode* uri); - -/** - Set a namespace prefix. -*/ -SERD_API -SerdStatus -serd_env_set_prefix_from_strings(SerdEnv* env, - const uint8_t* name, - const uint8_t* uri); - -/** - Qualify @c uri into a CURIE if possible. -*/ -SERD_API -bool -serd_env_qualify(const SerdEnv* env, - const SerdNode* uri, - SerdNode* prefix, - SerdChunk* suffix); - -/** - Expand @c curie. -*/ -SERD_API -SerdStatus -serd_env_expand(const SerdEnv* env, - const SerdNode* curie, - SerdChunk* uri_prefix, - SerdChunk* uri_suffix); - -/** - Expand @c node, which must be a CURIE or URI, to a full URI. -*/ -SERD_API -SerdNode -serd_env_expand_node(const SerdEnv* env, - const SerdNode* node); - -/** - Call @c func for each prefix defined in @c env. -*/ -SERD_API -void -serd_env_foreach(const SerdEnv* env, - SerdPrefixSink func, - void* handle); - -/** - @} - @name Reader - @{ -*/ - -/** - Create a new RDF reader. -*/ -SERD_API -SerdReader* -serd_reader_new(SerdSyntax syntax, - void* handle, - void (*free_handle)(void*), - SerdBaseSink base_sink, - SerdPrefixSink prefix_sink, - SerdStatementSink statement_sink, - SerdEndSink end_sink); - -/** - Set a function to be called when errors occur during reading. - - The @p error_sink will be called with @p handle as its first argument. If - no error function is set, errors are printed to stderr in GCC style. -*/ -SERD_API -void -serd_reader_set_error_sink(SerdReader* reader, - SerdErrorSink error_sink, - void* handle); - -/** - Return the @c handle passed to @ref serd_reader_new. -*/ -SERD_API -void* -serd_reader_get_handle(const SerdReader* reader); - -/** - Set a prefix to be added to all blank node identifiers. - - This is useful when multiple files are to be parsed into the same output - (e.g. a store, or other files). Since Serd preserves blank node IDs, this - could cause conflicts where two non-equivalent blank nodes are merged, - resulting in corrupt data. By setting a unique blank node prefix for each - parsed file, this can be avoided, while preserving blank node names. -*/ -SERD_API -void -serd_reader_add_blank_prefix(SerdReader* reader, - const uint8_t* prefix); - -/** - Set the URI of the default graph. - - If this is set, the reader will emit quads with the graph set to the given - node for any statements that are not in a named graph (which is currently - all of them since Serd currently does not support any graph syntaxes). -*/ -SERD_API -void -serd_reader_set_default_graph(SerdReader* reader, - const SerdNode* graph); - -/** - Read a file at a given @c uri. -*/ -SERD_API -SerdStatus -serd_reader_read_file(SerdReader* reader, - const uint8_t* uri); - -/** - Start an incremental read from a file handle. - - Iff @p bulk is true, @p file will be read a page at a time. This is more - efficient, but uses a page of memory and means that an entire page of input - must be ready before any callbacks will fire. To react as soon as input - arrives, set @p bulk to false. -*/ -SERD_API -SerdStatus -serd_reader_start_stream(SerdReader* me, - FILE* file, - const uint8_t* name, - bool bulk); - -/** - Read a single "chunk" of data during an incremental read. - - This function will read a single top level description, and return. This - may be a directive, statement, or several statements; essentially it reads - until a '.' is encountered. This is particularly useful for reading - directly from a pipe or socket. -*/ -SERD_API -SerdStatus -serd_reader_read_chunk(SerdReader* me); - -/** - Finish an incremental read from a file handle. -*/ -SERD_API -SerdStatus -serd_reader_end_stream(SerdReader* me); - -/** - Read @c file. -*/ -SERD_API -SerdStatus -serd_reader_read_file_handle(SerdReader* reader, - FILE* file, - const uint8_t* name); - -/** - Read @c utf8. -*/ -SERD_API -SerdStatus -serd_reader_read_string(SerdReader* me, const uint8_t* utf8); - -/** - Free @c reader. -*/ -SERD_API -void -serd_reader_free(SerdReader* reader); - -/** - @} - @name Writer - @{ -*/ - -/** - Create a new RDF writer. -*/ -SERD_API -SerdWriter* -serd_writer_new(SerdSyntax syntax, - SerdStyle style, - SerdEnv* env, - const SerdURI* base_uri, - SerdSink sink, - void* stream); - -/** - Free @c writer. -*/ -SERD_API -void -serd_writer_free(SerdWriter* writer); - -/** - Return the env used by @c writer. -*/ -SERD_API -SerdEnv* -serd_writer_get_env(SerdWriter* writer); - -/** - A convenience sink function for writing to a FILE*. - - This function can be used as a SerdSink when writing to a FILE*. The - @c stream parameter must be a FILE* opened for writing. -*/ -SERD_API -size_t -serd_file_sink(const void* buf, size_t len, void* stream); - -/** - A convenience sink function for writing to a string. - - This function can be used as a SerdSink to write to a SerdChunk which is - resized as necessary with realloc(). The @c stream parameter must point to - an initialized SerdChunk. When the write is finished, the string should be - retrieved with serd_chunk_sink_finish(). -*/ -SERD_API -size_t -serd_chunk_sink(const void* buf, size_t len, void* stream); - -/** - Finish a serialisation to a chunk with serd_chunk_sink(). - - The returned string is the result of the serialisation, which is NULL - terminated (by this function) and owned by the caller. -*/ -SERD_API -uint8_t* -serd_chunk_sink_finish(SerdChunk* stream); - -/** - Set a function to be called when errors occur during writing. - - The @p error_sink will be called with @p handle as its first argument. If - no error function is set, errors are printed to stderr. -*/ -SERD_API -void -serd_writer_set_error_sink(SerdWriter* writer, - SerdErrorSink error_sink, - void* handle); - -/** - Set a prefix to be removed from matching blank node identifiers. -*/ -SERD_API -void -serd_writer_chop_blank_prefix(SerdWriter* writer, - const uint8_t* prefix); - -/** - Set the current output base URI (and emit directive if applicable). - - Note this function can be safely casted to SerdBaseSink. -*/ -SERD_API -SerdStatus -serd_writer_set_base_uri(SerdWriter* writer, - const SerdNode* uri); - -/** - Set the current root URI. - - The root URI should be a prefix of the base URI. The path of the root URI - is the highest path any relative up-reference can refer to. For example, - with root <file:///foo/root> and base <file:///foo/root/base>, - <file:///foo/root> will be written as <../>, but <file:///foo> will be - written non-relatively as <file:///foo>. If the root is not explicitly set, - it defaults to the base URI, so no up-references will be created at all. -*/ -SERD_API -SerdStatus -serd_writer_set_root_uri(SerdWriter* writer, - const SerdNode* uri); - -/** - Set a namespace prefix (and emit directive if applicable). - - Note this function can be safely casted to SerdPrefixSink. -*/ -SERD_API -SerdStatus -serd_writer_set_prefix(SerdWriter* writer, - const SerdNode* name, - const SerdNode* uri); - -/** - Write a statement. - - Note this function can be safely casted to SerdStatementSink. -*/ -SERD_API -SerdStatus -serd_writer_write_statement(SerdWriter* writer, - SerdStatementFlags flags, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang); - -/** - Mark the end of an anonymous node's description. - - Note this function can be safely casted to SerdEndSink. -*/ -SERD_API -SerdStatus -serd_writer_end_anon(SerdWriter* writer, - const SerdNode* node); - -/** - Finish a write. -*/ -SERD_API -SerdStatus -serd_writer_finish(SerdWriter* writer); - -/** - @} - @} -*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* SERD_SERD_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/serd/serd.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,963 @@ +/* + Copyright 2011-2012 David Robillard <http://drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** + @file serd.h API for Serd, a lightweight RDF syntax library. +*/ + +#ifndef SERD_SERD_H +#define SERD_SERD_H + +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +#ifdef SERD_SHARED +# ifdef _WIN32 +# define SERD_LIB_IMPORT __declspec(dllimport) +# define SERD_LIB_EXPORT __declspec(dllexport) +# else +# define SERD_LIB_IMPORT __attribute__((visibility("default"))) +# define SERD_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef SERD_INTERNAL +# define SERD_API SERD_LIB_EXPORT +# else +# define SERD_API SERD_LIB_IMPORT +# endif +#else +# define SERD_API +#endif + +#ifdef __cplusplus +extern "C" { +#else +# include <stdbool.h> +#endif + +/** + @defgroup serd Serd + A lightweight RDF syntax library. + @{ +*/ + +/** + Environment. + + Represents the state required to resolve a CURIE or relative URI, e.g. the + base URI and set of namespace prefixes at a particular point. +*/ +typedef struct SerdEnvImpl SerdEnv; + +/** + RDF reader. + + Parses RDF by calling user-provided sink functions as input is consumed + (much like an XML SAX parser). +*/ +typedef struct SerdReaderImpl SerdReader; + +/** + RDF writer. + + Provides a number of functions to allow writing RDF syntax out to some + stream. These functions are deliberately compatible with the sink functions + used by SerdReader, so a reader can be directly connected to a writer to + re-serialise a document with minimal overhead. +*/ +typedef struct SerdWriterImpl SerdWriter; + +/** + Return status code. +*/ +typedef enum { + SERD_SUCCESS, /**< No error */ + SERD_FAILURE, /**< Non-fatal failure */ + SERD_ERR_UNKNOWN, /**< Unknown error */ + SERD_ERR_BAD_SYNTAX, /**< Invalid syntax */ + SERD_ERR_BAD_ARG, /**< Invalid argument */ + SERD_ERR_NOT_FOUND, /**< Not found */ + SERD_ERR_ID_CLASH, /**< Encountered clashing blank node IDs */ + SERD_ERR_BAD_CURIE, /**< Invalid CURIE (e.g. prefix does not exist) */ + SERD_ERR_INTERNAL /**< Unexpected internal error (should not happen) */ +} SerdStatus; + +/** + RDF syntax type. +*/ +typedef enum { + /** + Turtle - Terse RDF Triple Language (UTF-8). + @see <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a> + */ + SERD_TURTLE = 1, + + /** + NTriples - Line-based RDF triples (ASCII). + @see <a href="http://www.w3.org/TR/rdf-testcases#ntriples">NTriples</a> + */ + SERD_NTRIPLES = 2 +} SerdSyntax; + +/** + Flags indication inline abbreviation information for a statement. +*/ +typedef enum { + SERD_EMPTY_S = 1 << 1, /**< Empty blank node subject */ + SERD_EMPTY_O = 1 << 2, /**< Empty blank node object */ + SERD_ANON_S_BEGIN = 1 << 3, /**< Start of anonymous subject */ + SERD_ANON_O_BEGIN = 1 << 4, /**< Start of anonymous object */ + SERD_ANON_CONT = 1 << 5, /**< Continuation of anonymous node */ + SERD_LIST_S_BEGIN = 1 << 6, /**< Start of list subject */ + SERD_LIST_O_BEGIN = 1 << 7, /**< Start of list object */ + SERD_LIST_CONT = 1 << 8 /**< Continuation of list */ +} SerdStatementFlag; + +/** + Bitwise OR of SerdNodeFlag values. +*/ +typedef uint32_t SerdStatementFlags; + +/** + Type of a syntactic RDF node. + + This is more precise than the type of an abstract RDF node. An abstract + node is either a resource, literal, or blank. In syntax there are two ways + to refer to a resource (by URI or CURIE) and two ways to refer to a blank + (by ID or anonymously). Anonymous (inline) blank nodes are expressed using + SerdStatementFlags rather than this type. +*/ +typedef enum { + /** + The type of a nonexistent node. + + This type is useful as a sentinel, but is never emitted by the reader. + */ + SERD_NOTHING = 0, + + /** + Literal value. + + A literal optionally has either a language, or a datatype (not both). + */ + SERD_LITERAL = 1, + + /** + URI (absolute or relative). + + Value is an unquoted URI string, which is either a relative reference + with respect to the current base URI (e.g. "foo/bar"), or an absolute + URI (e.g. "http://example.org/foo"). + @see <a href="http://tools.ietf.org/html/rfc3986">RFC3986</a>. + */ + SERD_URI = 2, + + /** + CURIE, a shortened URI. + + Value is an unquoted CURIE string relative to the current environment, + e.g. "rdf:type". + @see <a href="http://www.w3.org/TR/curie">CURIE Syntax 1.0</a> + */ + SERD_CURIE = 3, + + /** + A blank node. + + Value is a blank node ID, e.g. "id3", which is meaningful only within + this serialisation. + @see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle + <tt>nodeID</tt></a> + */ + SERD_BLANK = 4, + +} SerdType; + +/** + Flags indicating certain string properties relevant to serialisation. +*/ +typedef enum { + SERD_HAS_NEWLINE = 1, /**< Contains line breaks ('\\n' or '\\r') */ + SERD_HAS_QUOTE = 1 << 1 /**< Contains quotes ('"') */ +} SerdNodeFlag; + +/** + Bitwise OR of SerdNodeFlag values. +*/ +typedef uint32_t SerdNodeFlags; + +/** + A syntactic RDF node. +*/ +typedef struct { + const uint8_t* buf; /**< Value string */ + size_t n_bytes; /**< Size in bytes (not including null) */ + size_t n_chars; /**< Length in characters (not including null)*/ + SerdNodeFlags flags; /**< Node flags (e.g. string properties) */ + SerdType type; /**< Node type */ +} SerdNode; + +/** + An unterminated string fragment. +*/ +typedef struct { + const uint8_t* buf; /**< Start of chunk */ + size_t len; /**< Length of chunk in bytes */ +} SerdChunk; + +/** + An error description. +*/ +typedef struct { + SerdStatus status; /**< Error code */ + const uint8_t* filename; /**< File where error was encountered, or NULL */ + unsigned line; /**< Line where error was encountered, or 0 */ + unsigned col; /**< Column where error was encountered */ + const char* fmt; /**< Message format string (printf style) */ + va_list* args; /**< Arguments for fmt */ +} SerdError; + +/** + A parsed URI. + + This struct directly refers to chunks in other strings, it does not own any + memory itself. Thus, URIs can be parsed and/or resolved against a base URI + in-place without allocating memory. +*/ +typedef struct { + SerdChunk scheme; /**< Scheme */ + SerdChunk authority; /**< Authority */ + SerdChunk path_base; /**< Path prefix if relative */ + SerdChunk path; /**< Path suffix */ + SerdChunk query; /**< Query */ + SerdChunk fragment; /**< Fragment */ +} SerdURI; + +/** + Syntax style options. + + The style of the writer output can be controlled by ORing together + values from this enumeration. Note that some options are only supported + for some syntaxes (e.g. NTriples does not support abbreviation and is + always ASCII). +*/ +typedef enum { + SERD_STYLE_ABBREVIATED = 1, /**< Abbreviate triples when possible. */ + SERD_STYLE_ASCII = 1 << 1, /**< Escape all non-ASCII characters. */ + SERD_STYLE_RESOLVED = 1 << 2, /**< Resolve URIs against base URI. */ + SERD_STYLE_CURIED = 1 << 3, /**< Shorten URIs into CURIEs. */ + SERD_STYLE_BULK = 1 << 4 /**< Write output in pages. */ +} SerdStyle; + +/** + @name String Utilities + @{ +*/ + +/** + Return a string describing a status code. +*/ +SERD_API +const uint8_t* +serd_strerror(SerdStatus status); + +/** + Measure a UTF-8 string. + @return Length of @c str in characters (except NULL). + @param str A null-terminated UTF-8 string. + @param n_bytes (Output) Set to the size of @c str in bytes (except NULL). + @param flags (Output) Set to the applicable flags. +*/ +SERD_API +size_t +serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags); + +/** + Parse a string to a double. + + The API of this function is identical to the standard C strtod function, + except this function is locale-independent and always matches the lexical + format used in the Turtle grammar (the decimal point is always "."). +*/ +SERD_API +double +serd_strtod(const char* str, char** endptr); + +/** + Decode a base64 string. + This function can be used to deserialise a blob node created with + serd_node_new_blob(). + + @param str Base64 string to decode. + @param len The length of @c str. + @param size Set to the size of the returned blob in bytes. + @return A newly allocated blob which must be freed with free(). +*/ +SERD_API +void* +serd_base64_decode(const uint8_t* str, size_t len, size_t* size); + +/** + @} + @name URI + @{ +*/ + +static const SerdURI SERD_URI_NULL = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; + +/** + Return the local path for @c uri, or NULL if @c uri is not a file URI. + Note this (inappropriately named) function only removes the file scheme if + necessary, and returns @c uri unmodified if it is an absolute path. Percent + encoding and other issues are not handled, to properly convert a file URI to + a path, use serd_file_uri_parse(). +*/ +SERD_API +const uint8_t* +serd_uri_to_path(const uint8_t* uri); + +/** + Get the unescaped path and hostname from a file URI. + @param uri A file URI. + @param hostname If non-NULL, set to the hostname, if present. + @return The path component of the URI. + + Both the returned path and @c hostname (if applicable) are owned by the + caller and must be freed with free(). +*/ +SERD_API +uint8_t* +serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname); + +/** + Return true iff @c utf8 starts with a valid URI scheme. +*/ +SERD_API +bool +serd_uri_string_has_scheme(const uint8_t* utf8); + +/** + Parse @c utf8, writing result to @c out. +*/ +SERD_API +SerdStatus +serd_uri_parse(const uint8_t* utf8, SerdURI* out); + +/** + Set @c out to @c uri resolved against @c base. +*/ +SERD_API +void +serd_uri_resolve(const SerdURI* uri, const SerdURI* base, SerdURI* out); + +/** + Sink function for raw string output. +*/ +typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream); + +/** + Serialise @c uri with a series of calls to @c sink. +*/ +SERD_API +size_t +serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream); + +/** + Serialise @c uri relative to @c base with a series of calls to @c sink. + + The @c uri is written as a relative URI iff if it a child of @c base and @c + root. The optional @c root parameter must be a prefix of @c base and can be + used keep up-references ("../") within a certain namespace. +*/ +SERD_API +size_t +serd_uri_serialise_relative(const SerdURI* uri, + const SerdURI* base, + const SerdURI* root, + SerdSink sink, + void* stream); + +/** + @} + @name Node + @{ +*/ + +static const SerdNode SERD_NODE_NULL = { 0, 0, 0, 0, SERD_NOTHING }; + +/** + Make a (shallow) node from @c str. + + This measures, but does not copy, @c str. No memory is allocated. +*/ +SERD_API +SerdNode +serd_node_from_string(SerdType type, const uint8_t* str); + +/** + Make a deep copy of @c node. + + @return a node that the caller must free with @ref serd_node_free. +*/ +SERD_API +SerdNode +serd_node_copy(const SerdNode* node); + +/** + Return true iff @c a is equal to @c b. +*/ +SERD_API +bool +serd_node_equals(const SerdNode* a, const SerdNode* b); + +/** + Simple wrapper for serd_node_new_uri to resolve a URI node. +*/ +SERD_API +SerdNode +serd_node_new_uri_from_node(const SerdNode* uri_node, + const SerdURI* base, + SerdURI* out); + +/** + Simple wrapper for serd_node_new_uri to resolve a URI string. +*/ +SERD_API +SerdNode +serd_node_new_uri_from_string(const uint8_t* str, + const SerdURI* base, + SerdURI* out); + +/** + Create a new file URI node from a file system path and optional hostname. + + Backslashes in Windows paths will be converted and '%' will always be + percent encoded. If @c escape is true, all other invalid characters will be + percent encoded as well. + + If @c path is relative, @c hostname is ignored. + If @c out is not NULL, it will be set to the parsed URI. +*/ +SERD_API +SerdNode +serd_node_new_file_uri(const uint8_t* path, + const uint8_t* hostname, + SerdURI* out, + bool escape); + +/** + Create a new node by serialising @c uri into a new string. + + @param uri The URI to parse and serialise. + + @param base Base URI to resolve @c uri against (or NULL for no resolution). + + @param out Set to the parsing of the new URI (i.e. points only to + memory owned by the new returned node). +*/ +SERD_API +SerdNode +serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out); + +/** + Create a new node by serialising @c d into an xsd:decimal string. + + The resulting node will always contain a `.', start with a digit, and end + with a digit (i.e. will have a leading and/or trailing `0' if necessary). + It will never be in scientific notation. A maximum of @c frac_digits digits + will be written after the decimal point, but trailing zeros will + automatically be omitted (except one if @c d is a round integer). + + Note that about 16 and 8 fractional digits are required to precisely + represent a double and float, respectively. + + @param d The value for the new node. + @param frac_digits The maximum number of digits after the decimal place. +*/ +SERD_API +SerdNode +serd_node_new_decimal(double d, unsigned frac_digits); + +/** + Create a new node by serialising @c i into an xsd:integer string. +*/ +SERD_API +SerdNode +serd_node_new_integer(int64_t i); + +/** + Create a node by serialising @c buf into an xsd:base64Binary string. + This function can be used to make a serialisable node out of arbitrary + binary data, which can be decoded using serd_base64_decode(). + + @param buf Raw binary input data. + @param size Size of @c buf. + @param wrap_lines Wrap lines at 76 characters to conform to RFC 2045. +*/ +SERD_API +SerdNode +serd_node_new_blob(const void* buf, size_t size, bool wrap_lines); + +/** + Free any data owned by @c node. + + Note that if @c node is itself dynamically allocated (which is not the case + for nodes created internally by serd), it will not be freed. +*/ +SERD_API +void +serd_node_free(SerdNode* node); + +/** + @} + @name Event Handlers + @{ +*/ + +/** + Sink (callback) for errors. + + @param handle Handle for user data. + @param error Error description. +*/ +typedef SerdStatus (*SerdErrorSink)(void* handle, + const SerdError* error); + +/** + Sink (callback) for base URI changes. + + Called whenever the base URI of the serialisation changes. +*/ +typedef SerdStatus (*SerdBaseSink)(void* handle, + const SerdNode* uri); + +/** + Sink (callback) for namespace definitions. + + Called whenever a prefix is defined in the serialisation. +*/ +typedef SerdStatus (*SerdPrefixSink)(void* handle, + const SerdNode* name, + const SerdNode* uri); + +/** + Sink (callback) for statements. + + Called for every RDF statement in the serialisation. +*/ +typedef SerdStatus (*SerdStatementSink)(void* handle, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + Sink (callback) for anonymous node end markers. + + This is called to indicate that the anonymous node with the given + @c value will no longer be referred to by any future statements + (i.e. the anonymous serialisation of the node is finished). +*/ +typedef SerdStatus (*SerdEndSink)(void* handle, + const SerdNode* node); + +/** + @} + @name Environment + @{ +*/ + +/** + Create a new environment. +*/ +SERD_API +SerdEnv* +serd_env_new(const SerdNode* base_uri); + +/** + Free @c ns. +*/ +SERD_API +void +serd_env_free(SerdEnv* env); + +/** + Get the current base URI. +*/ +SERD_API +const SerdNode* +serd_env_get_base_uri(const SerdEnv* env, + SerdURI* out); + +/** + Set the current base URI. +*/ +SERD_API +SerdStatus +serd_env_set_base_uri(SerdEnv* env, + const SerdNode* uri); + +/** + Set a namespace prefix. +*/ +SERD_API +SerdStatus +serd_env_set_prefix(SerdEnv* env, + const SerdNode* name, + const SerdNode* uri); + +/** + Set a namespace prefix. +*/ +SERD_API +SerdStatus +serd_env_set_prefix_from_strings(SerdEnv* env, + const uint8_t* name, + const uint8_t* uri); + +/** + Qualify @c uri into a CURIE if possible. +*/ +SERD_API +bool +serd_env_qualify(const SerdEnv* env, + const SerdNode* uri, + SerdNode* prefix, + SerdChunk* suffix); + +/** + Expand @c curie. +*/ +SERD_API +SerdStatus +serd_env_expand(const SerdEnv* env, + const SerdNode* curie, + SerdChunk* uri_prefix, + SerdChunk* uri_suffix); + +/** + Expand @c node, which must be a CURIE or URI, to a full URI. +*/ +SERD_API +SerdNode +serd_env_expand_node(const SerdEnv* env, + const SerdNode* node); + +/** + Call @c func for each prefix defined in @c env. +*/ +SERD_API +void +serd_env_foreach(const SerdEnv* env, + SerdPrefixSink func, + void* handle); + +/** + @} + @name Reader + @{ +*/ + +/** + Create a new RDF reader. +*/ +SERD_API +SerdReader* +serd_reader_new(SerdSyntax syntax, + void* handle, + void (*free_handle)(void*), + SerdBaseSink base_sink, + SerdPrefixSink prefix_sink, + SerdStatementSink statement_sink, + SerdEndSink end_sink); + +/** + Set a function to be called when errors occur during reading. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr in GCC style. +*/ +SERD_API +void +serd_reader_set_error_sink(SerdReader* reader, + SerdErrorSink error_sink, + void* handle); + +/** + Return the @c handle passed to @ref serd_reader_new. +*/ +SERD_API +void* +serd_reader_get_handle(const SerdReader* reader); + +/** + Set a prefix to be added to all blank node identifiers. + + This is useful when multiple files are to be parsed into the same output + (e.g. a store, or other files). Since Serd preserves blank node IDs, this + could cause conflicts where two non-equivalent blank nodes are merged, + resulting in corrupt data. By setting a unique blank node prefix for each + parsed file, this can be avoided, while preserving blank node names. +*/ +SERD_API +void +serd_reader_add_blank_prefix(SerdReader* reader, + const uint8_t* prefix); + +/** + Set the URI of the default graph. + + If this is set, the reader will emit quads with the graph set to the given + node for any statements that are not in a named graph (which is currently + all of them since Serd currently does not support any graph syntaxes). +*/ +SERD_API +void +serd_reader_set_default_graph(SerdReader* reader, + const SerdNode* graph); + +/** + Read a file at a given @c uri. +*/ +SERD_API +SerdStatus +serd_reader_read_file(SerdReader* reader, + const uint8_t* uri); + +/** + Start an incremental read from a file handle. + + Iff @p bulk is true, @p file will be read a page at a time. This is more + efficient, but uses a page of memory and means that an entire page of input + must be ready before any callbacks will fire. To react as soon as input + arrives, set @p bulk to false. +*/ +SERD_API +SerdStatus +serd_reader_start_stream(SerdReader* me, + FILE* file, + const uint8_t* name, + bool bulk); + +/** + Read a single "chunk" of data during an incremental read. + + This function will read a single top level description, and return. This + may be a directive, statement, or several statements; essentially it reads + until a '.' is encountered. This is particularly useful for reading + directly from a pipe or socket. +*/ +SERD_API +SerdStatus +serd_reader_read_chunk(SerdReader* me); + +/** + Finish an incremental read from a file handle. +*/ +SERD_API +SerdStatus +serd_reader_end_stream(SerdReader* me); + +/** + Read @c file. +*/ +SERD_API +SerdStatus +serd_reader_read_file_handle(SerdReader* reader, + FILE* file, + const uint8_t* name); + +/** + Read @c utf8. +*/ +SERD_API +SerdStatus +serd_reader_read_string(SerdReader* me, const uint8_t* utf8); + +/** + Free @c reader. +*/ +SERD_API +void +serd_reader_free(SerdReader* reader); + +/** + @} + @name Writer + @{ +*/ + +/** + Create a new RDF writer. +*/ +SERD_API +SerdWriter* +serd_writer_new(SerdSyntax syntax, + SerdStyle style, + SerdEnv* env, + const SerdURI* base_uri, + SerdSink sink, + void* stream); + +/** + Free @c writer. +*/ +SERD_API +void +serd_writer_free(SerdWriter* writer); + +/** + Return the env used by @c writer. +*/ +SERD_API +SerdEnv* +serd_writer_get_env(SerdWriter* writer); + +/** + A convenience sink function for writing to a FILE*. + + This function can be used as a SerdSink when writing to a FILE*. The + @c stream parameter must be a FILE* opened for writing. +*/ +SERD_API +size_t +serd_file_sink(const void* buf, size_t len, void* stream); + +/** + A convenience sink function for writing to a string. + + This function can be used as a SerdSink to write to a SerdChunk which is + resized as necessary with realloc(). The @c stream parameter must point to + an initialized SerdChunk. When the write is finished, the string should be + retrieved with serd_chunk_sink_finish(). +*/ +SERD_API +size_t +serd_chunk_sink(const void* buf, size_t len, void* stream); + +/** + Finish a serialisation to a chunk with serd_chunk_sink(). + + The returned string is the result of the serialisation, which is NULL + terminated (by this function) and owned by the caller. +*/ +SERD_API +uint8_t* +serd_chunk_sink_finish(SerdChunk* stream); + +/** + Set a function to be called when errors occur during writing. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr. +*/ +SERD_API +void +serd_writer_set_error_sink(SerdWriter* writer, + SerdErrorSink error_sink, + void* handle); + +/** + Set a prefix to be removed from matching blank node identifiers. +*/ +SERD_API +void +serd_writer_chop_blank_prefix(SerdWriter* writer, + const uint8_t* prefix); + +/** + Set the current output base URI (and emit directive if applicable). + + Note this function can be safely casted to SerdBaseSink. +*/ +SERD_API +SerdStatus +serd_writer_set_base_uri(SerdWriter* writer, + const SerdNode* uri); + +/** + Set the current root URI. + + The root URI should be a prefix of the base URI. The path of the root URI + is the highest path any relative up-reference can refer to. For example, + with root <file:///foo/root> and base <file:///foo/root/base>, + <file:///foo/root> will be written as <../>, but <file:///foo> will be + written non-relatively as <file:///foo>. If the root is not explicitly set, + it defaults to the base URI, so no up-references will be created at all. +*/ +SERD_API +SerdStatus +serd_writer_set_root_uri(SerdWriter* writer, + const SerdNode* uri); + +/** + Set a namespace prefix (and emit directive if applicable). + + Note this function can be safely casted to SerdPrefixSink. +*/ +SERD_API +SerdStatus +serd_writer_set_prefix(SerdWriter* writer, + const SerdNode* name, + const SerdNode* uri); + +/** + Write a statement. + + Note this function can be safely casted to SerdStatementSink. +*/ +SERD_API +SerdStatus +serd_writer_write_statement(SerdWriter* writer, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + Mark the end of an anonymous node's description. + + Note this function can be safely casted to SerdEndSink. +*/ +SERD_API +SerdStatus +serd_writer_end_anon(SerdWriter* writer, + const SerdNode* node); + +/** + Finish a write. +*/ +SERD_API +SerdStatus +serd_writer_finish(SerdWriter* writer); + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SERD_SERD_H */
--- a/osx/include/sord-0/sord/sord.h Thu May 16 16:47:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,627 +0,0 @@ -/* - Copyright 2011-2013 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 sord.h API for Sord, a lightweight RDF model library. -*/ - -#ifndef SORD_SORD_H -#define SORD_SORD_H - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> - -#include "serd/serd.h" - -#ifdef SORD_SHARED -# ifdef _WIN32 -# define SORD_LIB_IMPORT __declspec(dllimport) -# define SORD_LIB_EXPORT __declspec(dllexport) -# else -# define SORD_LIB_IMPORT __attribute__((visibility("default"))) -# define SORD_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef SORD_INTERNAL -# define SORD_API SORD_LIB_EXPORT -# else -# define SORD_API SORD_LIB_IMPORT -# endif -#else -# define SORD_API -#endif - -#ifdef __cplusplus -extern "C" { -#else -# include <stdbool.h> -#endif - -/** - @defgroup sord Sord - A lightweight RDF model library. - - Sord stores RDF (subject object predicate context) quads, where the context - may be omitted (to represent triples in the default graph). - @{ -*/ - -/** - Sord World. - The World represents all library state, including interned strings. -*/ -typedef struct SordWorldImpl SordWorld; - -/** - Sord Model. - - A model is an indexed set of Quads (i.e. it can contain several RDF - graphs). It may be searched using various patterns depending on which - indices are enabled. -*/ -typedef struct SordModelImpl SordModel; - -/** - Model Inserter. - - An inserter is used for writing statements to a model using the Serd sink - interface. This makes it simple to write to a model directly using a - SerdReader, or any other code that writes statements to a SerdStatementSink. -*/ -typedef struct SordInserterImpl SordInserter; - -/** - Model Iterator. -*/ -typedef struct SordIterImpl SordIter; - -/** - RDF Node. - A Node is a component of a Quad. Nodes may be URIs, blank nodes, or - (in the case of quad objects only) string literals. Literal nodes may - have an associate language or datatype (but not both). -*/ -typedef struct SordNodeImpl SordNode; - -/** - Quad of nodes (a statement), or a quad pattern. - - Nodes are ordered (S P O G). The ID of the default graph is 0. -*/ -typedef const SordNode* SordQuad[4]; - -/** - Index into a SordQuad. -*/ -typedef enum { - SORD_SUBJECT = 0, /**< Subject */ - SORD_PREDICATE = 1, /**< Predicate (a.k.a. "key") */ - SORD_OBJECT = 2, /**< Object (a.k.a. "value") */ - SORD_GRAPH = 3 /**< Graph (a.k.a. "context") */ -} SordQuadIndex; - -/** - Type of a node. -*/ -typedef enum { - SORD_URI = 1, /**< URI */ - SORD_BLANK = 2, /**< Blank node identifier */ - SORD_LITERAL = 3 /**< Literal (string with optional lang or datatype) */ -} SordNodeType; - -/** - Indexing option. -*/ -typedef enum { - SORD_SPO = 1, /**< Subject, Predicate, Object */ - SORD_SOP = 1 << 1, /**< Subject, Object, Predicate */ - SORD_OPS = 1 << 2, /**< Object, Predicate, Subject */ - SORD_OSP = 1 << 3, /**< Object, Subject, Predicate */ - SORD_PSO = 1 << 4, /**< Predicate, Subject, Object */ - SORD_POS = 1 << 5 /**< Predicate, Object, Subject */ -} SordIndexOption; - -/** - @name World - @{ -*/ - -/** - Create a new Sord World. - It is safe to use multiple worlds in one process, though no data - (e.g. nodes) can be shared between worlds, and this should be avoided if - possible for performance reasons. -*/ -SORD_API -SordWorld* -sord_world_new(void); - -/** - Free @c world. -*/ -SORD_API -void -sord_world_free(SordWorld* world); - -/** - Set a function to be called when errors occur. - - The @p error_sink will be called with @p handle as its first argument. If - no error function is set, errors are printed to stderr. -*/ -SORD_API -void -sord_world_set_error_sink(SordWorld* world, - SerdErrorSink error_sink, - void* handle); - -/** - @} - @name Node - @{ -*/ - -/** - Get a URI node from a string. - - Note this function measures @c str, which is a common bottleneck. - Use sord_node_from_serd_node instead if @c str is already measured. -*/ -SORD_API -SordNode* -sord_new_uri(SordWorld* world, const uint8_t* uri); - -/** - Get a URI node from a relative URI string. -*/ -SORD_API -SordNode* -sord_new_relative_uri(SordWorld* world, - const uint8_t* str, - const uint8_t* base_uri); - -/** - Get a blank node from a string. - - Note this function measures @c str, which is a common bottleneck. - Use sord_node_from_serd_node instead if @c str is already measured. -*/ -SORD_API -SordNode* -sord_new_blank(SordWorld* world, const uint8_t* str); - -/** - Get a literal node from a string. - - Note this function measures @c str, which is a common bottleneck. - Use sord_node_from_serd_node instead if @c str is already measured. -*/ -SORD_API -SordNode* -sord_new_literal(SordWorld* world, - SordNode* datatype, - const uint8_t* str, - const char* lang); - -/** - Copy a node (obtain a reference). - - Node that since nodes are interned and reference counted, this does not - actually create a deep copy of @c node. -*/ -SORD_API -SordNode* -sord_node_copy(const SordNode* node); - -/** - Free a node (drop a reference). -*/ -SORD_API -void -sord_node_free(SordWorld* world, SordNode* node); - -/** - Return the type of a node (SORD_URI, SORD_BLANK, or SORD_LITERAL). -*/ -SORD_API -SordNodeType -sord_node_get_type(const SordNode* node); - -/** - Return the string value of a node. -*/ -SORD_API -const uint8_t* -sord_node_get_string(const SordNode* node); - -/** - Return the string value of a node, and set @c len to its length. -*/ -SORD_API -const uint8_t* -sord_node_get_string_counted(const SordNode* node, size_t* len); - -/** - Return the language of a literal node (or NULL). -*/ -SORD_API -const char* -sord_node_get_language(const SordNode* node); - -/** - Return the datatype URI of a literal node (or NULL). -*/ -SORD_API -SordNode* -sord_node_get_datatype(const SordNode* node); - -/** - Return the flags (string attributes) of a node. -*/ -SORD_API -SerdNodeFlags -sord_node_get_flags(const SordNode* node); - -/** - Return true iff node can be serialised as an inline object. - - More specifically, this returns true iff the node is the object field - of exactly one statement, and therefore can be inlined since it needn't - be referred to by name. -*/ -SORD_API -bool -sord_node_is_inline_object(const SordNode* node); - -/** - Return true iff @c a is equal to @c b. - - Note this is much faster than comparing the node's strings. -*/ -SORD_API -bool -sord_node_equals(const SordNode* a, - const SordNode* b); - -/** - Return a SordNode as a SerdNode. - - The returned node is shared and must not be freed or modified. -*/ -SORD_API -const SerdNode* -sord_node_to_serd_node(const SordNode* node); - -/** - Create a new SordNode from a SerdNode. - - The returned node must be freed using sord_node_free. -*/ -SORD_API -SordNode* -sord_node_from_serd_node(SordWorld* world, - SerdEnv* env, - const SerdNode* node, - const SerdNode* datatype, - const SerdNode* lang); - -/** - @} - @name Model - @{ -*/ - -/** - Create a new model. - - @param world The world in which to make this model. - - @param indices SordIndexOption flags (e.g. SORD_SPO|SORD_OPS). Be sure to - enable an index where the most significant node(s) are not variables in your - queries (e.g. to make (? P O) queries, enable either SORD_OPS or SORD_POS). - - @param graphs If true, store (and index) graph contexts. -*/ -SORD_API -SordModel* -sord_new(SordWorld* world, - unsigned indices, - bool graphs); - -/** - Close and free @c model. -*/ -SORD_API -void -sord_free(SordModel* model); - -/** - Get the world associated with @c model. -*/ -SORD_API -SordWorld* -sord_get_world(SordModel* model); - -/** - Return the number of nodes stored in @c world. - - Nodes are included in this count iff they are a part of a quad in @c world. -*/ -SORD_API -size_t -sord_num_nodes(const SordWorld* world); - -/** - Return the number of quads stored in @c model. -*/ -SORD_API -size_t -sord_num_quads(const SordModel* model); - -/** - Return an iterator to the start of @c model. -*/ -SORD_API -SordIter* -sord_begin(const SordModel* model); - -/** - Search for statements by a quad pattern. - @return an iterator to the first match, or NULL if no matches found. -*/ -SORD_API -SordIter* -sord_find(SordModel* model, const SordQuad pat); - -/** - Search for statements by nodes. - @return an iterator to the first match, or NULL if no matches found. -*/ -SORD_API -SordIter* -sord_search(SordModel* model, - const SordNode* s, - const SordNode* p, - const SordNode* o, - const SordNode* g); -/** - Search for a single node that matches a pattern. - Exactly one of @p s, @p p, @p o must be NULL. - This function is mainly useful for predicates that only have one value. - The returned node must be freed using sord_node_free. - @return the first matching node, or NULL if no matches are found. -*/ -SORD_API -SordNode* -sord_get(SordModel* model, - const SordNode* s, - const SordNode* p, - const SordNode* o, - const SordNode* g); - -/** - Return true iff a statement exists. -*/ -SORD_API -bool -sord_ask(SordModel* model, - const SordNode* s, - const SordNode* p, - const SordNode* o, - const SordNode* g); - -/** - Return the number of matching statements. -*/ -SORD_API -uint64_t -sord_count(SordModel* model, - const SordNode* s, - const SordNode* p, - const SordNode* o, - const SordNode* g); - -/** - Check if @a model contains a triple pattern. -*/ -SORD_API -bool -sord_contains(SordModel* model, const SordQuad pat); - -/** - Add a quad to a model. -*/ -SORD_API -bool -sord_add(SordModel* model, const SordQuad quad); - -/** - Remove a quad from a model. - - Note that is it illegal to remove while iterating over @c model. -*/ -SORD_API -void -sord_remove(SordModel* model, const SordQuad quad); - -/** - @} - @name Inserter - @{ -*/ - -/** - Create an inserter for writing statements to a model. -*/ -SORD_API -SordInserter* -sord_inserter_new(SordModel* model, - SerdEnv* env); - -/** - Free an inserter. -*/ -SORD_API -void -sord_inserter_free(SordInserter* inserter); - -/** - Set the current base URI for writing to the model. - - Note this function can be safely casted to SerdBaseSink. -*/ -SORD_API -SerdStatus -sord_inserter_set_base_uri(SordInserter* inserter, - const SerdNode* uri); - -/** - Set a namespace prefix for writing to the model. - - Note this function can be safely casted to SerdPrefixSink. -*/ -SORD_API -SerdStatus -sord_inserter_set_prefix(SordInserter* inserter, - const SerdNode* name, - const SerdNode* uri); - -/** - Write a statement to the model. - - Note this function can be safely casted to SerdStatementSink. -*/ -SORD_API -SerdStatus -sord_inserter_write_statement(SordInserter* inserter, - SerdStatementFlags flags, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang); - -/** - @} - @name Iteration - @{ -*/ - -/** - Set @c quad to the quad pointed to by @c iter. -*/ -SORD_API -void -sord_iter_get(const SordIter* iter, SordQuad quad); - -/** - Return a field of the quad pointed to by @c iter. -*/ -SORD_API -const SordNode* -sord_iter_get_node(const SordIter* iter, SordQuadIndex index); - -/** - Return the store pointed to by @c iter. -*/ -SORD_API -const SordModel* -sord_iter_get_model(SordIter* iter); - -/** - Increment @c iter to point to the next statement. -*/ -SORD_API -bool -sord_iter_next(SordIter* iter); - -/** - Return true iff @c iter is at the end of its range. -*/ -SORD_API -bool -sord_iter_end(const SordIter* iter); - -/** - Free @c iter. -*/ -SORD_API -void -sord_iter_free(SordIter* iter); - -/** - @} - @name Utilities - @{ -*/ - -/** - Match two quads (using ID comparison only). - - This function is a straightforward and fast equivalence match with wildcard - support (ID 0 is a wildcard). It does not actually read node data. - @return true iff @c x and @c y match. -*/ -SORD_API -bool -sord_quad_match(const SordQuad x, const SordQuad y); - -/** - @} - @name Serialisation - @{ -*/ - -/** - Return a reader that will read into @c model. -*/ -SORD_API -SerdReader* -sord_new_reader(SordModel* model, - SerdEnv* env, - SerdSyntax syntax, - SordNode* graph); - -/** - Write a model to a writer. -*/ -SORD_API -bool -sord_write(SordModel* model, - SerdWriter* writer, - SordNode* graph); - -/** - Write a range to a writer. - - This increments @c iter to its end, then frees it. -*/ -SORD_API -bool -sord_write_iter(SordIter* iter, - SerdWriter* writer); - -/** - @} - @} -*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* SORD_SORD_H */
--- a/osx/include/sord-0/sord/sordmm.hpp Thu May 16 16:47:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,653 +0,0 @@ -/* - Copyright 2011-2013 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 sordmm.hpp - Public Sord C++ API. -*/ - -#ifndef SORD_SORDMM_HPP -#define SORD_SORDMM_HPP - -#include <cassert> -#include <cstring> -#include <cstdlib> -#include <iostream> -#include <set> -#include <string> -#include <sstream> - -#include "serd/serd.h" -#include "sord/sord.h" - -#define SORD_NS_XSD "http://www.w3.org/2001/XMLSchema#" - -namespace Sord { - -/** Utility base class to prevent copying. */ -class Noncopyable { -protected: - Noncopyable() {} - ~Noncopyable() {} -private: - Noncopyable(const Noncopyable&); - const Noncopyable& operator=(const Noncopyable&); -}; - -/** C++ wrapper for a Sord object. */ -template <typename T> -class Wrapper { -public: - inline Wrapper(T c_obj = NULL) : _c_obj(c_obj) {} - - inline T c_obj() { return _c_obj; } - inline const T c_obj() const { return _c_obj; } - -protected: - T _c_obj; -}; - -/** Collection of RDF namespaces with prefixes. */ -class Namespaces : public Wrapper<SerdEnv*> { -public: - Namespaces() : Wrapper<SerdEnv*>(serd_env_new(NULL)) {} - ~Namespaces() { serd_env_free(_c_obj); } - - static inline SerdNode string_to_node(SerdType type, const std::string& s) { - SerdNode ret = { - (const uint8_t*)s.c_str(), s.length(), s.length(), 0, type }; - return ret; - } - - inline void add(const std::string& name, - const std::string& uri) { - const SerdNode name_node = string_to_node(SERD_LITERAL, name); - const SerdNode uri_node = string_to_node(SERD_URI, uri); - serd_env_set_prefix(_c_obj, &name_node, &uri_node); - } - - inline std::string qualify(std::string uri) const { - const SerdNode uri_node = string_to_node(SERD_URI, uri); - SerdNode prefix; - SerdChunk suffix; - if (serd_env_qualify(_c_obj, &uri_node, &prefix, &suffix)) { - std::string ret((const char*)prefix.buf, prefix.n_bytes); - ret.append(":").append((const char*)suffix.buf, suffix.len); - return ret; - } - return uri; - } - - inline std::string expand(const std::string& curie) const { - assert(curie.find(":") != std::string::npos); - SerdNode curie_node = string_to_node(SERD_CURIE, curie); - SerdChunk uri_prefix; - SerdChunk uri_suffix; - if (!serd_env_expand(_c_obj, &curie_node, &uri_prefix, &uri_suffix)) { - std::string ret((const char*)uri_prefix.buf, uri_prefix.len); - ret.append((const char*)uri_suffix.buf, uri_suffix.len); - return ret; - } - std::cerr << "CURIE `" << curie << "' has unknown prefix." << std::endl; - return curie; - } -}; - -/** Sord library state. */ -class World : public Noncopyable, public Wrapper<SordWorld*> { -public: - inline World() - : _next_blank_id(0) - { - _c_obj = sord_world_new(); - } - - inline ~World() { - sord_world_free(_c_obj); - } - - inline uint64_t blank_id() { return _next_blank_id++; } - - inline void add_prefix(const std::string& prefix, const std::string& uri) { - _prefixes.add(prefix, uri); - } - - inline const Namespaces& prefixes() const { return _prefixes; } - inline SordWorld* world() { return _c_obj; } - -private: - Namespaces _prefixes; - std::set<std::string> _blank_ids; - uint64_t _next_blank_id; -}; - -/** An RDF Node (resource, literal, etc) - */ -class Node : public Wrapper<SordNode*> { -public: - enum Type { - UNKNOWN = 0, - URI = SORD_URI, - BLANK = SORD_BLANK, - LITERAL = SORD_LITERAL - }; - - inline Node() : Wrapper<SordNode*>(NULL), _world(NULL) {} - - inline Node(World& world, Type t, const std::string& s); - inline Node(World& world); - inline Node(World& world, const SordNode* node); - inline Node(World& world, SordNode* node, bool copy=false); - inline Node(const Node& other); - inline ~Node(); - - inline Type type() const { - return _c_obj ? (Type)sord_node_get_type(_c_obj) : UNKNOWN; - } - - inline const SordNode* get_node() const { return _c_obj; } - inline SordNode* get_node() { return _c_obj; } - - const SerdNode* to_serd_node() { - return sord_node_to_serd_node(_c_obj); - } - - inline bool is_valid() const { return type() != UNKNOWN; } - - inline bool operator<(const Node& other) const { - if (type() != other.type()) { - return type() < other.type(); - } else { - return to_string() < other.to_string(); - } - } - - Node& operator=(const Node& other) { - if (&other != this) { - if (_c_obj) { - sord_node_free(_world->c_obj(), _c_obj); - } - _world = other._world; - _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; - } - return *this; - } - - inline bool operator==(const Node& other) const { - return sord_node_equals(_c_obj, other._c_obj); - } - - inline const uint8_t* to_u_string() const; - inline const char* to_c_string() const; - inline std::string to_string() const; - - inline bool is_literal_type(const char* type_uri) const; - - inline bool is_uri() const { return _c_obj && type() == URI; } - inline bool is_blank() const { return _c_obj && type() == BLANK; } - inline bool is_int() const { return is_literal_type(SORD_NS_XSD "integer"); } - inline bool is_float() const { return is_literal_type(SORD_NS_XSD "decimal"); } - inline bool is_bool() const { return is_literal_type(SORD_NS_XSD "boolean"); } - - inline int to_int() const; - inline float to_float() const; - inline bool to_bool() const; - - inline static Node blank_id(World& world, const std::string base="b") { - const uint64_t num = world.blank_id(); - std::ostringstream ss; - ss << base << num; - return Node(world, Node::BLANK, ss.str()); - } - -private: - World* _world; -}; - -inline std::ostream& -operator<<(std::ostream& os, const Node& node) -{ - return os << node.to_string(); -} - -class URI : public Node { -public: - inline URI(World& world, const std::string& s) - : Node(world, Node::URI, s) {} - inline URI(World& world, const std::string& s, const std::string& base) - : Node(world, sord_new_relative_uri(world.world(), - (const uint8_t*)s.c_str(), - (const uint8_t*)base.c_str())) - {} -}; - -class Curie : public Node { -public: - inline Curie(World& world, const std::string& s) - : Node(world, Node::URI, world.prefixes().expand(s)) {} -}; - -class Literal : public Node { -public: - inline Literal(World& world, const std::string& s) - : Node(world, Node::LITERAL, s) {} - - static inline Node decimal(World& world, double d, unsigned frac_digits) { - const SerdNode val = serd_node_new_decimal(d, 7); - const SerdNode type = serd_node_from_string( - SERD_URI, (const uint8_t*)SORD_NS_XSD "decimal"); - - return Node( - world, - sord_node_from_serd_node( - world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), - false); - } - - static inline Node integer(World& world, int64_t i) { - const SerdNode val = serd_node_new_integer(i); - const SerdNode type = serd_node_from_string( - SERD_URI, (const uint8_t*)SORD_NS_XSD "integer"); - - return Node( - world, - sord_node_from_serd_node( - world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), - false); - } -}; - -inline -Node::Node(World& world, Type type, const std::string& s) - : _world(&world) -{ - switch (type) { - case URI: - _c_obj = sord_new_uri( - world.world(), (const unsigned char*)s.c_str()); - break; - case LITERAL: - _c_obj = sord_new_literal( - world.world(), NULL, (const unsigned char*)s.c_str(), NULL); - break; - case BLANK: - _c_obj = sord_new_blank( - world.world(), (const unsigned char*)s.c_str()); - break; - default: - _c_obj = NULL; - } - - assert(this->type() == type); -} - -inline -Node::Node(World& world) - : _world(&world) -{ - Node me = blank_id(world); - *this = me; -} - -inline -Node::Node(World& world, const SordNode* node) - : _world(&world) -{ - _c_obj = sord_node_copy(node); -} - -inline -Node::Node(World& world, SordNode* node, bool copy) - : _world(&world) -{ - _c_obj = copy ? sord_node_copy(node) : node; -} - -inline -Node::Node(const Node& other) - : Wrapper<SordNode*>() - , _world(other._world) -{ - if (_world) { - _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; - } - - assert((!_c_obj && !other._c_obj) || to_string() == other.to_string()); -} - -inline -Node::~Node() -{ - if (_world) { - sord_node_free(_world->c_obj(), _c_obj); - } -} - -inline std::string -Node::to_string() const -{ - return _c_obj ? (const char*)sord_node_get_string(_c_obj) : ""; -} - -inline const char* -Node::to_c_string() const -{ - return (const char*)sord_node_get_string(_c_obj); -} - -inline const uint8_t* -Node::to_u_string() const -{ - return sord_node_get_string(_c_obj); -} - -inline bool -Node::is_literal_type(const char* type_uri) const -{ - if (_c_obj && sord_node_get_type(_c_obj) == SORD_LITERAL) { - const SordNode* datatype = sord_node_get_datatype(_c_obj); - if (datatype && !strcmp((const char*)sord_node_get_string(datatype), - type_uri)) - return true; - } - return false; -} - -inline int -Node::to_int() const -{ - assert(is_int()); - char* endptr; - return strtol((const char*)sord_node_get_string(_c_obj), &endptr, 10); -} - -inline float -Node::to_float() const -{ - assert(is_float()); - char* endptr; - return serd_strtod((const char*)sord_node_get_string(_c_obj), &endptr); -} - -inline bool -Node::to_bool() const -{ - assert(is_bool()); - return !strcmp((const char*)sord_node_get_string(_c_obj), "true"); -} - -struct Iter : public Wrapper<SordIter*> { - inline Iter(World& world, SordIter* c_obj) - : Wrapper<SordIter*>(c_obj), _world(world) {} - inline ~Iter() { sord_iter_free(_c_obj); } - inline bool end() const { return sord_iter_end(_c_obj); } - inline bool next() const { return sord_iter_next(_c_obj); } - inline Iter& operator++() { - assert(!end()); - next(); - return *this; - } - inline const Node get_subject() const { - SordQuad quad; - sord_iter_get(_c_obj, quad); - return Node(_world, quad[SORD_SUBJECT]); - } - inline const Node get_predicate() const { - SordQuad quad; - sord_iter_get(_c_obj, quad); - return Node(_world, quad[SORD_PREDICATE]); - } - inline const Node get_object() const { - SordQuad quad; - sord_iter_get(_c_obj, quad); - return Node(_world, quad[SORD_OBJECT]); - } - World& _world; -}; - -/** An RDF Model (collection of triples). - */ -class Model : public Noncopyable, public Wrapper<SordModel*> { -public: - inline Model(World& world, - const std::string& base_uri, - unsigned indices = (SORD_SPO | SORD_OPS), - bool graphs = true); - - inline ~Model(); - - inline const Node& base_uri() const { return _base; } - - size_t num_quads() const { return sord_num_quads(_c_obj); } - - inline void load_file(SerdEnv* env, - SerdSyntax syntax, - const std::string& uri, - const std::string& base_uri=""); - - inline void load_string(SerdEnv* env, - SerdSyntax syntax, - const char* str, - size_t len, - const std::string& base_uri); - - inline SerdStatus write_to_file( - const std::string& uri, - SerdSyntax syntax = SERD_TURTLE, - SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED - |SERD_STYLE_CURIED - |SERD_STYLE_RESOLVED)); - - inline std::string write_to_string( - const std::string& base_uri, - SerdSyntax syntax = SERD_TURTLE, - SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED - |SERD_STYLE_CURIED - |SERD_STYLE_RESOLVED)); - - inline void add_statement(const Node& subject, - const Node& predicate, - const Node& object); - - inline Iter find(const Node& subject, - const Node& predicate, - const Node& object); - - inline Node get(const Node& subject, - const Node& predicate, - const Node& object); - - inline World& world() const { return _world; } - -private: - World& _world; - Node _base; - SerdWriter* _writer; - size_t _next_blank_id; -}; - -/** Create an empty in-memory RDF model. - */ -inline -Model::Model(World& world, - const std::string& base_uri, - unsigned indices, - bool graphs) - : _world(world) - , _base(world, Node::URI, base_uri) - , _writer(NULL) -{ - _c_obj = sord_new(_world.world(), indices, graphs); -} - -inline void -Model::load_string(SerdEnv* env, - SerdSyntax syntax, - const char* str, - size_t len, - const std::string& base_uri) -{ - SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); - serd_reader_read_string(reader, (const uint8_t*)str); - serd_reader_free(reader); -} - -inline Model::~Model() -{ - sord_free(_c_obj); -} - -inline void -Model::load_file(SerdEnv* env, - SerdSyntax syntax, - const std::string& data_uri, - const std::string& base_uri) -{ - uint8_t* path = serd_file_uri_parse((const uint8_t*)data_uri.c_str(), NULL); - if (!path) { - fprintf(stderr, "Failed to parse file URI <%s>\n", data_uri.c_str()); - return; - } - - // FIXME: blank prefix parameter? - SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); - serd_reader_read_file(reader, path); - serd_reader_free(reader); - free(path); -} - -inline SerdStatus -Model::write_to_file(const std::string& uri, SerdSyntax syntax, SerdStyle style) -{ - uint8_t* path = serd_file_uri_parse((const uint8_t*)uri.c_str(), NULL); - if (!path) { - fprintf(stderr, "Failed to parse file URI <%s>\n", uri.c_str()); - return SERD_ERR_BAD_ARG; - } - - FILE* const fd = fopen((const char*)path, "w"); - if (!fd) { - fprintf(stderr, "Failed to open file %s\n", path); - free(path); - return SERD_ERR_UNKNOWN; - } - free(path); - - SerdURI base_uri = SERD_URI_NULL; - if (serd_uri_parse((const uint8_t*)uri.c_str(), &base_uri)) { - fprintf(stderr, "Invalid base URI <%s>\n", uri.c_str()); - fclose(fd); - return SERD_ERR_BAD_ARG; - } - - SerdWriter* writer = serd_writer_new(syntax, - style, - _world.prefixes().c_obj(), - &base_uri, - serd_file_sink, - fd); - - serd_env_foreach(_world.prefixes().c_obj(), - (SerdPrefixSink)serd_writer_set_prefix, - writer); - - sord_write(_c_obj, writer, 0); - serd_writer_free(writer); - fclose(fd); - - return SERD_SUCCESS; -} - -static size_t -string_sink(const void* buf, size_t len, void* stream) -{ - std::string* str = (std::string*)stream; - str->append((const char*)buf, len); - return len; -} - -inline std::string -Model::write_to_string(const std::string& base_uri_str, - SerdSyntax syntax, - SerdStyle style) -{ - SerdURI base_uri = SERD_URI_NULL; - if (serd_uri_parse((const uint8_t*)base_uri_str.c_str(), &base_uri)) { - fprintf(stderr, "Invalid base URI <%s>\n", base_uri_str.c_str()); - return ""; - } - - std::string ret; - - SerdWriter* writer = serd_writer_new(syntax, - style, - _world.prefixes().c_obj(), - &base_uri, - string_sink, - &ret); - - serd_env_foreach(_world.prefixes().c_obj(), - (SerdPrefixSink)serd_writer_set_prefix, - writer); - - sord_write(_c_obj, writer, 0); - - serd_writer_free(writer); - return ret; -} - -inline void -Model::add_statement(const Node& subject, - const Node& predicate, - const Node& object) -{ - SordQuad quad = { subject.c_obj(), - predicate.c_obj(), - object.c_obj(), - NULL }; - - sord_add(_c_obj, quad); -} - -inline Iter -Model::find(const Node& subject, - const Node& predicate, - const Node& object) -{ - SordQuad quad = { subject.c_obj(), - predicate.c_obj(), - object.c_obj(), - NULL }; - - return Iter(_world, sord_find(_c_obj, quad)); -} - -inline Node -Model::get(const Node& subject, - const Node& predicate, - const Node& object) -{ - SordNode* c_node = sord_get( - _c_obj, subject.c_obj(), predicate.c_obj(), object.c_obj(), NULL); - Node node(_world, c_node); - sord_node_free(_world.c_obj(), c_node); - return node; -} - -} // namespace Sord - -#endif // SORD_SORDMM_HPP -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/sord/sord.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,627 @@ +/* + Copyright 2011-2013 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 sord.h API for Sord, a lightweight RDF model library. +*/ + +#ifndef SORD_SORD_H +#define SORD_SORD_H + +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +#include "serd/serd.h" + +#ifdef SORD_SHARED +# ifdef _WIN32 +# define SORD_LIB_IMPORT __declspec(dllimport) +# define SORD_LIB_EXPORT __declspec(dllexport) +# else +# define SORD_LIB_IMPORT __attribute__((visibility("default"))) +# define SORD_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef SORD_INTERNAL +# define SORD_API SORD_LIB_EXPORT +# else +# define SORD_API SORD_LIB_IMPORT +# endif +#else +# define SORD_API +#endif + +#ifdef __cplusplus +extern "C" { +#else +# include <stdbool.h> +#endif + +/** + @defgroup sord Sord + A lightweight RDF model library. + + Sord stores RDF (subject object predicate context) quads, where the context + may be omitted (to represent triples in the default graph). + @{ +*/ + +/** + Sord World. + The World represents all library state, including interned strings. +*/ +typedef struct SordWorldImpl SordWorld; + +/** + Sord Model. + + A model is an indexed set of Quads (i.e. it can contain several RDF + graphs). It may be searched using various patterns depending on which + indices are enabled. +*/ +typedef struct SordModelImpl SordModel; + +/** + Model Inserter. + + An inserter is used for writing statements to a model using the Serd sink + interface. This makes it simple to write to a model directly using a + SerdReader, or any other code that writes statements to a SerdStatementSink. +*/ +typedef struct SordInserterImpl SordInserter; + +/** + Model Iterator. +*/ +typedef struct SordIterImpl SordIter; + +/** + RDF Node. + A Node is a component of a Quad. Nodes may be URIs, blank nodes, or + (in the case of quad objects only) string literals. Literal nodes may + have an associate language or datatype (but not both). +*/ +typedef struct SordNodeImpl SordNode; + +/** + Quad of nodes (a statement), or a quad pattern. + + Nodes are ordered (S P O G). The ID of the default graph is 0. +*/ +typedef const SordNode* SordQuad[4]; + +/** + Index into a SordQuad. +*/ +typedef enum { + SORD_SUBJECT = 0, /**< Subject */ + SORD_PREDICATE = 1, /**< Predicate (a.k.a. "key") */ + SORD_OBJECT = 2, /**< Object (a.k.a. "value") */ + SORD_GRAPH = 3 /**< Graph (a.k.a. "context") */ +} SordQuadIndex; + +/** + Type of a node. +*/ +typedef enum { + SORD_URI = 1, /**< URI */ + SORD_BLANK = 2, /**< Blank node identifier */ + SORD_LITERAL = 3 /**< Literal (string with optional lang or datatype) */ +} SordNodeType; + +/** + Indexing option. +*/ +typedef enum { + SORD_SPO = 1, /**< Subject, Predicate, Object */ + SORD_SOP = 1 << 1, /**< Subject, Object, Predicate */ + SORD_OPS = 1 << 2, /**< Object, Predicate, Subject */ + SORD_OSP = 1 << 3, /**< Object, Subject, Predicate */ + SORD_PSO = 1 << 4, /**< Predicate, Subject, Object */ + SORD_POS = 1 << 5 /**< Predicate, Object, Subject */ +} SordIndexOption; + +/** + @name World + @{ +*/ + +/** + Create a new Sord World. + It is safe to use multiple worlds in one process, though no data + (e.g. nodes) can be shared between worlds, and this should be avoided if + possible for performance reasons. +*/ +SORD_API +SordWorld* +sord_world_new(void); + +/** + Free @c world. +*/ +SORD_API +void +sord_world_free(SordWorld* world); + +/** + Set a function to be called when errors occur. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr. +*/ +SORD_API +void +sord_world_set_error_sink(SordWorld* world, + SerdErrorSink error_sink, + void* handle); + +/** + @} + @name Node + @{ +*/ + +/** + Get a URI node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_uri(SordWorld* world, const uint8_t* uri); + +/** + Get a URI node from a relative URI string. +*/ +SORD_API +SordNode* +sord_new_relative_uri(SordWorld* world, + const uint8_t* str, + const uint8_t* base_uri); + +/** + Get a blank node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_blank(SordWorld* world, const uint8_t* str); + +/** + Get a literal node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_literal(SordWorld* world, + SordNode* datatype, + const uint8_t* str, + const char* lang); + +/** + Copy a node (obtain a reference). + + Node that since nodes are interned and reference counted, this does not + actually create a deep copy of @c node. +*/ +SORD_API +SordNode* +sord_node_copy(const SordNode* node); + +/** + Free a node (drop a reference). +*/ +SORD_API +void +sord_node_free(SordWorld* world, SordNode* node); + +/** + Return the type of a node (SORD_URI, SORD_BLANK, or SORD_LITERAL). +*/ +SORD_API +SordNodeType +sord_node_get_type(const SordNode* node); + +/** + Return the string value of a node. +*/ +SORD_API +const uint8_t* +sord_node_get_string(const SordNode* node); + +/** + Return the string value of a node, and set @c len to its length. +*/ +SORD_API +const uint8_t* +sord_node_get_string_counted(const SordNode* node, size_t* len); + +/** + Return the language of a literal node (or NULL). +*/ +SORD_API +const char* +sord_node_get_language(const SordNode* node); + +/** + Return the datatype URI of a literal node (or NULL). +*/ +SORD_API +SordNode* +sord_node_get_datatype(const SordNode* node); + +/** + Return the flags (string attributes) of a node. +*/ +SORD_API +SerdNodeFlags +sord_node_get_flags(const SordNode* node); + +/** + Return true iff node can be serialised as an inline object. + + More specifically, this returns true iff the node is the object field + of exactly one statement, and therefore can be inlined since it needn't + be referred to by name. +*/ +SORD_API +bool +sord_node_is_inline_object(const SordNode* node); + +/** + Return true iff @c a is equal to @c b. + + Note this is much faster than comparing the node's strings. +*/ +SORD_API +bool +sord_node_equals(const SordNode* a, + const SordNode* b); + +/** + Return a SordNode as a SerdNode. + + The returned node is shared and must not be freed or modified. +*/ +SORD_API +const SerdNode* +sord_node_to_serd_node(const SordNode* node); + +/** + Create a new SordNode from a SerdNode. + + The returned node must be freed using sord_node_free. +*/ +SORD_API +SordNode* +sord_node_from_serd_node(SordWorld* world, + SerdEnv* env, + const SerdNode* node, + const SerdNode* datatype, + const SerdNode* lang); + +/** + @} + @name Model + @{ +*/ + +/** + Create a new model. + + @param world The world in which to make this model. + + @param indices SordIndexOption flags (e.g. SORD_SPO|SORD_OPS). Be sure to + enable an index where the most significant node(s) are not variables in your + queries (e.g. to make (? P O) queries, enable either SORD_OPS or SORD_POS). + + @param graphs If true, store (and index) graph contexts. +*/ +SORD_API +SordModel* +sord_new(SordWorld* world, + unsigned indices, + bool graphs); + +/** + Close and free @c model. +*/ +SORD_API +void +sord_free(SordModel* model); + +/** + Get the world associated with @c model. +*/ +SORD_API +SordWorld* +sord_get_world(SordModel* model); + +/** + Return the number of nodes stored in @c world. + + Nodes are included in this count iff they are a part of a quad in @c world. +*/ +SORD_API +size_t +sord_num_nodes(const SordWorld* world); + +/** + Return the number of quads stored in @c model. +*/ +SORD_API +size_t +sord_num_quads(const SordModel* model); + +/** + Return an iterator to the start of @c model. +*/ +SORD_API +SordIter* +sord_begin(const SordModel* model); + +/** + Search for statements by a quad pattern. + @return an iterator to the first match, or NULL if no matches found. +*/ +SORD_API +SordIter* +sord_find(SordModel* model, const SordQuad pat); + +/** + Search for statements by nodes. + @return an iterator to the first match, or NULL if no matches found. +*/ +SORD_API +SordIter* +sord_search(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); +/** + Search for a single node that matches a pattern. + Exactly one of @p s, @p p, @p o must be NULL. + This function is mainly useful for predicates that only have one value. + The returned node must be freed using sord_node_free. + @return the first matching node, or NULL if no matches are found. +*/ +SORD_API +SordNode* +sord_get(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Return true iff a statement exists. +*/ +SORD_API +bool +sord_ask(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Return the number of matching statements. +*/ +SORD_API +uint64_t +sord_count(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Check if @a model contains a triple pattern. +*/ +SORD_API +bool +sord_contains(SordModel* model, const SordQuad pat); + +/** + Add a quad to a model. +*/ +SORD_API +bool +sord_add(SordModel* model, const SordQuad quad); + +/** + Remove a quad from a model. + + Note that is it illegal to remove while iterating over @c model. +*/ +SORD_API +void +sord_remove(SordModel* model, const SordQuad quad); + +/** + @} + @name Inserter + @{ +*/ + +/** + Create an inserter for writing statements to a model. +*/ +SORD_API +SordInserter* +sord_inserter_new(SordModel* model, + SerdEnv* env); + +/** + Free an inserter. +*/ +SORD_API +void +sord_inserter_free(SordInserter* inserter); + +/** + Set the current base URI for writing to the model. + + Note this function can be safely casted to SerdBaseSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_base_uri(SordInserter* inserter, + const SerdNode* uri); + +/** + Set a namespace prefix for writing to the model. + + Note this function can be safely casted to SerdPrefixSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_prefix(SordInserter* inserter, + const SerdNode* name, + const SerdNode* uri); + +/** + Write a statement to the model. + + Note this function can be safely casted to SerdStatementSink. +*/ +SORD_API +SerdStatus +sord_inserter_write_statement(SordInserter* inserter, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + @} + @name Iteration + @{ +*/ + +/** + Set @c quad to the quad pointed to by @c iter. +*/ +SORD_API +void +sord_iter_get(const SordIter* iter, SordQuad quad); + +/** + Return a field of the quad pointed to by @c iter. +*/ +SORD_API +const SordNode* +sord_iter_get_node(const SordIter* iter, SordQuadIndex index); + +/** + Return the store pointed to by @c iter. +*/ +SORD_API +const SordModel* +sord_iter_get_model(SordIter* iter); + +/** + Increment @c iter to point to the next statement. +*/ +SORD_API +bool +sord_iter_next(SordIter* iter); + +/** + Return true iff @c iter is at the end of its range. +*/ +SORD_API +bool +sord_iter_end(const SordIter* iter); + +/** + Free @c iter. +*/ +SORD_API +void +sord_iter_free(SordIter* iter); + +/** + @} + @name Utilities + @{ +*/ + +/** + Match two quads (using ID comparison only). + + This function is a straightforward and fast equivalence match with wildcard + support (ID 0 is a wildcard). It does not actually read node data. + @return true iff @c x and @c y match. +*/ +SORD_API +bool +sord_quad_match(const SordQuad x, const SordQuad y); + +/** + @} + @name Serialisation + @{ +*/ + +/** + Return a reader that will read into @c model. +*/ +SORD_API +SerdReader* +sord_new_reader(SordModel* model, + SerdEnv* env, + SerdSyntax syntax, + SordNode* graph); + +/** + Write a model to a writer. +*/ +SORD_API +bool +sord_write(SordModel* model, + SerdWriter* writer, + SordNode* graph); + +/** + Write a range to a writer. + + This increments @c iter to its end, then frees it. +*/ +SORD_API +bool +sord_write_iter(SordIter* iter, + SerdWriter* writer); + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SORD_SORD_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/sord/sordmm.hpp Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,653 @@ +/* + Copyright 2011-2013 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 sordmm.hpp + Public Sord C++ API. +*/ + +#ifndef SORD_SORDMM_HPP +#define SORD_SORDMM_HPP + +#include <cassert> +#include <cstring> +#include <cstdlib> +#include <iostream> +#include <set> +#include <string> +#include <sstream> + +#include "serd/serd.h" +#include "sord/sord.h" + +#define SORD_NS_XSD "http://www.w3.org/2001/XMLSchema#" + +namespace Sord { + +/** Utility base class to prevent copying. */ +class Noncopyable { +protected: + Noncopyable() {} + ~Noncopyable() {} +private: + Noncopyable(const Noncopyable&); + const Noncopyable& operator=(const Noncopyable&); +}; + +/** C++ wrapper for a Sord object. */ +template <typename T> +class Wrapper { +public: + inline Wrapper(T c_obj = NULL) : _c_obj(c_obj) {} + + inline T c_obj() { return _c_obj; } + inline const T c_obj() const { return _c_obj; } + +protected: + T _c_obj; +}; + +/** Collection of RDF namespaces with prefixes. */ +class Namespaces : public Wrapper<SerdEnv*> { +public: + Namespaces() : Wrapper<SerdEnv*>(serd_env_new(NULL)) {} + ~Namespaces() { serd_env_free(_c_obj); } + + static inline SerdNode string_to_node(SerdType type, const std::string& s) { + SerdNode ret = { + (const uint8_t*)s.c_str(), s.length(), s.length(), 0, type }; + return ret; + } + + inline void add(const std::string& name, + const std::string& uri) { + const SerdNode name_node = string_to_node(SERD_LITERAL, name); + const SerdNode uri_node = string_to_node(SERD_URI, uri); + serd_env_set_prefix(_c_obj, &name_node, &uri_node); + } + + inline std::string qualify(std::string uri) const { + const SerdNode uri_node = string_to_node(SERD_URI, uri); + SerdNode prefix; + SerdChunk suffix; + if (serd_env_qualify(_c_obj, &uri_node, &prefix, &suffix)) { + std::string ret((const char*)prefix.buf, prefix.n_bytes); + ret.append(":").append((const char*)suffix.buf, suffix.len); + return ret; + } + return uri; + } + + inline std::string expand(const std::string& curie) const { + assert(curie.find(":") != std::string::npos); + SerdNode curie_node = string_to_node(SERD_CURIE, curie); + SerdChunk uri_prefix; + SerdChunk uri_suffix; + if (!serd_env_expand(_c_obj, &curie_node, &uri_prefix, &uri_suffix)) { + std::string ret((const char*)uri_prefix.buf, uri_prefix.len); + ret.append((const char*)uri_suffix.buf, uri_suffix.len); + return ret; + } + std::cerr << "CURIE `" << curie << "' has unknown prefix." << std::endl; + return curie; + } +}; + +/** Sord library state. */ +class World : public Noncopyable, public Wrapper<SordWorld*> { +public: + inline World() + : _next_blank_id(0) + { + _c_obj = sord_world_new(); + } + + inline ~World() { + sord_world_free(_c_obj); + } + + inline uint64_t blank_id() { return _next_blank_id++; } + + inline void add_prefix(const std::string& prefix, const std::string& uri) { + _prefixes.add(prefix, uri); + } + + inline const Namespaces& prefixes() const { return _prefixes; } + inline SordWorld* world() { return _c_obj; } + +private: + Namespaces _prefixes; + std::set<std::string> _blank_ids; + uint64_t _next_blank_id; +}; + +/** An RDF Node (resource, literal, etc) + */ +class Node : public Wrapper<SordNode*> { +public: + enum Type { + UNKNOWN = 0, + URI = SORD_URI, + BLANK = SORD_BLANK, + LITERAL = SORD_LITERAL + }; + + inline Node() : Wrapper<SordNode*>(NULL), _world(NULL) {} + + inline Node(World& world, Type t, const std::string& s); + inline Node(World& world); + inline Node(World& world, const SordNode* node); + inline Node(World& world, SordNode* node, bool copy=false); + inline Node(const Node& other); + inline ~Node(); + + inline Type type() const { + return _c_obj ? (Type)sord_node_get_type(_c_obj) : UNKNOWN; + } + + inline const SordNode* get_node() const { return _c_obj; } + inline SordNode* get_node() { return _c_obj; } + + const SerdNode* to_serd_node() { + return sord_node_to_serd_node(_c_obj); + } + + inline bool is_valid() const { return type() != UNKNOWN; } + + inline bool operator<(const Node& other) const { + if (type() != other.type()) { + return type() < other.type(); + } else { + return to_string() < other.to_string(); + } + } + + Node& operator=(const Node& other) { + if (&other != this) { + if (_c_obj) { + sord_node_free(_world->c_obj(), _c_obj); + } + _world = other._world; + _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; + } + return *this; + } + + inline bool operator==(const Node& other) const { + return sord_node_equals(_c_obj, other._c_obj); + } + + inline const uint8_t* to_u_string() const; + inline const char* to_c_string() const; + inline std::string to_string() const; + + inline bool is_literal_type(const char* type_uri) const; + + inline bool is_uri() const { return _c_obj && type() == URI; } + inline bool is_blank() const { return _c_obj && type() == BLANK; } + inline bool is_int() const { return is_literal_type(SORD_NS_XSD "integer"); } + inline bool is_float() const { return is_literal_type(SORD_NS_XSD "decimal"); } + inline bool is_bool() const { return is_literal_type(SORD_NS_XSD "boolean"); } + + inline int to_int() const; + inline float to_float() const; + inline bool to_bool() const; + + inline static Node blank_id(World& world, const std::string base="b") { + const uint64_t num = world.blank_id(); + std::ostringstream ss; + ss << base << num; + return Node(world, Node::BLANK, ss.str()); + } + +private: + World* _world; +}; + +inline std::ostream& +operator<<(std::ostream& os, const Node& node) +{ + return os << node.to_string(); +} + +class URI : public Node { +public: + inline URI(World& world, const std::string& s) + : Node(world, Node::URI, s) {} + inline URI(World& world, const std::string& s, const std::string& base) + : Node(world, sord_new_relative_uri(world.world(), + (const uint8_t*)s.c_str(), + (const uint8_t*)base.c_str())) + {} +}; + +class Curie : public Node { +public: + inline Curie(World& world, const std::string& s) + : Node(world, Node::URI, world.prefixes().expand(s)) {} +}; + +class Literal : public Node { +public: + inline Literal(World& world, const std::string& s) + : Node(world, Node::LITERAL, s) {} + + static inline Node decimal(World& world, double d, unsigned frac_digits) { + const SerdNode val = serd_node_new_decimal(d, 7); + const SerdNode type = serd_node_from_string( + SERD_URI, (const uint8_t*)SORD_NS_XSD "decimal"); + + return Node( + world, + sord_node_from_serd_node( + world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), + false); + } + + static inline Node integer(World& world, int64_t i) { + const SerdNode val = serd_node_new_integer(i); + const SerdNode type = serd_node_from_string( + SERD_URI, (const uint8_t*)SORD_NS_XSD "integer"); + + return Node( + world, + sord_node_from_serd_node( + world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), + false); + } +}; + +inline +Node::Node(World& world, Type type, const std::string& s) + : _world(&world) +{ + switch (type) { + case URI: + _c_obj = sord_new_uri( + world.world(), (const unsigned char*)s.c_str()); + break; + case LITERAL: + _c_obj = sord_new_literal( + world.world(), NULL, (const unsigned char*)s.c_str(), NULL); + break; + case BLANK: + _c_obj = sord_new_blank( + world.world(), (const unsigned char*)s.c_str()); + break; + default: + _c_obj = NULL; + } + + assert(this->type() == type); +} + +inline +Node::Node(World& world) + : _world(&world) +{ + Node me = blank_id(world); + *this = me; +} + +inline +Node::Node(World& world, const SordNode* node) + : _world(&world) +{ + _c_obj = sord_node_copy(node); +} + +inline +Node::Node(World& world, SordNode* node, bool copy) + : _world(&world) +{ + _c_obj = copy ? sord_node_copy(node) : node; +} + +inline +Node::Node(const Node& other) + : Wrapper<SordNode*>() + , _world(other._world) +{ + if (_world) { + _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; + } + + assert((!_c_obj && !other._c_obj) || to_string() == other.to_string()); +} + +inline +Node::~Node() +{ + if (_world) { + sord_node_free(_world->c_obj(), _c_obj); + } +} + +inline std::string +Node::to_string() const +{ + return _c_obj ? (const char*)sord_node_get_string(_c_obj) : ""; +} + +inline const char* +Node::to_c_string() const +{ + return (const char*)sord_node_get_string(_c_obj); +} + +inline const uint8_t* +Node::to_u_string() const +{ + return sord_node_get_string(_c_obj); +} + +inline bool +Node::is_literal_type(const char* type_uri) const +{ + if (_c_obj && sord_node_get_type(_c_obj) == SORD_LITERAL) { + const SordNode* datatype = sord_node_get_datatype(_c_obj); + if (datatype && !strcmp((const char*)sord_node_get_string(datatype), + type_uri)) + return true; + } + return false; +} + +inline int +Node::to_int() const +{ + assert(is_int()); + char* endptr; + return strtol((const char*)sord_node_get_string(_c_obj), &endptr, 10); +} + +inline float +Node::to_float() const +{ + assert(is_float()); + char* endptr; + return serd_strtod((const char*)sord_node_get_string(_c_obj), &endptr); +} + +inline bool +Node::to_bool() const +{ + assert(is_bool()); + return !strcmp((const char*)sord_node_get_string(_c_obj), "true"); +} + +struct Iter : public Wrapper<SordIter*> { + inline Iter(World& world, SordIter* c_obj) + : Wrapper<SordIter*>(c_obj), _world(world) {} + inline ~Iter() { sord_iter_free(_c_obj); } + inline bool end() const { return sord_iter_end(_c_obj); } + inline bool next() const { return sord_iter_next(_c_obj); } + inline Iter& operator++() { + assert(!end()); + next(); + return *this; + } + inline const Node get_subject() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_SUBJECT]); + } + inline const Node get_predicate() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_PREDICATE]); + } + inline const Node get_object() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_OBJECT]); + } + World& _world; +}; + +/** An RDF Model (collection of triples). + */ +class Model : public Noncopyable, public Wrapper<SordModel*> { +public: + inline Model(World& world, + const std::string& base_uri, + unsigned indices = (SORD_SPO | SORD_OPS), + bool graphs = true); + + inline ~Model(); + + inline const Node& base_uri() const { return _base; } + + size_t num_quads() const { return sord_num_quads(_c_obj); } + + inline void load_file(SerdEnv* env, + SerdSyntax syntax, + const std::string& uri, + const std::string& base_uri=""); + + inline void load_string(SerdEnv* env, + SerdSyntax syntax, + const char* str, + size_t len, + const std::string& base_uri); + + inline SerdStatus write_to_file( + const std::string& uri, + SerdSyntax syntax = SERD_TURTLE, + SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED + |SERD_STYLE_CURIED + |SERD_STYLE_RESOLVED)); + + inline std::string write_to_string( + const std::string& base_uri, + SerdSyntax syntax = SERD_TURTLE, + SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED + |SERD_STYLE_CURIED + |SERD_STYLE_RESOLVED)); + + inline void add_statement(const Node& subject, + const Node& predicate, + const Node& object); + + inline Iter find(const Node& subject, + const Node& predicate, + const Node& object); + + inline Node get(const Node& subject, + const Node& predicate, + const Node& object); + + inline World& world() const { return _world; } + +private: + World& _world; + Node _base; + SerdWriter* _writer; + size_t _next_blank_id; +}; + +/** Create an empty in-memory RDF model. + */ +inline +Model::Model(World& world, + const std::string& base_uri, + unsigned indices, + bool graphs) + : _world(world) + , _base(world, Node::URI, base_uri) + , _writer(NULL) +{ + _c_obj = sord_new(_world.world(), indices, graphs); +} + +inline void +Model::load_string(SerdEnv* env, + SerdSyntax syntax, + const char* str, + size_t len, + const std::string& base_uri) +{ + SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); + serd_reader_read_string(reader, (const uint8_t*)str); + serd_reader_free(reader); +} + +inline Model::~Model() +{ + sord_free(_c_obj); +} + +inline void +Model::load_file(SerdEnv* env, + SerdSyntax syntax, + const std::string& data_uri, + const std::string& base_uri) +{ + uint8_t* path = serd_file_uri_parse((const uint8_t*)data_uri.c_str(), NULL); + if (!path) { + fprintf(stderr, "Failed to parse file URI <%s>\n", data_uri.c_str()); + return; + } + + // FIXME: blank prefix parameter? + SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); + serd_reader_read_file(reader, path); + serd_reader_free(reader); + free(path); +} + +inline SerdStatus +Model::write_to_file(const std::string& uri, SerdSyntax syntax, SerdStyle style) +{ + uint8_t* path = serd_file_uri_parse((const uint8_t*)uri.c_str(), NULL); + if (!path) { + fprintf(stderr, "Failed to parse file URI <%s>\n", uri.c_str()); + return SERD_ERR_BAD_ARG; + } + + FILE* const fd = fopen((const char*)path, "w"); + if (!fd) { + fprintf(stderr, "Failed to open file %s\n", path); + free(path); + return SERD_ERR_UNKNOWN; + } + free(path); + + SerdURI base_uri = SERD_URI_NULL; + if (serd_uri_parse((const uint8_t*)uri.c_str(), &base_uri)) { + fprintf(stderr, "Invalid base URI <%s>\n", uri.c_str()); + fclose(fd); + return SERD_ERR_BAD_ARG; + } + + SerdWriter* writer = serd_writer_new(syntax, + style, + _world.prefixes().c_obj(), + &base_uri, + serd_file_sink, + fd); + + serd_env_foreach(_world.prefixes().c_obj(), + (SerdPrefixSink)serd_writer_set_prefix, + writer); + + sord_write(_c_obj, writer, 0); + serd_writer_free(writer); + fclose(fd); + + return SERD_SUCCESS; +} + +static size_t +string_sink(const void* buf, size_t len, void* stream) +{ + std::string* str = (std::string*)stream; + str->append((const char*)buf, len); + return len; +} + +inline std::string +Model::write_to_string(const std::string& base_uri_str, + SerdSyntax syntax, + SerdStyle style) +{ + SerdURI base_uri = SERD_URI_NULL; + if (serd_uri_parse((const uint8_t*)base_uri_str.c_str(), &base_uri)) { + fprintf(stderr, "Invalid base URI <%s>\n", base_uri_str.c_str()); + return ""; + } + + std::string ret; + + SerdWriter* writer = serd_writer_new(syntax, + style, + _world.prefixes().c_obj(), + &base_uri, + string_sink, + &ret); + + serd_env_foreach(_world.prefixes().c_obj(), + (SerdPrefixSink)serd_writer_set_prefix, + writer); + + sord_write(_c_obj, writer, 0); + + serd_writer_free(writer); + return ret; +} + +inline void +Model::add_statement(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordQuad quad = { subject.c_obj(), + predicate.c_obj(), + object.c_obj(), + NULL }; + + sord_add(_c_obj, quad); +} + +inline Iter +Model::find(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordQuad quad = { subject.c_obj(), + predicate.c_obj(), + object.c_obj(), + NULL }; + + return Iter(_world, sord_find(_c_obj, quad)); +} + +inline Node +Model::get(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordNode* c_node = sord_get( + _c_obj, subject.c_obj(), predicate.c_obj(), object.c_obj(), NULL); + Node node(_world, c_node); + sord_node_free(_world.c_obj(), c_node); + return node; +} + +} // namespace Sord + +#endif // SORD_SORDMM_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/Plugin.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,47 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_HOSTSDK_PLUGIN_H_ +#define _VAMP_HOSTSDK_PLUGIN_H_ + +// Do not include vamp-sdk/Plugin.h directly from host code. Always +// use this header instead. + +#include "hostguard.h" + +#include <vamp-sdk/Plugin.h> + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginBase.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,47 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_HOSTSDK_PLUGIN_BASE_H_ +#define _VAMP_HOSTSDK_PLUGIN_BASE_H_ + +// Do not include vamp-sdk/PluginBase.h directly from host code. +// Always use this header instead. + +#include "hostguard.h" + +#include <vamp-sdk/PluginBase.h> + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginBufferingAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,194 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + This file by Mark Levy and Chris Cannam, Copyright 2007-2008 QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_BUFFERING_ADAPTER_H_ +#define _VAMP_PLUGIN_BUFFERING_ADAPTER_H_ + +#include "hostguard.h" +#include "PluginWrapper.h" + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginBufferingAdapter.h) + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginBufferingAdapter PluginBufferingAdapter.h <vamp-hostsdk/PluginBufferingAdapter.h> + * + * PluginBufferingAdapter is a Vamp plugin adapter that allows plugins + * to be used by a host supplying an audio stream in non-overlapping + * buffers of arbitrary size. + * + * A host using PluginBufferingAdapter may ignore the preferred step + * and block size reported by the plugin, and still expect the plugin + * to run. The value of blockSize and stepSize passed to initialise + * should be the size of the buffer which the host will supply; the + * stepSize should be equal to the blockSize. + * + * If the internal step size used for the plugin differs from that + * supplied by the host, the adapter will modify the sample type and + * rate specifications for the plugin outputs appropriately, and set + * timestamps on the output features for outputs that formerly used a + * different sample rate specification. This is necessary in order to + * obtain correct time stamping. + * + * In other respects, the PluginBufferingAdapter behaves identically + * to the plugin that it wraps. The wrapped plugin will be deleted + * when the wrapper is deleted. + */ + +class PluginBufferingAdapter : public PluginWrapper +{ +public: + /** + * Construct a PluginBufferingAdapter wrapping the given plugin. + * The adapter takes ownership of the plugin, which will be + * deleted when the adapter is deleted. + */ + PluginBufferingAdapter(Plugin *plugin); + virtual ~PluginBufferingAdapter(); + + /** + * Return the preferred step size for this adapter. + * + * Because of the way this adapter works, its preferred step size + * will always be the same as its preferred block size. This may + * or may not be the same as the preferred step size of the + * underlying plugin, which may be obtained by calling + * getPluginPreferredStepSize(). + */ + size_t getPreferredStepSize() const; + + /** + * Return the preferred block size for this adapter. + * + * This may or may not be the same as the preferred block size of + * the underlying plugin, which may be obtained by calling + * getPluginPreferredBlockSize(). + * + * Note that this adapter may be initialised with any block size, + * not just its supposedly preferred one. + */ + size_t getPreferredBlockSize() const; + + /** + * Initialise the adapter (and therefore the plugin) for the given + * number of channels. Initialise the adapter for the given step + * and block size, which must be equal. + * + * The step and block size used for the underlying plugin will + * depend on its preferences, or any values previously passed to + * setPluginStepSize and setPluginBlockSize. + */ + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + /** + * Return the preferred step size of the plugin wrapped by this + * adapter. + * + * This is included mainly for informational purposes. This value + * is not likely to be a valid step size for the adapter itself, + * and it is not usually of any use in interpreting the results + * (because the adapter re-writes OneSamplePerStep outputs to + * FixedSampleRate so that the hop size no longer needs to be + * known beforehand in order to interpret them). + */ + size_t getPluginPreferredStepSize() const; + + /** + * Return the preferred block size of the plugin wrapped by this + * adapter. + * + * This is included mainly for informational purposes. + */ + size_t getPluginPreferredBlockSize() const; + + /** + * Set the step size that will be used for the underlying plugin + * when initialise() is called. If this is not set, the plugin's + * own preferred step size will be used. You will not usually + * need to call this function. If you do call it, it must be + * before the first call to initialise(). + */ + void setPluginStepSize(size_t stepSize); + + /** + * Set the block size that will be used for the underlying plugin + * when initialise() is called. If this is not set, the plugin's + * own preferred block size will be used. You will not usually + * need to call this function. If you do call it, it must be + * before the first call to initialise(). + */ + void setPluginBlockSize(size_t blockSize); + + /** + * Return the step and block sizes that were actually used when + * initialising the underlying plugin. + * + * This is included mainly for informational purposes. You will + * not usually need to call this function. If this is called + * before initialise(), it will return 0 for both values. If it + * is called after a failed call to initialise(), it will return + * the values that were used in the failed call to the plugin's + * initialise() function. + */ + void getActualStepAndBlockSizes(size_t &stepSize, size_t &blockSize); + + void setParameter(std::string, float); + void selectProgram(std::string); + + OutputList getOutputDescriptors() const; + + void reset(); + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginBufferingAdapter.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginChannelAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,149 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_CHANNEL_ADAPTER_H_ +#define _VAMP_PLUGIN_CHANNEL_ADAPTER_H_ + +#include "hostguard.h" +#include "PluginWrapper.h" + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginChannelAdapter.h) + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginChannelAdapter PluginChannelAdapter.h <vamp-hostsdk/PluginChannelAdapter.h> + * + * PluginChannelAdapter is a Vamp plugin adapter that implements a + * policy for management of plugins that expect a different number of + * input channels from the number actually available in the source + * audio data. + * + * A host using PluginChannelAdapter may ignore the getMinChannelCount + * and getMaxChannelCount reported by the plugin, and still expect the + * plugin to run. + * + * PluginChannelAdapter implements the following policy: + * + * - If the plugin supports the provided number of channels directly, + * PluginChannelAdapter will just run the plugin as normal. + * + * - If the plugin only supports exactly one channel but more than + * one channel is provided, PluginChannelAdapter will use the mean of + * the channels. This ensures that the resulting values remain + * within the same magnitude range as expected for mono data. + * + * - If the plugin requires more than one channel but exactly one is + * provided, the provided channel will be duplicated across all the + * plugin input channels. + * + * If none of the above apply: + * + * - If the plugin requires more channels than are provided, the + * minimum acceptable number of channels will be produced by adding + * empty (zero valued) channels to those provided. + * + * - If the plugin requires fewer channels than are provided, the + * maximum acceptable number of channels will be produced by + * discarding the excess channels. + * + * Hosts requiring a different channel policy from the above will need + * to implement it themselves, instead of using PluginChannelAdapter. + * + * Note that PluginChannelAdapter does not override the minimum and + * maximum channel counts returned by the wrapped plugin. The host + * will need to be aware that it is using a PluginChannelAdapter, and + * be prepared to ignore these counts as necessary. (This contrasts + * with the approach used in PluginInputDomainAdapter, which aims to + * make the host completely unaware of which underlying input domain + * is in fact in use.) + * + * (The rationale for this is that a host may wish to use the + * PluginChannelAdapter but still discriminate in some way on the + * basis of the number of channels actually supported. For example, a + * simple stereo audio host may prefer to reject plugins that require + * more than two channels on the grounds that doesn't actually + * understand what they are for, rather than allow the channel adapter + * to make a potentially meaningless channel conversion for them.) + * + * In every respect other than its management of channels, the + * PluginChannelAdapter behaves identically to the plugin that it + * wraps. The wrapped plugin will be deleted when the wrapper is + * deleted. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginChannelAdapter : public PluginWrapper +{ +public: + /** + * Construct a PluginChannelAdapter wrapping the given plugin. + * The adapter takes ownership of the plugin, which will be + * deleted when the adapter is deleted. + */ + PluginChannelAdapter(Plugin *plugin); + virtual ~PluginChannelAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + /** + * Call process(), providing interleaved audio data with the + * number of channels passed to initialise(). The adapter will + * de-interleave into temporary buffers as appropriate before + * calling process(). + * + * \note This function was introduced in version 1.4 of the Vamp + * plugin SDK. + */ + FeatureSet processInterleaved(const float *inputBuffer, RealTime timestamp); + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginChannelAdapter.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginHostAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,123 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_HOST_ADAPTER_H_ +#define _VAMP_PLUGIN_HOST_ADAPTER_H_ + +#include "hostguard.h" +#include "Plugin.h" + +#include <vamp/vamp.h> + +#include <vector> + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.h) + +namespace Vamp { + +/** + * \class PluginHostAdapter PluginHostAdapter.h <vamp-hostsdk/PluginHostAdapter.h> + * + * PluginHostAdapter is a wrapper class that a Vamp host can use to + * make the C-language VampPluginDescriptor object appear as a C++ + * Vamp::Plugin object. + * + * The Vamp API is defined in vamp/vamp.h as a C API. The C++ objects + * used for convenience by plugins and hosts actually communicate + * using the C low-level API, but the details of this communication + * are handled seamlessly by the Vamp SDK implementation provided the + * plugin and host use the proper C++ wrapper objects. + * + * See also PluginAdapter, the plugin-side wrapper that makes a C++ + * plugin object available using the C query API. + */ + +class PluginHostAdapter : public Plugin +{ +public: + PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate); + virtual ~PluginHostAdapter(); + + static std::vector<std::string> getPluginPath(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + unsigned int getVampApiVersion() const; + std::string getIdentifier() const; + std::string getName() const; + std::string getDescription() const; + std::string getMaker() const; + int getPluginVersion() const; + std::string getCopyright() const; + + ParameterList getParameterDescriptors() const; + float getParameter(std::string) const; + void setParameter(std::string, float); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + size_t getMinChannelCount() const; + size_t getMaxChannelCount() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + void convertFeatures(VampFeatureList *, FeatureSet &); + + const VampPluginDescriptor *m_descriptor; + VampPluginHandle m_handle; +}; + +} + +_VAMP_SDK_HOSTSPACE_END(PluginHostAdapter.h) + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginInputDomainAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,236 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_ +#define _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_ + +#include "hostguard.h" +#include "PluginWrapper.h" + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.h) + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginInputDomainAdapter PluginInputDomainAdapter.h <vamp-hostsdk/PluginInputDomainAdapter.h> + * + * PluginInputDomainAdapter is a Vamp plugin adapter that converts + * time-domain input into frequency-domain input for plugins that need + * it. This permits a host to use time- and frequency-domain plugins + * interchangeably without needing to handle the conversion itself. + * + * This adapter uses a basic windowed FFT (using Hann window by + * default) that supports power-of-two block sizes only. If a + * frequency domain plugin requests a non-power-of-two blocksize, the + * adapter will adjust it to a nearby power of two instead. Thus, + * getPreferredBlockSize() will always return a power of two if the + * wrapped plugin is a frequency domain one. If the plugin doesn't + * accept the adjusted power of two block size, initialise() will + * fail. + * + * The adapter provides no way for the host to discover whether the + * underlying plugin is actually a time or frequency domain plugin + * (except that if the preferred block size is not a power of two, it + * must be a time domain plugin). + * + * The FFT implementation is simple and self-contained, but unlikely + * to be the fastest available: a host can usually do better if it + * cares enough. + * + * The window shape for the FFT frame can be set using setWindowType + * and the current shape retrieved using getWindowType. (This was + * added in v2.3 of the SDK.) + * + * In every respect other than its input domain handling, the + * PluginInputDomainAdapter behaves identically to the plugin that it + * wraps. The wrapped plugin will be deleted when the wrapper is + * deleted. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginInputDomainAdapter : public PluginWrapper +{ +public: + /** + * Construct a PluginInputDomainAdapter wrapping the given plugin. + * The adapter takes ownership of the plugin, which will be + * deleted when the adapter is deleted. + */ + PluginInputDomainAdapter(Plugin *plugin); + virtual ~PluginInputDomainAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + /** + * ProcessTimestampMethod determines how the + * PluginInputDomainAdapter handles timestamps for the data passed + * to the process() function of the plugin it wraps, in the case + * where the plugin is expecting frequency-domain data. + * + * The Vamp specification requires that the timestamp passed to + * the plugin for frequency-domain input should be that of the + * centre of the processing block, rather than the start as is the + * case for time-domain input. + * + * Since PluginInputDomainAdapter aims to be transparent in use, + * it needs to handle this timestamp adjustment itself. However, + * some control is available over the method used for adjustment, + * by means of the ProcessTimestampMethod setting. + * + * If ProcessTimestampMethod is set to ShiftTimestamp (the + * default), then the data passed to the wrapped plugin will be + * calculated from the same input data block as passed to the + * wrapper, but the timestamp passed to the plugin will be + * advanced by half of the window size. + * + * If ProcessTimestampMethod is set to ShiftData, then the + * timestamp passed to the wrapped plugin will be the same as that + * passed to the process call of the wrapper, but the data block + * used to calculate the input will be shifted back (earlier) by + * half of the window size, with half a block of zero padding at + * the start of the first process call. This has the advantage of + * preserving the first half block of audio without any + * deterioration from window shaping. + * + * If ProcessTimestampMethod is set to NoShift, then no adjustment + * will be made and the timestamps will be incorrect. + */ + enum ProcessTimestampMethod { + ShiftTimestamp, + ShiftData, + NoShift + }; + + /** + * Set the method used for timestamp adjustment in plugins taking + * frequency-domain input. See the ProcessTimestampMethod + * documentation for details. + * + * This function must be called before the first call to + * process(). + */ + void setProcessTimestampMethod(ProcessTimestampMethod); + + /** + * Retrieve the method used for timestamp adjustment in plugins + * taking frequency-domain input. See the ProcessTimestampMethod + * documentation for details. + */ + ProcessTimestampMethod getProcessTimestampMethod() const; + + /** + * Return the amount by which the timestamps supplied to process() + * are being incremented when they are passed to the plugin's own + * process() implementation. + * + * The Vamp API mandates that the timestamp passed to the plugin + * for time-domain input should be the time of the first sample in + * the block, but the timestamp passed for frequency-domain input + * should be the timestamp of the centre of the block. + * + * The PluginInputDomainAdapter adjusts its timestamps properly so + * that the plugin receives correct times, but in some + * circumstances (such as for establishing the correct timing of + * implicitly-timed features, i.e. features without their own + * timestamps) the host may need to be aware that this adjustment + * is taking place. + * + * If the plugin requires time-domain input or the + * PluginInputDomainAdapter is configured with its + * ProcessTimestampMethod set to ShiftData instead of + * ShiftTimestamp, then this function will return zero. + * + * The result of calling this function before initialise() has + * been called is undefined. + */ + RealTime getTimestampAdjustment() const; + + /** + * The set of supported window shapes. + */ + enum WindowType { + + RectangularWindow = 0, + + BartlettWindow = 1, /// synonym for RectangularWindow + TriangularWindow = 1, /// synonym for BartlettWindow + + HammingWindow = 2, + + HanningWindow = 3, /// synonym for HannWindow + HannWindow = 3, /// synonym for HanningWindow + + BlackmanWindow = 4, + + NuttallWindow = 7, + + BlackmanHarrisWindow = 8 + }; + + /** + * Return the current window shape. The default is HanningWindow. + */ + WindowType getWindowType() const; + + /** + * Set the current window shape. + */ + void setWindowType(WindowType type); + + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginInputDomainAdapter.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginLoader.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,243 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_LOADER_H_ +#define _VAMP_PLUGIN_LOADER_H_ + +#include <vector> +#include <string> +#include <map> + +#include "hostguard.h" +#include "PluginWrapper.h" + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginLoader.h) + +namespace Vamp { + +class Plugin; + +namespace HostExt { + +/** + * \class PluginLoader PluginLoader.h <vamp-hostsdk/PluginLoader.h> + * + * Vamp::HostExt::PluginLoader is a convenience class for discovering + * and loading Vamp plugins using the typical plugin-path, library + * naming, and categorisation conventions described in the Vamp SDK + * documentation. This class is intended to greatly simplify the task + * of becoming a Vamp plugin host for any C++ application. + * + * Hosts are not required by the Vamp specification to use the same + * plugin search path and naming conventions as implemented by this + * class, and are certainly not required to use this actual class. + * But we do strongly recommend it. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginLoader +{ +public: + /** + * Obtain a pointer to the singleton instance of PluginLoader. + * Use this to obtain your loader object. + */ + static PluginLoader *getInstance(); + + /** + * PluginKey is a string type that is used to identify a plugin + * uniquely within the scope of "the current system". It consists + * of the lower-cased base name of the plugin library, a colon + * separator, and the identifier string for the plugin. It is + * only meaningful in the context of a given plugin path (the one + * returned by PluginHostAdapter::getPluginPath()). + * + * Use composePluginKey() to construct a plugin key from a known + * plugin library name and identifier. + * + * Note: the fact that the library component of the key is + * lower-cased implies that library names are matched + * case-insensitively by the PluginLoader class, regardless of the + * case sensitivity of the underlying filesystem. (Plugin + * identifiers _are_ case sensitive, however.) Also, it is not + * possible to portably extract a working library name from a + * plugin key, as the result may fail on case-sensitive + * filesystems. Use getLibraryPathForPlugin() instead. + */ + typedef std::string PluginKey; + + /** + * PluginKeyList is a sequence of plugin keys, such as returned by + * listPlugins(). + */ + typedef std::vector<PluginKey> PluginKeyList; + + /** + * PluginCategoryHierarchy is a sequence of general->specific + * category names, as may be associated with a single plugin. + * This sequence describes the location of a plugin within a + * category forest, containing the human-readable names of the + * plugin's category tree root, followed by each of the nodes down + * to the leaf containing the plugin. + * + * \see getPluginCategory() + */ + typedef std::vector<std::string> PluginCategoryHierarchy; + + /** + * Search for all available Vamp plugins, and return a list of + * them in the order in which they were found. + */ + PluginKeyList listPlugins(); + + /** + * AdapterFlags contains a set of values that may be OR'd together + * to indicate in which circumstances PluginLoader should use a + * plugin adapter to make a plugin easier to use for a host that + * does not want to cater for complex features. + * + * The available flags are: + * + * ADAPT_INPUT_DOMAIN - If the plugin expects frequency domain + * input, wrap it in a PluginInputDomainAdapter that automatically + * converts the plugin to one that expects time-domain input. + * This enables a host to accommodate time- and frequency-domain + * plugins without needing to do any conversion itself. + * + * ADAPT_CHANNEL_COUNT - Wrap the plugin in a PluginChannelAdapter + * to handle any mismatch between the number of channels of audio + * the plugin can handle and the number available in the host. + * This enables a host to use plugins that may require the input + * to be mixed down to mono, etc., without having to worry about + * doing that itself. + * + * ADAPT_BUFFER_SIZE - Wrap the plugin in a PluginBufferingAdapter + * permitting the host to provide audio input using any block + * size, with no overlap, regardless of the plugin's preferred + * block size (suitable for hosts that read from non-seekable + * streaming media, for example). This adapter introduces some + * run-time overhead and also changes the semantics of the plugin + * slightly (see the PluginBufferingAdapter header documentation + * for details). + * + * ADAPT_ALL_SAFE - Perform all available adaptations that are + * meaningful for the plugin and "safe". Currently this means to + * ADAPT_INPUT_DOMAIN if the plugin wants FrequencyDomain input; + * ADAPT_CHANNEL_COUNT always; and ADAPT_BUFFER_SIZE never. + * + * ADAPT_ALL - Perform all available adaptations that are + * meaningful for the plugin. + * + * See PluginInputDomainAdapter, PluginChannelAdapter and + * PluginBufferingAdapter for more details of the classes that the + * loader may use if these flags are set. + */ + enum AdapterFlags { + + ADAPT_INPUT_DOMAIN = 0x01, + ADAPT_CHANNEL_COUNT = 0x02, + ADAPT_BUFFER_SIZE = 0x04, + + ADAPT_ALL_SAFE = 0x03, + + ADAPT_ALL = 0xff + }; + + /** + * Load a Vamp plugin, given its identifying key. If the plugin + * could not be loaded, returns 0. + * + * The returned plugin should be deleted (using the standard C++ + * delete keyword) after use. + * + * \param adapterFlags a bitwise OR of the values in the AdapterFlags + * enumeration, indicating under which circumstances an adapter should be + * used to wrap the original plugin. If adapterFlags is 0, no + * optional adapters will be used. Otherwise, the returned plugin + * may be of an adapter class type which will behave identically + * to the original plugin, apart from any particular features + * implemented by the adapter itself. + * + * \see AdapterFlags, PluginInputDomainAdapter, PluginChannelAdapter + */ + Plugin *loadPlugin(PluginKey key, + float inputSampleRate, + int adapterFlags = 0); + + /** + * Given a Vamp plugin library name and plugin identifier, return + * the corresponding plugin key in a form suitable for passing in to + * loadPlugin(). + */ + PluginKey composePluginKey(std::string libraryName, + std::string identifier); + + /** + * Return the category hierarchy for a Vamp plugin, given its + * identifying key. + * + * If the plugin has no category information, return an empty + * hierarchy. + * + * \see PluginCategoryHierarchy + */ + PluginCategoryHierarchy getPluginCategory(PluginKey plugin); + + /** + * Return the file path of the dynamic library from which the + * given plugin will be loaded (if available). + */ + std::string getLibraryPathForPlugin(PluginKey plugin); + +protected: + PluginLoader(); + virtual ~PluginLoader(); + + class Impl; + Impl *m_impl; + + static PluginLoader *m_instance; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginLoader.h) + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginSummarisingAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,197 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_SUMMARISING_ADAPTER_H_ +#define _VAMP_PLUGIN_SUMMARISING_ADAPTER_H_ + +#include "hostguard.h" +#include "PluginWrapper.h" + +#include <set> + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginSummarisingAdapter.h) + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginSummarisingAdapter PluginSummarisingAdapter.h <vamp-hostsdk/PluginSummarisingAdapter.h> + * + * PluginSummarisingAdapter is a Vamp plugin adapter that provides + * summarisation methods such as mean and median averages of output + * features, for use in any context where an available plugin produces + * individual values but the result that is actually needed is some + * sort of aggregate. + * + * To make use of PluginSummarisingAdapter, the host should configure, + * initialise and run the plugin through the adapter interface just as + * normal. Then, after the process and getRemainingFeatures methods + * have been properly called and processing is complete, the host may + * call getSummaryForOutput or getSummaryForAllOutputs to obtain + * summarised features: averages, maximum values, etc, depending on + * the SummaryType passed to the function. + * + * By default PluginSummarisingAdapter calculates a single summary of + * each output's feature across the whole duration of processed audio. + * A host needing summaries of sub-segments of the whole audio may + * call setSummarySegmentBoundaries before retrieving the summaries, + * providing a list of times such that one summary will be provided + * for each segment between two consecutive times. + * + * PluginSummarisingAdapter is straightforward rather than fast. It + * calculates all of the summary types for all outputs always, and + * then returns only the ones that are requested. It is designed on + * the basis that, for most features, summarising and storing + * summarised results is far cheaper than calculating the results in + * the first place. If this is not true for your particular feature, + * PluginSummarisingAdapter may not be the best approach for you. + * + * \note This class was introduced in version 2.0 of the Vamp plugin SDK. + */ + +class PluginSummarisingAdapter : public PluginWrapper +{ +public: + /** + * Construct a PluginSummarisingAdapter wrapping the given plugin. + * The adapter takes ownership of the plugin, which will be + * deleted when the adapter is deleted. + */ + PluginSummarisingAdapter(Plugin *plugin); + virtual ~PluginSummarisingAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + void reset(); + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + FeatureSet getRemainingFeatures(); + + typedef std::set<RealTime> SegmentBoundaries; + + /** + * Specify a series of segment boundaries, such that one summary + * will be returned for each of the contiguous intra-boundary + * segments. This function must be called before + * getSummaryForOutput or getSummaryForAllOutputs. + * + * Note that you cannot retrieve results with multiple different + * segmentations by repeatedly calling this function followed by + * one of the getSummary functions. The summaries are all + * calculated at the first call to any getSummary function, and + * once the summaries have been calculated, they remain + * calculated. + */ + void setSummarySegmentBoundaries(const SegmentBoundaries &); + + enum SummaryType { + Minimum = 0, + Maximum = 1, + Mean = 2, + Median = 3, + Mode = 4, + Sum = 5, + Variance = 6, + StandardDeviation = 7, + Count = 8, + + UnknownSummaryType = 999 + }; + + /** + * AveragingMethod indicates how the adapter should handle + * average-based summaries of features whose results are not + * equally spaced in time. + * + * If SampleAverage is specified, summary types based on averages + * will be calculated by treating each result individually without + * regard to its time: for example, the mean will be the sum of + * all values divided by the number of values. + * + * If ContinuousTimeAverage is specified, each feature will be + * considered to have a duration, either as specified in the + * feature's duration field, or until the following feature: thus, + * for example, the mean will be the sum of the products of values + * and durations, divided by the total duration. + * + * Although SampleAverage is useful for many types of feature, + * ContinuousTimeAverage is essential for some situations, for + * example finding the result that spans the largest proportion of + * the input given a feature that emits a new result only when the + * value changes (the modal value integrated over time). + */ + enum AveragingMethod { + SampleAverage = 0, + ContinuousTimeAverage = 1 + }; + + /** + * Return summaries of the features that were returned on the + * given output, using the given SummaryType and AveragingMethod. + * + * The plugin must have been fully run (process() and + * getRemainingFeatures() calls all made as appropriate) before + * this function is called. + */ + FeatureList getSummaryForOutput(int output, + SummaryType type, + AveragingMethod method = SampleAverage); + + /** + * Return summaries of the features that were returned on all of + * the plugin's outputs, using the given SummaryType and + * AveragingMethod. + * + * The plugin must have been fully run (process() and + * getRemainingFeatures() calls all made as appropriate) before + * this function is called. + */ + FeatureSet getSummaryForAllOutputs(SummaryType type, + AveragingMethod method = SampleAverage); + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginSummarisingAdapter.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/PluginWrapper.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,135 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2009 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_WRAPPER_H_ +#define _VAMP_PLUGIN_WRAPPER_H_ + +#include "hostguard.h" +#include <vamp-hostsdk/Plugin.h> + +_VAMP_SDK_HOSTSPACE_BEGIN(PluginWrapper.h) + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginWrapper PluginWrapper.h <vamp-hostsdk/PluginWrapper.h> + * + * PluginWrapper is a simple base class for adapter plugins. It takes + * a pointer to a "to be wrapped" Vamp plugin on construction, and + * provides implementations of all the Vamp plugin methods that simply + * delegate through to the wrapped plugin. A subclass can therefore + * override only the methods that are meaningful for the particular + * adapter. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginWrapper : public Plugin +{ +public: + virtual ~PluginWrapper(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + unsigned int getVampApiVersion() const; + std::string getIdentifier() const; + std::string getName() const; + std::string getDescription() const; + std::string getMaker() const; + int getPluginVersion() const; + std::string getCopyright() const; + + ParameterList getParameterDescriptors() const; + float getParameter(std::string) const; + void setParameter(std::string, float); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + size_t getMinChannelCount() const; + size_t getMaxChannelCount() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + + /** + * Return a pointer to the plugin wrapper of type WrapperType + * surrounding this wrapper's plugin, if present. + * + * This is useful in situations where a plugin is wrapped by + * multiple different wrappers (one inside another) and the host + * wants to call some wrapper-specific function on one of the + * layers without having to care about the order in which they are + * wrapped. For example, the plugin returned by + * PluginLoader::loadPlugin may have more than one wrapper; if the + * host wanted to query or fine-tune some property of one of them, + * it would be hard to do so without knowing the order of the + * wrappers. This function therefore gives direct access to the + * wrapper of a particular type. + */ + template <typename WrapperType> + WrapperType *getWrapper() { + WrapperType *w = dynamic_cast<WrapperType *>(this); + if (w) return w; + PluginWrapper *pw = dynamic_cast<PluginWrapper *>(m_plugin); + if (pw) return pw->getWrapper<WrapperType>(); + return 0; + } + +protected: + PluginWrapper(Plugin *plugin); // I take ownership of plugin + Plugin *m_plugin; +}; + +} + +} + +_VAMP_SDK_HOSTSPACE_END(PluginWrapper.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/RealTime.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,46 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_HOSTSDK_REALTIME_H_ +#define _VAMP_HOSTSDK_REALTIME_H_ + +// Do not include vamp-sdk/RealTime.h directly from host code. Always +// use this header instead. + +#include "hostguard.h" +#include <vamp-sdk/RealTime.h> + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/hostguard.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,73 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_HOSTSDK_HOSTGUARD_H_ +#define _VAMP_HOSTSDK_HOSTGUARD_H_ + +#ifdef _VAMP_IN_PLUGINSDK +#error You have included headers from both vamp-sdk and vamp-hostsdk in the same source file. Please include only vamp-sdk headers in plugin code, and only vamp-hostsdk headers in host code. +#else + +#define _VAMP_IN_HOSTSDK + +#define VAMP_SDK_VERSION "2.5" +#define VAMP_SDK_MAJOR_VERSION 2 +#define VAMP_SDK_MINOR_VERSION 5 + +#ifdef _VAMP_NO_HOST_NAMESPACE +#define _VAMP_SDK_HOSTSPACE_BEGIN(h) +#define _VAMP_SDK_HOSTSPACE_END(h) +#define _VAMP_SDK_PLUGSPACE_BEGIN(h) +#define _VAMP_SDK_PLUGSPACE_END(h) +#else +#define _VAMP_SDK_HOSTSPACE_BEGIN(h) \ + namespace _VampHost { + +#define _VAMP_SDK_HOSTSPACE_END(h) \ + } \ + using namespace _VampHost; +#define _VAMP_SDK_PLUGSPACE_BEGIN(h) \ + namespace _VampHost { + +#define _VAMP_SDK_PLUGSPACE_END(h) \ + } \ + using namespace _VampHost; +#endif + +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-hostsdk/vamp-hostsdk.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,53 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_HOSTSDK_SINGLE_INCLUDE_H_ +#define _VAMP_HOSTSDK_SINGLE_INCLUDE_H_ + +#include "PluginBase.h" +#include "PluginBufferingAdapter.h" +#include "PluginChannelAdapter.h" +#include "Plugin.h" +#include "PluginHostAdapter.h" +#include "PluginInputDomainAdapter.h" +#include "PluginLoader.h" +#include "PluginSummarisingAdapter.h" +#include "PluginWrapper.h" +#include "RealTime.h" + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/FFT.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,98 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2012 Chris Cannam and QMUL. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_FFT_H_ +#define _VAMP_FFT_H_ + +#include "plugguard.h" +_VAMP_SDK_PLUGSPACE_BEGIN(FFT.h) + +namespace Vamp { + +/** + * A simple FFT implementation provided for convenience of plugin + * authors. + * + * This class provides double-precision FFTs in power-of-two sizes + * only. It is slower than more sophisticated library + * implementations. If these requirements aren't suitable, make other + * arrangements. + * + * The inverse transform is scaled by 1/n. + * + * The implementation is from Don Cross's public domain FFT code. + */ +class FFT +{ +public: + /** + * Calculate a forward transform of size n. + * + * ri and ii must point to the real and imaginary component arrays + * of the input. For real input, ii may be NULL. + * + * ro and io must point to enough space to receive the real and + * imaginary component arrays of the output. + * + * All input and output arrays are of size n. + */ + static void forward(unsigned int n, + const double *ri, const double *ii, + double *ro, double *io); + + /** + * Calculate an inverse transform of size n. + * + * ri and ii must point to the real and imaginary component arrays + * of the input. For real input, ii may be NULL. + * + * ro and io must point to enough space to receive the real and + * imaginary component arrays of the output. The output is scaled + * by 1/n. The output pointers may not be NULL, even if the output + * is expected to be real. + * + * All input and output arrays are of size n. + */ + static void inverse(unsigned int n, + const double *ri, const double *ii, + double *ro, double *io); +}; + +} + +_VAMP_SDK_PLUGSPACE_END(FFT.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/Plugin.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,446 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_SDK_PLUGIN_H_ +#define _VAMP_SDK_PLUGIN_H_ + +#include <string> +#include <vector> +#include <map> + +#include "PluginBase.h" +#include "RealTime.h" + +#include "plugguard.h" +_VAMP_SDK_PLUGSPACE_BEGIN(Plugin.h) + +namespace Vamp { + +/** + * \class Plugin Plugin.h <vamp-sdk/Plugin.h> + * + * Vamp::Plugin is a base class for plugin instance classes + * that provide feature extraction from audio or related data. + * + * In most cases, the input will be audio and the output will be a + * stream of derived data at a lower sampling resolution than the + * input. + * + * Note that this class inherits several abstract methods from + * PluginBase. These must be implemented by the subclass. + * + * + * PLUGIN LIFECYCLE + * + * Feature extraction plugins are managed differently from real-time + * plugins (such as VST effects). The main difference is that the + * parameters for a feature extraction plugin are configured before + * the plugin is used, and do not change during use. + * + * 1. Host constructs the plugin, passing it the input sample rate. + * The plugin may do basic initialisation, but should not do anything + * computationally expensive at this point. You must make sure your + * plugin is cheap to construct, otherwise you'll seriously affect the + * startup performance of almost all hosts. If you have serious + * initialisation to do, the proper place is in initialise() (step 5). + * + * 2. Host may query the plugin's available outputs. + * + * 3. Host queries programs and parameter descriptors, and may set + * some or all of them. Parameters that are not explicitly set should + * take their default values as specified in the parameter descriptor. + * When a program is set, the parameter values may change and the host + * will re-query them to check. + * + * 4. Host queries the preferred step size, block size and number of + * channels. These may all vary depending on the parameter values. + * (Note however that you cannot make the number of distinct outputs + * dependent on parameter values.) + * + * 5. Plugin is properly initialised with a call to initialise. This + * fixes the step size, block size, and number of channels, as well as + * all of the parameter and program settings. If the values passed in + * to initialise do not match the plugin's advertised preferred values + * from step 4, the plugin may refuse to initialise and return false + * (although if possible it should accept the new values). Any + * computationally expensive setup code should take place here. + * + * 6. Host finally checks the number of values, resolution, extents + * etc per output (which may vary depending on the number of channels, + * step size and block size as well as the parameter values). + * + * 7. Host will repeatedly call the process method to pass in blocks + * of input data. This method may return features extracted from that + * data (if the plugin is causal). + * + * 8. Host will call getRemainingFeatures exactly once, after all the + * input data has been processed. This may return any non-causal or + * leftover features. + * + * 9. At any point after initialise was called, the host may + * optionally call the reset method and restart processing. (This + * does not mean it can change the parameters, which are fixed from + * initialise until destruction.) + * + * A plugin does not need to handle the case where setParameter or + * selectProgram is called after initialise has been called. It's the + * host's responsibility not to do that. Similarly, the plugin may + * safely assume that initialise is called no more than once. + */ + +class Plugin : public PluginBase +{ +public: + virtual ~Plugin() { } + + /** + * Initialise a plugin to prepare it for use with the given number + * of input channels, step size (window increment, in sample + * frames) and block size (window size, in sample frames). + * + * The input sample rate should have been already specified at + * construction time. + * + * Return true for successful initialisation, false if the number + * of input channels, step size and/or block size cannot be + * supported. + */ + virtual bool initialise(size_t inputChannels, + size_t stepSize, + size_t blockSize) = 0; + + /** + * Reset the plugin after use, to prepare it for another clean + * run. Not called for the first initialisation (i.e. initialise + * must also do a reset). + */ + virtual void reset() = 0; + + enum InputDomain { TimeDomain, FrequencyDomain }; + + /** + * Get the plugin's required input domain. + * + * If this is TimeDomain, the samples provided to the process() + * function (below) will be in the time domain, as for a + * traditional audio processing plugin. + * + * If this is FrequencyDomain, the host will carry out a windowed + * FFT of size equal to the negotiated block size on the data + * before passing the frequency bin data in to process(). The + * input data for the FFT will be rotated so as to place the + * origin in the centre of the block. + * The plugin does not get to choose the window type -- the host + * will either let the user do so, or will use a Hanning window. + */ + virtual InputDomain getInputDomain() const = 0; + + /** + * Get the preferred block size (window size -- the number of + * sample frames passed in each block to the process() function). + * This should be called before initialise(). + * + * A plugin that can handle any block size may return 0. The + * final block size will be set in the initialise() call. + */ + virtual size_t getPreferredBlockSize() const { return 0; } + + /** + * Get the preferred step size (window increment -- the distance + * in sample frames between the start frames of consecutive blocks + * passed to the process() function) for the plugin. This should + * be called before initialise(). + * + * A plugin may return 0 if it has no particular interest in the + * step size. In this case, the host should make the step size + * equal to the block size if the plugin is accepting input in the + * time domain. If the plugin is accepting input in the frequency + * domain, the host may use any step size. The final step size + * will be set in the initialise() call. + */ + virtual size_t getPreferredStepSize() const { return 0; } + + /** + * Get the minimum supported number of input channels. + */ + virtual size_t getMinChannelCount() const { return 1; } + + /** + * Get the maximum supported number of input channels. + */ + virtual size_t getMaxChannelCount() const { return 1; } + + struct OutputDescriptor + { + /** + * The name of the output, in computer-usable form. Should be + * reasonably short and without whitespace or punctuation, using + * the characters [a-zA-Z0-9_-] only. + * Example: "zero_crossing_count" + */ + std::string identifier; + + /** + * The human-readable name of the output. + * Example: "Zero Crossing Counts" + */ + std::string name; + + /** + * A human-readable short text describing the output. May be + * empty if the name has said it all already. + * Example: "The number of zero crossing points per processing block" + */ + std::string description; + + /** + * The unit of the output, in human-readable form. + */ + std::string unit; + + /** + * True if the output has the same number of values per sample + * for every output sample. Outputs for which this is false + * are unlikely to be very useful in a general-purpose host. + */ + bool hasFixedBinCount; + + /** + * The number of values per result of the output. Undefined + * if hasFixedBinCount is false. If this is zero, the output + * is point data (i.e. only the time of each output is of + * interest, the value list will be empty). + */ + size_t binCount; + + /** + * The (human-readable) names of each of the bins, if + * appropriate. This is always optional. + */ + std::vector<std::string> binNames; + + /** + * True if the results in each output bin fall within a fixed + * numeric range (minimum and maximum values). Undefined if + * binCount is zero. + */ + bool hasKnownExtents; + + /** + * Minimum value of the results in the output. Undefined if + * hasKnownExtents is false or binCount is zero. + */ + float minValue; + + /** + * Maximum value of the results in the output. Undefined if + * hasKnownExtents is false or binCount is zero. + */ + float maxValue; + + /** + * True if the output values are quantized to a particular + * resolution. Undefined if binCount is zero. + */ + bool isQuantized; + + /** + * Quantization resolution of the output values (e.g. 1.0 if + * they are all integers). Undefined if isQuantized is false + * or binCount is zero. + */ + float quantizeStep; + + enum SampleType { + + /// Results from each process() align with that call's block start + OneSamplePerStep, + + /// Results are evenly spaced in time (sampleRate specified below) + FixedSampleRate, + + /// Results are unevenly spaced and have individual timestamps + VariableSampleRate + }; + + /** + * Positioning in time of the output results. + */ + SampleType sampleType; + + /** + * Sample rate of the output results, as samples per second. + * Undefined if sampleType is OneSamplePerStep. + * + * If sampleType is VariableSampleRate and this value is + * non-zero, then it may be used to calculate a resolution for + * the output (i.e. the "duration" of each sample, in time, + * will be 1/sampleRate seconds). It's recommended to set + * this to zero if that behaviour is not desired. + */ + float sampleRate; + + /** + * True if the returned results for this output are known to + * have a duration field. + */ + bool hasDuration; + + OutputDescriptor() : // defaults for mandatory non-class-type members + hasFixedBinCount(false), hasKnownExtents(false), isQuantized(false), + sampleType(OneSamplePerStep), sampleRate(0), hasDuration(false) { } + }; + + typedef std::vector<OutputDescriptor> OutputList; + + /** + * Get the outputs of this plugin. An output's index in this list + * is used as its numeric index when looking it up in the + * FeatureSet returned from the process() call. + */ + virtual OutputList getOutputDescriptors() const = 0; + + struct Feature + { + /** + * True if an output feature has its own timestamp. This is + * mandatory if the output has VariableSampleRate, optional if + * the output has FixedSampleRate, and unused if the output + * has OneSamplePerStep. + */ + bool hasTimestamp; + + /** + * Timestamp of the output feature. This is mandatory if the + * output has VariableSampleRate or if the output has + * FixedSampleRate and hasTimestamp is true, and unused + * otherwise. + */ + RealTime timestamp; + + /** + * True if an output feature has a specified duration. This + * is optional if the output has VariableSampleRate or + * FixedSampleRate, and and unused if the output has + * OneSamplePerStep. + */ + bool hasDuration; + + /** + * Duration of the output feature. This is mandatory if the + * output has VariableSampleRate or FixedSampleRate and + * hasDuration is true, and unused otherwise. + */ + RealTime duration; + + /** + * Results for a single sample of this feature. If the output + * hasFixedBinCount, there must be the same number of values + * as the output's binCount count. + */ + std::vector<float> values; + + /** + * Label for the sample of this feature. + */ + std::string label; + + Feature() : // defaults for mandatory non-class-type members + hasTimestamp(false), hasDuration(false) { } + }; + + typedef std::vector<Feature> FeatureList; + + typedef std::map<int, FeatureList> FeatureSet; // key is output no + + /** + * Process a single block of input data. + * + * If the plugin's inputDomain is TimeDomain, inputBuffers will + * point to one array of floats per input channel, and each of + * these arrays will contain blockSize consecutive audio samples + * (the host will zero-pad as necessary). The timestamp in this + * case will be the real time in seconds of the start of the + * supplied block of samples. + * + * If the plugin's inputDomain is FrequencyDomain, inputBuffers + * will point to one array of floats per input channel, and each + * of these arrays will contain blockSize/2+1 consecutive pairs of + * real and imaginary component floats corresponding to bins + * 0..(blockSize/2) of the FFT output. That is, bin 0 (the first + * pair of floats) contains the DC output, up to bin blockSize/2 + * which contains the Nyquist-frequency output. There will + * therefore be blockSize+2 floats per channel in total. The + * timestamp will be the real time in seconds of the centre of the + * FFT input window (i.e. the very first block passed to process + * might contain the FFT of half a block of zero samples and the + * first half-block of the actual data, with a timestamp of zero). + * + * Return any features that have become available after this + * process call. (These do not necessarily have to fall within + * the process block, except for OneSamplePerStep outputs.) + */ + virtual FeatureSet process(const float *const *inputBuffers, + RealTime timestamp) = 0; + + /** + * After all blocks have been processed, calculate and return any + * remaining features derived from the complete input. + */ + virtual FeatureSet getRemainingFeatures() = 0; + + /** + * Used to distinguish between Vamp::Plugin and other potential + * sibling subclasses of PluginBase. Do not reimplement this + * function in your subclass. + */ + virtual std::string getType() const { return "Feature Extraction Plugin"; } + +protected: + Plugin(float inputSampleRate) : + m_inputSampleRate(inputSampleRate) { } + + float m_inputSampleRate; +}; + +} + +_VAMP_SDK_PLUGSPACE_END(Plugin.h) + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/PluginAdapter.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,121 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_ADAPTER_H_ +#define _VAMP_PLUGIN_ADAPTER_H_ + +#include <map> +#include <vamp/vamp.h> + +#include "Plugin.h" + +#include "plugguard.h" +_VAMP_SDK_PLUGSPACE_BEGIN(PluginAdapter.h) + +namespace Vamp { + +/** + * \class PluginAdapterBase PluginAdapter.h <vamp-sdk/PluginAdapter.h> + * + * PluginAdapter and PluginAdapterBase provide a wrapper class that a + * plugin library can use to make its C++ Vamp::Plugin objects + * available through the Vamp C API. + * + * Almost all Vamp plugin libraries will want to make use of this. To + * do so, all they need to do is declare a PluginAdapter<T> for each + * plugin class T in their library. It's very simple, and you need to + * know absolutely nothing about how it works in order to use it. + * Just cut and paste from an existing plugin's discovery function. + * \see vampGetPluginDescriptor + */ + +class PluginAdapterBase +{ +public: + virtual ~PluginAdapterBase(); + + /** + * Return a VampPluginDescriptor describing the plugin that is + * wrapped by this adapter. + */ + const VampPluginDescriptor *getDescriptor(); + +protected: + PluginAdapterBase(); + + virtual Plugin *createPlugin(float inputSampleRate) = 0; + + class Impl; + Impl *m_impl; +}; + +/** + * \class PluginAdapter PluginAdapter.h <vamp-sdk/PluginAdapter.h> + * + * PluginAdapter turns a PluginAdapterBase into a specific wrapper for + * a particular plugin implementation. + * + * See PluginAdapterBase. + */ + +template <typename P> +class PluginAdapter : public PluginAdapterBase +{ +public: + PluginAdapter() : PluginAdapterBase() { } + virtual ~PluginAdapter() { } + +protected: + Plugin *createPlugin(float inputSampleRate) { + P *p = new P(inputSampleRate); + Plugin *plugin = dynamic_cast<Plugin *>(p); + if (!plugin) { + std::cerr << "ERROR: PluginAdapter::createPlugin: " + << "Template type is not a plugin!" + << std::endl; + delete p; + return 0; + } + return plugin; + } +}; + +} + +_VAMP_SDK_PLUGSPACE_END(PluginAdapter.h) + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/PluginBase.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,258 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_SDK_PLUGIN_BASE_H_ +#define _VAMP_SDK_PLUGIN_BASE_H_ + +#include <string> +#include <vector> + +#include "plugguard.h" +_VAMP_SDK_PLUGSPACE_BEGIN(PluginBase.h) + +namespace Vamp { + +/** + * A base class for plugins with optional configurable parameters, + * programs, etc. The Vamp::Plugin is derived from this, and + * individual Vamp plugins should derive from that. + * + * This class does not provide the necessary interfaces to instantiate + * or run a plugin. It only specifies an interface for retrieving + * those controls that the host may wish to show to the user for + * editing. It could meaningfully be subclassed by real-time plugins + * or other sorts of plugin as well as Vamp plugins. + */ + +class PluginBase +{ +public: + virtual ~PluginBase() { } + + /** + * Get the Vamp API compatibility level of the plugin. + */ + virtual unsigned int getVampApiVersion() const { return 2; } + + /** + * Get the computer-usable name of the plugin. This should be + * reasonably short and contain no whitespace or punctuation + * characters. It may only contain the characters [a-zA-Z0-9_-]. + * This is the authoritative way for a program to identify a + * plugin within a given library. + * + * This text may be visible to the user, but it should not be the + * main text used to identify a plugin to the user (that will be + * the name, below). + * + * Example: "zero_crossings" + */ + virtual std::string getIdentifier() const = 0; + + /** + * Get a human-readable name or title of the plugin. This + * should be brief and self-contained, as it may be used to + * identify the plugin to the user in isolation (i.e. without also + * showing the plugin's "identifier"). + * + * Example: "Zero Crossings" + */ + virtual std::string getName() const = 0; + + /** + * Get a human-readable description for the plugin, typically + * a line of text that may optionally be displayed in addition + * to the plugin's "name". May be empty if the name has said + * it all already. + * + * Example: "Detect and count zero crossing points" + */ + virtual std::string getDescription() const = 0; + + /** + * Get the name of the author or vendor of the plugin in + * human-readable form. This should be a short identifying text, + * as it may be used to label plugins from the same source in a + * menu or similar. + */ + virtual std::string getMaker() const = 0; + + /** + * Get the copyright statement or licensing summary for the + * plugin. This can be an informative text, without the same + * presentation constraints as mentioned for getMaker above. + */ + virtual std::string getCopyright() const = 0; + + /** + * Get the version number of the plugin. + */ + virtual int getPluginVersion() const = 0; + + + struct ParameterDescriptor + { + /** + * The name of the parameter, in computer-usable form. Should + * be reasonably short, and may only contain the characters + * [a-zA-Z0-9_-]. + */ + std::string identifier; + + /** + * The human-readable name of the parameter. + */ + std::string name; + + /** + * A human-readable short text describing the parameter. May be + * empty if the name has said it all already. + */ + std::string description; + + /** + * The unit of the parameter, in human-readable form. + */ + std::string unit; + + /** + * The minimum value of the parameter. + */ + float minValue; + + /** + * The maximum value of the parameter. + */ + float maxValue; + + /** + * The default value of the parameter. The plugin should + * ensure that parameters have this value on initialisation + * (i.e. the host is not required to explicitly set parameters + * if it wants to use their default values). + */ + float defaultValue; + + /** + * True if the parameter values are quantized to a particular + * resolution. + */ + bool isQuantized; + + /** + * Quantization resolution of the parameter values (e.g. 1.0 + * if they are all integers). Undefined if isQuantized is + * false. + */ + float quantizeStep; + + /** + * Names for the quantized values. If isQuantized is true, + * this may either be empty or contain one string for each of + * the quantize steps from minValue up to maxValue inclusive. + * Undefined if isQuantized is false. + * + * If these names are provided, they should be shown to the + * user in preference to the values themselves. The user may + * never see the actual numeric values unless they are also + * encoded in the names. + */ + std::vector<std::string> valueNames; + + ParameterDescriptor() : // the defaults are invalid: you must set them + minValue(0), maxValue(0), defaultValue(0), isQuantized(false) { } + }; + + typedef std::vector<ParameterDescriptor> ParameterList; + + /** + * Get the controllable parameters of this plugin. + */ + virtual ParameterList getParameterDescriptors() const { + return ParameterList(); + } + + /** + * Get the value of a named parameter. The argument is the identifier + * field from that parameter's descriptor. + */ + virtual float getParameter(std::string) const { return 0.0; } + + /** + * Set a named parameter. The first argument is the identifier field + * from that parameter's descriptor. + */ + virtual void setParameter(std::string, float) { } + + + typedef std::vector<std::string> ProgramList; + + /** + * Get the program settings available in this plugin. A program + * is a named shorthand for a set of parameter values; changing + * the program may cause the plugin to alter the values of its + * published parameters (and/or non-public internal processing + * parameters). The host should re-read the plugin's parameter + * values after setting a new program. + * + * The programs must have unique names. + */ + virtual ProgramList getPrograms() const { return ProgramList(); } + + /** + * Get the current program. + */ + virtual std::string getCurrentProgram() const { return ""; } + + /** + * Select a program. (If the given program name is not one of the + * available programs, do nothing.) + */ + virtual void selectProgram(std::string) { } + + /** + * Get the type of plugin. This is to be implemented by the + * immediate subclass, not by actual plugins. Do not attempt to + * implement this in plugin code. + */ + virtual std::string getType() const = 0; +}; + +} + +_VAMP_SDK_PLUGSPACE_END(PluginBase.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/RealTime.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,167 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2006 Chris Cannam. + Relicensed by the author as detailed above. +*/ + +#ifndef _VAMP_REAL_TIME_H_ +#define _VAMP_REAL_TIME_H_ + +#include <iostream> +#include <string> + +#ifndef _WIN32 +struct timeval; +#endif + +#include "plugguard.h" +_VAMP_SDK_PLUGSPACE_BEGIN(RealTime.h) + +namespace Vamp { + +/** + * \class RealTime RealTime.h <vamp-sdk/RealTime.h> + * + * RealTime represents time values to nanosecond precision + * with accurate arithmetic and frame-rate conversion functions. + */ + +struct RealTime +{ + int sec; + int nsec; + + int usec() const { return nsec / 1000; } + int msec() const { return nsec / 1000000; } + + RealTime(): sec(0), nsec(0) {} + RealTime(int s, int n); + + RealTime(const RealTime &r) : + sec(r.sec), nsec(r.nsec) { } + + static RealTime fromSeconds(double sec); + static RealTime fromMilliseconds(int msec); + +#ifndef _WIN32 + static RealTime fromTimeval(const struct timeval &); +#endif + + RealTime &operator=(const RealTime &r) { + sec = r.sec; nsec = r.nsec; return *this; + } + + RealTime operator+(const RealTime &r) const { + return RealTime(sec + r.sec, nsec + r.nsec); + } + RealTime operator-(const RealTime &r) const { + return RealTime(sec - r.sec, nsec - r.nsec); + } + RealTime operator-() const { + return RealTime(-sec, -nsec); + } + + bool operator <(const RealTime &r) const { + if (sec == r.sec) return nsec < r.nsec; + else return sec < r.sec; + } + + bool operator >(const RealTime &r) const { + if (sec == r.sec) return nsec > r.nsec; + else return sec > r.sec; + } + + bool operator==(const RealTime &r) const { + return (sec == r.sec && nsec == r.nsec); + } + + bool operator!=(const RealTime &r) const { + return !(r == *this); + } + + bool operator>=(const RealTime &r) const { + if (sec == r.sec) return nsec >= r.nsec; + else return sec >= r.sec; + } + + bool operator<=(const RealTime &r) const { + if (sec == r.sec) return nsec <= r.nsec; + else return sec <= r.sec; + } + + RealTime operator/(int d) const; + + /** + * Return the ratio of two times. + */ + double operator/(const RealTime &r) const; + + /** + * Return a human-readable debug-type string to full precision + * (probably not a format to show to a user directly) + */ + std::string toString() const; + + /** + * Return a user-readable string to the nearest millisecond + * in a form like HH:MM:SS.mmm + */ + std::string toText(bool fixedDp = false) const; + + /** + * Convert a RealTime into a sample frame at the given sample rate. + */ + static long realTime2Frame(const RealTime &r, unsigned int sampleRate); + + /** + * Convert a sample frame at the given sample rate into a RealTime. + */ + static RealTime frame2RealTime(long frame, unsigned int sampleRate); + + static const RealTime zeroTime; +}; + +std::ostream &operator<<(std::ostream &out, const RealTime &rt); + +} + +_VAMP_SDK_PLUGSPACE_END(RealTime.h) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/plugguard.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,102 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_SDK_PLUGGUARD_H_ +#define _VAMP_SDK_PLUGGUARD_H_ + +/** + * Normal usage should be: + * + * - Plugins include vamp-sdk/Plugin.h or vamp-sdk/PluginBase.h. + * These files include this header, which specifies an appropriate + * namespace for the plugin classes to avoid any risk of conflict + * with non-plugin class implementations in the host on load. + * + * - Hosts include vamp-hostsdk/Plugin.h, vamp-hostsdk/PluginBase.h, + * vamp-hostsdk/PluginHostAdapter, vamp-hostsdk/PluginLoader.h etc. + * These files include vamp-hostsdk/hostguard.h, which makes a note + * that we are in a host. A file such as vamp-hostsdk/Plugin.h + * then simply includes vamp-sdk/Plugin.h, and this guard header + * takes notice of the fact that it has been included from a host + * and leaves the plugin namespace unset. + * + * Problems will occur when a host includes files directly from the + * vamp-sdk directory. There are two reasons this might happen: + * mistake, perhaps owing to ignorance of the fact that this isn't + * allowed (particularly since it was the normal mechanism in v1 of + * the SDK); and a wish to incorporate plugin code directly into the + * host rather than having to load it. + * + * What if the host does include a vamp-sdk header by mistake? We can + * catch it if it's included before something from vamp-hostsdk. If + * it's included after something from vamp-hostsdk, it will work OK + * anyway. The remaining problem case is where nothing from + * vamp-hostsdk is included in the same file. We can't catch that. + */ + +#ifndef _VAMP_IN_HOSTSDK + +#define _VAMP_IN_PLUGINSDK 1 + +#define VAMP_SDK_VERSION "2.5" +#define VAMP_SDK_MAJOR_VERSION 2 +#define VAMP_SDK_MINOR_VERSION 5 + +#ifdef _VAMP_NO_PLUGIN_NAMESPACE +#define _VAMP_SDK_PLUGSPACE_BEGIN(h) +#define _VAMP_SDK_PLUGSPACE_END(h) +#else +#ifdef _VAMP_PLUGIN_IN_HOST_NAMESPACE +#define _VAMP_SDK_PLUGSPACE_BEGIN(h) \ + namespace _VampHost { + +#define _VAMP_SDK_PLUGSPACE_END(h) \ + } \ + using namespace _VampHost; +#else +#define _VAMP_SDK_PLUGSPACE_BEGIN(h) \ + namespace _VampPlugin { + +#define _VAMP_SDK_PLUGSPACE_END(h) \ + } \ + using namespace _VampPlugin; +#endif +#endif + +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp-sdk/vamp-sdk.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,47 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_SDK_SINGLE_INCLUDE_H_ +#define _VAMP_SDK_SINGLE_INCLUDE_H_ + +#include "PluginBase.h" +#include "Plugin.h" +#include "RealTime.h" +#include "FFT.h" + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/include/vamp/vamp.h Fri Jul 04 08:16:02 2014 +0100 @@ -0,0 +1,388 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + 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 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. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef VAMP_HEADER_INCLUDED +#define VAMP_HEADER_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Plugin API version. This is incremented when a change is made that + * changes the binary layout of the descriptor records. When this + * happens, there should be a mechanism for retaining compatibility + * with older hosts and/or plugins. + * + * See also the vampApiVersion field in the plugin descriptor, and the + * hostApiVersion argument to the vampGetPluginDescriptor function. + */ +#define VAMP_API_VERSION 2 + +/** + * C language API for Vamp plugins. + * + * This is the formal plugin API for Vamp. Plugin authors may prefer + * to use the C++ classes provided in the Vamp plugin SDK, instead of + * using this API directly. There is an adapter class provided that + * makes C++ plugins available using this C API with relatively little + * work, and the C++ headers are more thoroughly documented. + * + * IMPORTANT: The comments in this file summarise the purpose of each + * of the declared fields and functions, but do not provide a complete + * guide to their permitted values and expected usage. Please refer + * to the C++ headers in the Vamp plugin SDK for further details and + * plugin lifecycle documentation. + */ + +typedef struct _VampParameterDescriptor +{ + /** Computer-usable name of the parameter. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the parameter. May be translatable. */ + const char *name; + + /** Human-readable short text about the parameter. May be translatable. */ + const char *description; + + /** Human-readable unit of the parameter. */ + const char *unit; + + /** Minimum value. */ + float minValue; + + /** Maximum value. */ + float maxValue; + + /** Default value. Plugin is responsible for setting this on initialise. */ + float defaultValue; + + /** 1 if parameter values are quantized to a particular resolution. */ + int isQuantized; + + /** Quantization resolution, if isQuantized. */ + float quantizeStep; + + /** Human-readable names of the values, if isQuantized. May be NULL. */ + const char **valueNames; + +} VampParameterDescriptor; + +typedef enum +{ + /** Each process call returns results aligned with call's block start. */ + vampOneSamplePerStep, + + /** Returned results are evenly spaced at samplerate specified below. */ + vampFixedSampleRate, + + /** Returned results have their own individual timestamps. */ + vampVariableSampleRate + +} VampSampleType; + +typedef struct _VampOutputDescriptor +{ + /** Computer-usable name of the output. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the output. May be translatable. */ + const char *name; + + /** Human-readable short text about the output. May be translatable. */ + const char *description; + + /** Human-readable name of the unit of the output. */ + const char *unit; + + /** 1 if output has equal number of values for each returned result. */ + int hasFixedBinCount; + + /** Number of values per result, if hasFixedBinCount. */ + unsigned int binCount; + + /** Names of returned value bins, if hasFixedBinCount. May be NULL. */ + const char **binNames; + + /** 1 if each returned value falls within the same fixed min/max range. */ + int hasKnownExtents; + + /** Minimum value for a returned result in any bin, if hasKnownExtents. */ + float minValue; + + /** Maximum value for a returned result in any bin, if hasKnownExtents. */ + float maxValue; + + /** 1 if returned results are quantized to a particular resolution. */ + int isQuantized; + + /** Quantization resolution for returned results, if isQuantized. */ + float quantizeStep; + + /** Time positioning method for returned results (see VampSampleType). */ + VampSampleType sampleType; + + /** Sample rate of returned results, if sampleType is vampFixedSampleRate. + "Resolution" of result, if sampleType is vampVariableSampleRate. */ + float sampleRate; + + /** 1 if the returned results for this output are known to have a + duration field. + + This field is new in Vamp API version 2; it must not be tested + for plugins that report an older API version in their plugin + descriptor. + */ + int hasDuration; + +} VampOutputDescriptor; + +typedef struct _VampFeature +{ + /** 1 if the feature has a timestamp (i.e. if vampVariableSampleRate). */ + int hasTimestamp; + + /** Seconds component of timestamp. */ + int sec; + + /** Nanoseconds component of timestamp. */ + int nsec; + + /** Number of values. Must be binCount if hasFixedBinCount. */ + unsigned int valueCount; + + /** Values for this returned sample. */ + float *values; + + /** Label for this returned sample. May be NULL. */ + char *label; + +} VampFeature; + +typedef struct _VampFeatureV2 +{ + /** 1 if the feature has a duration. */ + int hasDuration; + + /** Seconds component of duratiion. */ + int durationSec; + + /** Nanoseconds component of duration. */ + int durationNsec; + +} VampFeatureV2; + +typedef union _VampFeatureUnion +{ + // sizeof(featureV1) >= sizeof(featureV2) for backward compatibility + VampFeature v1; + VampFeatureV2 v2; + +} VampFeatureUnion; + +typedef struct _VampFeatureList +{ + /** Number of features in this feature list. */ + unsigned int featureCount; + + /** Features in this feature list. May be NULL if featureCount is + zero. + + If present, this array must contain featureCount feature + structures for a Vamp API version 1 plugin, or 2*featureCount + feature unions for a Vamp API version 2 plugin. + + The features returned by an API version 2 plugin must consist + of the same feature structures as in API version 1 for the + first featureCount array elements, followed by featureCount + unions that contain VampFeatureV2 structures (or NULL pointers + if no V2 feature structures are present). + */ + VampFeatureUnion *features; + +} VampFeatureList; + +typedef enum +{ + vampTimeDomain, + vampFrequencyDomain + +} VampInputDomain; + +typedef void *VampPluginHandle; + +typedef struct _VampPluginDescriptor +{ + /** API version with which this descriptor is compatible. */ + unsigned int vampApiVersion; + + /** Computer-usable name of the plugin. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the plugin. May be translatable. */ + const char *name; + + /** Human-readable short text about the plugin. May be translatable. */ + const char *description; + + /** Human-readable name of plugin's author or vendor. */ + const char *maker; + + /** Version number of the plugin. */ + int pluginVersion; + + /** Human-readable summary of copyright or licensing for plugin. */ + const char *copyright; + + /** Number of parameter inputs. */ + unsigned int parameterCount; + + /** Fixed descriptors for parameter inputs. */ + const VampParameterDescriptor **parameters; + + /** Number of programs. */ + unsigned int programCount; + + /** Fixed names for programs. */ + const char **programs; + + /** Preferred input domain for audio input (time or frequency). */ + VampInputDomain inputDomain; + + /** Create and return a new instance of this plugin. */ + VampPluginHandle (*instantiate)(const struct _VampPluginDescriptor *, + float inputSampleRate); + + /** Destroy an instance of this plugin. */ + void (*cleanup)(VampPluginHandle); + + /** Initialise an instance following parameter configuration. */ + int (*initialise)(VampPluginHandle, + unsigned int inputChannels, + unsigned int stepSize, + unsigned int blockSize); + + /** Reset an instance, ready to use again on new input data. */ + void (*reset)(VampPluginHandle); + + /** Get a parameter value. */ + float (*getParameter)(VampPluginHandle, int); + + /** Set a parameter value. May only be called before initialise. */ + void (*setParameter)(VampPluginHandle, int, float); + + /** Get the current program (if programCount > 0). */ + unsigned int (*getCurrentProgram)(VampPluginHandle); + + /** Set the current program. May only be called before initialise. */ + void (*selectProgram)(VampPluginHandle, unsigned int); + + /** Get the plugin's preferred processing window increment in samples. */ + unsigned int (*getPreferredStepSize)(VampPluginHandle); + + /** Get the plugin's preferred processing window size in samples. */ + unsigned int (*getPreferredBlockSize)(VampPluginHandle); + + /** Get the minimum number of input channels this plugin can handle. */ + unsigned int (*getMinChannelCount)(VampPluginHandle); + + /** Get the maximum number of input channels this plugin can handle. */ + unsigned int (*getMaxChannelCount)(VampPluginHandle); + + /** Get the number of feature outputs (distinct sets of results). */ + unsigned int (*getOutputCount)(VampPluginHandle); + + /** Get a descriptor for a given feature output. Returned pointer + is valid only until next call to getOutputDescriptor for this + handle, or releaseOutputDescriptor for this descriptor. Host + must call releaseOutputDescriptor after use. */ + VampOutputDescriptor *(*getOutputDescriptor)(VampPluginHandle, + unsigned int); + + /** Destroy a descriptor for a feature output. */ + void (*releaseOutputDescriptor)(VampOutputDescriptor *); + + /** Process an input block and return a set of features. Returned + pointer is valid only until next call to process, + getRemainingFeatures, or cleanup for this handle, or + releaseFeatureSet for this feature set. Host must call + releaseFeatureSet after use. */ + VampFeatureList *(*process)(VampPluginHandle, + const float *const *inputBuffers, + int sec, + int nsec); + + /** Return any remaining features at the end of processing. */ + VampFeatureList *(*getRemainingFeatures)(VampPluginHandle); + + /** Release a feature set returned from process or getRemainingFeatures. */ + void (*releaseFeatureSet)(VampFeatureList *); + +} VampPluginDescriptor; + + +/** Get the descriptor for a given plugin index in this library. + Return NULL if the index is outside the range of valid indices for + this plugin library. + + The hostApiVersion argument tells the library code the highest + Vamp API version supported by the host. The function should + return a plugin descriptor compatible with the highest API version + supported by the library that is no higher than that supported by + the host. Provided the descriptor has the correct vampApiVersion + field for its actual compatibility level, the host should be able + to do the right thing with it: use it if possible, discard it + otherwise. + + This is the only symbol that a Vamp plugin actually needs to + export from its shared object; all others can be hidden. See the + accompanying documentation for notes on how to achieve this with + certain compilers. +*/ +const VampPluginDescriptor *vampGetPluginDescriptor + (unsigned int hostApiVersion, unsigned int index); + + +/** Function pointer type for vampGetPluginDescriptor. */ +typedef const VampPluginDescriptor *(*VampGetPluginDescriptorFunction) + (unsigned int, unsigned int); + +#ifdef __cplusplus +} +#endif + +#endif