在连续的时间帧上应用IIR滤波器时的连续性问题 [英] Continuity issue when applying an IIR filter on successive time-frames

查看:125
本文介绍了在连续的时间帧上应用IIR滤波器时的连续性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to apply a FIR or IIR filter (example: lowpass filter) on successive blocks/time-frames of 1024 samples each.

可能的应用程序:

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

  • realtime audio processing, such as EQing. At a precise time, we only have the next 1024 samples in a buffer. The next samples to process are not available yet (realtime).

按照输入答案中的建议在此答案中制作一个时变截止滤波器,方法是将输入信号分成多个块. >.

make a cutoff-time-varying filter by splitting the input signal in blocks, as suggested 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)

我尝试过:

  • 都带有Butterworth滤波器或FIR(用b, a = firwin(1000, cutoff=f, fs=sr), 1.0替换之前的行)

两者都带有 lfilter filtfilt (后者具有向前和向后应用过滤器的优势,这解决了相位问题),

both with lfilter and filtfilt (the latter has the advantage to apply the filter forward and backwards, and this solves phase issues),

但这是问题所在:

**在每个时间帧输出的边界处,存在连续性问题,这会使音频信号严重失真.

**At the boundaries of each time-frames' output, there is a continuity issue, that makes the audio signal heavily distorded.

如何解决这种不连续性问题?我曾考虑过windowing + OverlapAdd方法,但是肯定有一种更简单的方法.

How to solve this discontinuity problem? I thought about windowing+OverlapAdd method, but there surely must be an easier way.

推荐答案

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

As mentioned by @sobek in a comment, it's of course needed to specify the initial conditions to allow continuity. This is done with the zi parameter of lfilter.

通过以下方法更改主循环即可解决该问题:

The problem is solved by changing the main loop by:

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),这似乎仍然有效.

This seems to work even if the filter's cutoff (and thus the a and b) is modified at each iteration.

这篇关于在连续的时间帧上应用IIR滤波器时的连续性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆