I have an audio buffer with 1024 samples per second. The sample rate is 44100. I am trying to identify the frequency tones. Using the Gorzel algorithm, I can get the frequency but it's not that accurate. I was trying some other scope program and I got better results with the same hardware. How can I decrease the id-bandwidth (to be sharper) so the id will be accurate for the target frequency? (I can't use FFT because it's real time and takes some memory.)

float goertzel_mag(int16_t* data ,int SAMPLING_RATE ,double TARGET_FREQUENCY,int numSamples )
    int     k,i;
    float   floatnumSamples;
    float   omega,sine,cosine,coeff,q0,q1,q2,magnitude,real,imag;
    float   scalingFactor = numSamples / 2; // -2

    floatnumSamples = (float) numSamples;
    k = (int) (0.5 + ((floatnumSamples * TARGET_FREQUENCY) / SAMPLING_RATE));
    omega = (2.0 * M_PI * k) / floatnumSamples;
    sine = sin(omega);
    cosine = cos(omega);
    coeff = 2.0 * cosine;

    for(i=0; i<numSamples; i++)
        q0 = coeff * q1 - q2 + data[i];
        q2 = q1;
        q1 = q0;

    real = (q1 - q2 * cosine) / scalingFactor;
    imag = (q2 * sine) / scalingFactor;

    //double theta = atan2 ( imag, real); //PHASE
    magnitude = sqrtf(real*real + imag*imag);
    return magnitude;
  • $\begingroup$ As you know, the Goertzel algorithm simply computes the DTFT of the input signal at a given frequency. So it's all about how this algorithm is embedded in your method of IDing the tones. There's nothing wrong with the Goertzel algorithm itself (assuming you've implemented it correctly). So, how do you actually do it? $\endgroup$ – Matt L. Jun 3 '13 at 12:38

There are two things you can do:

  1. Use a different algorithm, like autocorrelation.
  2. Use the phase information! This technique is discussed in chapter 9 of DAFX. You can find matlab source here.

DAFX discussed the phase-based technique using the FFT, but it should apply to Goerzel's algorithm as well, assuming you have real data at that frequency. The key concept is that you must note how much the phase changes over time to determine the exact frequency.

You may want to experiment with an FFT of smaller size instead of Goerzel's algorithm to validate the assumptions.

| improve this answer | |
  • $\begingroup$ Thanks a lot, know auto correlation , but the truth is that i couldn't find the right code to insert samples and get the max at the relevant point. reading about it is something else than performing . i will check the phase thing. $\endgroup$ – Rant Jun 3 '13 at 9:10

The bandwidth of a Goertzel filter is roughly inversely proportional to its length (there are some scalloping effects if the Goertzel length isn't an exact multiple of the resonant frequency's period). So longer for a more accurate frequency selector.

| improve this answer | |
  • $\begingroup$ Thanks .longer you mean more samples ? i know the bandwidth is determined by samples/n , where n is the number you dividing your samples at . so how can i correct the algorithm specifically according to your answer ? $\endgroup$ – Rant Jun 3 '13 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.