All pastes #1207240 Raw Edit

Staz

public java v1 · immutable
#1207240 ·published 2008-09-21 07:25 UTC
rendered paste body
package prototypes.audioAnalysis;import java.util.ArrayList;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioFormat;import java.io.IOException;import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D;public class FrequencySelectedSoundEnergy extends BeatDetectionAlgorithm {	/* Constants used in this algorithm */	private final int NUM_SAMPLES_TO_TAKE = 1024; //How many samples to take in each iteration of the algorithm    private final int NUM_SUBBANDS = 32;    private final int ENERGY_HISTORY_BUFFER_SIZE = 43;    private final int C_CONSTANT = 250;    private final int ONE_MILLION = 1000000;    private final int SUBBAND_SIZE = NUM_SAMPLES_TO_TAKE / NUM_SUBBANDS;    private final int MINIMUM_BEAT_INTERVAL = 10;        /* Used for averaging energy in a subband */    private double average(double[] array, int offset, int count)    {    	double average = 0;    	for (int i = offset; i < offset + count; i++)    		average += array[i];    	    	return average / count;    }        /* Used for averaging the values in a history buffer */	private double average(RingBuffer buffer)	{		double average = 0;		for (double d : buffer)			average += d; //Note this is d and not 'd * d' (algorithm had a mistake in it).		return average / buffer.getCount();	}		private double variance(RingBuffer buffer, double averageLocalEnergy)	{		double variance = 0;		for (double d : buffer)			variance += (d - averageLocalEnergy) * (d - averageLocalEnergy);		return variance /= buffer.getCount();	}		public ArrayList<Long> getBeats(AudioInputStream pcmIn, AudioFormat format) throws IOException 	{		/* Used to store all of the beats that we detect */    	ArrayList<Long> beats = new ArrayList<Long>();    	boolean beatFound = false;		/* Used to read multiple audio frames at a time */		PCMReader pcmReader;		long numFramesRead, totalFramesRead = 0;			/* Used to perform the fast fourier transform on our samples */		DoubleFFT_1D fft;				/* Arrays used by the frequency selected sound energy algorithm */        double[] frequencyAmplitudes = new double[NUM_SAMPLES_TO_TAKE];        RingBuffer[] energyHistoryBuffer = new RingBuffer[NUM_SUBBANDS];        double[] pcmSamples = new double[NUM_SAMPLES_TO_TAKE * 2];		int[] numBeatsInSubband = new int[NUM_SUBBANDS];                /* Used to skip some beats */        boolean beatSkip = false;		int beatWaitTime = 0;            	/* Other variables used by the algorithm */    	double averageEnergy;    	double microsecondsPerFrame;    	double subbandEnergy;    	    	fft = new DoubleFFT_1D(NUM_SAMPLES_TO_TAKE);    	pcmReader = new PCMReader(pcmIn);    	microsecondsPerFrame =  ONE_MILLION / format.getFrameRate();    	    	/* Initialise the energy history buffers */    	for(int i=0; i< NUM_SUBBANDS; i++)        	energyHistoryBuffer[i] = new RingBuffer(ENERGY_HISTORY_BUFFER_SIZE);    	    	while ((numFramesRead = pcmReader.readFrames(pcmSamples,NUM_SAMPLES_TO_TAKE)) != 0)	        {        	beatFound = false;        	totalFramesRead += numFramesRead;        	        	//* Perform the Fast Fourier Transform */        	fft.complexForward(pcmSamples);        	        	/* Calculate the frequency amplitudes of the signal returned from the FFT */        	for(int i=0; i < NUM_SAMPLES_TO_TAKE; i++) {        		frequencyAmplitudes[i] = (pcmSamples[2 * i] * pcmSamples[2 * i])         				+ (pcmSamples[2*i + 1] * pcmSamples[2*i + 1]);        	}        	        	/* Work out whether or not we should skip a beat detected in this channel */			if (beatSkip)			{				beatWaitTime++;				if (beatWaitTime == MINIMUM_BEAT_INTERVAL)				{					beatSkip = false;					beatWaitTime = 0;				}			}        	        	for(int subband = 0; subband < NUM_SUBBANDS; subband++) {        		        		/* Calculate the energy of the current subband */        		subbandEnergy = average(frequencyAmplitudes,subband * SUBBAND_SIZE, SUBBAND_SIZE);         		        		/* Don't start checking for beats until the history buffer is full */        		if (! energyHistoryBuffer[subband].isFull())        			energyHistoryBuffer[subband].add(subbandEnergy);        		else        		{        			/* Calculate the average energy for the past second of audio data */        			averageEnergy = average(energyHistoryBuffer[subband]);      		        		        			/* Add the new subband energy value to the energy history buffer for         		 	* the current subband */        			energyHistoryBuffer[subband].add(subbandEnergy);        		        			/* Check if we have found a beat on the current subband */        			if(beatSkip == false && subbandEnergy > (5 * averageEnergy))        			{        				beatFound = true;        				numBeatsInSubband[subband]++;        			}        		}        	}        	        	if(beatFound)        	{        		beats.add((long)(microsecondsPerFrame * totalFramesRead));        		beatSkip = true;        	}        }    	    	for (int i = 0; i < numBeatsInSubband.length; i++)    		System.out.println("Channel " + i + ": " + numBeatsInSubband[i]);    	    	System.out.println("TOTAL FRAMES READ : " + totalFramesRead);    	return beats;	}}