ruohoruotsi / Butterworth-Filter-Design

C++ classes for designing high-order Butterworth IIR & equalization filters
GNU General Public License v3.0
163 stars 42 forks source link

Why a1, a2 of SOS are always inverse sign compare to matlab results? #9

Open yangbo opened 8 months ago

yangbo commented 8 months ago

Hi ruohoruotsi, Thanks for your work on this library.

I found the Butterworth class's output a1 and a2 of SOS are awayls change sign compare to matlab results. Such as if c++ output a1=0.1,a2=-0.2 then matlab's a1=-0.1, a2=0.2.

Is there something that I missing? If the output of Butterworth.bandPass() gives digital filter Biquad coefficients then is it should be the same as matlab's results?

Thanks for your help.

C++ Test code like below:

int filterOrder = 4;
double gain = 1.0;
double Fs = 100;
double fp1 = 0.5;
double fs1 = 10;

vector <Biquad> coeffs;  // second-order sections (sos)
Butterworth butterworth;

bool designedCorrectly = butterworth.bandPass(Fs,             // fs
                                            fp1,            // freq1
                                            fs1,            // freq2. N/A for lowpass
                                            filterOrder,
                                            coeffs,
                                            gain);

Matlab test code like:

  order = 4; 
  Fs=100;     
  fp1=0.5;    
  fs1=10;     
  % design digital Butter-Worth-Filter in SOS form
  [z,p,k]=butter(order,[fp1*2/Fs,fs1*2/Fs],'bandpass');
  [bsos,bk] = zp2sos(z,p,k);

Then you can see coeffs[i].a1 == -bsos[i+1, 5] and coeffs[i].a2 == -bsos[i+1, 6]. i from 0 to length of coeffs.

ruohoruotsi commented 8 months ago

A good question that I'll need to get into the code to debug why.

As you can tell I haven't been active here much, but there seem to be some small bugs popping up that I need to fix/improve. I'll have a look this weekend.

Also, please feel free to make a PR from your fork, I appreciate your contributions and code contributions 🙇 🙏

yangbo commented 8 months ago

Thanks for your reply.

I have added some features in my fork of this project.

They are:

  1. Added sos2tf() function to convert SOS to Transfer Function coefficients like matlab's SOS2TF.
  2. Added conv() function to do convolution.
  3. Added CMake as building system, and move tests to 'tests/' subdirectory. Because I do not use SConstruct so I didn't change it, but changed the doc to cmake.
  4. Added some cross-compile support for arm64 target, but they are specific to my development environment, so I don't know if I should include them in PR.

I will try to make a PR, if there are something wrong, please tell me. : )

Cheers!