Note that in practice you'll will likely not need to use this module directly and instead use OSCx.encode/1.
At it's core, OSC has the following data types:
Type
Description
Integer
a 32-bit signed integer and also a 64-bit integer type)
Float
a 32-bit IEEE 754 floating-point number and also a 64-bit double type
String
a sequence of printable ASCII characters (there are also Symbols and Char types)
Blob
a sequence of arbitrary binary data, with its size prepended
Timetag
a 64-bit fixed-point number that represents a time in seconds since midnight on January 1, 1900. The first 32 bits of the timetag represent the number of seconds, and the last 32 bits represent fractional parts of a second to a precision of about 200 picoseconds.
The above are considered 'required' types by the OSC spec, however, OSC can be extended to support additional or optional types.
The main function in this module is encode_arg/1, which takes one of the recognised Elixir data types, and returns it as an OSC type.
Tag-specific types
Additionally the OSC 1.1 Specification includes some types which carry no data arguments, but can be encoded directly into the tag type string. These are True, False, Null and Impluse.
OSC data is aligned on 4-byte boundaries. 32-bit types like Integers and Floats are 4-bytes, but Strings and Blobs can be of an arbintary length. For this reason they may be padded with extra null characters (<<0>>> is used in Elixir) to make the total length a multiple of 4 bytes.
Values returned
Most functions in this module return a tuple in the form {type, value}. These are defined as follows:
type: first element is an OSC type tag, which is a unicode charater representing the type
value: second element is the encoded OSC value.
For example, {105, <<0, 0, 0, 128>>} is returned for encoding a the integer 128. See the example below.
Type tags
OSC type tags are unicode characters which represent each type. This library currently implements the following types:
Type tag
Unicode number
Type
OSC spec version
i
105
32 bit integer
1.0+ required
f
102
32 bit float
1.0+ required
s
115
String
1.0+ required
b
98
Blob
1.0+ required
h
104
64-bit big-endian two’s complement integer
1.0 non-standard
d
100
64 bit (“double”) IEEE 754 floating point number
1.0 non-standard
c
99
An ascii character, sent as 32 bits
1.0 non-standard
m
109
4 byte MIDI message
1.0 non-standard
t
116
OSC time tag
1.1+ required
r
144
32 bit RGBA color
1.0 non-standard
[ and ]
91 and 93
List
1.0 non-standard
T
84
True (tag only, no arguments)
1.1+ required
F
80
False (tag only, no arguments)
1.1+ required
N
78
Null (tag only, no arguments)
1.1+ required
I
73
Impulse (tag only, no arguments)
1.1+ required
These type tags are used to build a type tag string, which is part of the OSC message.
Example
iex> aliasOSCx.Encoderiex> my_integer=128iex> Encoder.integer(my_integer)# Returns the type 105 (integer), and the encoded value:{105,<<0,0,0,128>>}iex> very_big_integer=9_223_372_036_854_775_700iex> Encoder.integer(very_big_integer)# Returns the type 104 (64-bit big-endian two’s complement integer), with the encoded value{104,<<127,255,255,255,255,255,255,148>>}iex> my_string="hello world"iex> Encoder.string(my_string)# Returns the type 115 (string), and a list containing the string with any required padding:{115,<<104,101,108,108,111,32,119,111,114,108,100,0>>}
More information
To learn more about how this library encodes and decodes data, see: Arguments and types.
You can call this function with the following Elixir types:
Elixir type
OSC type tag
Unicode number
OSC type
Integer
i
105
32 bit integer
Float
f
102
32 bit float
String
s
115
String
Atom
s
115
String
Bitstring
b
98
Blob
Integer (64 bit)
h
104
64-bit big-endian two’s complement integer
Float (64 bit)
d
104
64-bit big-endian two’s complement integer
Time map
t
116
OSC time tag
MIDI map
m
109
4-byte MIDI message
Char map
c
99
4-byte ASCII character
Note the:
time map is in the format %{seconds: seconds, fraction: fraction} where seconds and fraction are 32-bit numbers.
MIDI map is in the format %{midi: value} where the value is a 4 byte MIDI message
Char map is in the format %{char: value} where value is a single character string (e.g. "A"), a single char (e.g. 'A' or ~c"A") or an integer of an ASCII char (e.g. 65).
Return format
The function will return a tuple with the first element containing the OSC type tag, and the second element the OSC encoded value such as {105, <<0, 0, 0, 1>>}.
If an elixir List is given, each argument in the list will be encoded and a list is returned, for example:
An unrecognised Elixir type will return an error tuple in the following format:
{:error,"Unknown type"}
Examples
aliasOSCx.Encoder# Encode an integer of value 1iex> Encoder.encode_arg(1){105,<<0,0,0,1>>}# Encode a float of 2.1iex> Encoder.encode_arg(2.1){102,<<64,6,102,102>>}# Encode a string of "hello world" (this will also add padding do the end)# Bitiex> Encoder.encode_arg("hello world"){115,<<104,101,108,108,111,32,119,111,114,108,100,0>>}# Encode a 64-bit integeriex> Encoder.encode_arg(9_223_372_036_854_775_700){104,<<127,255,255,255,255,255,255,148>>}
OSC-timetag: 64 bit, big-endian, fixed-point floating point number
Takes a map in the format of either:
%{seconds: seconds, fraction: fraction} where seconds and fraction are 32-bit integers
%{time: value} where value is a 64-bit integer.
Immediate time
OSC can encode a time tag which means "process immediately". This is a time tag with a value of 63 zero bits followed by a one in the least signifigant bit.
You can set an immediate time by using the :immediate atom as follows:
%{time::immediate}
OSC time tag specification
The OSC Specification defines a time tag as a 64-bit fixed-point number that represents a time in seconds since midnight on January 1, 1900.
The first 32 bits of the timetag represent the number of seconds, and the last 32 bits represent fractional parts of a second to a precision of about 200 picoseconds.
This is the representation used by Internet NTP timestamps.