我正在尝试实现 IIR 滤波器。
我试图实现以下过滤器,但
FIR : y(n) = b0(x[n]) + ... +bM-1(x[n-M+1])
IIR : y(n) = {b0(x[n]) + ... +bM-1(x[n-M+1])} - {a1(y[n-1]) + ... +aN(y[n-N}
我对如何实现
y[n-1].....
感到困惑.这是我的代码。
void IIRFloat(double *coeffs_B, double *coeffs_A, double *input, double *output, int length, int filterLength)
{
double bcc, acc;
double *coeffa, *coeffb;
double *inputp;
double *outputp;
int n,k;
//filter length =7
for (n = 0; n < length; n++) {
coeffa = coeffs_A;
coeffb = coeffs_B;
inputp = &insamp[filterLength - 1 + n]; //insamp[6]~insamp[85]
acc = 0;
bcc = 0;
for (k = 0; k < filterLength; k++) {
bcc += (*coeffb++) * (*inputp--); //b[0] * x[6] + b[1] * x[5]...+b[6] * x[0]
}
for (k = 1; k < filterLength; k++) {
acc += (*coeffa++) * (*output--); //a[1] * y[5] + a[2] * y[4]...+a[6] * y[0]
}
output[n] = bcc-acc;
}
}
我不会在这里复制
memove
的代码寻求简洁的功能。
最佳答案
如果你真的想用指针来做:
void filter1(const double *b, const double *a, size_t filterLength, const double *in, double *out, size_t length) {
const double a0 = a[0];
const double *a_end = &a[filterLength-1];
const double *out_start = out;
a++;
out--;
size_t m;
for (m = 0; m < length; m++) {
const double *b_macc = b;
const double *in_macc = in;
const double *a_macc = a;
const double *out_macc = out;
double b_acc = (*in_macc--) * (*b_macc++);
double a_acc = 0;
while (a_macc <= a_end && out_macc >= out_start) {
b_acc += (*in_macc--) * (*b_macc++);
a_acc += (*out_macc--) * (*a_macc++);
}
*++out = (b_acc - a_acc) / a0;
in++;
}
}
我将这个算法的结果与 MATLAB 的过滤函数进行了比较。
备注 :如果您将系数归一化(即
a0 == 1
),您可以获得很大的性能提升。为此,您只需将 a
分开即可。和 b
vector 来自 a0
, 然后就不用除 b_acc - a_acc
来自 a0
在每次迭代中。
关于c - 如何在 C 中实现 IIR 滤波器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50588879/