aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2016-05-17 11:11:01 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2016-05-17 11:11:01 +0200
commitf7b07b9ea2fa9088882490d89dcbfb7e4399a062 (patch)
tree5aafffbb49a27e60d560a9a21b7c41d42a16d9cf
parentf9006de6a37e211592101addb36c65a002edd369 (diff)
downloadsherlock.lv2-f7b07b9ea2fa9088882490d89dcbfb7e4399a062.tar.xz
extend unit test with forge/deforge.
-rw-r--r--forge.h35
-rw-r--r--osc.h42
-rw-r--r--osc_test.c88
-rw-r--r--util.h45
-rw-r--r--writer.h38
5 files changed, 230 insertions, 18 deletions
diff --git a/forge.h b/forge.h
index c37dbac..817d5cb 100644
--- a/forge.h
+++ b/forge.h
@@ -86,7 +86,22 @@ static inline LV2_Atom_Forge_Ref
lv2_osc_forge_blob(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid,
const uint8_t *buf, uint32_t size)
{
- return lv2_osc_forge_chunk(forge, forge->Chunk, buf, size);
+ return lv2_osc_forge_chunk(forge, osc_urid->ATOM_Chunk, buf, size);
+}
+
+static inline LV2_Atom_Forge_Ref
+lv2_osc_forge_char(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid,
+ char val)
+{
+ return lv2_osc_forge_chunk(forge, osc_urid->OSC_Char, (const uint8_t *)&val, 1);
+}
+
+static inline LV2_Atom_Forge_Ref
+lv2_osc_forge_rgba(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid,
+ uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+{
+ const uint8_t val [4] = {r, g, b, a};
+ return lv2_osc_forge_chunk(forge, osc_urid->OSC_RGBA, val, 4);
}
static inline LV2_Atom_Forge_Ref
@@ -267,12 +282,18 @@ lv2_osc_forge_message_varlist(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid,
}
case LV2_OSC_CHAR:
{
- //FIXME
+ if(!(ref = lv2_osc_forge_char(forge, osc_urid, (char)va_arg(args, int))))
+ return 0;
break;
}
case LV2_OSC_RGBA:
{
- //FIXME
+ if(!(ref = lv2_osc_forge_rgba(forge, osc_urid,
+ (uint8_t)va_arg(args, unsigned),
+ (uint8_t)va_arg(args, unsigned),
+ (uint8_t)va_arg(args, unsigned),
+ (uint8_t)va_arg(args, unsigned))))
+ return 0;
break;
}
}
@@ -415,18 +436,20 @@ lv2_osc_forge_packet(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid,
}
case LV2_OSC_MIDI:
{
- if(!(ref = lv2_osc_forge_blob(forge, osc_urid, arg->b, arg->size)))
+ if(!(ref = lv2_osc_forge_midi(forge, osc_urid, &arg->b[1], arg->size - 1)))
return 0;
break;
}
case LV2_OSC_CHAR:
{
- //FIXME
+ if(!(ref = lv2_osc_forge_char(forge, osc_urid, arg->c)))
+ return 0;
break;
}
case LV2_OSC_RGBA:
{
- //FIXME
+ if(!(ref = lv2_osc_forge_rgba(forge, osc_urid, arg->R, arg->G, arg->B, arg->A)))
+ return 0;
break;
}
}
diff --git a/osc.h b/osc.h
index e635707..4a9342d 100644
--- a/osc.h
+++ b/osc.h
@@ -21,6 +21,8 @@
#include <stdint.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/midi/midi.h>
#define LV2_OSC_URI "http://open-music-kontrollers.ch/lv2/osc"
#define LV2_OSC_PREFIX LV2_OSC_URI "#"
@@ -44,6 +46,8 @@
#define LV2_OSC__timetagFraction LV2_OSC_PREFIX "timetagFraction" // atom object property
#define LV2_OSC__Impulse LV2_OSC_PREFIX "Impulse" // atom type
+#define LV2_OSC__Char LV2_OSC_PREFIX "Char" // atom type
+#define LV2_OSC__RGBA LV2_OSC_PREFIX "RGBA" // atom type
#define LV2_OSC_PADDED_SIZE(size) ( ( (size_t)(size) + 3 ) & ( ~3 ) )
#define LV2_OSC_IMMEDIATE 1ULL
@@ -126,6 +130,8 @@ typedef struct _LV2_OSC_URID {
LV2_URID OSC_timetagFraction;
LV2_URID OSC_Impulse;
+ LV2_URID OSC_Char;
+ LV2_URID OSC_RGBA;
LV2_URID MIDI_MidiEvent;
@@ -141,6 +147,42 @@ typedef struct _LV2_OSC_URID {
LV2_URID ATOM_Chunk;
} LV2_OSC_URID;
+static inline void
+lv2_osc_urid_init(LV2_OSC_URID *osc_urid, LV2_URID_Map *map)
+{
+ osc_urid->OSC_Packet = map->map(map->handle, LV2_OSC__Packet);
+ osc_urid->OSC_packetBody = map->map(map->handle, LV2_OSC__packetBody);
+
+ osc_urid->OSC_Bundle = map->map(map->handle, LV2_OSC__Bundle);
+ osc_urid->OSC_bundleTimetag = map->map(map->handle, LV2_OSC__bundleTimetag);
+ osc_urid->OSC_bundleItems = map->map(map->handle, LV2_OSC__bundleItems);
+
+ osc_urid->OSC_Message = map->map(map->handle, LV2_OSC__Message);
+ osc_urid->OSC_messagePath = map->map(map->handle, LV2_OSC__messagePath);
+ osc_urid->OSC_messageArguments = map->map(map->handle, LV2_OSC__messageArguments);
+
+ osc_urid->OSC_Timetag = map->map(map->handle, LV2_OSC__Timetag);
+ osc_urid->OSC_timetagIntegral = map->map(map->handle, LV2_OSC__timetagIntegral);
+ osc_urid->OSC_timetagFraction = map->map(map->handle, LV2_OSC__timetagFraction);
+
+ osc_urid->OSC_Impulse = map->map(map->handle, LV2_OSC__Impulse);
+ osc_urid->OSC_Char = map->map(map->handle, LV2_OSC__Char);
+ osc_urid->OSC_RGBA = map->map(map->handle, LV2_OSC__RGBA);
+
+ osc_urid->MIDI_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
+
+ osc_urid->ATOM_Int = map->map(map->handle, LV2_ATOM__Int);
+ osc_urid->ATOM_Long = map->map(map->handle, LV2_ATOM__Long);
+ osc_urid->ATOM_String = map->map(map->handle, LV2_ATOM__String);
+ osc_urid->ATOM_Float = map->map(map->handle, LV2_ATOM__Float);
+ osc_urid->ATOM_Double = map->map(map->handle, LV2_ATOM__Double);
+ osc_urid->ATOM_URID = map->map(map->handle, LV2_ATOM__URID);
+ osc_urid->ATOM_Bool = map->map(map->handle, LV2_ATOM__Bool);
+ osc_urid->ATOM_Tuple = map->map(map->handle, LV2_ATOM__Tuple);
+ osc_urid->ATOM_Object = map->map(map->handle, LV2_ATOM__Object);
+ osc_urid->ATOM_Chunk = map->map(map->handle, LV2_ATOM__Chunk);
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/osc_test.c b/osc_test.c
index bb6e789..f131bb8 100644
--- a/osc_test.c
+++ b/osc_test.c
@@ -5,13 +5,30 @@
#include <osc.h>
#include <reader.h>
#include <writer.h>
+#include <forge.h>
#define BUF_SIZE 8192
+#define MAX_URIDS 512
typedef void (*test_t)(LV2_OSC_Writer *writer);
+typedef struct _urid_t urid_t;
+typedef struct _handle_t handle_t;
+struct _urid_t {
+ LV2_URID urid;
+ char *uri;
+};
+
+struct _handle_t {
+ urid_t urids [MAX_URIDS];
+ LV2_URID urid;
+};
+
+static handle_t __handle;
static uint8_t buf0 [BUF_SIZE];
static uint8_t buf1 [BUF_SIZE];
+static uint8_t buf2 [BUF_SIZE];
+static const LV2_Atom_Object *obj2= (const LV2_Atom_Object *)buf2;
const uint8_t raw_0 [] = {
'/', 0x0, 0x0, 0x0,
@@ -100,6 +117,53 @@ const uint8_t raw_7 [] = {
',', 0x0, 0x0, 0x0
};
+static LV2_URID
+_map(LV2_URID_Map_Handle instance, const char *uri)
+{
+ handle_t *handle = instance;
+
+ urid_t *itm;
+ for(itm=handle->urids; itm->urid; itm++)
+ {
+ if(!strcmp(itm->uri, uri))
+ return itm->urid;
+ }
+
+ assert(handle->urid + 1 < MAX_URIDS);
+
+ // create new
+ itm->urid = ++handle->urid;
+ itm->uri = strdup(uri);
+
+ return itm->urid;
+}
+
+static const char *
+_unmap(LV2_URID_Unmap_Handle instance, LV2_URID urid)
+{
+ handle_t *handle = instance;
+
+ urid_t *itm;
+ for(itm=handle->urids; itm->urid; itm++)
+ {
+ if(itm->urid == urid)
+ return itm->uri;
+ }
+
+ // not found
+ return NULL;
+}
+
+static LV2_URID_Map map = {
+ .handle = &__handle,
+ .map = _map
+};
+
+static LV2_URID_Unmap unmap = {
+ .handle = &__handle,
+ .unmap = _unmap
+};
+
static void
_dump(const uint8_t *src, const uint8_t *dst, size_t size)
{
@@ -193,21 +257,39 @@ _clone(LV2_OSC_Reader *reader, LV2_OSC_Writer *writer, size_t size)
static void
_test_a(LV2_OSC_Writer *writer, const uint8_t *raw, size_t size)
{
+ LV2_OSC_URID osc_urid;
+ lv2_osc_urid_init(&osc_urid, &map);
+
+ // check writer against raw bytes
size_t len;
assert(osc_writer_finalize(writer, &len) == buf0);
assert(len == size);
- //_dump(raw, buf0, size);
assert(memcmp(raw, buf0, size) == 0);
+ // check reader & writer
LV2_OSC_Reader reader;
osc_reader_initialize(&reader, buf0, size);
osc_writer_initialize(writer, buf1, BUF_SIZE);
-
_clone(&reader, writer, size);
+ // check cloned against raw bytes
+ assert(osc_writer_finalize(writer, &len) == buf1);
+ assert(len == size);
+ assert(memcmp(raw, buf1, size) == 0);
+
+ // check forge
+ LV2_Atom_Forge forge;
+ lv2_atom_forge_init(&forge, &map);
+ lv2_atom_forge_set_buffer(&forge, buf2, BUF_SIZE);
+ assert(lv2_osc_forge_packet(&forge, &osc_urid, &map, buf0, size));
+
+ // check deforge
+ osc_writer_initialize(writer, buf1, BUF_SIZE);
+ assert(osc_writer_packet(writer, &osc_urid, &unmap, obj2->atom.size, &obj2->body));
+
+ // check deforged against raw bytes
assert(osc_writer_finalize(writer, &len) == buf1);
assert(len == size);
- //_dump(raw, buf0, size);
assert(memcmp(raw, buf1, size) == 0);
}
diff --git a/util.h b/util.h
index c066faa..616bc6a 100644
--- a/util.h
+++ b/util.h
@@ -141,6 +141,51 @@ lv2_osc_is_message_or_bundle_type(LV2_OSC_URID *osc_urid, LV2_URID type)
|| lv2_osc_is_bundle_type(osc_urid, type);
}
+static inline LV2_OSC_Type
+lv2_osc_argument_type(LV2_OSC_URID *osc_urid, const LV2_Atom *atom)
+{
+ const LV2_Atom_Object *obj = (const LV2_Atom_Object *)atom;
+
+ if(atom->type == osc_urid->ATOM_Int)
+ return LV2_OSC_INT32;
+ else if(atom->type == osc_urid->ATOM_Float)
+ return LV2_OSC_FLOAT;
+ else if(atom->type == osc_urid->ATOM_String)
+ return LV2_OSC_STRING;
+ else if(atom->type == osc_urid->ATOM_Chunk)
+ return LV2_OSC_BLOB;
+
+ else if(atom->type == osc_urid->ATOM_Long)
+ return LV2_OSC_INT64;
+ else if(atom->type == osc_urid->ATOM_Double)
+ return LV2_OSC_DOUBLE;
+ else if( (atom->type == osc_urid->ATOM_Object) && (obj->body.otype == osc_urid->OSC_Timetag) )
+ return LV2_OSC_TIMETAG;
+
+ else if(atom->type == osc_urid->ATOM_Bool)
+ {
+ if(((const LV2_Atom_Bool *)atom)->body)
+ return LV2_OSC_TRUE;
+ else
+ return LV2_OSC_FALSE;
+ }
+ else if( (atom->type == 0) && (atom->size == 0) )
+ return LV2_OSC_NIL;
+ else if(atom->type == osc_urid->OSC_Impulse)
+ return LV2_OSC_IMPULSE;
+
+ else if(atom->type == osc_urid->ATOM_URID)
+ return LV2_OSC_SYMBOL;
+ else if(atom->type == osc_urid->MIDI_MidiEvent)
+ return LV2_OSC_MIDI;
+ else if(atom->type == osc_urid->OSC_Char)
+ return LV2_OSC_CHAR;
+ else if(atom->type == osc_urid->OSC_RGBA)
+ return LV2_OSC_RGBA;
+
+ return '\0';
+}
+
/**
TODO
*/
diff --git a/writer.h b/writer.h
index 7d47e23..32be35d 100644
--- a/writer.h
+++ b/writer.h
@@ -429,9 +429,9 @@ osc_writer_packet(LV2_OSC_Writer *writer, LV2_OSC_URID *osc_urid,
if(!osc_writer_push_bundle(writer, &bndl, lv2_osc_timetag_parse(&tt)))
return false;
- LV2_ATOM_OBJECT_BODY_FOREACH(body, size, prop)
+ LV2_ATOM_TUPLE_FOREACH(items, atom)
{
- const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&prop->value;
+ const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom;
LV2_OSC_Writer_Frame itm;
if( !osc_writer_push_item(writer, &itm)
@@ -454,15 +454,19 @@ osc_writer_packet(LV2_OSC_Writer *writer, LV2_OSC_URID *osc_urid,
if(!osc_writer_add_path(writer, LV2_ATOM_BODY_CONST(path)))
return false;
- LV2_ATOM_OBJECT_BODY_FOREACH(body, size, prop)
+ char fmt [128]; //TODO how big?
+ char *ptr = fmt;
+ LV2_ATOM_TUPLE_FOREACH(arguments, atom)
{
- //FIXME write format string
+ *ptr++ = lv2_osc_argument_type(osc_urid, atom);
}
+ *ptr = '\0';
+ if(!osc_writer_add_format(writer, fmt))
+ return false;
- LV2_ATOM_OBJECT_BODY_FOREACH(body, size, prop)
+ LV2_ATOM_TUPLE_FOREACH(arguments, atom)
{
- const LV2_Atom *atom = &prop->value;
- const LV2_Atom_Object *obj= (const LV2_Atom_Object *)&prop->value;
+ const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom;
if(atom->type == osc_urid->ATOM_Int)
{
@@ -503,6 +507,8 @@ osc_writer_packet(LV2_OSC_Writer *writer, LV2_OSC_URID *osc_urid,
return false;
}
+ // there is nothing to do for: true, false, nil, impulse
+
else if(atom->type == osc_urid->ATOM_URID)
{
const char *symbol = unmap->unmap(unmap->handle, ((const LV2_Atom_URID *)atom)->body);
@@ -511,10 +517,24 @@ osc_writer_packet(LV2_OSC_Writer *writer, LV2_OSC_URID *osc_urid,
}
else if(atom->type == osc_urid->MIDI_MidiEvent)
{
- if(!osc_writer_add_midi(writer, atom->size, LV2_ATOM_BODY_CONST(atom)))
+ uint8_t *m = NULL;
+ if(!osc_writer_add_midi_inline(writer, atom->size + 1, &m))
+ return false;
+ m[0] = 0x0; // port
+ memcpy(&m[1], LV2_ATOM_BODY_CONST(atom), atom->size);
+ }
+ else if(atom->type == osc_urid->OSC_Char)
+ {
+ const char c = *(const char *)LV2_ATOM_BODY_CONST(atom);
+ if(!osc_writer_add_char(writer, c))
+ return false;
+ }
+ else if(atom->type == osc_urid->OSC_RGBA)
+ {
+ const uint8_t *rgba = LV2_ATOM_BODY_CONST(atom);
+ if(!osc_writer_add_rgba(writer, rgba[0], rgba[1], rgba[2], rgba[3]))
return false;
}
- //FIXME CHAR, RGBA
}
}