[LV2] Mapping of OSC to LV2 Atoms

Hanspeter Portner ventosus at airpost.net
Fri Jun 19 13:33:01 PDT 2015


Hi

So, I'm in need of an atomified representation of OSC [1] to route it:
* from plugin to UI and back
* from plugin to plugin
* from plugin to host and back

Prerequisites are:
* 1-to-1 mapping of bundles/messages and nested bundles/messages
* 1-to-1 maping of arguments
* no information loss
* based on existing atom types
* coverage of most prominent OSC types

Here's what I've come up with
=============================

OSC    C             LV2 Atom
---------------------------------------------------
base types
'i'    int32_t       LV2_Atom_Int
'f'    float         LV2_Atom_Float
's'    char []       LV2_Atom_String
'b'    uint8_t []    LV2_Atom_Chunk

extended types
'h'    int64_t       LV2_Atom_Long
'd'    double        LV2_Atom_Double
't'    uint64_t      LV2_Atom_Long

exotic types
'T'    -             - or LV2_Atom_Bool (body=1)
'F'    -             - or LV2_Atom_Bool (body=0)
'N'    -             - or LV2_Atom (size=0, type=0)
'I'    -             - or LV2_Atom_Float (body=INFINITY)

even more exotic types
'c'    char          LV2_Atom_Int
'S'    char []       LV2_Atom_String
'm'    uint8_t [4]   LV2_Atom_Chunk (type=MIDI__MidiEvent)
'['']' ?             LV2_Atom_Vector (ctype=LV2_Atom_Int/Float/...)

An OSC Bundle is mapped to an object and 2 properties:

LV2_Atom_Object (object.otype=LV2_OSC__Bundle)
  key=LV2_OSC__bundleTimestamp (value.type=LV2_Atom_Long)
  key=LV2_OSC__bundleItems (value.type=LV2_Atom_Tuple)

The bundle items tuple may be empty or else contains nested
bundles and/or messages.

An OSC Message is mapped to an object and 3 properties:

LV2_Atom_Object (object.otype=LV2_OSC__Message)
  key=LV2_OSC__messagePath (value.type=LV2_Atom_String)
  key=LV2_OSC__messageFormat (value.type=LV2_Atom_String)
  key=LV2_OSC__messageArguments (value.type=LV2_Atom_Tuple)

The message arguments tuple may be empty or else contains the
mapped arguments according to the table above.

Potential Issues
================

* The OSC bundle timestamp and timestamp type 't' must be cast
  from unsigned to signed as there are no usigned atoms.

I actually only care for the base and extended types but
it may make sense to include the exotic types too for
the sake of completeness.

* The four exotic OSC types 'T'rue, 'F'alse, 'N'il, 'I'nfinitum have
  no associated data in OSC. Should they be mapped to atoms and
  packed into the arguments tuple or only show up in the message
  format string like in OSC?
* Mapping of 'N' and 'I' is kludgy, 'N' may be mapped to an
  empty atom, but what should 'I' be mapped to, Infinity?
* Even more exotic types 'c'har, 'S'ymbol and 'm'idi are seldom
  used. 'm' type is special as it's four bytes only and first
  byte represents a port number. So it's not fully up to the
  definition of MIDI__MidiEvent.
* It seems to be possible to send arrayed values with '['
  ']', but I've never seen it used anywhere and can't figure
  out how it's supposed to work. I guess it could be mapped
  to a LV2_Atom_Vector, though.

osc.lv2 [2] is a working prototype of an extension
implementing the mapping above, It's data only (aka URI
definitions for object types and property keys) plus a
utility header to help in easy forging.

An example of how I use this can be found in e.g. moony.lv2 [3].

Questions
=========
* Is the mapping that I've come up with sensible, stupid, ...?

* Anybody else interested in OSC <-> Atom mapping?
  If so:
  * Are the exotic types needed?
  * Something else missing?

Hanspeter

[1] http://opensoundcontrol.org/spec-1_0
[2] https://github.com/OpenMusicKontrollers/osc.lv2
[3]
https://github.com/OpenMusicKontrollers/moony.lv2/blob/master/api.c#L1249


More information about the Devel mailing list