## DSP tutorial: Calculating FFT of a live source

This example records audio and periodically prints the dominant frequency of the recorded audio signal.

 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 public class AudioRecordFFT implements Runnable {     private final static int SAMPLERATE = 8000;     private final static int BUFFERSIZE = SAMPLERATE / 2;     private TargetDataLine tdl;     private DoubleFFT_1D fft;     AudioRecordFFT(TargetDataLine tdl) {         this.tdl = tdl;     }     private void calculateFFT(final double[] audioData, final int storedSamples) {         // we need to initialize a buffer where we store our samples as complex numbers. first value is the real part, second is the imaginary.         double[] fftData = new double[audioData.length*2];         for (int i = 0; i < storedSamples; i++) {             // copying audio data to the fft data buffer, imaginary part is 0             fftData[2 * i] = audioData[i];             fftData[2 * i + 1] = 0;         }         // calculating the fft of the data, so we will have spectral power of each frequency component         fft.complexForward(fftData);         int max_i = -1;         double max_fftval = -1;         for (int i = 0; i < fftData.length/2; i += 2) { // we are only looking at the half of the spectrum             // complex numbers -> vectors, so we compute the length of the vector, which is sqrt(realpart^2+imaginarypart^2)             double vlen = Math.sqrt(fftData[i] * fftData[i] + fftData[i + 1] * fftData[i + 1]);             if (max_fftval < vlen && vlen > 0.1) {                 // if this length is bigger than our stored biggest length                 max_fftval = vlen;                 max_i = i;             }         }         if (max_i < 0)             max_fftval = max_i = 0;         double dominantFreq = ((max_i) / (double)fftData.length) * SAMPLERATE;         System.out.println("Dominant frequency: " + dominantFreq + "hz (bin no. " + max_i + ")");     }     @Override     public void run() {         byte[] abBuffer = new byte[tdl.getBufferSize()];         double[] abBufferDouble = new double[abBuffer.length/2];         fft = new DoubleFFT_1D(abBufferDouble.length);         tdl.start();         try {             while (!Thread.interrupted()) {                 // waiting for the buffer to get filled                 while (tdl.available() < tdl.getBufferSize() * 0.5)                     Thread.sleep(0, 1); // without this, the audio will be choppy                     int bytesRead = tdl.read(abBuffer, 0, tdl.available());                     // converting frames stored as bytes to double values                 int samplesRead = bytesRead/tdl.getFormat().getFrameSize();                 for (int i = 0; i < samplesRead; i++)                     abBufferDouble[i] = ((abBuffer[i*2] & 0xFF) | (abBuffer[i*2 + 1] << 8)) / 32768.0;                     calculateFFT(abBufferDouble, samplesRead);             }         } catch (InterruptedException e) {         }         tdl.stop();         tdl.close();     }     public static void main(String[] args) {         AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, SAMPLERATE, 16, 1, 2, SAMPLERATE, false);         DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat, BUFFERSIZE);         TargetDataLine targetDataLine = null;         try {             targetDataLine = (TargetDataLine) AudioSystem.getLine(info);             targetDataLine.open(audioFormat, BUFFERSIZE);             System.out.println("Buffer size: " + targetDataLine.getBufferSize());         } catch (LineUnavailableException e1) {             e1.printStackTrace();         }         // creating the recorder thread from this class' instance         AudioRecordFFT audioRecordFFT = new AudioRecordFFT(targetDataLine);         Thread audioRecorderThread = new Thread(audioRecordFFT);         // we use this to read line from the standard input         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));         audioRecorderThread.setPriority(Thread.MAX_PRIORITY);         audioRecorderThread.start();         System.out.println("Recording... press ENTER to stop recording!");         try {             br.readLine();         } catch (IOException e) {             e.printStackTrace();         }         audioRecorderThread.interrupt();         try {             // waiting for the recorder thread to stop             audioRecorderThread.join();         } catch (InterruptedException e) {             e.printStackTrace();         }         System.out.println("Recording stopped.");     } }

download (mirror2) (849.2 kb, 86 dls, today: 0)

## No comments yet.

Name (required)
E-mail (required - never shown publicly)
Webpage URL
Comment:
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> in your comment.

## About me I'm Nonoo. This is my blog about music, sounds, filmmaking, amateur radio, computers, programming, electronics and other things I'm obsessed with. ... »