LEMUR

[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.

QLabScreenSnapz001

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

Lemur EditorScreenSnapz001

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

Lemur EditorScreenSnapz002

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.

Reflector 2ScreenSnapz001

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

LEMUR Faders

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.

Lemur EditorScreenSnapz003

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:

/cue/selected/level/1/1

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:

Lemur EditorScreenSnapz004

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.

Lemur EditorScreenSnapz005

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.

 

Lemur EditorScreenSnapz007

(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

range(Fader1.x,-60,0)

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

Lemur EditorScreenSnapz008

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.

Lemur EditorScreenSnapz009

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.

Lemur EditorScreenSnapz010

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.

Lemur EditorScreenSnapz011

Create a new script called setup

Lemur EditorScreenSnapz012

In the script pane, bottom centre, set it to to execute on load.

type the following into the script window

setattribute(MultiBall,’ball_enable’,{0,1});

Lemur EditorScreenSnapz013

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:

Fader1.x=(1-x[1])*y[1];
Fader2.x=x[1]*y[1];
Fader3.x=(1-x[1])*(1-y[1]);
Fader4.x=x[1]*(1-y[1]);

Lemur EditorScreenSnapz014

(Note that  x[1] 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:

Fader1.x=1+log((1-x[1])*y[1])/6.4;

(Thanks to Rich Walsh for help with the maths on this)

Replace the script for faderDriver in the MultiBall object with this:

decl panlawval;
panlawval=6.4;
Fader1.x=1+log((1-x[1])*y[1])/panlawval;
Fader2.x=1+log(x[1]*y[1])/panlawval;
Fader3.x=1+log((1-x[1])*(1-y[1]))/panlawval;
Fader4.x=1+log(x[1]*(1-y[1]))/panlawval;

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:

range(speed.x,-0,5)

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.

Lemur EditorScreenSnapz016

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

setattribute (MultiBall,’physic’,1);

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

setattribute (MultiBall,’physic’,2);

This sets the Physics of the MultiBall object to Mass-Spring

Lemur EditorScreenSnapz017

We then need to set the physics variables in the behaviour panel

Set cursor mode to Barycentric

Set attraction to:
(1*range(speed.x,0,5))+Motion.x

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:

(range(speed.x,0,5))*Motion.x

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.

Lemur EditorScreenSnapz018

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

range(LFOx.x,-1,1)*range(speed.x,0,5) 

LFO_y needs:

range(LFOy.x,-1,1)*range(speed.x,0,5)

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

if(LFOswitch.x==1)
{
MultiBall.x[1]=sin(time*(range(LFOx.x,-1,1)*range(speed.x,0,5)))*0.5+ 0.5;
MultiBall.y[1]=sin(time*(range(LFOy.x,-1,1)*range(speed.x,0,5)))*0.5+ 0.5;
}

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

LFOswitch.x=0;

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.

Lemur EditorScreenSnapz019

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:

clock_start (0);
clock_setbpm (0,60);

Select the MultiBall faderDriver script in the Project and set the execution to :

On Clock      Clock 0         On 1/64 note

Lemur EditorScreenSnapz019

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

 

Chapter Graphic modified by Mic Pool from an original photograph by Francis C Franklin  licensed and  redistributed under a
Creative Commons
Attribution-Share Alike 3.0  license

 

MenuGraphic