package be.tarsos.dsp.test; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.sound.sampled.UnsupportedAudioFileException; import be.tarsos.dsp.AudioDispatcher; import be.tarsos.dsp.AudioEvent; import be.tarsos.dsp.AudioProcessor; import be.tarsos.dsp.SilenceDetector; import be.tarsos.dsp.io.jvm.AudioDispatcherFactory; import be.tarsos.dsp.pitch.GeneralizedGoertzel; import be.tarsos.dsp.pitch.Goertzel.FrequenciesDetectedHandler; import be.tarsos.dsp.util.fft.FFT; import be.tarsos.dsp.util.fft.HammingWindow; public class CrossCorrelation implements AudioProcessor{ private final float[] zeroPaddedInvesedQuery; private final float[] zeroPaddedData; static interface CrossCorrelationHandler{ void handleCrossCorrelation(float audioBufferTime,float maxTime,float value); } private final FFT fft; private final CrossCorrelationHandler handler; public CrossCorrelation(float[] query,CrossCorrelationHandler handler){ zeroPaddedInvesedQuery = new float[query.length*2]; zeroPaddedData= new float[query.length*2]; int queryIndex = query.length-1; for(int i = query.length/2; i < query.length + query.length/2 ; i++){ zeroPaddedInvesedQuery[i] = query[queryIndex]; queryIndex--; } this.handler = handler; fft = new FFT(zeroPaddedInvesedQuery.length,new HammingWindow()); fft.forwardTransform(zeroPaddedInvesedQuery); } boolean prev; @Override public boolean process(AudioEvent audioEvent) { float[] fftData = audioEvent.getFloatBuffer().clone(); Arrays.fill(zeroPaddedData, 0); System.arraycopy(fftData, 0, zeroPaddedData, fftData.length/2, fftData.length); fft.forwardTransform(zeroPaddedData); fft.multiply(zeroPaddedData, zeroPaddedInvesedQuery); fft.backwardsTransform(zeroPaddedData); float maxVal = -100000; int maxIndex = 0; for(int i = 0 ; i<zeroPaddedData.length ; i++){ if(zeroPaddedData[i]> maxVal){ maxVal = zeroPaddedData[i]; maxIndex=i; } } float time = (float) (audioEvent.getTimeStamp() - audioEvent.getBufferSize()/audioEvent.getSampleRate() + maxIndex/2 /audioEvent.getSampleRate()); handler.handleCrossCorrelation((float)audioEvent.getTimeStamp(), time, maxVal); return true; } @Override public void processingFinished() { } static float[] query; static float bufferTime; static float maxTime; public static void main(String...strings) throws UnsupportedAudioFileException, IOException{ AudioDispatcher q = AudioDispatcherFactory.fromFile(new File("/home/joren/Desktop/44kHz_1024_samples.wav"), 1024, 0); q.addAudioProcessor(new AudioProcessor() { @Override public void processingFinished() { // TODO Auto-generated method stub } @Override public boolean process(AudioEvent audioEvent) { query = audioEvent.getFloatBuffer().clone(); return false; } }); q.run(); final List<Float> potentialMatch = new ArrayList<Float>(); AudioDispatcher ref; //ref = AudioDispatcherFactory.fromPipe("/home/joren/Desktop/sort/1044026.mp3",44100, 1024, 1024-128); //ref = AudioDispatcherFactory.fromPipe("/home/joren/Desktop/ref_other_new.wav",44100, 1024, 1024-128); //ref = AudioDispatcherFactory.fromPipe("/home/joren/Desktop/mixed_clip_09.wav",44100, 1024, 1024-128); ref = AudioDispatcherFactory.fromPipe("/home/joren/Recordings/Clip 12",44100, 1024, 1024-128); //ref = AudioDispatcherFactory.fromPipe("/home/joren/Desktop/clip_09_amplified.wav",44100, 1024, 1024-128); double[] frequencies = {697,941,1209}; CrossCorrelation crosscorr = new CrossCorrelation(query,new CrossCorrelationHandler() { @Override public void handleCrossCorrelation(float audioBufferTime, float maxTime, float value) { if(value > 500){ bufferTime = audioBufferTime; CrossCorrelation.maxTime = maxTime; //System.out.println(maxTime + " " + value); } } }); GeneralizedGoertzel gengoe = new GeneralizedGoertzel(44100.0f, 1024, frequencies, new FrequenciesDetectedHandler() { @Override public void handleDetectedFrequencies(double time,double[] frequencies, double[] powers, double[] allFrequencies, double[] allPowers) { if(powers[0] > 3 && powers[1] > 3 && powers[2] > 3 && powers[0] + powers[1] + powers[2] > 20 ){ if((float) time == bufferTime){ //System.out.println(time + " " + powers[0] + " " + powers[1] + " " + powers[2]); //System.out.println(maxTime); potentialMatch.add( maxTime); } } } }); ref.addAudioProcessor(new SilenceDetector(-45, true)); ref.addAudioProcessor(crosscorr); ref.addAudioProcessor(gengoe); ref.run(); float maxMsDifference = 207.5f; float minDifference = 193.5f; float minI = -1000; for(int i = 0 ; i < potentialMatch.size();i++){ if(minI < potentialMatch.get(i) ){ float max = potentialMatch.get(i) + maxMsDifference/1000.0f; float min = potentialMatch.get(i) + minDifference/1000.0f; for(int j = i+1 ; j < potentialMatch.size(); j++ ){ if( potentialMatch.get(j) >= min && potentialMatch.get(j) <= max){ System.out.println("Match at: " + potentialMatch.get(i)); minI = max; break; } } } } } }