tests.be.tarsos.dsp.test.CrossCorrelation Maven / Gradle / Ivy
The newest version!
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 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 potentialMatch = new ArrayList();
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;
}
}
}
}
}
}