I've built a python class that has methods to read, record, save, replay, and display an audio file with PyAudio and Matplotlib. I now want to implement a simple low-pass filter. I've managed to put together a method that produces a low-pass filter using a windowed running mean, but that results in a signal that is slightly smaller than the original signal.
My next attempt involved using a Butterworth filter with scipy.signal. I've scoured stackoverflow to make sure I am implementing it correctly, and I think I am. However, when I apply my low-pass filter, my signal becomes white noise. Is there something I am missing here?
I've attached the relevant code below; keep in mind these functions are part of a larger class. audio
is the raw audio signal, self.RATE
is the sampling rate at which the audio recording was taken, and self.filename
is the name of the file in which the original audio recording is stored.
def butter_lowpass(self,cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
def butter_lowpass_filter(self,data, cutoff, fs, order=5):
b, a = self.butter_lowpass(cutoff, fs, order=order)
y = lfilter(b, a, data)
return y
def lowpass(self):
# Filter requirements.
order = 6
fs = self.RATE # sample rate, Hz
cutoff = 1000 # desired cutoff frequency of the filter, Hz
# Get the filter coefficients.
b, a = self.butter_lowpass(cutoff, fs, order)
audio,duration,frames,bps,dt = self.read_audio(self.filename)
filtered = self.butter_lowpass_filter(audio, cutoff, fs, order)
# Rewrite to file.
wav_file = wave.open(self.filename, "w")
wav_file.setparams((1, bps, self.RATE, frames, 'NONE', 'not compressed'))
wav_file.writeframes(filtered.tobytes('C'))
wav_file.close()