具有复杂输出或幅度+相位的C / C ++ Goertzel算法?

时间:2012-01-12 13:26:00

标签: c++ c algorithm signal-processing

有人知道在哪里可以获得代码或库来执行具有复杂输出的Goertzel算法吗? (或任何其他1-bin-DFT算法?)

1 个答案:

答案 0 :(得分:3)

以下是几年前我写的代码。我刚刚测试了它,它似乎工作。您可以随意使用它,并根据需要进行归属。

goertzelfilter.h

/* goertzelfilter.h
*/

#ifndef GOERTZELFILTER_H_
#define GOERTZELFILTER_H_

#include <complex.h>

typedef struct goertzelfilterstruct {
  double coeff ;
  double sine ;
  double cosine ;
} GoertzelFilter;

GoertzelFilter goertzelSetup( double normalizedfreq );

double complex goertzelFilterC( double *sample, int nsamples, GoertzelFilter *g );

#endif

goerzelfilter.c

/* goertzelfilter.c
*/

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

#include "goertzelfilter.h"

GoertzelFilter goertzelSetup( double normalizedfreq )
{
  double w = 2*M_PI*normalizedfreq;
  double wr, wi;

  GoertzelFilter g;

  wr = cos(w);
  wi = sin(w);
  g.coeff = 2 * wr;
  g.cosine = wr;
  g.sine = wi;

  return g;
}

double complex goertzelFilterC( double *samples, int nsamples, GoertzelFilter *g )
{
  double sprev = 0.0;
  double sprev2 = 0.0;
  double s, imag, real;
  int n;

  for (n=0; n<nsamples; n++ ) {
    s = samples[n] + g->coeff * sprev - sprev2;
    sprev2 = sprev;
    sprev = s;
  }

  real = sprev*g->cosine - sprev2;
  imag = -sprev*g->sine;

  return real + I*imag;
}

对于测试,你可以试试这个,

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

#include "goertzelfilter.h"

#define LEN(a) (sizeof(a)/sizeof(a[0]) )

int main() {

  double data[1024] = { 0. };
  double complex filtered[1024] = { 0. };

  GoertzelFilter g = { 0. };

  int n;
  int nwindow = 64;

  double f = 10./LEN(data) ;

  for ( n = 0 ; n < LEN(data) ; n++ ) {
    data[n] = sin( n * (2.*M_PI) * f ) + 0.5*((float)rand()/RAND_MAX - 1.);
  }

  g = goertzelSetup( f );

  for( n = 0 ; n < LEN(data)-nwindow ; n++ ) {
    filtered[n]  = goertzelFilterC( &data[n], nwindow, &g )/nwindow;
  }

  for( n = 0 ; n < LEN(data) ; n++ ) {
    printf( "%g %g %g\n", data[n], creal(filtered[n]), cimag(filtered[n]) );
  }

}