I have to apply a downsampling filter on a realtime data stream (signal) and I want to do it in python. The data is sampled at 16 kHz and loaded in a loop in chunks of 1 second. I have to downsample the data with the following:

  1. Forward-backward filter for downsampling to preserve phase (zero-phase filter).
  2. Downsample in "real-time" (i.e. one second at a time) from 16 kHz to 2 kHz.

I've tried to use Scipy.signal.butter to output b and a and pass them to Scipy.signal.lfilter. I'm having issues at the edges between two 1 second chunks, in the form of a transient. Scipy.signal.filtfilt does not solve the issue. I suspect the problem is with the initial conditions of the backward filter zi_back, but I am not sure. I have tried initializing them at rest and then passing zi_back and zi_forw this way:

firstpass, zi_forw = signal.lfilter(b, a, signal, zi_forw)

signal_downsampled, zi_back = signal.lfilter(b, a, firstpass[::-1], zi_back)[::-1]

I don't mind the transient on the first chunk (~0sec), but the ones at 1sec, 2sec, 3sec, 4sec and so on are an issue.

How can I implement this near real time forward-backward filter without encountering this transient?

  • $\begingroup$ I don't think you can. Backwards filtering flips the signal in time but the individual frames move forward in time. This will always create a discontinuity of the backwards signal at the frame boundary, Consider using a linear phase FIR filter instead. $\endgroup$
    – Hilmar
    Mar 21 at 12:53
  • $\begingroup$ Thank you for your comment @Hilmar . Can you give a reference as to why it should not be possible? Suppose I just do the forward filtering on the first 1s frame, I should be able to pass on the filter state and filter the next frame without a transient effect at the edge. I probably lack some understanding, but is the issue arising from the fact that I can't fix the initial conditions for the backward filter? $\endgroup$
    – GWSurfer
    Mar 21 at 15:20
  • $\begingroup$ Here is my line of thinking (which could be wrong!). Since you are using an IIR, you cannot flip the filter so you have to flip the signal. But you can only flip one frame at a time which makes the signal "out of order" at the frame boundary. Let's assume a frame size of 4. The order of your "frame-wise flipped signal" is then 0,3,2,1,7,6,5,4,11,10,9,8, etc. Do you see the problem here? It has nothing to do with the filter state. In order you do backwards filtering you need to flip the WHOLE signal and you can't do this frame by frame $\endgroup$
    – Hilmar
    Mar 21 at 16:43
  • $\begingroup$ One way to circumvent the problem is to turn the IIR into an FIR by truncating the impulse response. Then you can flip the impulse response instead or just cascade the truncated impulse response and it's time flip for a linear phase filter. $\endgroup$
    – Hilmar
    Mar 21 at 16:45


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.