[requires QLab 4.1]
If you are familiar with constructing TouchOSC controls on tablets (or phones) then you may have been frustrated with some of the limitations of that program. LEMUR by liine is a more advanced type of programmable controller for tablets that, although more complex, has significant advantages when creating controllers for QLab.
Objects in Lemur can define what state changes will trigger OSC (or MIDI) outpu. e.g trigger when value x goes from 0 to positive. This avoids the double trigger problem in OSC when a message is sent on the press AND release of switches.
Objects in Lemur are scriptable so can offer far more functionality than just sending the OSC message associated with the control.
There is a greater range of objects including physics based objects
The computer based editor syncs with the tablet and all changes to programming are reflected almost immediately on the tablet.
Lemur is also a real bargain. It started life, in 2007, as a touch screen hardware device called Lemur Jazz Mutant. This cost thousands of dollars. If you have a tablet you can now have even greater functionality than the original controller for around $25.
The example tutorial constructs a physics based Quad Auto Panner to control the crosspoint matrix in a QLab audio cue.
Here’s it is in action (Best Viewed full screen):
Because the QLab crosspoints do not update continuously, I have used a sine wave as the target of the audio cue, so the changes can be observed on the slider level meters.
The four sliders on the left of the Lemur controller send OSC to QLab to control the crosspoint matrix of an Audio Cue with a mono file to cue outputs 1-4.
Under the faders is a readout of the current fader levels, scaled to match the QLab dB levels.
In the centre of the screen is a LEMUR Multiball Object. This is an X-Y pad which also has a physics engine which allows up to 10 balls to bounce around within its bounds.
Beneath that is a switch which enables the physics engine for Motion or disables it for Manual / LFO control.
A fader across the top of the MultiBall Object controls the speed of the ball in the Motion mode
In Motion Mode you can throw the ball by dragging and releasing it. It will continue for ever at the release velocity, which can be modified from 0x to 2x using the speed controller.
In Manual mode the ball can be dragged around the window and remains where it is left when you lift your finger. Set the speed to maximum for fastest response.
Alternatively set a slower speed e.g 0.03, and click at the point you would like the ball to travel to, at the speed set.
When in Manual Mode the LFO can be switched on. This allows the ball to be driven by a sine wave generator, with variable frequencies for the x and y axis set by the 2 knobs on the right of the controller in conjunction with the speed controller. This allows complex but regularly repeating pan patterns to be set.
The tutorial produces a Quad Panner that is usable, but the main purpose of this chapter is to introduce some LEMUR programming examples. If you are mathematically inclined you will be able to improve many aspects of the project e.g pan laws, LFO shapes etc.
Before starting this tutorial I recommend a quick skim of the Lemur manual and watching a few of the manufacturers tutorial videos here
Here is the QLab workspace we are going to control.
The audio cue has a mono file as it’s target which is sent to outputs 1-4 using the crosspoint matrix. You can control the overall level in QLab using the sliders. The Quad Panning will be achieved through Lemur sending OSC messages to control the crosspoints. You can download the workspace here
Connecting your Mac to LEMUR
Open Lemur Editor on the Mac and Lemur on your tablet
Open a new document in Lemur Editor and set the document size to iPad (or your devices size) using the pop up menu in the top right of the editor window
Click the play arrow in the top right to get a list of available devices running Lemur
Select the iPad you want to sync to and connect.
Click on the Lemur synchro icon next to the connect icon in the top right.
You are now synchronised.
Connecting LEMUR to QLab
From the gearwheel menu in the top left of Lemur on your tablet select more settings.
In OSC targets connect OSC 0 to your Mac running QLab by typing it’s IP address into the host field and typing 53000 (QLabs OSC receive port) into the Port field Then Click Done
First we will create 4 faders and set them up to send OSC messages to control the QLab crosspoints.
In Lemur Editor on the Mac; Drag a fader object from the palette to the left of the Lemur work area.
In it’s OSC mapping tab at the top right of the editor type a custom address into the address area for the x parameter:
note that the pop up menu to the right of the field is set to any which means this will be transmitted any time the value of x changes. Have a look at the other options offered on this menu (but make sure you set it back to any)
This is the OSC message that will set the level in the selected cue in QLab of the crosspoint that feeds cue output 1 .
QLab will want levels in the range -60 to 0, so we type these into the custom scale fields. (If you want the messages to be sent to a specific cue number you can change all references to selected throughout the tutorial to the cue number you want to address).
All other parameters can be left as the default.
When you have made any edits click outside the script window to update the script.
When you finish, the OSC mapping pane should look like this:
We can now test this by moving the fader and checking the crosspoint level changes in QLab (QLab will only update when it finishes receiving OSC)
We can now copy and paste this fader object 3 times to make the 4 faders we need. We also need to edit the custom address fields for each slider so they control the correct crosspoints in QLab.
Fader 2 will have /cue/selected/level/1/2, Fader 3 /cue/selected/level/1/3, and Fader 4 will be /cue/selected/level/1/4
Again check these are controlling the 4 QLab crosspoint correctly.
At this stage we can label the Faders. If we use Monitor objects to label them we can also have them display the fader value.
Lemur Faders produce an OSC output between 0 and 1. These outputs are scaled to the values in the scale box underneath our custom address in our case -60 to 0
We can also get a Monitor object to display values scaled to this range.
Drag a monitor object from the palette and place it under Fader 1
In the properties tab in the lower left of the editor name it slider1
Set the width to 50, the height to 32 and the font size to 9pt
type Fader1.x in the value field to tell it what to display
Set the precision to 1 decimal place.
(It’s probably worth pointing out at this stage that all names in Lemur are case sensitive. If you typed fader.x your value will be in red which means it is invalid, typing Fader.x will correct it and the text in the field will turn black indicating a valid value)
If you move the fader up and down a value between 0.0 and 1.0 will be displayed.
To get the actual value sent to the QLab crosspoint we change the value to
which scales the displayed value to a float between -60.0 and 0.0.
Copy and paste 3 times to get 4 monitors and place them beneath each fader. Lemur editor will automatically name them slider2…..slider 4
Edit the value of slider 2 to:
range(Fader2.x,-60,0) and so on for sliders 3 and 4
The X/Y Pad
We need to create an X/Y pad that can interpret the cursor position as a level for each of our four faders, so the apparent position of a sound source corresponds to its geographical xy coordinates on the pad.
The X/Y pad in Lemur is a controller object on steroids!. It can have up to 10 cursors, represented by balls. These balls have a full physics engine, so their speed, friction and attraction to the operators fingers can all be controlled, either directly, or through mathematical expressions.
This example just uses a single ball to control 4 faders for a mono source, but is easily expanded to, for instance, 4 balls to control each track of a 4 track wav, by simultaneously sending OSC to 16 crosspoints.
We’ll start by creating an xy controller and linking it to control our 4 faders
Drag the multiball object to the centre of the editor workspace.
In properties set the number of balls to 1
This creates a ball numbered 0. If we add more balls then it might be confusing to have a ball numbered 0 so we are going to change the ball numbering.
We increase the number of balls to 2.
We then highlight the project folder in the Project Pane in the bottom right of Lemur editor and click the script button at the bottom of the pane.
Create a new script called setup
In the script pane, bottom centre, set it to to execute on load.
type the following into the script window
note that each script line is terminated with a ;
This instruction tells Lemur to only enable the second ball, i.e the one labelled 1, and hides the ball labelled 0.
We now need to link the ball to the 4 faders.
Highlight the Multiball object in the Project pane and click the script button
Make a new script with the name faderDriver.
The script will be nested under the MultiBall Object
Select the script in the project window
Set the execution to frame, which means the script will execute 60 times per second
Type the following in the script window:
(Note that x in the script means the x value of ball 1.)
Fader 1 which will control the front left output of QLab is set to a value which decreases as the ball moves away from the top left of the MultiBall Object. Remember the raw output of the object for each axis (x and y) is a value between 0.0 and 1.0 As the ball moves left to right the x value increases. Subtracting the x value from 1 gives the decreasing value we need. we multiply the x value by the y value. When the ball is at the top we are multiplying by 1, when it is in the middle by .5, and at the bottom by 0, For faders 1 and 2 these are the values we want so we use the y value as is. For the rear outputs (faders 3 and 4) we want the values to increase as the y value decreases so again we subtract the y value from 1.
Remember to click outside the script window to finish the script.
You can now test that the movement of the ball in the MultiBall Object is acting on the faders.
Move the ball to the corners and you will see that the fader for that corner of the Quad Pan is at 0dB and all others are at -60dB
If you move the ball to the centre top of the controller window you will see that faders 1+2 are at equal level but that this level is 30dB quieter than the level at the corners. Even allowing for the fact that the sound is coming out of 2 speakers at that level, this will create a significant dip.
If you move the ball to the centre of the left hand side of the object you will see the same level dip between faders 1 and 3. With the ball in the centre of the object the sound comes from all 4 speakers but at a level of -44dB again a substantial dip.
What we need to do is transform the linear output of the MultiBall Object to produce a logarithmic relationship with the Fader, so that when the ball is between 2 outputs the dip is only around 6dB and when it is in the centre the dip is around 12dB. This will result in a reasonably constant output regardless of the position of the ball.
For fader 1 a formula that achieves the above is:
(Thanks to Rich Walsh for help with the maths on this)
Replace the script for faderDriver in the MultiBall object with this:
We have replaced the value 6.4 with a variable panlawval (which is declared at the top of the script). Changing the value of this variable will allow fine control of the pan law applied to the controller.
Repeat the test and you will see that the dip is reduced to the level required, to just compensate for the number of speakers in use at any position.
Adding the Physics engine
First we will create a horizontal fader named speed
Drag a Fader object from the Palette to the controller. Move the handles so it has a horizontal orientation and place it above the MultiBall Object. Name it speed
Drag a Monitor object from the palette to a position above the Fader and Name it SPEED.
In the script panel define what the object will monitor by typing:
This displays the speed.x value (from the fader) with it’s range scaled (from its raw range of 0.0 to 0.1) to 0.0 to 5.0
Set the precision of the Monitor Object to 2 in the properties panel.
Next create a button to switch MOTION mode ON:
Drag a CustomButton object from the Palette to the controller. Name it Motion and set it’s Behaviour to Switch
Drag a CustomButton object from the Palette to the controller. Name it Motion.
Label its off state as Manual/LFO, and its on state as MOTION in the properties panel in the bottom left of the editor.
In the project window select the MultiBall Object create 2 scripts called switchOFF and switchON.
In the script window:
For the switchOFF script
Set execution to On Expression x and set the trigger to message sent when value goes from positive to 0
This sets the Physics of the MultiBall object to interpolate
For the switchON script
Set execution to On Expression x and set the trigger to message sent when value goes from 0 to positive
This sets the Physics of the MultiBall object to Mass-Spring
We then need to set the physics variables in the behaviour panel
Set cursor mode to Barycentric
Set attraction to:
This sets the speed the ball will travel to a finger placed on the pad.
Set Friction to: 0+z
This means that in Motion mode the ball will continue to move until a finger is placed on the object. When this happens MultiBall.z will change to from 0 to 1, which when added to the friction will result in full friction being applied causing the ball to stop.
Finally set the speed Behaviour with this:
If the Motion switch is OFF (Manual/LFO Mode) it’s x value is 0 so the speed will be 0
If the Motion Switch is ON the speed will be that set on the speed controller as Motion.x will have a value of 1.
Set the speed to 1. Test the physics engine by switching MOTION ON and throwing the ball by dragging and releasing it.
Increase and decrease the speed
Stop the ball by placing a finger on it
Switch to Manual/LFO Mode
Set the speed to maximum
Drag the ball around
Set the speed to 0.03 and place a finger some distance from the ball.
Create The LFO
Drag a CustomButton object from the Palette to the controller. Name it LFOswitch, and set it’s behaviour to Switch.
Label its off state as LFO OFF, and its on state as LFO ON in the properties panel in the bottom left of the editor.
Drag 2 Knobs from the palette and name them LFOx and LFOy
Drag 2 Monitor Objects name them LFO_X and LFO_Y.
LFO_X needs this in the script window
In the Project Pane select Project and create a new script by clicking the script button.
name the script LFO
set the execution to On Frame
type this in the script window
This means if the expression in the brackets is true (in this case that LFOswitch.x==1, i.e is ON, note the 2 equals signs to denote is equal to) the script between the curly braces will be executed.
This script is a fairly conventional sine wave generator
Set the speed controller somewhere in the middle and set 2 values on the LFO knobs.
Switch the LFO ON
Experiment with different values of Speed and Knob controls.
Select the Motion switchON script in the Project Panel
In the script add the following line
This means the LFO will be switched off when the MOTION switch is ON.
Finally, we can slightly reduce the data rate of the OSC messages. Lemur is very good at filtering unnecessary messages and will only send them when a value changes. In our case this means when the fader levels change. When the ball is moving the sliders are continuously updated and send OSC messages to QLab once per frame i.e 60 times a second or around every 16ms.
We can probably reduce this to a quarter this rate without causing any audible artifacts. To do this we will only execute the Multiball faderDriver script every 64ms.
We do this by starting 1 of Lemur’s 10 clocks and setting it’s tempo to 60bpm and then setting the execution of the fader driver script to use this clock rather than triggering on every frame.
Select the setup script in the Project Panel
Add the following script lines to the existing script:
Select the MultiBall faderDriver script in the Project and set the execution to :
On Clock Clock 0 On 1/64 note
a ¼ note at 60bpm would give a trigger every second so a 1/64 note gives a trigger 16 times a second which should be fine for our needs and cut the number of OSC messages to a ¼ of their previous rate.
The example QLab workspace, together with the LEMUR file can be downloaded for QLab 4 here