Docs / Nebula Sound System manual / 8. Hardware controllers (OSC)
8. Hardware controllers (OSC)
Nebula has a small, one-way door for hardware controllers, stage surfaces and controller apps (TouchOSC-style layouts, a Stream-Deck-style pad grid, a lighting/show-control rig) that speak OSC (Open Sound Control) — so they do not have to open a JSON-RPC socket and match up replies by id the way a script does (chapter 9 is for that).
Turning it on
The OSC door opens and closes together with the Local API switch — there is no separate toggle. In Options > Settings > Local API, switch it on. OSC then listens on:
- Host:
127.0.0.1only (never the network — the same reason the Control API is loopback only: neither door has real authentication that would be safe to expose beyond your own machine). - Port: UDP 8643 by default (next to the Control API's TCP 8642), changeable in the same settings page.
What it can do
OSC in Nebula is write-only, actions only — no replies, no way to read state back (use the
Control API or the MCP server for that; chapters 9 and 10). Each OSC address mirrors a Control
API method name: /nebula/<area>/<method>.
| OSC address | Arguments | Does the same as |
|---|---|---|
/nebula/transport/play |
— | Play |
/nebula/transport/stop |
— | Stop |
/nebula/transport/setTempo |
f bpm |
Set the tempo |
/nebula/project/setName |
s name |
Rename the project |
/nebula/project/setTempo |
f bpm |
Set the tempo |
/nebula/history/undo |
— | Undo |
/nebula/history/redo |
— | Redo |
/nebula/tracks/add |
— | Add a track |
/nebula/tracks/remove |
s target |
Remove a track |
/nebula/tracks/rename |
s target, s name |
Rename a track |
/nebula/tracks/setInstrument |
s target, s patch |
Set a track's instrument |
/nebula/tracks/setMuted |
s target, T/F |
Mute / unmute |
/nebula/tracks/setSolo |
s target, T/F |
Solo / unsolo |
/nebula/tracks/setVolume |
s target, f volume |
Set volume (0–1.5) |
/nebula/clips/quantize |
s track, s clip |
Quantize a clip |
/nebula/devices/add |
s track, s deviceId, s preset |
Add an effect |
/nebula/devices/remove |
s track, s refId |
Remove an effect |
/nebula/devices/setEnabled |
s track, s refId, T/F |
Bypass / un-bypass an effect |
/nebula/devices/move |
s track, s refId, i newIndex |
Reorder an effect |
/nebula/devices/setParameter |
s track, s refId, s key, f value |
Turn an effect's knob |
Argument types are the standard OSC ones: i (whole number), f (decimal), s (text), T/F
(true/false). Timeline editing (adding/moving/resizing clips, notes) and anything that needs a
reply (rendering to WAV) are deliberately not on this door — use the Control API for those.
Addressing a track without knowing its id
Every action above that targets a track or a clip takes a target/track argument as text. You
can send:
- a real id (the same UUID the Control API uses — from
tracks.listor a reply you already have), or - a plain number as text, 1-based:
"2"means the second track in the project. This is the practical choice for a controller surface, which usually only knows "fader 2", not a UUID.
("selected" — meaning "whatever is selected in the window" — is planned but not implemented
yet; sending it is refused like any other unrecognised target.)
Safety
A clumsy or misconfigured surface cannot hurt your song: unknown addresses, wrong argument types,
read-only addresses, and anything that is not a well-formed OSC packet at all are silently
ignored — nothing crashes, nothing changes, nothing floods the log. Every change that does go
through is a normal, undoable edit — Ctrl+Z in the window undoes something a hardware
controller just did exactly the same way it undoes a mouse click.
Updated 2026-10-31