Hey all,
I want to put beat detection into my game. It doesn't have to be super accurate, nothing fancy really, so I have settled for the simple sound energy algorithm, as outlined here.
That's all really cool, but to be honest I have no idea how to implement that in LÖVE. The maths behind it are doable for me, so I just need to know how to handle the sample history buffer, and the "do this every 1024 samples" thing. I know I can pass my audio file into love.sound.newSoundData, but I don't know how to proceed from there. Should I just store all samples beforehand? In my love.update, how would I know what sample position to use for the algorithm? How would I handle a looping background song?
As the end result, I want to be able to make the background of a screen flash whenever it detects a beat in the music that's playing.
If I could get code examples that'd be great, but I can make do with some pointers on how to do this as well. Thanks!
~ Fang
[resolved] Implementing a beat detection algorithm
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
[resolved] Implementing a beat detection algorithm
Last edited by Fang on Sun Jun 09, 2013 7:05 pm, edited 1 time in total.
~palfun-foslup
Re: Implementing a beat detection algorithm
LÖVE is not designed to handle real time audio processing very efficiently. It requires you to load the whole song into memory with love.sound.newSoundData and then check the current offset of the playing source with Source:tell to get the right samples with SoundData:getSample. (Note that getSample returns the samples of a stereo track in an interleaved manner)
Here's an example.
Here's an example.
Shallow indentations.
Re: Implementing a beat detection algorithm
Thanks Boolsheet, I got it working now! It's quite flawed still, only using the simple sound energy algorithm #1, but it runs fine, so that's great!
When instantiating:
In the update function:
Sure, this could use a lot of optimization, but I'm happy to have it running this easily. Thanks again!
When instantiating:
Code: Select all
self.soundData = love.sound.newSoundData( "filename.mp3" )
self.source = love.audio.newSource( self.soundData )
self.lastChecked = 0
self.beat = false
love.audio.play( self.source )
Code: Select all
local curSample = self.source:tell( "samples" )
if curSample-1024 > self.lastChecked then
local instantEnergy = 0
for i=curSample, curSample+1024 do
instantEnergy = instantEnergy + self.soundData:getSample(i)^2
end
local localAverageEnergy = 0
for i=curSample-44032, curSample do
localAverageEnergy = localAverageEnergy + self.soundData:getSample(i)^2
end
localAverageEnergy = localAverageEnergy * (1024/44100)
if instantEnergy > localAverageEnergy*1.8 then
self.beat = true
else
self.beat = false
end
self.lastChecked = curSample
end
~palfun-foslup
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 4 guests