实现一个数字滤波器-通过卷积或差分方程



我是一个非常有经验的软件工程师,我在大学里学过一些EE课程。我在iPhone和Android上编程,我想为实时麦克风和加速度计数据实现数字滤波器(例如低通,带通,带阻等)。

我知道有多种等效的方法来实现时域样本窗口上的数字滤波器。我正在考虑的两种方法是:

  1. 直接在C/Java代码中实现差分方程Y [i] = Y [i-1] + 2 * x[i])。我相信它可以在O(N)时间内运行,式中,N为采样窗口的长度,如N=512。

  2. 实现在样本窗口和FIR滤波器的时域表示,通常是某种形式的sinc函数。我之前问过这个问题。这可以在0 (N)内完成

  3. 如果你使用快速卷积涉及FFT和IFFT。

现在,通过阅读各种在线资源,我发现C/Java编程首选的传统智慧方法是(1),实现一个差分方程。这是一个正确的结论吗?

以下是我的发现:

  • Apple的加速度计滤波器代码实现了一个差异方程。

  • 这个Stackoverflow的问题如何实现一个低通滤波器?建议使用差异方程。

  • 维基百科关于低通滤波器的文章提供了一种算法

总之,我的问题是:

  1. 是实现差分方程(而不是通过快速卷积)的方式去写C/Java过滤器?

  2. 上述参考文献均未说明如何在给定特定截止频率或带阻频率的情况下设计差分方程。我知道我之前学过这个。对于程序员来说,这类信息有什么过滤器参考吗?

时域差分方程卷积。你想到的基于fft的方法是频域卷积又名快速卷积,这实际上只是一个性能优化-它在数学上等同于时域卷积。通常,当滤波器长度较小时,直接时域卷积更快,而当滤波器长度较大时,频域方法更有效。作为经验法则,对于一维滤波,"大"意味着,例如,N> 50。

在上面的段落中,我们只讨论FIR滤波器。对于IIR滤波器,频域卷积不是一种选择(除非在任意点截断脉冲响应),但通常IIR滤波器与FIR滤波器相比往往相对较短。

为了生成过滤系数(即。design a filter),您通常从过滤器规范开始,然后使用许多现有软件包中的一个来生成系数。如果你真的想要的话,你可以实现你自己的过滤器设计例程——看看Remez exchange等算法。

低阶IIR滤波器(使用短差分方程)在计算上可以比FIR卷积或使用fft的快速卷积快得多,如果它们符合您的滤波器规格。它们也类似于电路设计人员可能熟悉的低分量计数模拟滤波器。

如果您没有复杂的滤波器规格或要求(不能在少量极点和零中足够接近),为什么要在FIR或FFT上消耗更多的CPU周期?但如果你确实需要一个更专门的过滤器,那么你就需要了。

这是一个非常常用的公式来确定biquads的IIR系数。双组IIR滤波器也可以级联进行高阶滤波。

我支持使用传统时域数字滤波器的建议,即使用延迟、加法器和乘法器。对于简单的实时过滤,这种方法可能更快,更简单。

在实时应用程序中使用fft是可以的,具体取决于目标。例如,如果你想做实时光谱分析(比如,对于一个涉及音频的机器学习任务),那么fft工作得很好,因为它们快速、简单,并且可以提供高光谱分辨率。

你关于FIR和IIR的评论是正确的。如果您提供一些(示例)过滤器规格,那么我们可能能够在选择哪种过滤器类型以及如何定义过滤器抽头(即系数)方面提供更多帮助。例如,如果您可以访问Matlab或Python-Scipy,您可以使用它们来设计您的过滤器。

(检查dsp。

最新更新