libdspl-2.0/dspl/src/goertzel.c

110 wiersze
2.6 KiB
C

/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
/******************************************************************************
Goertzel algorithm for real vector
*******************************************************************************/
int DSPL_API goertzel(double *x, int n, int *ind, int k, complex_t *y)
{
int m, p;
double wR, wI;
double alpha;
double v[3];
if(!x || !y || !ind)
return ERROR_PTR;
if(n < 1 || k < 1)
return ERROR_SIZE;
for(p = 0; p < k; p++)
{
wR = cos(M_2PI * (double)ind[p] / (double)n);
wI = sin(M_2PI * (double)ind[p] / (double)n);
alpha = 2.0 * wR;
v[0] = v[1] = v[2] = 0.0;
for(m = 0; m < n; m++)
{
v[2] = v[1];
v[1] = v[0];
v[0] = x[m]+alpha*v[1] - v[2];
}
RE(y[p]) = wR * v[0] - v[1];
IM(y[p]) = wI * v[0];
}
return RES_OK;
}
/******************************************************************************
Goertzel algorithm for complex vector
*******************************************************************************/
int DSPL_API goertzel_cmplx(complex_t *x, int n, int *ind, int k, complex_t *y)
{
int m, p;
complex_t w;
double alpha;
complex_t v[3];
if(!x || !y || !ind)
return ERROR_PTR;
if(n < 1 || k < 1)
return ERROR_SIZE;
for(p = 0; p < k; p++)
{
RE(w) = cos(M_2PI * (double)ind[p] / (double)n);
IM(w) = sin(M_2PI * (double)ind[p] / (double)n);
alpha = 2.0 * RE(w);
memset(v, 0, 3*sizeof(complex_t));
for(m = 0; m < n; m++)
{
RE(v[2]) = RE(v[1]);
RE(v[1]) = RE(v[0]);
RE(v[0]) = RE(x[m]) + alpha * RE(v[1]) - RE(v[2]);
IM(v[2]) = IM(v[1]);
IM(v[1]) = IM(v[0]);
IM(v[0]) = IM(x[m]) + alpha * IM(v[1]) - IM(v[2]);
}
RE(y[p]) = CMRE(w, v[0]) - RE(v[1]);
IM(y[p]) = CMIM(w, v[0]) - IM(v[1]);
}
return RES_OK;
}