vinniefalco / DSPFilters

A Collection of Useful C++ Classes for Digital Signal Processing
1.87k stars 379 forks source link

Coefficients for odd-order highpass filters mixed up? #29

Open galchinsky opened 8 years ago

galchinsky commented 8 years ago

https://www.kvraudio.com/forum/viewtopic.php?f=33&t=386712 says that Biquad.cpp may contain an error and suggests the following patch:

--- a/DSPFiltersCPP/source/Biquad.cpp 
+++ b/DSPFiltersCPP/source/Biquad.cpp 
@@ -143,8 +143,8 @@ void BiquadBase::setOnePole (complex_t pole, complex_t zero) 
const double a0 = 1; 
const double a1 = -pole.real(); 
const double a2 = 0; 
- const double b0 = -zero.real(); 
- const double b1 = 1; 
+ const double b0 = 1; 
+ const double b1 = -zero.real(); 
const double b2 = 0; 

But I don't undestand if this is correct solution or ad-hoc workaround which can break someone's code. If you know more, let me know.

sagamusix commented 8 years ago

All I can say from a few quick experiments is that the solution does indeed fix the issue of phase inversion, and that it does not appear to alter the sound, so the suggested fix from that thread is possibly correct.

IkerMesa commented 8 years ago

The computation of odd-order high-pass filters of type Butterworth is broken. I have checked it with Matlab: If I run this filter with C++, for(int theOrder=1; theOrder<20; ++theOrder) { Dsp::SimpleFilter <Dsp::Butterworth::HighPass<20>, 1> myFilter; //1 channel, 20th order. Latter i can change the order. myFilter.setup(theOrder, fs, cuttOffFreq); myFilter.process(numSamples, mySignal); }

If I perform the same filtering with MATLAB: Filter algorithm: [z,p,k] = butter(theOrder, (2_cuttOffFreq / fs) , 'high'); [sos,gain] = zp2sos(z,p,k); f = dfilt.df2sos(sos); signalFiltered= gain_filter(f, mySignal);

If theOrder is even the resulted signals are the same with this library and with matlab. However, if theOrder is odd the filtered signals are different.

IkerMesa commented 7 years ago

Hi, any news regarding this issue?

The computation of odd-order high-pass filters of type Butterworth is erroneous.

berndporr commented 1 year ago

id-0001 Certainly correct that this causes a phase inversion and the fix is correct. @anleu confirmed that now with a unit test using scipy output. Also makes total sense as there is complete symmetry between zero and pole. See my scribbles.