Skip to content

Instantly share code, notes, and snippets.

@stella3d
Last active February 22, 2022 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stella3d/6019e60781e8fee6b28755845b428ae1 to your computer and use it in GitHub Desktop.
Save stella3d/6019e60781e8fee6b28755845b428ae1 to your computer and use it in GitHub Desktop.
C# struct in OSC

Basics

We're only talking about writing the OSC messages here for brevity, just imagine the reverse process for reading.

Assume we already know about the OSC primitive types available. What if we want to transmit messages that involve multiple of these primitives at once?

As long as all fields of the struct map directly to an OSC primitive, then this is trivial, as OSC message have multiple fields.

struct OurOscMessage {
  int NumberOf;
  float DegreeOf;
}

becomes an OSC message with two fields: int then float.

oscWriter.Write(intValue);
oscWriter.Write(floatValue);

this works recursively - as long as all contained structs' fields map directly to OSC primitives, trivial to do.

struct ComplexOscMessage {
  int NumberOf;
  float DegreeOf;
  Vector3 Position;
}

becomes an OSC message with 5 elements:

oscWriter.Write(intValue);
oscWriter.Write(floatValue);
// next 3 are the Vector3 struct fields
oscWriter.Write(xFloat);      
oscWriter.Write(yFloat);
oscWriter.Write(zFloat);

Array support

Arrays of primitives should be trivial.

struct IntBufferMessage {
  int[] Data;
}

Serialization is fairly simple if the other size knows how to interpret the message: 1 OSC field of the proper type for each element in the array

foreach (int element in intBufferMsg)
{
  oscWriter.Write(element); 
}

However we may need to add Array type tags for some cases, where the receiver doesn't have the type definition of a message being received. OscCore doesn't really support this yet

// this runs during type tags writing step
const msgData = new int[16];    // assume this is real data not zeros
const intElemTags = new String("i", msgData.Length);
const string intArrTypeTags = $"[{intElemTags}]";

// actual array value serialization functions just as before
foreach (int element in intBufferMsg)
  { oscWriter.Write(element); }

array support should also mean that fixed-size buffers in unsafe structs work.

Arrays of structs

struct Element {
  public int Number;
  public Vector3 Position;
}

struct Message {
  public Element[] Data;
}

serializes like:

const bufferMsg = new Element[16];   // fill with real data

// this runs during type tags writing step
// repeat the Element struct's type tags ("ifff", int then 3 floats for Vector3)
const intElemTags = new String("ifff", msgData.Length);
const string intArrTypeTags = $"[{intElemTags}]";

// actual array value serialization functions just as before
foreach (int element in bufferMsg)
{ 
  oscWriter.Write(element.Number);
  oscWriter.Write(element.Position);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment