This is the first post in a series of articles on Open Sound Control (OSC) written by field service engineer and programmer Sam Smallman.
Open Sound Control (OSC) was invented in 1997 by Adrian Freed and Matt Wright at the Center for New Music and Audio Technologies (CNMAT). It goes without saying, with the clue being in the name, that this was a technology designed, much the same as MIDI, for the audio industry. It was designed as a means of communication between computers, sound synthesizers and other multimedia devices, and optimized for modern networking. Needless to say, OSC has come a long way since 1997. After receiving its final revision to the spec, becoming 1.1 in 2009, the protocol has expanded into many industries and is used in a variety of different ways, including robotics, web services, video and, of course, lighting control. One might suggest that its name should be changed to reflect its use and become “Open Systems Control” as suggested in the NIME 2009 Paper, but it’s lasted so long as Open Sound Control, I doubt it will change or that my gentle nudge will have an impact.
OSC is a content format, often referred to as a protocol, but only in the weakest sense, in that it defines a message format. Simply put, OSC does not define the semantics or language of a message, it only states how the message should be composed. This means that unlike protocols such as MIDI Show Control where a “Go” command is universally understood and standardized between different devices, with OSC the message could be, and often is, composed in a variety of different ways. There is no set structure for any such commands, which gives a wealth of flexibility, allowing manufacturers to publish their OSC Dictionaries, enabling users to easily connect different systems and applications together. Triggering cues, moving faders, gathering and changing data from each other. OSC is your oyster.
It’s important to state that OSC is classified as a Layer 6 or Presentation Layer entity. What is meant by that is that it is transport independent. To use our postcard analogy again, OSC describes how we should write our message but it doesn’t dictate how the message should be sent, whether it be via Royal Mail, UPS or walking down the street ourselves and hand delivering it. In this particular article, we will discuss OSC as a content format, but don’t worry, the use of OSC across different transport protocols will certainly follow within this series.
The format of an OSC Message can be broken up into three parts – an Address Pattern, an OSC Type Tag String, followed by zero or more Arguments.
1. An address pattern is a string of Unicode characters encoded in UTF-8, beginning with the character “/” (forward slash) e.g “/eos/cue/1/0.5/fire.” Sometimes referred to as the namespace, it is often based around “slash” notation similar to URLs, where the structure of a system or devices functions, and parameters can be laid out as a tree hierarchy, which can be called the “address space.” An address pattern is simply the full path from the root of the address space tree to a particular node.
2. An OSC Type Tag String is a string of characters beginning with the character ‘,’ (comma) followed by a sequence of characters corresponding exactly to the sequence of arguments in the message (e.g “,ifsbt”). Each character after the comma is called an OSC Type Tag and represents the type of data of the corresponding argument.
OSC Type Tag | Data Types | Examples |
i | Integer | 18, 79, 21 |
f | Float | 3.8, 0.4, 36.9 |
s | String | King Kong, Eos Console, Hello World |
b | Blob (aka a byte array) | 01001010 01011111 01001011 10111000 |
t | Time Tag | An OSC Timetag encoded in NTP Format |
An argument can also have no bytes assigned in the argument data; at this point the Type Tag corresponding to the argument is used to define the meaning.
OSC Type Tag | Meaning |
T | TRUE |
F | FALSE |
N | Null (aka nil, none) |
I | Impulse (aka “bang”), used for triggers. This type was named “infinitum” in OSC 1.0. |
For a typical OSC application, user knowledge of the OSC Type Tag is not necessary. The OSC Type Tag is generally used to distinguish what type of data is about to be read, and perhaps some error checking.
3. Each OSC Message can have multiple arguments of varying types, or none at all. In most cases, developers use the address pattern to self-document and describe the data within the arguments that are to follow. E.g.:
Example 1:
Address Pattern = “/time/out/hoursPerDay”
OSC Type Tag String = “,i”
Arguments (1) = “24”
Example 2:
Address Pattern = “/cue/{cue number}/colorName”
OSC Type Tag String = “,s”
Arguments (1) = “green”
Example 3:
To retrieve cue information from ETC’s Eos family consoles, you would send an OSC message with an address pattern “/eos/get/cue/{cue list number}/{cue number}.” In turn, it would return the OSC message:
Address Pattern = “/eos/out/get/cue/{cue list number}/{cue number}”
OSC Type Tag String = “,issiiii…”
Arguments (27) =
1 <- Index
B0BAW0A0-3BBE-888B-F61CA125D0B0 <- OSC UID
Houselights Out <- Label
3 <- Up Time
5 <- Down Time
0 <- Up Time Delay
0 <- Down Time Delay
…
A Bundle is a sequence of messages or bundles. This allows for the nesting of OSC Messages where all of the messages in the same bundle will be processed by the application atomically; in other words it should be as if all of the messages in the bundle are processed in a single instance.
Each bundle has a timetag that specifies the desired time at which the messages in the bundle should execute and, for those who read closely, you will have noticed you could add an argument to an OSC Message as a timetag, allowing precise timing of the execution of an OSC Message, which could allow pre-defining a sequence of events to play out.
OSC Bundles offer the solution of being verbose with the address pattern of an OSC Message, describing individual attributes of an element but allowing the application to treat them as one, unified and processed together.
For Example an OSC Bundle could be made up of two OSC Messages:
OSC Message 1:
Address Pattern = “/fixture/1/pan”
OSC Type Tag String = “,f”
Arguments (1) = “270.0”
OSC Message 2:
Address Pattern = “/fixture/1/tilt”
OSC Type Tag String = “,f”
Arguments (1) = “14.6”
This example describes the pan and tilt attributes of fixture 1. Sending two OSC Messages within a bundle, each with an address pattern that clearly describes the accompanying argument, removes all confusion.
In comparison, the same information for our fixture 1 could be sent as a single OSC Message, but notice there could be confusion as to which accompanying argument relates to which attribute:
OSC Message:
Address Pattern = “/fixture/1/focus”
OSC Type Tag String = “,ff”
Arguments (1) = “270.0”
Arguments (1) = “14.6”
So, let’s take a step back here and look at what we have. A “protocol” that allows a creative, intuitive and extensible addressing scheme or dictionary of commands to allow a user to interact with devices to trigger actions or request information from them. You need only look at the OSC Dictionaries for our Eos, Cobalt and ColorSource families to see the wealth of information that can be retrieved and the actions available to use. These allow users to create and use applications that can act as remotes to view and interact with the rig, create custom paperwork for documentation of touring and archived productions, and not to mention the ability to create incredible shows of truly interactive capabilities.
You’re probably asking yourself, “But how do I use this wonderful protocol, Sam?” Well, stayed tuned. We’ve started with a good overview of the protocol. In the rest of the series, we will explore how to implement it and, if you can’t wait, my inbox is always open: sam.smallman@etcconnect.com