Controlling Plugins

In this example we show how to control plugin values in real time, in two ways:

Audio Setup

For this example we'll create two LV2 plugins: a software synthesizer and a reverb; we'll feed the output of the synth into the reverb and connect the reverb to the main system outputs.

Also note that we set the initial value of the reverb amount to zero.



local synth = Lv2.Plugin("http://calf.sourceforge.net/plugins/Monosynth", "Velo Bee")

local reverb = Lv2.Plugin("http://calf.sourceforge.net/plugins/Reverb")
reverb.setControl("amount", 0.0)
reverb.connect(synth)

local mainOutput = Audio.StereoOutput("main", "system:playback_1", "system:playback_2")
mainOutput.connect(reverb)



Controller Setup

First we'll show how to control the plugin by sending MIDI control messages. Any controller that sends MIDI control change (CC) messages will work, we get a reference to the controller by creating a MIDI input and connecting it to our controller.


local controller = Midi.Input("synthControl")


Now we want to use one of the controller dials to control the oscillator mix on the synthisizer, we will use the dial that sends MIDI control change number 16, we connect the controller to the plugin using the addController method:



synth.addController(controller, 16, "o12_mix")


We can also set the range of values for the controller by specifying a minimum and maximum value for this particular control, now when we operate our controller the values received on the plugin will vary between these two extremes.

This is useful for cases where the useful portion is a small section of the physical control, we can spread that useful range of values over the entire physical control.

In this example we'll add a controller for the synth filter cutoff value and restrict the values to a minimum of 5 (Hz) and a maximum of 170 (Hz), note we can use a different dial on the same control surface, in this case the dial that sends MIDI CC number 17:


synth.addController(controller, 17, "cutoff", 5, 170)


Sample Melody

Now we'll define a sample melody to play, we've chosen a phrase by J.S. Bach. We specify the notes in ABC notation and use a Midi.ABCReader to read into a Midi.Pattern:



local melody = Midi.ABCReader().read(@"
d2 f2 e2| ^d2 ^d2 e2 B2| ^c2 A2 =d4-|  d4 =c4-|
c4 ^A4| =A6- A3/2x/2| G4- G3/2x/2 AG| F2 D2 x2 d2|
e2 d2 e2 ^f2| g2 d2 g4-| g4 =f4-| f4 ^d4|
=d6- d3/2x/2| x2 c2 ^d2 =d2| ^c2 ^c2 d2 A2| B2 G2 c4|")


To schedule the melody to start at the first measure:



synth.schedule(melody, 1)


Scheduling Control Changes

Another way to change plugin control values is to schedule the value change on a point in the transport using the scheduleControl method.

In this case we'll schedule two changes to the reverb amount: it was originally set to zero, we'll bump it up to 0.3 at the beginning of measure 5 and then up again to 0.7 at measure 9.



reverb.scheduleControl("amount", 0.3, 5, 0, 4)
reverb.scheduleControl("amount", 0.7, 9, 0, 4)


Schedule changes like this may work for many situations but will be too abrupt for others. When that is the case we can achieve a smoother response by sending smaller control change events within a short interval.

In this case we will ramp the reverb amount from 0.7 back down to 0 over the course of measure 13 by sending a total of 32 control changes on each 32nd note:



for(local i = 0; i < 32; i++) {
    local amount = 0.7 * (1 - i / 32.0)
    reverb.scheduleControl("amount", amount, 13, i, 32)
}


Finally, a transport master object to control the tempo:



Transport.Master(133)



Complete Script

local synth = Lv2.Plugin("http://calf.sourceforge.net/plugins/Monosynth", "Velo Bee")

local reverb = Lv2.Plugin("http://calf.sourceforge.net/plugins/Reverb")
reverb.setControl("amount", 0.0)
reverb.connect(synth)

local mainOutput = Audio.StereoOutput("main", "system:playback_1", "system:playback_2")
mainOutput.connect(reverb)

local controller = Midi.Input("synthControl")

synth.addController(controller, 16, "o12_mix")

synth.addController(controller, 17, "cutoff", 5, 170)

local melody = Midi.ABCReader().read(@"
d2 f2 e2| ^d2 ^d2 e2 B2| ^c2 A2 =d4-|  d4 =c4-|
c4 ^A4| =A6- A3/2x/2| G4- G3/2x/2 AG| F2 D2 x2 d2|
e2 d2 e2 ^f2| g2 d2 g4-| g4 =f4-| f4 ^d4|
=d6- d3/2x/2| x2 c2 ^d2 =d2| ^c2 ^c2 d2 A2| B2 G2 c4|")

synth.schedule(melody, 1)

reverb.scheduleControl("amount", 0.3, 5, 0, 4)
reverb.scheduleControl("amount", 0.7, 9, 0, 4)

for(local i = 0; i < 32; i++) {
    local amount = 0.7 * (1 - i / 32.0)
    reverb.scheduleControl("amount", amount, 13, i, 32)
}

Transport.Master(133)


Tutorial IndexList of All Examples


Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.