Version: 6.0.0

# OSC

Visibox listens for **OSC** (Open Sound Control) messages over the network, so anything that speaks OSC can drive it: a phone running TouchOSC, a QLab cue stack, Resolume, a Max patch, a Lemur layout, or a lighting console with an OSC module. Visibox can also send its state back, so a fader on your tablet moves when someone changes the volume in the app.

If you are choosing between integrations: OSC is the right one for a purpose-built control surface and for cue systems that already talk OSC. For scripting from a shell, see [Command Line Interface](https://manual.spaceage.tv/6.0.0/integrations/cli/). For an application you are writing yourself, see [Visibox API](https://manual.spaceage.tv/6.0.0/integrations/api/).

## Connecting

|  |  |
| --- | --- |
| **Protocol** | OSC 1.0 over UDP |
| **Port** | `17735`, unless you change it under **OSC Port** in [Settings > Remote](https://manual.spaceage.tv/6.0.0/integrations/remote-pairing/#osc-port) |
| **Address** | Your computer’s IP address on the local network |

Point your OSC app at your computer’s IP address and port `17735`. Everything on this page goes to that one address, and the examples below all assume the default port.

### Discovery

Visibox advertises itself on the local network with Bonjour, under the service type `_visibox._tcp`. The OSC port is published as an `oscPort` field in that service’s TXT record. There is no separate `_osc._udp` service, so an app that browses only for OSC services will not find Visibox. Point it at the IP address and port instead.

### Pairing

Every OSC sender has to be a paired device first, and that includes an app on the same machine as Visibox.

OSC has no pairing step of its own. Pair the device over the regular API connection first, and pairing it authorizes its IP address for OSC as well. See [Remote Pairing](https://manual.spaceage.tv/6.0.0/integrations/remote-pairing/). Once the IP is paired, OSC messages from it are accepted with no token in the message.

If OSC seems to be doing nothing at all, an unpaired sender is the first thing to check.

## The Address Space

### Playback

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/play` | none | Start playback. |
| `/visibox/stop` | none | Stop playback. |
| `/visibox/pause` | none | Pause. |
| `/visibox/resume` | none | Resume from a pause. |
| `/visibox/play-toggle` | none | Toggle between play and stop. |
| `/visibox/pause-toggle` | none | Toggle between pause and resume. |

### Clips

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/clip/trigger` | `index` (int), `songID` (string, optional) | Trigger a Clip by its position. |
| `/visibox/clip/release` | `index` (int), `songID` (string, optional) | Release a Clip. See below. |
| `/visibox/clip/next` | `anySong` (int, optional) | Next Clip. Pass `1` to cross into the next Song. |
| `/visibox/clip/prev` | `anySong` (int, optional) | Previous Clip. |
| `/visibox/clip/random` | `allSongs` (int, optional) | A random Clip from the active Song. Pass `1` to pick from every Song. |

`/visibox/clip/release` is the other half of a held button. It does nothing unless the Clip is in Gate launch mode, so a button that sends trigger on press and release on release is safe to point at any Clip. Gate is covered on the [Launch Modes](https://manual.spaceage.tv/6.0.0/launch-modes/) page.

### Songs

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/song/select` | `index` (int), `stopPlaying` (int, optional) | Select a Song by its position. |
| `/visibox/song/next` | `noStop` (int, optional) | Next Song. Pass `1` to leave playback running. |
| `/visibox/song/prev` | `noStop` (int, optional) | Previous Song. |

### Volume

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/volume` | `level` (float, 0 to 1) | Set the master output level. |

### Real-Time Control

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/control/<letter>` | `value` (float) | Drive a Control. |
| `/visibox/param/<targetId>` | `value` (float) | Write one Target directly. |

`<letter>` is a Control’s letter: `/visibox/control/A`, `/visibox/control/b`, and so on. Case does not matter. Addressing by letter is the portable way to do it, because a layout you built for one project still lands on the right Control in another.

`<targetId>` is everything after `/visibox/param/`, slashes and colons included. `/visibox/param/clip:abc123/opacity` addresses the Target `clip:abc123/opacity`. Use this when you want to skip Controls and write a parameter straight from your surface.

Both take a real number: an OSC float or int. A string is rejected even when it looks like a number, because an empty string would read as zero and black out a Control bound to opacity mid-show. Send a float.

Neither address is clamped at this end. A Control is conventionally driven 0 to 1, and the shaping happens in the Control’s own settings. See [Real-Time Control](https://manual.spaceage.tv/6.0.0/real-time-control/).

### System

| Address | Arguments | What it does |
| --- | --- | --- |
| `/visibox/panic` | none | Reload every Visibox window. |
| `/visibox/fullscreen` | none | Toggle full screen. |

### Counting from zero or one

Clip and Song positions count from zero by default, so the first Clip is `0`. The Controller shows them numbered from one. To make your surface match what you see on screen, send this once:

```
/visibox/config/index-base  1
```

The setting applies to `/visibox/clip/trigger`, `/visibox/clip/release`, and `/visibox/song/select`, and only for the sender that asked for it. Visibox remembers the opt-in by the sender’s address and port, so an app that reconnects from a different port needs to send it again. It does not change the numbers Visibox sends back in state messages, which stay zero-based. It does not affect the Real-Time Control addresses, which do not use positions at all.

Each way into Visibox counts separately. OSC and the [API](https://manual.spaceage.tv/6.0.0/integrations/api/#counting-from-zero-or-one) are zero-based unless you ask otherwise; the [command line tool](https://manual.spaceage.tv/6.0.0/integrations/cli/) is one-based unless you ask otherwise. Set the base explicitly on anything you build and you never have to remember which is which.

## State Feedback

Ask Visibox to send its state back and a fader on your surface can follow what the app is doing.

### Subscribing

```
/visibox/subscribe  <replyHost:string>  <replyPort:int>
```

You can shorten it. Send one integer and Visibox uses your IP address with that port. Send nothing at all and it replies to the address and port the message came from, which is what most surfaces want.

To stop, send `/visibox/unsubscribe`.

Visibox tracks up to 32 subscribed endpoints at once. A 33rd pushes out the oldest.

### What comes back

| Address | Arguments | Sent when |
| --- | --- | --- |
| `/visibox/state/playback` | `status` (string) | Playback changes. `playing`, `paused`, or `stopped`. |
| `/visibox/state/song` | `songID` (string) | The active Song changes. |
| `/visibox/state/volume` | `level` (float) | The master output level changes. |

Playback and volume are sent as soon as you subscribe, so your surface can catch up without waiting for something to move. These go out when a value actually changes, not on a timer.

### Errors

A Real-Time Control message Visibox refuses is answered rather than ignored:

```
/visibox/error  <message:string>
```

You get one for an unknown Control letter, a missing value, or a value sent as a string. Three things to know before you rely on it:

*   **It needs somewhere to land.** The reply goes to a feedback endpoint subscribed from the same IP address, and otherwise back to the port the message came from. Many OSC apps send from a port they never listen on, so unless you subscribe first, the reply is thrown away.
*   **Replies are matched by IP address**, not by application. If two OSC apps are running on one machine and one of them is subscribed, it gets the other’s error messages.
*   **Replies are throttled** to one per sender per second. A fader sends messages far faster than that, and one error you read beats two hundred you drop.

## Examples

### TouchOSC

1.  Open TouchOSC on your phone or tablet.
2.  Set the target host to your computer’s IP address.
3.  Set the target port to `17735`.
4.  Give each button and fader an OSC address from the tables above.
5.  For feedback, set a receive port in TouchOSC, then send `/visibox/subscribe` with that port number.

A fader mapped to `/visibox/control/A` sending a float from 0 to 1 is the whole setup for driving a Control from a tablet.

### QLab

Use a Network cue. Set its destination to your computer’s IP address and port `17735`, then set the OSC message on the cue. A cue that reads `/visibox/clip/trigger 3` fires the fourth Clip of the current Song as part of your cue stack, so lighting, sound, and visuals all move on one Go.

### Resolume

Resolume can send OSC out to another application. Point its OSC output at your computer’s IP address and port `17735`, then map a Resolume control to a Visibox address. Sending `/visibox/song/next` from a Resolume clip lets one operator’s deck advance the other’s.

### Max

```
[udpsend <your-ip> 17735]  |[prepend /visibox/play]  |[bang]
```

Swap the address in the `prepend` object for any of the ones above. To drive a Control, put a float in front of the address:

```
[udpsend <your-ip> 17735]  |[prepend /visibox/control/A]  |[slider]
```

### From a terminal

The `oscsend` tool that ships with liblo is a quick way to test an address without building anything:

```
oscsend localhost 17735 /visibox/playoscsend localhost 17735 /visibox/clip/trigger i 0oscsend localhost 17735 /visibox/volume f 0.75oscsend localhost 17735 /visibox/control/A f 0.75oscsend localhost 17735 /visibox/subscribe i 9000
```

## Troubleshooting

**Nothing happens at all.** The sender is probably not paired. Pair the device in [Settings > Remote](https://manual.spaceage.tv/6.0.0/integrations/remote-pairing/) first, even if it is on the same machine.

**Playback addresses work but Control addresses do not.** Real-Time Control is answered separately. Subscribe for feedback and read `/visibox/error` to see why a message was refused.

**A fader does nothing until it reaches a certain point.** That is takeover on the binding, doing its job. See [Real-Time Control](https://manual.spaceage.tv/6.0.0/real-time-control/).

**The wrong clip fires, always one off.** Send `/visibox/config/index-base 1` from your surface, or renumber your buttons from zero.

## See Also

*   [Real-Time Control](https://manual.spaceage.tv/6.0.0/real-time-control/) for what Controls are and how to shape them.
*   [Remote Pairing](https://manual.spaceage.tv/6.0.0/integrations/remote-pairing/) for pairing a device.
*   [Visibox API](https://manual.spaceage.tv/6.0.0/integrations/api/) for the WebSocket and HTTP interfaces.

Source: https://manual.spaceage.tv/6.0.0/integrations/osc/
