在 Python 中实现分块低通 IIR 滤波器
Implementing Blockwise Low-Pass IIR Filter in Python
此问题与 https://dsp.stackexchange.com/questions/60694 类似,但我将其重新定义为 Python 实施问题,以便更符合我正在寻求的解决方案。
我想实现一个低通 IIR 滤波器,它对几乎实时的音频块(每个块 441 个数据点 X 100 Hz = 44.1 kHz)进行操作。有很多嗡嗡作响的文物。我希望它与我如何使用 scipy.signal 方法和设置初始条件有关。
首先,我试图通过 DSP 论坛上的对话了解我正在做的事情背后的理论,但我早就忘记了我的 DSP 大学课程,所以它对我来说没有多大意义。接下来,我尝试了很多很多代码组合,唯一有效(没有伪影)的是函数和参数的非常具体的组合。
Bparam, Aparam = signal.iirfilter(2, 0.020, btype = 'lowpass', analog =
False, ftype = 'butter') # 2nd order Butterworth coefficients
Z = signal.lfilter_zi(Bparam, Aparam) # Part of the init conditions calc
IC = Z * (prevSignal[::-1])[0:2] # Reverse prevSignal and then grab
# only the last two elements
filteredSignal, _ = signal.lfilter(Bparam, Aparam, inputSignal, zi = IC)
# Result is continuous and clear
prevSignal = filteredSignal # Save for the next pass
我用两种方式测试我的过滤器。第一个是 inputSignal 是 np.sin 波,预期输出是未失真的正弦波。第二种是添加一些奇次谐波(构建带限方波)并验证结果具有较小的谐波振幅,就像低通滤波器一样。
当阶数为二阶时,上述代码符合预期,但阶数更高时会出现失真。例如,我尝试将 IC 范围设置为 [0:4],但它似乎并没有以同样的方式工作。
在@Warren 的论文中(恕我直言,这篇论文非常好),批量过滤长信号 部分帮助回答了我的问题。连同该部分中提供的示例代码,我通过以下方式形成了 sos
数组:
Bparam, Aparam = signal.iirfilter(2, 0.02,
btype = 'lowpass', analog = False, ftype = 'butter')
Z, P, K = signal.tf2zpk(Bparam, Aparam)
sos = signal.zpk2sos(Z, P, K)
我也在高通滤波器上试过这个,最高 8 阶,没问题!
此问题与 https://dsp.stackexchange.com/questions/60694 类似,但我将其重新定义为 Python 实施问题,以便更符合我正在寻求的解决方案。
我想实现一个低通 IIR 滤波器,它对几乎实时的音频块(每个块 441 个数据点 X 100 Hz = 44.1 kHz)进行操作。有很多嗡嗡作响的文物。我希望它与我如何使用 scipy.signal 方法和设置初始条件有关。
首先,我试图通过 DSP 论坛上的对话了解我正在做的事情背后的理论,但我早就忘记了我的 DSP 大学课程,所以它对我来说没有多大意义。接下来,我尝试了很多很多代码组合,唯一有效(没有伪影)的是函数和参数的非常具体的组合。
Bparam, Aparam = signal.iirfilter(2, 0.020, btype = 'lowpass', analog =
False, ftype = 'butter') # 2nd order Butterworth coefficients
Z = signal.lfilter_zi(Bparam, Aparam) # Part of the init conditions calc
IC = Z * (prevSignal[::-1])[0:2] # Reverse prevSignal and then grab
# only the last two elements
filteredSignal, _ = signal.lfilter(Bparam, Aparam, inputSignal, zi = IC)
# Result is continuous and clear
prevSignal = filteredSignal # Save for the next pass
我用两种方式测试我的过滤器。第一个是 inputSignal 是 np.sin 波,预期输出是未失真的正弦波。第二种是添加一些奇次谐波(构建带限方波)并验证结果具有较小的谐波振幅,就像低通滤波器一样。
当阶数为二阶时,上述代码符合预期,但阶数更高时会出现失真。例如,我尝试将 IC 范围设置为 [0:4],但它似乎并没有以同样的方式工作。
在@Warren 的论文中(恕我直言,这篇论文非常好),批量过滤长信号 部分帮助回答了我的问题。连同该部分中提供的示例代码,我通过以下方式形成了 sos
数组:
Bparam, Aparam = signal.iirfilter(2, 0.02,
btype = 'lowpass', analog = False, ftype = 'butter')
Z, P, K = signal.tf2zpk(Bparam, Aparam)
sos = signal.zpk2sos(Z, P, K)
我也在高通滤波器上试过这个,最高 8 阶,没问题!