Touch OSC Wizardry

This chapter explores the creation of a complex iPad control surface for remote controlling QLab over a wifi network. If you are using QLab 4, much of what’s discussed here is best achieved using cue carts and the QLab Remote iOS app, an approach that’s described in detail in the cookbook chapter called Carts And Remotes. Nevertheless, it’s still worth reading this chapter as it contains a good deal of useful information about OSC.

There are a number of apps that will run on tablets or smartphones which enable you to construct remote control applications for QLab using OSC or MIDI. There are quite a few reasons you might want to do this:

  • You want to operate QLab at a distance from your computer (although it must be said that, in general, the official QLab Remote app is usually the best way to do this.)
  • You are operating QLab locally, and want to use a touch surface to extend its functionality.
  • You want to use a custom GUI to interact with QLab, possibly to limit the range of operations available to a user.
  • You want to create a simple interface as part of a display or interactive exhibit.
  • You want to operate more than one control at a time, e.g. drag five faders at once.

Touch OSC is a popular app for creating such a control surface. Although it is limited in internal programming functions, it is quite straightforward. Before we get into the main example, let’s look at just creating a simple GO button.

The OSC for a workspace-level GO command is very straightforward: /go. So we might create a button and assign the /go message to it. Touch OSC layouts, as they’re called, are created in the Touch OSC Editor app which can be downloaded here from the Touch OSC link above.

Touch OSC Editor Go Button

We then set up our OSC networking. This is done from the Touch OSC app on the iPad. “Host” is the field where you put the IP address of the Mac running QLab.

Touch OSC Network Setup

And finally, in QLab, go to Workspace Settings → OSC Controls and make sure Use OSC controls is switched on.


We now have a big green button which lights up when pressed and sends a /go OSC message to QLab. Like this:

How It Works

As you can see in the video, when you press the button the workspace GO is triggered. Unfortunately, when you release it, it sends the message again, and you get a double go. If you look at the Touch OSC edit screen above you will see it is sending two different messages: /go 1 for the press and /go 0 for the release (message plus value range). QLab listens for the OSC /go message but ignores the argument, the 1 or 0, when processing the message, and treats both the same resulting in the double go. There are various workarounds for this, none of which are entirely satisfactory. This doesn’t matter for all the major controls, because there is another method of OSC control already built-in to QLab. This method doesn’t even require any custom messages in Touch OSC, it will just work with the defaults.

Here’s our controller in Touch OSC editor, with the default message for the pushbutton: /1/push1 This means the button called “push 1” on Page 1 of the layout.

TouchOSC default

It will send /1/push1 1 for a press and /1/push1 0 for the release. In QLab, in Workspace Settings → OSC Controls, we click the Capture button, next to the GO field, and press the Touch OSC button.

TouchOSC capture

This captures the complete OSC message, including the argument. So the press message, /1/push1 1, will trigger the GO, because that’s what QLab is listening for. The release message, /1/push1 0, won’t trigger the GO, because the message is different. You can create all 15 buttons, one for each OSC control, and capture the default press messages for each.

Now that we have a simple example up and running, we will attempt something more complex.

The Touch OSC Jingle Player

This QLab workspace and associated Touch OSC layout provide a “Jingle Player” style set of 32 push buttons on the iPad. When you press a hotkey in QLab (the project uses 1), the player will load the first 32 files in a folder called “audio” inside the project folder with the workspace. Each Touch OSC button is named for the cue that will play when it’s pressed, and the buttons light up while their cue is playing and go dark when their cue stops. In order to do this, there has to be full bidirectional communication between QLab and Touch OSC. This is a bit of a problem as Touch OSC doesn’t have any built-in programming to parse any information that QLab sends to it, so all the clever stuff has to be done within QLab and passed to Touch OSC as simple OSC messages.

Here it is in action:

How It Works

First, you need to ensure that you have two-way communication between Touch OSC and your Mac. On the iPad, put the IP address of your Mac in the host field, in the example, this is

Touch OSC settings

You also need to enter ports 53000 and 53001 in the ports incoming and outgoing fields.

In QLab, in Workspace Settings → OSC (or, in QLab 4, Workspace Settings → Network), you need to set up a patch to send OSC to Touch OSC on the iPad. Patch 1 is usually used for loopback to localhost for QLab to send commands to itself. In this example, we have used Patch 2. Put the IP address of your iPad in the IP address field mine is

QLab settings

In the Touch OSC editor, we create 32 push buttons named 1-32 and with a custom OSC message: /cue/{button name}/start with a value range from 0 to 1. So for button 1, the name is 1 and the OSC is: /cue/1/start So if this button is pushed, it sends the OSC to QLab to start cue 1:

Button 1

On top of each button we create a label object and name it “n” plus the name of the button, so the label on button 1 is named “n1”. This gives us a name which QLab can use to address each label.

Touch OSC label

We also create a large push button, named PANIC, that will send: /cue/FAD/start. This will trigger the cue numbered “FAD” in QLab which fades and stops all running cues. We also need to make a label with the text “FADE ALL”, named “Fadelabel”, which QLab can use to address it.

All the scripts are kept out of the way in the QLab workspace in a cue list called Routines. Here is the Routines cue list in QLab:


The cue numbered SYNC is a Script cue, which finds the first 32 files in the audio folder of the workspace folder, loads them into the 32 cues in the Main Cue List, and sends the name of each cue to the labels on the buttons in Touch OSC.

tell application id "com.figure53.qlab.3" to tell front workspace
  set workspacepath to path
  if workspacepath is missing value then
    display dialog "The current workspace has not yet been saved anywhere." with title dialogTitle ¬
    with icon 0 buttons {"OK"} default button "OK" giving up after 5
  end if
  tell application "System Events"
    --Find the path of the audio folder that is in the folder with this workspace
    tell application "System Events"
      set sharedPath to POSIX path of container of file workspacepath
    end tell
    set workspacepath to sharedPath & "/audio"
    set theTitleList to list folder workspacepath without invisibles
    set theitemcount to number of items in theTitleList
  end tell
  set theindexnumber to 1
  repeat 32 times
    if theindexnumber is less than or equal to theitemcount then
      --set the filetarget for each cue to the correct item in the audio folder
      set newfiletarget to workspacepath & "/" & item theindexnumber of theTitleList
      set file target of cue ((theindexnumber as string) & "S") to newfiletarget
      set the armed of cue (theindexnumber as string) to true
      set the q name of cue ((theindexnumber as string) & "S") to item theindexnumber of theTitleList
      delay 0.1
      --set the button name to the first 12 characters title of the cue
      set thebuttonname to q list name of cue ((theindexnumber as string) & "S")
      if length of thebuttonname is greater than 12 then
        set thebuttonname to text 1 thru 12 of thebuttonname
      end if
      set thebuttonname to "--"
      set the armed of cue (theindexnumber as string) to false
      set the q name of cue (theindexnumber as string) to "--"
    end if
    set thecustomstring to "/1/n" & theindexnumber & " \"" & thebuttonname & "\""
    set the custom message of cue "OSC" to thecustomstring
    start cue "OSC"
    set theindexnumber to theindexnumber \+ 1
  end repeat
end tell

The files are loaded, the label names are created, and then the last part of the script sets the custom message of the cue called OSC and starts that cue. So in our example for button 1 the script creates a custom message to send to Touch OSC: /1/n1 "06 Ambush.wa" which tells Touch OSC to set the name of label n1 on page 1 to the name of the file that will be played.

The second Script cue is inside a loop, which repeats three times per second all the time. This cue is (re-)started by every button push, in case there has been an ESC key press.

tell application id "com.figure53.qlab.3" to tell front workspace
  set thecueindex to 1
  repeat 32 times
    set cueindex to (thecueindex as string)
    set therunning to the running of cue cueindex
    if therunning is false then
      set the custom message of cue "OSC1" to "/1/" & cueindex & " 0"
      set the custom message of cue "OSC1" to "/1/" & cueindex & " 1"
    end if
    start cue "OSC1"
    set thecueindex to thecueindex \+ 1
  end repeat
end tell

This script checks each button to see if its associated audio file is playing. If it is, it sends a message to Touch OSC to light up the corresponding button. For example, if cue 1 is playing, the following message is sent to Touch OSC:

/1/1 1

which lights up button 1 on page 1. If the script discovers that the cue has stopped playing, it sends:

/1/1 0

which switches the light off.

Music in Demo Video: “Ambush”, “Darkness is Coming” Kevin MacLeod ( Licensed under a Creative Commons Attribution 3.0 Unported License.

Creative Commons License