Tone Detection with the Goertzel Algorithm

Discussion created by KJBob on Nov 7, 2012
Latest reply on Nov 7, 2012 by KJBob

    The Goertzel algorithm detects the presence of a chosen frequency range in an audio stream. 

It's often used for tone decoding, such as in DTMF (tone dialing) and CTCSS (subaudible tone

squelch).  Unlike many frequency-domain techniques such as the FFT, the Goertzel algorithm can be

done with SigmaStudio on SigmaDSP chips.  This post describes a basic implementation, which I hope

others would improve on.


    Goertzel's method is described in R. G. Lyons' book Understanding Digital Signal Processing,

pages 529-532, also in Wikipedia.  It looks like a high-Q IIR filter but instead of running continuously

it processes frames of samples, like the FFT.  Thus as with the FFT, you can easily trade off

frequency accuracy with aquisition time.


    Most SigmaDSP flows operate at 48KHz, too high to efficiently detect DTMF tones around 1KHz.

That's why each delay in the signal path below totals six samples.  This effectively runs the

Goertzel algorithm at (48/6) = 8KHz, the usual telephone rate.  From here on in my text, fs' refers

to this effective sample rate.  The rest of your system can still process hi-fi audio at 48KHz.


    As with the FFT, choose the number of bins N dividing the input frequency range from 0 to

fs'.  Your frequency resolution is (fs'/N), here (8000Hz/200) = 40 Hz.  The algorithm updates after

each N samples, in the time (N/fs').  In the case shown that's (200/8000Hz) = 25mS.  In the upper

right a square wave oscillator sets the frame time -- the frame runs while this is high, so set its

frequency to (fs'/2N).  Here that's 20Hz.


    Multiply your target frequency by N, then divide by fs' to get its frequency bin m.  For example,

m = 1480*200 / 8000 = 37.  Unlike the FFT, m need not be an integer -- Goertzel's method allows in-between bins.

Plug m into this formula to get the needed filter coefficient:


    coeff = 2cos(2pi*m/N)


The cosine is in radians.  If your coefficient is nearly 2.0, either the calculator is set for degrees, or your

effective sample rate is rather high for your target frequency.  This coefficient is used twice in

the algorithm, in the second place it's negative.  To change frequency within the constraints of fs' and

N, all you need do is change the coefficient.




    As shown the project runs the Goertzel algorithm while the square wave timer is high, saves

the result at the square wave's downward transition, then flushes out the delays and rests during the

low time.  Unfortunately this halves your update rate.  There's probably a more efficient way to time

the algorithm (perhaps with counters), which I'll leave for later.


    The attached project file runs directly on a mini ADAU1701 board.  How well does it work?  I

made the test input a VCO to produce the graph below.  You get quite a precise resolution of frequency.

  In addition, each update jumps right to its new value -- there's no long tail to wait for.   

Goertzel's method is the standard for DSP tone detection -- and yes, you really can run it on any





Message was edited by: Robert Blowsky to correct the example calculation for m.