Overview

Messages and bundles

An OpenSoundControl message is an address and some values: /freq 440. A bundle is a list of messages and bundles. Everything here is one or the other: a value is a message, a program is a bundle, a function is a bundle stored under a name, and so is the machine that runs them.

In OSC a bundle’s elements have no names, so a bundle with a name is a message whose payload holds the bundle as a blob, and the message carries the address. That is what a register is, and why /_s is an address. The same shape has a typetag of its own inside a message, |, a bundle laid out like a blob.

The machine and its registers

The machine keeps its state in registers — bundles with names, inside the machine’s own bundle:

Because every register is a bundle, the whole machine is one valid OSC bundle at every moment; nothing is serialised on the way out because nothing was ever in another form. Hosts and modules can add registers of their own. The registers has the naming rule and how an address’s first segment selects one; the C reference’s machine page has the run loop.

Two languages

osen is the language people write; the machine runs ose, its instruction language, one message per instruction, and osen is a module that turns source into it. Every host runs both. Side by side:

  ose osen
what it is the machine’s instruction language the language people write
made of OSC messages, one per instruction OSC bundles with a syntax
bind a name /@ :
read a name /$ the bare name
call /! before an address (args) /o/fn
comment /#/ #
separator one message per element , — a newline is whitespace
files .ose .osen

The same thing, twice. Binding 10 to /foo and reading it back, in ose — three instructions, each an OSC message:

/,/i/10        push the integer 10
/@/foo         assign it to /foo
/$/foo         look /foo up again

and in osen:

/foo : 10,
/foo             →  : 10

The osen form is not shorthand for the other. It is source text that the osen module turns into a bundle, which the machine then runs; /foo : 10 never becomes an instruction, it becomes a bundle. An analogy that fits: ose is to osen roughly as assembly is to C. Everyone porting the machine needs the instruction set written down; almost nobody writing programs looks at it.

Addresses are the interface

A host binds what it can do — pins and WiFi, WebAudio, inlets and outlets, Python functions, UDP and files — into its host register as addresses. A program calls a capability on another host the way it calls one on its own. What each host binds: command line, Max, browser, microcontroller, Python.

What travels

A program is a bundle of messages the machine has not run yet. A running machine is a bundle holding its registers, the unrun program among them. Either can be sent. A program that arrives is run there; a machine that arrives continues where it was, and finds the far host’s capabilities in that host’s own host register, which stays where it is. How each host takes what you send, and what carries it: Between hosts.

The layers

host unix.o.se max.o.se web.o.se mcu.o.se py.o.se osekit lookup, types, module loading libose the machine ose, its instruction language OSC: the state and the wire o.se.osen osen, the language people write o.se.stdlib o.se.udp o.se.tcp o.se.time

A host is a program with the machine inside it, through the kit; a module is a library the host loads or links in, and what it provides lands in the machine as addresses.