Jump to content

  • Log In with Google      Sign In   
  • Create Account

Problem implementing GameDev's beat detection algorithm


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 s4edev   Members   -  Reputation: 111

Like
0Likes
Like

Posted 21 February 2014 - 03:33 PM

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



Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS