2

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()
user470062
  • 21
  • 2
  • I'm trying something similar, still installing scipy, one thing that did occur to me, in DSP world (atleast when I've been creating VSTs in C++) you tend to either have a filter per channel or reset the filter between each channel so that you don't end up with data from one channel spilling over into the other, this usually sounds like weird audio glitching / clicking. Not sure how you could check this, also perhaps the Nyquist param could be wrong? Doesn't this need to be Nyquist sampling (f) = d/2, where d=the smallest object, or highest frequency, you wish to record, so 20000 = 44100/2 – Henry James Mar 27 '21 at 11:54

0 Answers0