Improving FFT Frequency Resolution
Improving FFT Frequency Resolution
Introduction
When taking the FFT of a signal, the size of the transform is equivalent to the number of frequency bins
that will be created. Each bin represents the amount of energy that the signal has at that particular
frequency. The frequency resolution is the difference in frequency between each bin, and thus sets a limit
on how precise the results can be. The frequency resolution is equal to the sampling frequency divided by
FFT size. For example, an FFT of size 256 of a signal sampled at 8000Hz will have a frequency resolution
of 31.25Hz. If the signal is a sine wave of 110 Hz, the ideal FFT would show a sharp peak at 110Hz.
Unfortunately, with the given frequency resolution, the energy will be split between bins 4 and 5 (93.75Hz
and 125Hz, respectively). For some applications, it may be necessary to get a more accurate frequency
measurement; this document describes how to do so.
2930 Hz Bin
3047 Hz Bin
3164 Hz Bin
2930 2941 2953 2965 2977 2988 3000 3012 3023 3035 3047 3059 3070 3082 3094 3105 3117 3129 3141 3152 3164
Input Frequency (Hz)
Clearly, there is a relationship between consecutive FFT bin magnitudes. Using this information, the
exact frequency of the input sine can be approximated, even if it is not equal to one of the bin
frequencies. The FFT that is computed in software is a discrete spectrum of bins1. For spectrum
interpolation, the spectrum will be considered continuous, with the frequency of interest lying
somewhere between bins. In the example from the introduction, the input frequency lies between
bins 4 and 5, so on a continuous spectrum, a peak would be expected around “bin” 4.5. Interpolation
involves approximating this intermittent bin based on three consecutive bins (henceforth described as
the “main lobe”) that create a peak in the discrete frequency spectrum.
We will denote the maximum bin of interest as km, the deviation of the “true” maximum from km as Δm,
and the magnitude of a bin as a function M[k]. Δm can be approximated based on the magnitudes
M[km – 1], M[km], and M[km + 1]. Adding that deviation to km will obtain the intermittent frequency bin,
which can be multiplied by the frequency resolution of the FFT to determine the input signal
frequency.
1
The DC bin will be considered as bin 0
Two possible methods of frequency estimation will be discussed: parabolic interpolation (PI) and
Gaussian interpolation (GI). Spectrum Interpolation involves floating point operations and division, so
any hardware or performance limitations must be taken into account. While PI requires less
processing, GI produces more accurate results. Either can be used depending on the specific needs
of the application.
Parabolic Interpolation:
Though the shape of the main lobe may not be exactly parabolic, the assumption that it is can be used
to find a fairly good approximation of the intermittent frequency with PI using the formula below:
𝑀[𝑘𝑚 + 1] − 𝑀[𝑘𝑚 − 1]
∆𝑚 =
2(2 ∗ 𝑀[𝑘𝑚 ] − 𝑀[𝑘𝑚 − 1] − 𝑀[𝑘𝑚 + 1])
Gaussian Interpolation:
GI produces a better approximation of the continuous spectrum, but requires more processing power
because it involves logarithmic calculations. The formula is as follows:
𝑀[𝑘𝑚 + 1]
ln ( )
𝑀[𝑘𝑚 − 1]
∆𝑚 =
𝑀[𝑘𝑚 ]2
2𝑙𝑛 ( )
𝑀[𝑘𝑚 − 1] ∗ 𝑀[𝑘𝑚 + 1]
The input frequency is then calculated by multiplying the intermittent bin value with the frequency
resolution:
𝐹𝑠
𝑓= (𝑘 + ∆𝑚 )
𝑁 𝑚
Note that this approximation works best on input signals with frequency components that are
reasonably spread out, such as a sine wave, square wave, or single instrument note. Any harmonics
should be far enough away from the fundamental frequency so that they will not interfere with the
main lobe of the spectrum. If the input signal contains additional frequencies between (km – 1) and
(km + 1), it will be more difficult to approximate the true maximum frequency.
Windowing:
Spectrum interpolation works best when the input signal is windowed before the FFT is calculated.
Hanning, Blackman, Gaussian, etc. windows will all improve the accuracy of interpolation. A
Gaussian window used with Gaussian Interpolation is particularly effective. Use Matlab to generate N
windowing coefficients and multiply them with the input samples of the FFT. See the document
referenced below for accuracy comparisons between various windowing and interpolation
combinations.
Example Code:
The following code utilizes Gaussian interpolation with a Gaussian window to determine the
fundamental frequency of a musical note. The sampling window has already been adjusted by
Gaussian windowing.
RFFT_SIZE = 256
magAddr: points to array of FFT magnitude results
sample_freq = 8000Hz
TI_FFT(): TI optimized function to calculate FFT
maxidx_SP_RV_2(): TI optimized function to find maximum value in array