使用 Python 进行信号过滤

信息处理 过滤器 信号分析 声音的 过滤器设计 Python
2022-01-14 10:07:49

我正在尝试使用 python 创建一个应用程序,该应用程序能够记录音频信号并检测信号中的短毛刺。例如,我可能正在录制一个 1000Hz 的正弦波,并寻找音频中断一两个样本的情况。我一直通过使用陷波滤波器去除所有 1000Hz 频率并搜索剩余峰值出现的位置来实现这一点。当我开始记录信号、完成记录然后过滤整个记录的信号、搜索峰值等时,我的程序似乎工作正常,但我想让它实时工作,在那里我可以开始记录,分析 5 秒的音频然后继续播放接下来的 5 秒音频,依此类推,直到我完成录制。不幸的是,当我这样做时,我以前工作的陷波滤波器似乎不再正常工作。

f0 = 1000.0  # Frequency to be removed from signal (Hz)
Q = 30.0  # Quality factor
w0 = f0/(fs/2)  # Normalized Frequency
# Design notch filter
b, a = signal.iirnotch(w0, Q)
zi = signal.lfilter_zi(b, a)
z, _ = signal.lfilter(b, a, xn, zi=zi*xn[0])
z2, _ = signal.lfilter(b, a, z, zi=zi*z[0])
y = signal.filtfilt(b, a, xn)

下图是过滤后的 5 秒音频。1 秒后的大峰值是真正的故障,但 2,3 和 4 秒后的较小峰值不应该存在。滤波信号

当我分析接下来 5 秒的音频时,这些较小的峰值也会继续出现,尽管在这段音频中根本没有任何故障,如下所示。 滤波信号

当我开始录制音频、完成录制然后检查故障时,根本不会出现这些微型峰值,它们仅在我尝试将传入的音频分成块并在录制音频时检查故障时才会出现。谁能解释它们是什么(与谐波有关?)以及我是否可以摆脱它们?理想情况下,我还想摆脱每 5 秒块开始和结束时出现的峰值。我在 DSP 方面没有太多背景,而且我仍在学习很多关于它的知识,因此我将不胜感激。

1个回答

嘿,我也一直想写这个程序。:D

使用初始条件的方式是将它们从一个阶段传递到下一个阶段。

lfilter 也返回(y, zf),不是(zf, y)

所以它应该看起来更像:

zi = signal.lfilter_zi(b, a) * xn[0]
z, zi2 = signal.lfilter(b, a, xn, zi=zi)
z2, zi3 = signal.lfilter(b, a, z, zi=zi2)
z3, zi4 = signal.lfilter(b, a, z2, zi=zi3)

当然,虽然您不需要重命名每一个。初始化它

zi = signal.lfilter_zi(b, a) * xn[0]

然后在每个循环中执行类似的操作

for x in chunks(signal):
    y, zi = signal.lfilter(b, a, x, zi=zi)
    look_for_glitches_in(y)