aboutsummaryrefslogtreecommitdiff
path: root/osc.lv2
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2015-05-22 22:09:13 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2015-05-22 22:09:13 +0200
commit05deca621b40e0e14054aea437e7b0afaf2b940f (patch)
tree778231ee71086ae9e2e8b776c33f616439028027 /osc.lv2
parent9133690bf7addc5979613952f25da3fa038c77bd (diff)
parent84c39c614f89b193862fc55965e81c257af638ae (diff)
downloadmoony.lv2-05deca621b40e0e14054aea437e7b0afaf2b940f.tar.xz
Add 'osc.lv2/' from commit '84c39c614f89b193862fc55965e81c257af638ae'
git-subtree-dir: osc.lv2 git-subtree-mainline: 9133690bf7addc5979613952f25da3fa038c77bd git-subtree-split: 84c39c614f89b193862fc55965e81c257af638ae
Diffstat (limited to 'osc.lv2')
-rw-r--r--osc.lv2/COPYING201
-rw-r--r--osc.lv2/README.md3
-rw-r--r--osc.lv2/lv2_osc.h417
3 files changed, 621 insertions, 0 deletions
diff --git a/osc.lv2/COPYING b/osc.lv2/COPYING
new file mode 100644
index 0000000..ddb9a46
--- /dev/null
+++ b/osc.lv2/COPYING
@@ -0,0 +1,201 @@
+ The Artistic License 2.0
+
+ Copyright (c) 2000-2006, The Perl Foundation.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/osc.lv2/README.md b/osc.lv2/README.md
new file mode 100644
index 0000000..b48021f
--- /dev/null
+++ b/osc.lv2/README.md
@@ -0,0 +1,3 @@
+# osc.lv2
+
+## Open Sound Control Extension for the LV2 Plugin Specification
diff --git a/osc.lv2/lv2_osc.h b/osc.lv2/lv2_osc.h
new file mode 100644
index 0000000..c1f0f3d
--- /dev/null
+++ b/osc.lv2/lv2_osc.h
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the Artistic License 2.0 as published by
+ * The Perl Foundation.
+ *
+ * This source is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Artistic License 2.0 for more details.
+ *
+ * You should have received a copy of the Artistic License 2.0
+ * along the source as a COPYING file. If not, obtain it from
+ * http://www.perlfoundation.org/artistic_license_2_0.
+ */
+
+#ifndef _LV2_OSC_H_
+#define _LV2_OSC_H_
+
+#include <math.h> // INFINITY
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
+#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
+#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
+#include <lv2/lv2plug.in/ns/ext/midi/midi.h>
+
+#define OSC_URI "http://opensoundcontrol.org"
+#define OSC_PREFIX OSC_URI "#"
+
+#define OSC__Event OSC_PREFIX "Event" // object id
+#define OSC__Bundle OSC_PREFIX "Bundle" // object otype
+#define OSC__Message OSC_PREFIX "Message" // object otype
+#define OSC__bundleTimestamp OSC_PREFIX "bundleTimestamp" // property key
+#define OSC__bundleItems OSC_PREFIX "bundleItems" // property key
+#define OSC__messagePath OSC_PREFIX "messagePath" // property key
+#define OSC__messageFormat OSC_PREFIX "messageFormat" // property key
+#define OSC__messageArguments OSC_PREFIX "messageArguments" // property key
+
+typedef struct _osc_forge_t osc_forge_t;
+
+struct _osc_forge_t {
+ LV2_URID OSC_Event;
+
+ LV2_URID OSC_Bundle;
+ LV2_URID OSC_Message;
+
+ LV2_URID OSC_bundleTimestamp;
+ LV2_URID OSC_bundleItems;
+
+ LV2_URID OSC_messagePath;
+ LV2_URID OSC_messageFormat;
+ LV2_URID OSC_messageArguments;
+
+ LV2_URID MIDI_MidiEvent;
+
+ LV2_URID ATOM_Object;
+};
+
+static inline void
+osc_forge_init(osc_forge_t *oforge, LV2_URID_Map *map)
+{
+ oforge->OSC_Event = map->map(map->handle, OSC__Event);
+
+ oforge->OSC_Bundle = map->map(map->handle, OSC__Bundle);
+ oforge->OSC_Message = map->map(map->handle, OSC__Message);
+
+ oforge->OSC_bundleTimestamp = map->map(map->handle, OSC__bundleTimestamp);
+ oforge->OSC_bundleItems = map->map(map->handle, OSC__bundleItems);
+
+ oforge->OSC_messagePath = map->map(map->handle, OSC__messagePath);
+ oforge->OSC_messageFormat = map->map(map->handle, OSC__messageFormat);
+ oforge->OSC_messageArguments = map->map(map->handle, OSC__messageArguments);
+
+ oforge->MIDI_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
+
+ oforge->ATOM_Object = map->map(map->handle, LV2_ATOM__Object);
+}
+
+static inline int
+osc_atom_is_bundle(osc_forge_t *oforge, const LV2_Atom_Object *obj)
+{
+ return (obj->atom.type == oforge->ATOM_Object)
+ && (obj->body.id == oforge->OSC_Event)
+ && (obj->body.otype == oforge->OSC_Bundle);
+}
+
+static inline void
+osc_atom_bundle_unpack(osc_forge_t *oforge, const LV2_Atom_Object *obj,
+ const LV2_Atom_Long **timestamp, const LV2_Atom_Tuple **items)
+{
+ *timestamp = NULL;
+ *items = NULL;
+
+ LV2_Atom_Object_Query q [] = {
+ { oforge->OSC_bundleTimestamp, (const LV2_Atom **)timestamp },
+ { oforge->OSC_bundleItems, (const LV2_Atom **)items },
+ LV2_ATOM_OBJECT_QUERY_END
+ };
+
+ lv2_atom_object_query(obj, q);
+}
+
+static inline int
+osc_atom_is_message(osc_forge_t *oforge, const LV2_Atom_Object *obj)
+{
+ return (obj->atom.type == oforge->ATOM_Object)
+ && (obj->body.id == oforge->OSC_Event)
+ && (obj->body.otype == oforge->OSC_Message);
+}
+
+static inline void
+osc_atom_message_unpack(osc_forge_t *oforge, const LV2_Atom_Object *obj,
+ const LV2_Atom_String **path, const LV2_Atom_String **format,
+ const LV2_Atom_Tuple **arguments)
+{
+ *path = NULL;
+ *format = NULL;
+ *arguments = NULL;
+
+ LV2_Atom_Object_Query q [] = {
+ { oforge->OSC_messagePath, (const LV2_Atom **)path },
+ { oforge->OSC_messageFormat, (const LV2_Atom **)format },
+ { oforge->OSC_messageArguments, (const LV2_Atom **)arguments },
+ LV2_ATOM_OBJECT_QUERY_END
+ };
+
+ lv2_atom_object_query(obj, q);
+}
+
+typedef void (*osc_message_cb_t)(uint64_t timestamp, const char *path,
+ const char *fmt, const LV2_Atom_Tuple *arguments, void *data);
+
+static inline void osc_atom_event_unroll(osc_forge_t *oforge,
+ const LV2_Atom_Object *obj, osc_message_cb_t cb, void *data);
+
+static inline void
+osc_atom_message_unroll(osc_forge_t *oforge, uint64_t timestamp,
+ const LV2_Atom_Object *obj, osc_message_cb_t cb, void *data)
+{
+ if(!cb)
+ return;
+
+ const LV2_Atom_String* path;
+ const LV2_Atom_String* fmt;
+ const LV2_Atom_Tuple* args;
+
+ osc_atom_message_unpack(oforge, obj, &path, &fmt, &args);
+
+ const char *path_str = path ? LV2_ATOM_BODY_CONST(path) : NULL;
+ const char *fmt_str = fmt ? LV2_ATOM_BODY_CONST(fmt) : NULL;
+
+ if(path_str && fmt_str)
+ cb(timestamp, path_str, fmt_str, args, data);
+}
+
+static inline void
+osc_atom_bundle_unroll(osc_forge_t *oforge, const LV2_Atom_Object *obj,
+ osc_message_cb_t cb, void *data)
+{
+ if(!cb)
+ return;
+
+ const LV2_Atom_Long* timestamp;
+ const LV2_Atom_Tuple* items;
+
+ osc_atom_bundle_unpack(oforge, obj, &timestamp, &items);
+
+ if(!items)
+ return;
+
+ uint64_t timestamp_body = timestamp ? timestamp->body : 1ULL;
+
+ // iterate over tuple body
+ for(const LV2_Atom *itr = lv2_atom_tuple_begin(items);
+ !lv2_atom_tuple_is_end(LV2_ATOM_BODY(items), items->atom.size, itr);
+ itr = lv2_atom_tuple_next(itr))
+ {
+ osc_atom_event_unroll(oforge, (const LV2_Atom_Object *)itr, cb, data);
+ }
+}
+
+static inline void
+osc_atom_event_unroll(osc_forge_t *oforge, const LV2_Atom_Object *obj,
+ osc_message_cb_t cb, void *data)
+{
+ if(!cb)
+ return;
+
+ if(osc_atom_is_bundle(oforge, obj))
+ osc_atom_bundle_unroll(oforge, obj, cb, data);
+ else if(osc_atom_is_message(oforge, obj))
+ osc_atom_message_unroll(oforge, 1ULL, obj, cb, data);
+ else
+ ; // no OSC packet, obviously
+}
+
+static inline void
+osc_forge_bundle_push(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ LV2_Atom_Forge_Frame frame [2], uint64_t timestamp)
+{
+ lv2_atom_forge_object(forge, &frame[0], oforge->OSC_Event,
+ oforge->OSC_Bundle);
+
+ lv2_atom_forge_key(forge, oforge->OSC_bundleTimestamp);
+ lv2_atom_forge_long(forge, timestamp);
+
+ lv2_atom_forge_key(forge, oforge->OSC_bundleItems);
+ lv2_atom_forge_tuple(forge, &frame[1]);
+}
+
+static inline void
+osc_forge_bundle_pop(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ LV2_Atom_Forge_Frame frame [2])
+{
+ lv2_atom_forge_pop(forge, &frame[1]);
+ lv2_atom_forge_pop(forge, &frame[0]);
+}
+
+static inline void
+osc_forge_message_push(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ LV2_Atom_Forge_Frame frame [2], const char *path, const char *fmt)
+{
+ lv2_atom_forge_object(forge, &frame[0], oforge->OSC_Event,
+ oforge->OSC_Message);
+
+ lv2_atom_forge_key(forge, oforge->OSC_messagePath);
+ lv2_atom_forge_string(forge, path, strlen(path));
+
+ lv2_atom_forge_key(forge, oforge->OSC_messageFormat);
+ lv2_atom_forge_string(forge, fmt, strlen(fmt));
+
+ lv2_atom_forge_key(forge, oforge->OSC_messageArguments);
+ lv2_atom_forge_tuple(forge, &frame[1]);
+}
+
+static inline void
+osc_forge_message_pop(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ LV2_Atom_Forge_Frame frame [2])
+{
+ lv2_atom_forge_pop(forge, &frame[1]);
+ lv2_atom_forge_pop(forge, &frame[0]);
+}
+
+static inline void
+osc_forge_int32(osc_forge_t *oforge, LV2_Atom_Forge *forge, int32_t i)
+{
+ lv2_atom_forge_int(forge, i);
+}
+
+static inline void
+osc_forge_float(osc_forge_t *oforge, LV2_Atom_Forge *forge, float f)
+{
+ lv2_atom_forge_float(forge, f);
+}
+
+static inline void
+osc_forge_string(osc_forge_t *oforge, LV2_Atom_Forge *forge, const char *s)
+{
+ lv2_atom_forge_string(forge, s, strlen(s));
+}
+
+static inline void
+osc_forge_symbol(osc_forge_t *oforge, LV2_Atom_Forge *forge, const char *s)
+{
+ lv2_atom_forge_string(forge, s, strlen(s));
+}
+
+static inline void
+osc_forge_blob(osc_forge_t *oforge, LV2_Atom_Forge *forge, int32_t size,
+ const uint8_t *b)
+{
+ lv2_atom_forge_atom(forge, size, forge->Chunk);
+ lv2_atom_forge_raw(forge, b, size);
+ lv2_atom_forge_pad(forge, size);
+}
+
+static inline void
+osc_forge_int64(osc_forge_t *oforge, LV2_Atom_Forge *forge, int64_t h)
+{
+ lv2_atom_forge_long(forge, h);
+}
+
+static inline void
+osc_forge_double(osc_forge_t *oforge, LV2_Atom_Forge *forge, double d)
+{
+ lv2_atom_forge_double(forge, d);
+}
+
+static inline void
+osc_forge_timestamp(osc_forge_t *oforge, LV2_Atom_Forge *forge, uint64_t t)
+{
+ lv2_atom_forge_long(forge, t);
+}
+
+static inline void
+osc_forge_char(osc_forge_t *oforge, LV2_Atom_Forge *forge, char c)
+{
+ lv2_atom_forge_int(forge, c);
+}
+
+static inline void
+osc_forge_midi(osc_forge_t *oforge, LV2_Atom_Forge *forge, const uint8_t *m)
+{
+ lv2_atom_forge_atom(forge, 4, oforge->MIDI_MidiEvent);
+ lv2_atom_forge_raw(forge, m, 4);
+ lv2_atom_forge_pad(forge, 4);
+}
+
+static inline void
+osc_forge_true(osc_forge_t *oforge, LV2_Atom_Forge *forge)
+{
+ lv2_atom_forge_bool(forge, 1);
+}
+
+static inline void
+osc_forge_false(osc_forge_t *oforge, LV2_Atom_Forge *forge)
+{
+ lv2_atom_forge_bool(forge, 0);
+}
+
+static inline void
+osc_forge_nil(osc_forge_t *oforge, LV2_Atom_Forge *forge)
+{
+ lv2_atom_forge_atom(forge, 0, 0);
+}
+
+static inline void
+osc_forge_bang(osc_forge_t *oforge, LV2_Atom_Forge *forge)
+{
+ lv2_atom_forge_float(forge, INFINITY);
+}
+
+static inline void
+osc_forge_message_varlist(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ const char *path, const char *fmt, va_list args)
+{
+ LV2_Atom_Forge_Frame frame [2];
+
+ osc_forge_message_push(oforge, forge, frame, path, fmt);
+
+ for(const char *type = fmt; *type; type++)
+ {
+ switch(*type)
+ {
+ case 'i':
+ osc_forge_int32(oforge, forge, va_arg(args, int32_t));
+ break;
+ case 'f':
+ osc_forge_float(oforge, forge, (float)va_arg(args, double));
+ break;
+ case 's':
+ osc_forge_string(oforge, forge, va_arg(args, const char *));
+ break;
+ case 'S':
+ osc_forge_symbol(oforge, forge, va_arg(args, const char *));
+ break;
+ case 'b':
+ {
+ int32_t size = va_arg(args, int32_t);
+ const uint8_t *b = va_arg(args, const uint8_t *);
+ osc_forge_blob(oforge, forge, size, b);
+ break;
+ }
+
+ case 'h':
+ osc_forge_int64(oforge, forge, va_arg(args, int64_t));
+ break;
+ case 'd':
+ osc_forge_double(oforge, forge, va_arg(args, double));
+ break;
+ case 't':
+ osc_forge_timestamp(oforge, forge, va_arg(args, uint64_t));
+ break;
+
+ case 'c':
+ osc_forge_char(oforge, forge, (char)va_arg(args, unsigned int));
+ break;
+ case 'm':
+ osc_forge_midi(oforge, forge, va_arg(args, const uint8_t *));
+ break;
+
+ case 'T':
+ osc_forge_true(oforge, forge);
+ break;
+ case 'F':
+ osc_forge_false(oforge, forge);
+ break;
+ case 'N':
+ osc_forge_nil(oforge, forge);
+ break;
+ case 'I':
+ osc_forge_bang(oforge, forge);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ osc_forge_message_pop(oforge, forge, frame);
+}
+
+static inline void
+osc_forge_message_vararg(osc_forge_t *oforge, LV2_Atom_Forge *forge,
+ const char *path, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ osc_forge_message_varlist(oforge, forge, path, fmt, args);
+
+ va_end(args);
+}
+
+#endif // _LV2_OSC_H_