【问题标题】:Continuity issue when applying an IIR filter on successive time-frames在连续时间范围内应用 IIR 滤波器时的连续性问题
【发布时间】:2019-02-27 07:54:39
【问题描述】:

我想在每个 1024 个样本的连续块/时间帧上应用 FIR 或 IIR 滤波器(例如:低通滤波器)。

可能的应用:

  • 实时音频处理,例如 EQing。在一个精确的时间,我们在缓冲区中只有接下来的 1024 个样本。下一个要处理的样本尚不可用(实时)。

  • 按照in this answer 的建议,通过将输入信号分成块来制作截止时变滤波器。

我在这里尝试过:

import numpy as np
from scipy.io import wavfile
from scipy.signal import butter, lfilter, filtfilt, firwin

sr, x = wavfile.read('input.wav')
x = np.float32(x)
y = np.zeros_like(x)

N  = 1024  # buffer block size = 23ms for a 44.1 Khz audio file
f = 1000  # cutoff
pos = 0  # position

while True:
    b, a = butter(2, 2.0 * f / sr, btype='low')
    y[pos:pos+N] = filtfilt(b, a, x[pos:pos+N])
    pos += N
    f -= 1   # cutoff decreases of 1 hz every 23 ms, but the issue described here also present with constant cutoff!
    print f
    if pos+N > len(x):
        break

y /= max(y)  # normalize

wavfile.write('out_fir.wav', sr, y)

我试过了:

  • 都带有巴特沃斯滤波器或 FIR(将前面的行替换为 b, a = firwin(1000, cutoff=f, fs=sr), 1.0

  • lfilterfiltfilt 都有(后者的优点是可以向前和向后应用过滤器,这解决了相位问题),

但问题出在这里:

在每个时间帧输出的边界处,存在连续性问题,导致音频信号严重失真。

如何解决这种不连续性问题?我想过windowing+OverlapAdd方法,但肯定有更简单的方法。

【问题讨论】:

  • 由于您使用的是 IIR 过滤器,因此您需要将过滤器的状态从一个块持续到下一个块。
  • 不是参数,过滤器的状态,内存中的数据。如果您从一个块跳到下一个块并使用完全未初始化的 IIR 滤波器,那么您当然会得到一个伪像。处理的输出必须与未按块处理时的输出相同,但缓冲的延迟除外。
  • 查看lfiltz_f输出和z_i输入参数。您需要将当前块的过滤器的z_i设置为前一个块的过滤器的z_f。这样,您的过滤器状态就会从一个块持续到下一个块。来自 dsp stackexchange 的这个主题也可能有用。 dsp.stackexchange.com/questions/28725/… 另外,您最好了解一下如何在内部构建过滤器的基础知识,所以这一切都很有意义。
  • @sobek 谢谢!我发布了一个答案。它似乎工作。你认为即使在每次迭代中截止值都发生变化的情况下也可以(因此ab 也是如此)?
  • 我认为在这种情况下还可以。

标签: python numpy audio scipy signal-processing


【解决方案1】:

正如@sobek 在评论中提到的,当然需要指定初始条件以允许连续性。这是通过lfilterzi 参数完成的。

通过改变主循环来解决问题:

while True:
    b, a = butter(2, 2.0 * f / sr, btype='low')
    if pos == 0:
        zi = lfilter_zi(b, a)
    y[pos:pos+N], zi = lfilter(b, a, x[pos:pos+N], zi=zi)
    pos += N
    f -= 1 
    if pos+N > len(x):
        break

即使过滤器的截止值(以及 ab)在每次迭代中都被修改,这似乎也有效。

【讨论】:

  • 再添加一条评论,如果您只计算和更新滤波器系数(如果它们实际发生了变化),则可以节省性能。
  • @sobek 也许您对filtfilt 案例有想法? stackoverflow.com/questions/52502874/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
相关资源
最近更新 更多