Hello, I'm new here so I don't really know if this should go to Game Programming or General Programming. Hopefully I'm in the right place.
I am currently having a problem implementing GameDev's beat detection algorithm in a Unity game to introduce rythm based elements (a la Audiosurf), more precisely Frequency selected sound energy algorithm #1. I'm pretty sure I've implemented the full algorithm, but I am doing it wrong somewhere. I put the print if a beat is found thanks to the last step, where I compare a subband's energy to the average of its history buffer multiplied by a threshold (250 as advised by the article), but nothing gets printed at all (and it should probably freeze Unity because of the billions of print that would occur if it did work, but anyway...)
I have included my implementation of the algorithm in the post. Note that Unity doesn't seem to let me separate the data between left and right channel with AudioClip.GetData but packs both together instead, so I'm only using the real part of the complex numbers since the imaginary part is empty.
audio.clip.GetData(samples, 0);
int i = 0;
while(i < samples.Length){ //navigate through the samples
if(i%(1024 - 1) < 1){ //every 1024 samples...
int k = 0;
for(int j = i; j < i+1024; j++){
if(j<samples.Length){
data[k] = (double)samples[j]; //...fill a 1024 values array so we can FFT it
k++;
}
}
FFT.FFT(data, true); //FFT the data!
for(int j = 0; j < data.Length; j++){
buffer[j] = data[j]*data[j]; //we compute the square of our data to get frequency amplitudes
}
//divide the buffer in 32 subbands, compute the energy of these subbands and store them
for(int j = 0; j < energySubband.Length; j++){
double sum = 0;
for(int l = j*32; l < (j+1)*32; l++){
sum += buffer[l];
}
energySubband[j] = 32/1024 * sum;
shift (energyHistoryBuffer, j); //shifts the history buffer
energyHistoryBuffer[j,0] = energySubband[j]; //pile in the new energy of subband j
//we compute the average of the current subband's history buffer
double average = 0;
for(int l = 0; l<43; l++){
average += energyHistoryBuffer[j,l];
}
average *= 1/43;
//For each subband 'i' if energySubband[j] > (C*<energyHistoryBuffer[j]>) we have a beat !
//C == 250 here
if(energySubband[j] > (250 * average))
Debug.Log ("Beat! at subband number " + j);
}
}
i++;
}
Thanks in advance