0
$\begingroup$

I have found an implementation of the Goertzel algorithm that contains code that I don't understand. And more specifically the pre-calculation of coefficients.

At the top of the code there is :

#define DTMF_697Hz  27980
#define DTMF_770Hz  26956
#define DTMF_852Hz  25701
#define DTMF_941Hz  24219

These defines are used inside the goertzel calculation like such :

for (i = 0; i < N; i++)
{
  v0 = ((cos_fact * v1) >> 14) - v2 + *x;
  x++;
  v2 = v1;
  v1 = v0;
}

x is my buffer.

v0, v1 and v2 are long int

cos_fact is the one of defines I showed above and passed as a function parameter.

My questions would be: What do these define correspond to? How to pre-calculate them for other frequencies? Is it normal that the values are so far apart?

ps: This code is part of ampm_open_lib and my goal would be to use it for detecting other frequencies than DTMFs tones.

EDIT:

Following the answer of Peter K. Here is a little C program that output the desired values.

#include        <stdio.h>
#include        <stdlib.h>
#include        <math.h>

#define         TAB     {697.0f, 770.0f, 852.0f, 941.0f, 1209.0f, 1336.0f, 1477.0f, 1633.0f}
#define         LEN     8

int             main(int ac, char **av)
{
  float         tab[LEN] = TAB;
  float         sr;

  if (ac >= 1)
    printf("Usage: ./a.out sample_rate\n");
  else
    sr = atof(av[1]);

  if (sr > 0)
    {
      printf("+-----------------------+-----------------------+\n");
      float coef = 0;
      for (unsigned int i = 0; i < LEN; i++)
        {
          coef = cos(2.0f * 3.14159f * (tab[i] / sr)) * 256 * 128;
          printf("|     %f      |       %f      |\n", tab[i], coef);
          printf("+-----------------------+-----------------------+\n");
        }
    }
  else
    {
      printf("You cannot use a sample rate that is smaller or equal to 0\n");
      exit (0);
    }

}

You can use it like this:

gcc yourFile.c -lm && ./a.out 8000

Thanks for the help.

$\endgroup$
2
$\begingroup$

Check out the comment in this code:

// ----- Parameters and Variables for Tone Detector ----- 
// cos = (cos (2*PI*(DTMF_Freq/8000.0))) * 256*128;
#define DTMF_697Hz   27980        // DTMF Row Frequency
#define DTMF_770Hz   26956
#define DTMF_852Hz   25701
#define DTMF_941Hz   24219
#define DTMF_1209Hz  19073        // DTMF Column Frequency
#define DTMF_1336Hz  16325
#define DTMF_1477Hz  13085
#define DTMF_1633Hz   9315
#define DTMF_1394Hz  15014        // DTMF Row Frequency    2nd harm
#define DTMF_1540Hz  11583
#define DTMF_1704Hz   7549
#define DTMF_1882Hz   3032
#define DTMF_2418Hz -10565        // DTMF Column Frequency 2nd harm
#define DTMF_2672Hz -16503
#define DTMF_2954Hz -22318
#define DTMF_3266Hz -27472

It explains how the cos_fact is being calculated pretty directly. For example, for the first item in the list:

$$ \cos( 2 \pi \times 697 / 8000) \times 256 \times 128 = 27979.5762684 \approx 27980 $$

$\endgroup$

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.