Signal filtering using Python

I'm trying to create an application using python that is capable of recording an audio signal and detecting short glitches in the signal. For example, I could be recording a 1000Hz sine wave and looking for instances when the audio cuts out for a sample or two. I've been achieving this by removing all the 1000Hz frequencies using a notch filter and searching where the remaining peaks occur. My program seems to work fine when I begin recording a signal, finish recording and then filter the entire recorded signal, search for peaks etc but I would like to get it working in real time, where I can begin recording, analyze 5 seconds worth of audio then move on to the next 5 seconds of audio and so on until I finish recording. Unfortunately my notch filter that worked previously no longer seems to work correctly when I do this. The code for my notch filter is shown below (I am using scipy for signal processing and pyaudio for recording audio))

f0 = 1000.0  # Frequency to be removed from signal (Hz)
Q = 30.0  # Quality factor
w0 = f0/(fs/2)  # Normalized Frequency
# Design notch filter
b, a = signal.iirnotch(w0, Q)
zi = signal.lfilter_zi(b, a)
z, _ = signal.lfilter(b, a, xn, zi=zi*xn[0])
z2, _ = signal.lfilter(b, a, z, zi=zi*z[0])
y = signal.filtfilt(b, a, xn)


The graph shown below is a filtered 5 seconds of audio. The large peak just after 1 seconds is a genuine glitch but the smaller peaks just after 2,3 and 4 seconds should not be there.

These smaller peaks also continue to occur when I analyze the next 5 seconds of audio, despite there being no glitches at all in this chunk of audio, shown below.

When I begin recording audio, finish recording and then check for glitches, these miniature peaks do not occur at all, they only occur when I try to divde the incoming audio into chunks and check for glitches as the audio is being recorded. Can anyone explain what they are (something to do with harmonics?) and whether or not I can get rid of them? Ideally I would also like to get rid of the peaks that occur at the beginning and the end of every 5 second chunk as well. I dont have much of a background in DSP and I'm still learning a lot about it so I would appreciate any help.

Hey I've been meaning to write this program, too. :D

The way you use the initial conditions is to just pass them from one stage to the next.

Also lfilter returns (y, zf), not (zf, y).

So it should look more like:

zi = signal.lfilter_zi(b, a) * xn[0]
z, zi2 = signal.lfilter(b, a, xn, zi=zi)
z2, zi3 = signal.lfilter(b, a, z, zi=zi2)
z3, zi4 = signal.lfilter(b, a, z2, zi=zi3)


Though you don't need to rename each one, of course. Initialize it with

zi = signal.lfilter_zi(b, a) * xn[0]


and then in each loop do something like

for x in chunks(signal):
y, zi = signal.lfilter(b, a, x, zi=zi)
look_for_glitches_in(y)

• since you also mean to write the same type of program, then can you please tell what's the purpose of a real-time audio glitch detection ? :-) – Fat32 Aug 22 '17 at 19:26
• Oh I guess I wasn't going to write a real-time one, but one to analyze recordings to measure how many dropouts there are instead of doing it manually. – endolith Aug 22 '17 at 19:32
• hmm I see now. The offline version is quite useful... – Fat32 Aug 22 '17 at 19:40
• @Fat32 And actually this notch method wouldn't allow you to measure the duration of dropouts, which is what I had intended. – endolith Aug 22 '17 at 20:44
• Hey, I'm away from my computer for the minute, I'll try it out later, thanks for your help. Real time probably isn't the right way of describing It, I had been intending to analyse hours of audio data, and it would take a very long time to process if I was first recording the audio and then processing the entire signal at once, so I thought it would be much quicker to analyse chunks of the audio as I am recording it. – CJF Aug 22 '17 at 21:31