/** * The UltrasoundDetector class can be used to help analyze an ultrasound signal. * This class is based on a C program implemented by Kevin Banks of * Embedded Systems Programming. * * @author Chris Palistrant, Tony Offer * @version 0.0, May 2004 */ public class UltrasoundDetector{ int THRESHOLD = 3500; float SAMPLING_RATE = 44100.0F; float TARGET_FREQUENCY = 21000.0F; int N = 420; Goertzel g; static double[] signal; /** * Default Constructor */ UltrasoundDetector(){ this(44100.0F, 21000.0F, 420); } /** * Constructor. * @param sampleRate is the sampling rate of the signal to be analyzed * @param targetFreq is the frequency that Goertzel will look for. * @param n is the block size to use with Goertzel */ UltrasoundDetector(float sampleRate, float targetFreq, int n){ g = new Goertzel(sampleRate, targetFreq, n); SAMPLING_RATE = sampleRate; TARGET_FREQUENCY = targetFreq; N = n; /* //Not tested; but intended to eliminate n from param list by computing n based on N float temp_n; float a = targetFreq/sampleRate; for(int n = 200; n <= 600; n++){ temp_n = a*n; //if temp_n is accurate to 0.0XXX of an int, then its okay if( ( (int)(temp_n*10) - ((int)temp_n)*10 ) == 0 ) N = temp_n; } if(n==0){ System.out.println("Block size error"); System.exit(0); } */ } /** * This method should be called to initialize signal porcessing method. * * @param debug is a boolean that prints out debug messages when true * @return */ void signalAnalysisInit(boolean debug){ if(debug) g.DEBUG = true; g.initGoertzel(); } /** * This should not be called until after signalAnalysisInit * has been called. * * @param samples is an array of doubles * @return returns true if loaded, false otherwise */ boolean loadSignal(double[] samples){ signal = new double[samples.length]; if(g.DEBUG){ System.out.println("USD:loadSignal:length of N " + N); System.out.println("USD:loadSignal:length of sample.length " + samples.length); } for(int i = 0; i < samples.length; i++) signal[i] = samples[i]; return true; } /** * This method is called once the signal is loaded and ready to * be analyzed. * * * @return boolean indicating true when the targetFrequency is found * and false otherwise. */ boolean testSignal(){ boolean freq_present = false; int debounceValue = 20; double[] parts = new double[2]; double real, img, magnitudeSquared, mag; // Process the samples int iters = signal.length/N; if(g.DEBUG){ System.out.println("The val of N is " + N); System.out.println("The val of iters is " + iters); } int index = 0; int count = 0; for(int j = 1; j <= iters; j++){ for(; index < N*j; index++){ g.processSample(signal[index]); } parts = g.getRealImag(parts); real = parts[0]; img = parts[1]; magnitudeSquared = real*real + img*img; //magnitudeSquared = g.getMagnitudeSquared(); mag = java.lang.Math.sqrt(magnitudeSquared); g.resetGoertzel(); if(g.DEBUG){ System.out.println("The mag is " + mag + " and the mag_squared " + magnitudeSquared + " count: " + count); if(real != 0) System.out.println("The phase is " + java.lang.Math.atan((double)img/real)); System.out.println("The real is " + real + " and the img is: " + img); } if(mag > THRESHOLD){ count++; if(count >= debounceValue) return true; } else count = 0; } if(count >= debounceValue) return true; else return false; } public static void main(String[] args){ } }