Using Random Numbers

Using random numbers can be useful to create scripts that have variations in execution, this can create a more dynamic feel than a "static" composition that plays exactly the same each time.

In this simple example we will make a script that plays a drum beat and chooses drum fills at random.

Audio Setup

First we create a drum machine sampler and connect it to the system outputs:



local sampler = Lv2.Plugin("http://www.openavproductions.com/fabla", "fabla808")
sampler.setControl("volume", 0.5)
local mainOutput = Audio.StereoOutput("main", "system:playback_1", "system:playback_2")
mainOutput.connect(sampler)


Drum Patterns

Now we are going to create several patterns from drum tabs, so we create a DrumTabReader that can be reused:



local drumtabReader = Midi.DrumTabReader()


Now a simple drum beat:



local drumBeat = drumtabReader.read(@"
40|--o---o-|
36|o---oo--|
")


and a few fills:



local fill1 = drumtabReader.read(@"
40|--o-oooo|
36|o-------|
")

local fill2 = drumtabReader.read(@"
40|--------|
36|o---oooo|
")

local fill3 = drumtabReader.read(@"
40|oooo----|
36|----oooo|
")


Arrangment

First we create our random number generator:



local random = Math.Random()


Now we create the arrangement, as usual, by looping over measures, if a measure is not a multiple of 4, we'll just play the beat:



for(local measure = 1; measure <= 16; measure++) {
    if(measure % 4 != 0) { // measure is not a multiple of 4
        sampler.schedule(drumBeat, measure)
    }
    else {

If the measure is a multiple of 4, we will make a decision whether or not to do a fill. We will use the Random.integer(2) method to randomly return a value of 0 or 1, like a coin toss: if the value is 1 we continue to play the beat, otherwise play a fill:


        // measure *is* a multiple of 4
        if(random.integer(2) == 1) { // keep the beat
            sampler.schedule(drumBeat, measure)
        }
        else {


If we are going to play a fill we need to decide which fill to use, once again we make the decision with a random number. Since there are three fills however we will call Random.integer(3) which returns 1, 2, or 3, then we schedule the corresponding fill:


            // play a fill
            local fillChoice = random.integer(3)
            if(fillChoice == 1) {
                sampler.schedule(fill1, measure)
            }
            else if(fillChoice == 2) {
                sampler.schedule(fill2, measure)
            }
            else {
                sampler.schedule(fill3, measure)
            }
        }
    }
}


Add a transport master object with a tempo of 120 BPM:


Transport.Master(120)


Now when we play the script, we don't know in advance when it will choose to do a fill, or which fill it will use, because these decisions are made at random.



Complete Script

local sampler = Lv2.Plugin("http://www.openavproductions.com/fabla", "fabla808")
sampler.setControl("volume", 0.5)
local mainOutput = Audio.StereoOutput("main", "system:playback_1", "system:playback_2")
mainOutput.connect(sampler)

local drumtabReader = Midi.DrumTabReader()

local drumBeat = drumtabReader.read(@"
40|--o---o-|
36|o---oo--|
")

local fill1 = drumtabReader.read(@"
40|--o-oooo|
36|o-------|
")

local fill2 = drumtabReader.read(@"
40|--------|
36|o---oooo|
")

local fill3 = drumtabReader.read(@"
40|oooo----|
36|----oooo|
")

local random = Math.Random()

for(local measure = 1; measure <= 16; measure++) {
    if(measure % 4 != 0) { // measure is not a multiple of 4
        sampler.schedule(drumBeat, measure)
    }
    else {

        // measure *is* a multiple of 4
        if(random.integer(2) == 1) { // keep the beat
            sampler.schedule(drumBeat, measure)
        }
        else {

            // play a fill
            local fillChoice = random.integer(3)
            if(fillChoice == 1) {
                sampler.schedule(fill1, measure)
            }
            else if(fillChoice == 2) {
                sampler.schedule(fill2, measure)
            }
            else {
                sampler.schedule(fill3, measure)
            }
        }
    }
}

Transport.Master(120)


Tutorial IndexList of All Examples


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