1. Anders Ruud
  2. love
  3. Issues

Issues

Issue #1279 closed

How to implement real-time audio DSP?

Anastasia Dunbar
created an issue

Here's the code of what I'm trying to do:

function dsp(time)
    return math.sin(time*3000)*math.sin(time*10)
end
function love.load()
    sampleRate=44100
    dspTime=0
end
function love.update()
    soundData=love.sound.newSoundData(sampleRate/60,sampleRate,16,1) --60 is the FPS.
    for i=0,soundData:getSampleCount()-1 do
        soundData:setSample(i,dsp(dspTime))
        dspTime=dspTime+(1/sampleRate)
    end
    love.audio.play(love.audio.newSource(soundData,"static"))
end

Comments (5)

  1. Gabe Stilez

    I have no idea what you really mean by that.

    There is inherent latency with everything, but my experience is that it's low enough to allow someone to code a DAW in Löve (Like Cubase, or whatever); i could go down to 128 smp-s in some cases, or 5 ms.

    But if you mean if it will "desync" more and more over time, then no, my implementation works perfectly. (Although making it run in a thread would be better, as to not let graphics stuff introduce hiccups...)

    Here's a simpler example, and again, you need 0.11 for this; nightly builds are available.

    function love.load()
        bitDepth = 16
        samplingRate = 44100
        channelCount = 1
        -- With the above sampling rate, a buffer length of 1024 samplepoints should be enough.
        bufferSize = 1024
        pointer = 0
        sd = love.sound.newSoundData(bufferSize, samplingRate, bitDepth, channelCount)
        qs = love.audio.newQueuableSource(samplingRate, bitDepth, channelCount)
    
        dspTime = 0.0
    end
    
    function love.update()
         if qs:getFreeBufferCount() == 0 then return end -- only render if we can.
         local samplesToMix = bufferSize -- easy way of doing things.
         for smp = 0, samplesToMix-1 do
             -- put your generator function here.
             sd:setSample(pointer, math.sin(440*math.pi*2*dspTime))
             pointer = pointer + 1
             dspTime = dspTime + (1 / samplingRate)
             if pointer >= sd:getSampleCount() then
                 pointer = 0
                 qs:queue(sd)
                 qs:play()
             end
         end
    end
    

    That said, this conversation is still in the wrong place, since this issue tracker is for issues related to the framework, which this isn't. If you require further assistance, i strongly recommend doing it over at https://love2d.org/forums/

  2. Log in to comment