0

I have been working on a guitar tuner application. I understand that the FFT is a bad choice for this kind of application. However, as deadlines get ever closer, and my original specification submission specified use of this algorithm. So unfortunately I am stuck with it.

Thanks to answers to previous questions and use of this blog: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html

I have an application that takes in audio, calculates the frequency and both graphs and compares the result to known note ranges at 5 octaves.

The final issue is that the frequency calculated still varies from the frequency read in. I have used a frequency generator provided online an I have found that It will get the frequency of a note above or bellow the given one.

for example a C read in will get B sharp or C sharp at different octaves. Distance of the phone from the noise source also effects the readings.

Is there a known example of this occurring and fixes, or is it because of the FFT algorithm, and my application can't work correctly?

My code can be found at a previous: Displaying a double (frequency) that is updated constantly while recording with Android

A low pass filter has been added to remove background environmental noise, and a ring buffer has been added to get the average of several frequencies given.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    You should do some debugging first. For example, have you looked at a graph of the output of your FFT? Is the peak where you expect? – Oliver Charlesworth May 26 '13 at 19:01
  • The graph appears correct. in that the frequency it calculates corresponds to the point on the graph. However, it isn't the same frequency that is being read in. – Cillian Donlon May 26 '13 at 19:30
  • What do you mean by "the frequency being read in"? Do you mean the frequency of the audio source? If so, in what way do they differ? – Oliver Charlesworth May 26 '13 at 19:36
  • Using the frequency generator here: http://www.seventhstring.com/tuningfork/tuningfork.html I can control the tone being recorded. The frequency it calculates and returns is generally off by a full note. It fluctuates octaves as well. So 440.0hz (A) at the most recent test (as I write this) is returning between (300 - 396.2) hz. So It reads in an A and returns between E - G – Cillian Donlon May 26 '13 at 19:40
  • 2
    Ok. You need a more controlled test. You should programmatically populate the contents of your input buffer with a sine wave at a known frequency. – Oliver Charlesworth May 26 '13 at 19:41
  • One of the most common mistakes in this kind of project is neglecting to apply a window function prior to the FFT. What kind of window function are you using ? – Paul R May 26 '13 at 20:35
  • I am reading the information from the mic to a short[] buffer (size 1024) and then transferring it to a double[] audioData of the same size to work on. – Cillian Donlon May 26 '13 at 21:12
  • The Graph is working correctly now. The peak occurs where I expect, however the freuency is still inccorect – Cillian Donlon May 28 '13 at 10:50

1 Answers1

1

If your frequency is off by a little, it might mean you either need to use a longer FFT or a peak estimation algorithm (such as a parabolic or other interpolation kernel) on the FFT result.

If your FFT frequency result jumps octaves, it may mean you need to narrow your allowable frequency estimate range or your low pass filter bandwidth using a pitch estimation algorithm, such as a cepstrum/cepstral estimator, autocorrelation/lag estimator, or harmonic product spectrum, et.al.

Also watch out for bugs such as using the wrong sample rate or the wrong data formats, etc.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153