在 C/C++ 中实现 FIR 滤波器的最简单方法

信息处理 过滤器 过滤器设计 信号分析 C
2022-02-20 05:22:17

在 C/C++ 中实现 FIR 滤波器的最简单方法是什么?

(我不想使用 Matlab 或 Octave 之类的第三方软件来计算系数,因为我必须对数千个文件使用不同的过滤器,每个文件具有不同的频率。)

因此,是否有一个现成的具有类似功能的 C/C++ DSP 库file.FIR_NotchFilter(frequency,Qfactor)或类似的东西?(商业或开源)

提前非常感谢。

PS1:我看到有http://aquila-dsp.org,但是还没有二进制版本,而且对于旧版本,似乎很难使用它

PS2: IIR 滤波器有一个真正现成的解决方案: https ://github.com/vinniefalco/DSPFilters

// Create a Chebyshev type I Band Stop filter of order 3
Dsp::SimpleFilter <Dsp::ChebyshevI::BandStop <3>, 2> f;
f.setup (3,    // order
     44100,// sample rate
     4000, // center frequency
     880,  // band width
     1);   // ripple dB
f.process (numSamples, arrayOfChannels);
4个回答

您是否考虑过使用 Parks McClellan 算法来生成 FIR 滤波器。它的源代码可以在 Fortran 或 C 的多个站点上找到。

原始 Fortran 代码可在 Wikipedia 上找到。

这是C代码的两个来源

你说你试图理解过滤器,所以让我解释一下 Parks McClellan 算法是经典的。它是在 70 年代初开发的,至今仍被认为是可用的最佳 FIR 设计算法之一。

如果您在非实时过滤(例如当数据已经在文件中时)并且需要线性相位陷波,那么合适的 IIR 滤波器向前和向后馈送数据将为您提供线性相位和更深的陷波.

在 C 代码中,您可以在每个向量 IIR 函数调用后反转数组。

由于您对设计自己的 FIR 滤波器感兴趣,您可以从加窗 sinc 滤波器开始。如果你“窗口化”一个“sinc”,你基本上会得到一个低通滤波器的脉冲响应。由于滤波是线性的,你可以混合多个低通滤波器的脉冲响应和单位脉冲来做各种各样的事情(高通、带通、陷波)。滤波器在样本中的脉冲响应范围基本上控制了拐角频率处的过渡带宽:“更长”滤波器=“更锐利的截止”。实际的窗口函数是锐截止和强拒绝之间的另一个折衷。查看 Wikipedia 关于窗口函数的文章。

请参阅http://www.dspguide.com/ch16.htm

但是对于某些特定频率,低阶 IIR 滤波器也可以是一个不错且快速的陷波。不过,设计这些更棘手。解决这个问题的一种方法是离线设计一些任意的陷波频率,例如 Nyquist/2,然后在运行时进行“频率扭曲”以向上或向下移动陷波频率。如果您之前将滤波器分解为一系列二阶部分,那么频率扭曲实际上并不难。频率扭曲可以独立(使用相同的参数)应用于每个部分。

如果您不必实时计算 FIR 系数,您可以使用任何离线工具来计算系数并将其添加到您的程序代码中。进行 FIR 滤波的简单函数是微不足道的。Matlab(或其免费的模拟 Octave)几乎是设计 FIR 系数的标准工具。

如果您想要实时计算 FIR 系数和/或想要非常快速地进行数据过滤,您可以使用 Intel Integrated Performance Primitives library ("IPP Filtering Functions)"