I would like to apply a FIR or IIR filter (example: lowpass filter) on successive blocks/time-frames of 1024 samples each.
Possible applications:
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.
I tried this here:
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)
I tried:
both with a Butterworth filter or a FIR (replace the line before by b, a = firwin(1000, cutoff=f, fs=sr), 1.0
)
both with lfilter
and filtfilt
(the latter has the advantage to apply the filter forward and backwards, and this solves phase issues),
but here is the problem:
At the boundaries of each time-frames' output, there is a continuity issue, that makes the audio signal heavily distorded.
How to solve this discontinuity problem? I thought about windowing+OverlapAdd method, but there surely must be an easier way.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…