I've seen many questions on this forum regarding pitch detection for musical instruments (commonly guitar), and spent a while reading through the answers to create a basic implementation of auto-correlation to make an Android guitar tuner.

This is the algorithm I'm using (implemented in Java on an Android phone):

1) Record a short[4096] array of raw audio data from an Android phone's microphone at 48kHz sample rate
2) Apply a Hanning window to the raw audio data
3) Zero-pad the result to double the length (8192)
4) Apply auto-correlation with FFTs
5) Normalize the auto-correlation result
6) Get the periodicity from the peak bin indexes

My problem is that with an actual guitar it is not robust (around 50% accurate at best), and I don't know how to filter noise either (without any loud noise, just ambient white noise, it outputs garbage frequencies).

It fares much better when I whistle at it, or play a generated sine tone from a computer, but that's expected.

In my search for ways to improve my implementation, many answers (on this forum and others) usually point to using a better algorithm like YIN, but I think its more likely that I've made a mistake in my implementation.

Does anything seem obviously incorrect from the algorithm I posted? Are there tweaks I can apply?

1) Increase the Android microphone sensitivty
2) Band-pass the raw data before the algorithm
3) Record more samples
4) ???
And does anybody have any idea how I could filter out noise by using the auto-correlation result?

Thanks in advance.

  • $\begingroup$ i wouldn't use the FFT for autocorrelation applied to pitch detection at all. consider using just the basic time-domain version of it and think about how that can be made more efficient, for what you're trying to do. $\endgroup$ Nov 29, 2014 at 16:51
  • $\begingroup$ FFT autocorrelation should work fine, and will be faster than time-domain. Can you plot the autocorrelation result and see which peak bin it's finding? When you say "50% accurate", can you describe what's going wrong? Is it reading the correct note, but an octave too high? Is it reading 0 Hz? Look at the autocorrelation plot and see which peak it's picking that isn't correct. $\endgroup$
    – endolith
    Nov 29, 2014 at 17:01
  • 1
    $\begingroup$ @endolith It produces the wrong note. I think the problem is that the frequency it returns is a multiple of what it should be - there could be a mistake in how I get the frequency after the auto-correlation. Right now I played an open low E (82Hz), and my app detected some Es, some F#s, and a B or two, but the actual frequency its reading is in the 200-300 range which is several octaves too high. I've read that iPhone microphones are bad at <100Hz for speech reasons. $\endgroup$
    – Sevag
    Nov 29, 2014 at 17:07
  • 1
    $\begingroup$ take a look at this paper. look at what they say about autocorrelation (Type I and Type II) and tapering. the kind of autocorrelation you do with the FFT (and zero-padding) is what these guys are calling "Type II" and you might have to think about this "tapering" issue a bit, so that you don't pick the wrong peak. and this tapering is even more pronounced using the Hann window than it is using the rectangular window as is done in the paper. $\endgroup$ Nov 29, 2014 at 17:34
  • $\begingroup$ the real trick in pitch detection is that of first determining the appropriate pitch candidates, and second picking the "correct" or best pitch candidate. $\endgroup$ Nov 29, 2014 at 17:36

1 Answer 1


I realized I had forgotten to make an update to this.

I ended up following @robert bristow-johnson's recommendations in the comments.

I used time-domain McLeod Pitch Method in a live application (records audio in a loop) which works very well.

You can see the source code here: https://github.com/sevagh/Pitcha


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.