Is it possible to find precise peak frequency using FFT phase shifts? Been experimenting with FFT on a generated sinusoid and found something strange that doesn't seem to be described anywhere (though I may be missing something of course).

A sinusoid that exactly corresponds to a bin gives what we all know: an amplitude and a phase shift of the sinusoid in that bin.

However, for a frequency that falls between two bins the phase shift of the strongest bin expressed in polar angle seems to be shifted by almost exactly the amount by which the peak frequency is shifted from the strongest bin number. The phase shifts of the neighbouring bins also seem to show some correlation but it is not as strong.

For example, if the distance between bins is $\Delta = 44Hz$, I generate $f = 440Hz$, I get a clear sinusoid at bin $i = 10$ that yields phase angle $\phi = 0$ (the sinusoid itself is shifted by a quarter period for simplicity, hence $0$).

If I generate say

$f = 440Hz + k·\Delta$, where $k \in [-0.5, 0.5]$

then $\phi$ for the strongest bin 10 looks like $k·\pi$.

Some sample measurements:

$k=-0.5 \Rightarrow \phi=-0.499·\pi$

$k=-0.25 \Rightarrow \phi=-0.252·\pi$

$k=-0.15 \Rightarrow \phi=-0.151·\pi$

$k=-0.05 \Rightarrow \phi=-0.054·\pi$

The deviation gets bigger as you move towards the bin, though it's pretty good near the middle. Is this some kind of a parabolic correlation?

So what's the math behind this? Why do these values seem correlated?

And if they are correlated, could this be used for finding the peak frequency with some precision?
For a set of exact equations that describe how a pure real tone works in a DFT check out equations (23)-(25) in my blog article:


DFT Bin Value Formulas for Pure Real Tones


The phenomenon you have found can be seen clearer if you consider the complex definition of a real valued sinusiodal.

$$ \cos( \theta ) = \frac{e^{i\theta}+e^{-i\theta}}{2} $$

So, when you are near a peak bin, one of the numerator values is dominant, and you have an approximation of a complex tone.  Using equation (24) in this article shows how a the distance to the bin $\delta$ rotates the bin value.


DFT Bin Value Formulas for Pure Complex Tones


Hope this helps.

To answer your last question: Yes, I've done it different ways with more coming.

Check out:


Exact Frequency Formula for a Pure Real Tone in a DFT
Two Bin Exact Frequency Formulas for a Pure Real Tone in a DFT
Improved Three Bin Exact Frequency Formula for a Pure Real Tone in a DFT
A Two Bin Exact Frequency Formula for a Pure Complex Tone in a DFT
Three Bin Exact Frequency Formulas for a Pure Complex Tone in a DFT
[Jacobsen's Frequency Formula as an Approximation]
[Candan's Tweak of Jacobsen's Frequency Formula]
[Tweaking Macleod's Frequency Formula]




Your $k$ is the fraction of a bin distance from a bin on the frequency scale of cycles per frame.

Thus, from (20):

$$ k = -\frac{N}{2\pi} \delta $$

The negative sign is unfortunate, I should have done it differently in the article.

$$ \delta = -\frac{2\pi}{N} k $$

Your $\phi$ is the angle of the nearest complex bin value, so I will use $\theta$ in the formula for the phase angle from the signal definition in (24):

$$ \phi = \arg(X[]) = -\delta (N-1)/2 + \theta $$

$$ \phi = \frac{2\pi}{N} k (N-1)/2 + \theta $$

$$ \phi = \frac{N-1}{N} k \pi + \theta $$

So, for N being large, and $\theta$ being zero, $\phi$ looks like $k \pi$.

Remember, this is based on using a complex tone as an approximation for the real value tone, so it won't be exact.  I am not sure why your ratios are slightly larger than one when they should be slightly smaller.