Using an Audio Mixer

In this example we show how to use an audio mixer to combine the output of two or more instruments into a single stereo output.

Audio Setup

First we create plugins to represent drums and bass respectively, note we do not take the usual step of connecting them to the main audio outputs:



local sampler = Lv2.Plugin("http://www.openavproductions.com/fabla", "fabla808")
local synth = Lv2.Plugin("http://calf.sourceforge.net/plugins/Monosynth", "Goa Bass")


Next we create our audio mixer, specifying the number of inputs and outputs. Since we have two instruments, each with two outputs (stereo left and right), we specify four inputs, and two outputs to represent left and right stereo output channels:



local mixer = Audio.Mixer(4, 2)


At this point we connect the mixer output to the main audio outputs:


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


Next we connect our inputs using the connect method which assigns the instruments to the next available input channel(s). How many inputs are assigned depends on what we plug in, most audio sources are either mono or stereo meaning 1 or 2 channels respectively.

At this point all the input channels are unused and available and we are dealing with stereo instruments with two channels each. So the first call to connect will assign the drum sampler to mixer input channels 1 and 2, and the following call will assign the bass synth to channels 3 and 4:



mixer.connect(sampler)
mixer.connect(synth)


MIDI Control

We can also connect a hardware controller to the mixer, in this case we have a simple control surface and we want the faders to control the input gains. We create a Midi.Input that will connect to the control surface and then use that as the gain controller for all four input channels.



local mixerControl = Midi.Input("mixerControl")


The first fader on our hardware controller sends MIDI control number 2, so we will use that as a control for both input 1 (sampler left) to output 1 (output left) and also for input 2 (sampler right) to output 2 (output right).


mixer.addGainController(mixerControl, 2, 1, 1)
mixer.addGainController(mixerControl, 2, 2, 2)

Likewise we'll map the next fader, which sends MIDI control change number 3 to adjust the gain for both input 3 (bass left) and input 4 (bass right) to the respective outputs.


mixer.addGainController(mixerControl, 3, 3, 1)
mixer.addGainController(mixerControl, 3, 4, 2)


Sample Arrangement

Now we create a simple drumbeat and bassline and schedule them to play for a few measures:



local tabReader = Midi.DrumTabReader()

local beat = tabReader.read(@"
42|xxxxxxxx|
40|--o---o-|
36|o---oo--|
")

local bassline = tabReader.read(@"
28|--x-xx-x|
")

for(local m = 1; m <= 8; m++) {
    sampler.schedule(beat, m)
    synth.schedule(bassline, m)
}


Automated Faders

We can also automate gain changes by scheduling when the changes are to occur.

Here we fade the bass out over the course of the 3rd measure by sending control messages on every 16th note to successively knock down the gain for channels 3 and 4:



for(local i = 0; i < 16; i++) {
    local gain = 1 - i / 16.0
    mixer.scheduleGain(3, 1, gain, 3, i, 16)
    mixer.scheduleGain(4, 2, gain, 3, i, 16)
}


And fade it back in again on the 4th measure:



for(local i = 0; i < 16; i++) {
    local gain = i / 16.0
    mixer.scheduleGain(3, 1, gain, 4, i, 16)
    mixer.scheduleGain(4, 2, gain, 4, i, 16)
}


Add a transport master object to specify that the script controls the tempo:


Transport.Master(125)



Complete Script

local sampler = Lv2.Plugin("http://www.openavproductions.com/fabla", "fabla808")
local synth = Lv2.Plugin("http://calf.sourceforge.net/plugins/Monosynth", "Goa Bass")

local mixer = Audio.Mixer(4, 2)

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

mixer.connect(sampler)
mixer.connect(synth)

local mixerControl = Midi.Input("mixerControl")

mixer.addGainController(mixerControl, 2, 1, 1)
mixer.addGainController(mixerControl, 2, 2, 2)

mixer.addGainController(mixerControl, 3, 3, 1)
mixer.addGainController(mixerControl, 3, 4, 2)

local tabReader = Midi.DrumTabReader()

local beat = tabReader.read(@"
42|xxxxxxxx|
40|--o---o-|
36|o---oo--|
")

local bassline = tabReader.read(@"
28|--x-xx-x|
")

for(local m = 1; m <= 8; m++) {
    sampler.schedule(beat, m)
    synth.schedule(bassline, m)
}

for(local i = 0; i < 16; i++) {
    local gain = 1 - i / 16.0
    mixer.scheduleGain(3, 1, gain, 3, i, 16)
    mixer.scheduleGain(4, 2, gain, 3, i, 16)
}

for(local i = 0; i < 16; i++) {
    local gain = i / 16.0
    mixer.scheduleGain(3, 1, gain, 4, i, 16)
    mixer.scheduleGain(4, 2, gain, 4, i, 16)
}

Transport.Master(125)


Tutorial IndexList of All Examples


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