berndporr / iir1

DSP IIR realtime filter library written in C++

Home Page:http://berndporr.github.io/iir1/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question about SOSCascade Filter Conversion from Python to C++

Pimvandermeer opened this issue · comments

Hello,

I am currently encountering an issue while attempting to translate a filter designed in Python into C++. Specifically, the problem arises with the SOSCascade filter, which does not perform as expected in the C++ implementation.

In Python, I defined the filter parameters and generated the SOS coefficients as follows:

lowcut = 1.0
highcut = 10
sample_freq = 400
filter_order = 3

Wn = [lowcut / (0.5 * sample_freq), highcut / (0.5 * sample_freq)]
rp = 1 
rs = 40  
b, a = signal.ellip(filter_order, rp, rs, Wn, btype='bandpass', output='ba')
sos = tf2sos(b, a)


self.filtered_signal = filtfilt(b, a, self.adc_data)

I use the resulting sos matrix with the setup() method in C++:

static constexpr double m_coeff[3][6] = { {4.72873036e-03, -8.74017723e-03, 4.72873036e-03, 1.00000000e+00, -1.92610620e+00, 9.28488859e-01}, {1.00000000e+00, 3.84050014e-10, -1.00000000e+00, 1.00000000e+00, -1.91979537e+000, 9.43492428e-01}, {1.00000000e+00, -1.99996123e+00, 1.00000000e+00, 1.00000000e+00, -1.99387331e+00, 9.94121727e-01}};

Attached below are images showing the original signal, the signal processed in Python, and the signal filtered using the C++ library. This comparison illustrates the discrepancies I'm encountering.

Could someone tell me what I am doing wrong?

Thank you in advance
Figure_1

code.zip
Figure_6
All works here. See code attached which is hacked from the /demo dir. I'd recommend to have a look there.

  1. Your sine wave has a massive (!) DC shift. Every causal filter will need to settle as it's like a massive step response. So the CPP response looks bang on.
  2. You use "filtfilt" which is an a-causal (!) operation. This filter cannot exist in real life. You have been fooled by array calcs and not sample by sample realtime calcs.

Filtfilt isn't causal. It runs forwards and backwards in time. You get a 0-phase result, but there are consequences. See https://youtu.be/q2nNzNo_Xps 😁