Advertisement Jump to content
Sign in to follow this  
s4edev

Unity Problem implementing GameDev's beat detection algorithm

This topic is 1793 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!