DSPRelated.com

Goertzel Algorithm

Category: Algorithms

The Goertzel algorithm is a recursive, block-based method for computing a single bin of the Discrete Fourier Transform (DFT), detecting the energy at one specific frequency without computing the full spectrum. Internally it uses a second-order recursive structure, but it is best understood as a block DFT evaluator rather than a general-purpose filter. It trades the FFT's broad spectral output for lower per-frequency computational cost when only a small number of frequencies are of interest.

In practice

The most common embedded application is DTMF (dual-tone multi-frequency) tone detection, where a telephone or keypad decoder needs to check only 8 frequencies rather than a full spectrum. At those scales, running 8 Goertzel filters is often cheaper than an FFT of sufficient resolution, though the actual crossover depends on block size, FFT radix, and platform. Similar targeted detection tasks include answering-machine tone detection, sonar ping detection, and power-line frequency monitoring.

The algorithm operates in two phases over a block of N samples. The first phase iterates a simple two-coefficient recursive update (s[n] = x[n] + 2*cos(2*pi*k/N)*s[n-1] - s[n-2]) for N steps. The second phase computes the complex DFT coefficient or power estimate from the final two state values; this step involves several multiply-accumulate operations and is done only once per block, which is why the algorithm is more efficient than naively evaluating the DFT sum when only a few bins are needed. Note that extracting the full complex coefficient requires additional arithmetic beyond the simpler power-only form.

A common pitfall involves the basic integer-bin form of the algorithm, which assumes the target frequency falls exactly on a DFT bin boundary for the chosen N. When it does not, spectral leakage can degrade detection accuracy, though the severity depends on the detector design and whether windowing is applied. The block post "Goertzel Algorithm for a Non-integer Frequency Index" addresses a generalized form that evaluates the DFT at arbitrary frequencies without this constraint. Separately, "Correcting an Important Goertzel Filter Misconception" clarifies how the power output of the standard form relates to the true DFT magnitude, which developers sometimes conflate.

On resource-constrained MCUs without an FPU (such as Cortex-M0-class cores or 8-bit PIC/AVR targets), the algorithm is often implemented in fixed-point arithmetic. Coefficient quantization and accumulator overflow must be managed carefully; Q15 or Q31 arithmetic is typical. On Cortex-M4/M7 cores with a single-precision FPU and CMSIS-DSP available, floating-point implementations are straightforward and usually preferred for accuracy.

Discussed on DSPRelated

Frequently asked

When is the Goertzel algorithm faster than an FFT?
As a rough heuristic, Goertzel tends to be more efficient than an FFT when you need to detect only a small number of frequencies in a block of N samples -- sometimes cited as fewer than roughly log2(N), though the actual crossover varies with block size, FFT implementation, radix, and whether the FFT result is reused across many bins. For N=256, this heuristic suggests a threshold around 8 frequencies, but treat that as a starting point for profiling rather than a firm rule. If you need 20 or more bins from a 256-point block, an FFT will typically be cheaper overall.
Does the Goertzel algorithm give the same result as an FFT bin?
Yes, when the target frequency corresponds exactly to an integer DFT bin index k for the chosen block length N, the Goertzel algorithm produces the same complex DFT coefficient as the equivalent FFT bin. The blog post 'A Simpler Goertzel Algorithm' walks through the derivation clearly.
What happens if my target frequency does not land on an exact DFT bin?
The standard integer-bin form suffers spectral leakage, just as a rectangular-windowed FFT would for a non-integer bin. You can either choose N to make the frequency land on a bin, apply a window function before processing, or use the generalized form described in 'Goertzel Algorithm for a Non-integer Frequency Index', which evaluates the DFT at an arbitrary frequency index.
How do I implement Goertzel in fixed-point on a low-end MCU?
Represent the coefficient 2*cos(2*pi*k/N) in Q15 or Q31 format. Use a 32- or 64-bit accumulator for the recursive state to prevent overflow, and saturate or scale inputs as needed. The final power computation involves squaring state values, so promote to 64-bit before multiplying if using Q15 states to avoid overflow. Validate against a floating-point reference on a desktop before porting.
Can the Goertzel algorithm detect amplitude and phase, or only power?
It can provide both. The two final state values yield a complex DFT coefficient from which magnitude and phase can be extracted. The simpler 'power only' form skips the complex output step and is sufficient for tone detection, but if phase information is needed (for example, in coherent demodulation), the full complex output must be computed.

Differentiators vs similar concepts

The Goertzel algorithm is often compared to the FFT. The FFT computes all N/2 or more unique frequency bins simultaneously in O(N log N) operations (the exact count and number of unique bins depend on the FFT variant and whether the input is real-valued) and is the right choice when broad spectral analysis or many bins are needed. Goertzel computes a single bin in O(N) operations per bin, making it more efficient only when a small number of target frequencies are needed. Goertzel is also sometimes compared to a simple bandpass FIR or biquad IIR filter. Note that Goertzel itself uses IIR-like recursion internally, so the distinction is in usage pattern rather than structure: a biquad can continuously filter a signal sample-by-sample with a fixed per-sample cost, whereas Goertzel produces one energy estimate per N-sample block and resets state between blocks. They serve different purposes: Goertzel is a block energy detector, not a continuous-time filter.