基本2极低通滤波器的实现

信息处理 过滤器 离散信号 过滤器设计 低通滤波器
2022-02-15 11:49:46

我知道这个问题已经被很多人问到了地狱,并且在被删除之前它可能会被否决,但请多多包涵。

我正在为我的一个项目设计一个声音引擎,它需要支持低通滤波(不需要其他滤波,因此不需要极其强大的均衡或高通滤波器)。

不幸的是,我并不完全精通 DSP 数学(因为我更像是一名程序员),所以这变得越来越棘手。

我通过在互联网上搜索发现的是一个“1-RC 和 C 过滤器”,它的实现方式为:

// Coefficient computation
// Cutoff and reso are [0,128) integers
c = 0.5^[(128-Cutoff) / 16.0]
r = 0.5^[( 24+Reso)   / 16.0]

v0 = (1.0 - r*c)*v0 - c*v1 + c*input
v1 = (1.0 - r*c)*v1 + c*v0

在同一个网站上,我还发现 c 可以用公式按频率编写

c = 2.0 * sin(Freq * pi/SampRate)

由于我只是在没有共振的情况下进行可变低通滤波,这导致

c = 2.0 * sin(Freq * pi/SampRate)
r = pow(0.5, 24 / 16.0) = 1 / sqrt(8) = ~0.3536

由于声音引擎主要与 MIDI 相关,因此我使用了在互联网上其他地方找到的频率截止,这导致了一个相对简单的公式

CutoffFreq = 250.0 * 32^x

其中 x 绑定到 [0.0,1.0],导致频率范围为 250Hz~8kHz。

但是,这是我的问题开始的地方。

假设我们正在使用最大截止频率(也就是说,不应该对数据进行过滤)并且我在 44.1kHz 进行混音。

c   = 2.0 * sin(8000.0 * pi/44100.0) = ~1.0791
r   = 8^(-0.5)                       = ~0.3536
      1.0 - r*c                      = ~0.6184

现在让我们假设输入信号是一个基本三角形:

Input[] = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 0.8, 0.6, 0.4, 0.2}

应用上面的代码会导致

// Beforehand...
v0 = 0.0
v1 = 0.0

// 1st Sample [works okay]
v0 = 0.6184*0.0 - 1.0791*0.0 + 1.0791*0.0 = 0.0
v1 = 0.6184*0.0 + 1.0791*0.0              = 0.0

// 2nd Sample [incorrect]
v0 = 0.6184*0.0 - 1.0791*0.0 + 1.0791*0.2 = ~0.2158
v1 = 0.6184*0.0 + 1.0791*0.2158           = ~0.2329 [residual 0.0329]

// 3rd Sample [more than doubly incorrect]
v0 = 0.6184*0.2158 - 1.0791*0.2329 + 1.0791*0.4 = ~0.3138
v1 = 0.6184*0.2329 + 1.0791*0.3138              = ~0.4826 [residual 0.0826]

如您所见,这并不完全正确。事实上,从它的声音来看,就好像我引入了一个轻微的高通滤波器,同时也略微增加了共振。

因此,我想知道是否有人可以提供一个与编程相关的人可以理解的解释,以计算低通滤波器系数和方程,并阐明如何正确实现这一点。

提前致谢。

1个回答

首先,您的滤波器是非典型低通滤波器。过滤器的传递函数是

H(z)=β21+(β22α)z1+α2z2

其中α=1rcβ=c

在示例中,您使用这些值

c=2sin(8000π/44100) ,r=80.5

它们给出以下频率响应。

在此处输入图像描述

在您逐步处理三角波形的第一个样本的示例中,您似乎希望输入能够不失真地通过。那是对的吗?如果是这样,你为什么期望这个?

作为替代方案,您可以使用二阶巴特沃斯低通滤波器。在这里http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt你可以找到系数的表达式以及你必须实现的差分方程。