Sound Synthesis with LÖVE Part II – Sine Waves

Sound Synthesis with LÖVE Part I – Introduction

 

In the first Part we discussed some basics of LPCM and sound synthesis. This time we want get more practical and generate a sine wave tone.

Beep

Since we use LÖVE for this we want to write all the following code in the love.load() callback so it only get’s executed once.

First we initialize set up some variables in the love.load() callback:


function love.load()
    len = 2
    rate = 44100
    bits = 16
    channel = 1
end

We need this in order to set up the soundData object. The length of the sound we are about to generate is specified by the len variable in seconds. 44100 Hertz and 16 bit is a common format of LPCM Data. For the sake of this tutorial we will use one channel, meaning that our sound will be mono.

Next we set up a soundData object with these settings and write a loop to fill in the samples. At last we generate a Source object and play it. The love.load() will then look like this:


function love.load()
    len = 2
    rate = 44100
    bits = 16
    channel = 1

    soundData = love.sound.newSoundData(len*rate,rate,bits,channel)

    amplitude = 0.2

    for i=1,len*rate do
        local sample = amplitude
        soundData:setSample(i, sample)
    end

    source = love.audio.newSource(soundData)
    love.audio.play(source)
end

We fill in a static value, so executing this will still result in silence. We have to set up an oscillator to get some kind of sound going. I choose to use a closure function for this:


function Oscillator(freq)
    local phase = 0
    return function()
        phase = phase + 2*math.pi/rate            
        if phase >= 2*math.pi then
            phase = phase - 2*math.pi
        end
        return math.sin(freq*phase)
    end
end

The advantage of this method is that we can generate as many oscillators as we want – which may also be useful for modulating the signal later on. We also don’t have to bother about managing the oscillating variables. Using this in our love.load() from above:


function love.load()
    len = 2
    rate = 44100
    bits = 16
    channel = 1

    soundData = love.sound.newSoundData(len*rate,rate,bits,channel)

    osc = Oscillator(440)
    amplitude = 0.2

    for i=1,len*rate do
        sample = osc() * amplitude
        soundData:setSample(i, sample)
    end

    source = love.audio.newSource(soundData)
    love.audio.play(source)
end

Now, this code generates the desired beep for 2 seconds at a frequency of 440 Hertz, the A above the middle C which is also called the ‘Concert A’ or ‘Chamber Tone’.


This is a tutorial about Löve(aka Love2d) a framework to make games in Lua. I also have a beginner tutorial series on Löve: 

Love2d – What is Love? An Introduction
Love2d – Introduction: Installing/Choose a Texteditor on Windows
Love2d – Introduction: Installing/Choose Texteditor on OS X
Love2d – Tutorial Part 0 | Hello Wörld
Love2d – Tutorial Part 1 | Invaders must die!

Leave a Reply

Your email address will not be published. Required fields are marked *


+ eight = 15


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment moderation is enabled. Your comment may take some time to appear.