logoalt Hacker News

codedokodeyesterday at 2:11 PM1 replyview on HN

The code mentions "autocorrelation" method: this is a method where you multiply the signal with delayed version of itself: result = sum(x[i] * x[i - delay] for i in some range). You vary the "delay" and pick the value that maximizes the result. This is based on the idea, that the sequential periods of the signal should be similar to each other.

Not a very good method, prone to octave errors (showing pitch one octave lower than the correct one). Furthermore, the "delay" is an integer which limits the precision, so you need to use some form of interpolation. Also it doesn't allow to recognize multiple notes sounding together. Also, slow.

You can read the paper on the "YIN" pitch estimation algorithm which describes the method in details.

I think FFT-based methods are more reliable. I did little experimentation and when measuring a pure sine wave, the frequency can be determined with high precision (tenths-hundredths of a Herz). Not so good in presence of a noise or multiple instruments - I tried to use descending from the hill optimization to figure out the pitch of each harmonic, but it didn't work out.


Replies

dsegoyesterday at 5:44 PM

I implemented the McLeod NSDF pitch method, which normalizes the autocorrelation to get a pretty reliable estimate with fewer octave jumps. For precise tuning I used phase tracking between successive single-bin DFTs tuned to the target frequency.

https://github.com/dsego/strobe-tuner/