Reputation: 11
When I use the butter function from scipy for a bandpass filter of order 4 onto a .wav audio file, it is working but when I use the same filter coefficients directly on to the same audio it is not working.
I'm trying to implement a bandpass filter on a .wav audio file using Python. Initially, I used the butter function from scipy to generate filter coefficients and applied the filter using filtfilt, which worked fine. However, when I tried to directly use the same filter coefficients with lfilter, I didn't get the expected results. Here's what I've tried:
First, here's the code that worked using filtfilt:
from scipy.signal import butter, filtfilt
from scipy.io import wavfile
def butter_bandpass(lowcut, highcut, fs, order=4):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = butter(order, [low, high], btype='band')
return b, a
def butter_bandpass_filter(data, lowcut, highcut, fs, order=4):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = filtfilt(b, a, data)
return y
filename = "Heart Data 1 (1).wav"
fs, data = wavfile.read(filename)
lowcut = 30
highcut = 450
order = 4
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
print("Filter Coefficients (b):", b)
print("Filter Coefficients (a):", a)
filtered_data = butter_bandpass_filter(data, lowcut, highcut, fs, order=order)
This code produced the desired filtered audio with the coefficients
b = [3.76138361e-05, 0.00000000e+00, -1.50455344e-04, 0.00000000e+00,
2.25683017e-04, 0.00000000e+00, -1.50455344e-04, 0.00000000e+00,
3.76138361e-05]
a = [1.0, -7.56134654, 25.03021633, -47.37940103, 56.09188775,
-42.53071304, 20.16985559, -5.46999014, 0.64949108]
However, when I tried to use the same filter coefficients directly with lfilter
, I didn't get the expected results:
from scipy.signal import lfilter
from scipy.io import wavfile
filename = "Heart Data 1 (1).wav"
fs, data = wavfile.read(filename)
b = [3.76138361e-05, 0.00000000e+00, -1.50455344e-04, 0.00000000e+00,
2.25683017e-04, 0.00000000e+00, -1.50455344e-04, 0.00000000e+00,
3.76138361e-05]
a = [1.0, -7.56134654, 25.03021633, -47.37940103, 56.09188775,
-42.53071304, 20.16985559, -5.46999014, 0.64949108]
filtered_data = lfilter(b, a, data)
This code didn't produce the desired filtered audio.
I expected both methods to produce the same filtered audio since I used the same filter coefficients. Can someone help me understand what might be going wrong with the second method using lfilter
? Thank you!
Upvotes: 1
Views: 67
Reputation: 4138
Lfilter is different than filtfilt.
lfilter
method applies filtering once, using standard method
a[0]*y[n] = b[0]*x[n] + b[1]*x[n-1] + ... + b[nb]*x[n-nb]
- a[1]*y[n-1] - ... - a[na]*y[n-na]
filtfilt
method applies filtering twice, each time using the standard method as above, but second time it does it with reversed signal. So:
Upvotes: 2