get frenquencies in Processing with Minim

benoît picture benoît · Apr 14, 2012 · Viewed 10.6k times · Source

I try to get frequencies from microphone using Processing. I have mix two examples from the doc, but "highest" is not really in Hz (a is 440 Hz). Do you know how to have something better than this ?

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioInput in;
FFT fft;
int highest=0;

void setup()
{
  size(1024, 200, P2D);

  minim = new Minim(this);
  minim.debugOn();

  in = minim.getLineIn(Minim.MONO, 4096, 44100);
  fft = new FFT(in.left.size(), 44100);
}

void draw()
{


  background(0);
  stroke(255);

  fft.forward(in.left);
  highest=0;
  for (int n = 0; n < fft.specSize(); n++) {
    // draw the line for frequency band n, scaling it by 4 so we can see it a bit better
    line(n/4, height, n/4, height - fft.getBand(n)*4);

    //find frequency with highest amplitude
    if (fft.getBand(n)>fft.getBand(highest))
      highest=n;
  }
  println(highest);

  //println(fft.getFreq(110));
  // draw the waveforms
  for (int i = 0; i < in.bufferSize() - 1; i++)
  {
    line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
    line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
  }
}


void stop()
{
  // always close Minim audio classes when you are done with them
  in.close();
  minim.stop();

  super.stop();
}

Answer

George Profenza picture George Profenza · Apr 15, 2012

You need to do a bit of conversion, depending what you want to get:

The spectrum does not represent individual frequencies, but actually represents frequency bands centered on particular frequencies. The center frequency of each band is usually expressed as a fraction of the sampling rate of the time domain signal and is equal to the index of the frequency band divided by the total number of bands. The total number of frequency bands is usually equal to the length of the time domain signal, but access is only provided to frequency bands with indices less than half the length, because they correspond to frequencies below the Nyquist frequency. In other words, given a signal of length N, there will be N/2 frequency bands in the spectrum.

As an example, if you construct an FFT with a timeSize of 1024 and and a sampleRate of 44100 Hz, then the spectrum will contain values for frequencies below 22010 Hz, which is the Nyquist frequency (half the sample rate). If you ask for the value of band number 5, this will correspond to a frequency band centered on 5/1024 * 44100 = 0.0048828125 * 44100 = 215 Hz. The width of that frequency band is equal to 2/1024, expressed as a fraction of the total bandwidth of the spectrum. The total bandwith of the spectrum is equal to the Nyquist frequency, which in this case is 22100, so the bandwidth is equal to about 50 Hz. It is not necessary for you to remember all of these relationships, though it is good to be aware of them. The getFreq allows you to query the spectrum with a frequency in Hz and the method getBandWidth will return the bandwidth in Hz of each frequency band in the spectrum.

from the Minim Manual, FFT section.