Open johnmgithub opened 5 years ago
Thank you John, do you want to submit a pull-request and a unit test? This issues highlights the need for more comprehensive tests as well as visual reasoning aids for pedagogical purposes. Cheers.
Afraid I don't have a C++ dev environment, Java for me. Was just mooching about looking at Butterworth pole calculations to extract Q values for cascaded biquads and noticed it looked off.
okay, thank you for the heads up. I'll fix it, I also wonder if its related to the gain issues someone else reported https://github.com/ruohoruotsi/Butterworth-Filter-Design/issues/3 (which I also need to fix). Cheers!
@johnmgithub is actually right with this. The poles for all odd filter orders are wrong if not corrected as show in the code he shared. I converted your code to c# and with that i was able to show that against some manual test i did against matlab. This bug however is not related to the one described in #3.
i verified all zero, poles and gains before the method zp2SOS which makes me believe that zp2Sos is actually wrong. If you apply the fix from here and use the method described in #3 where you multiple the gain with the values from ab[] then you can get first order and second order running for everything
thank you @Uight, looks like I need to get on with fixing some of these issues, notably with zp2SOS
...thank you for you comment and attention. I'll make it a priority! 🙇
For odd filter orders a pair of real poles get added rather than a single pole, don't think that is right. In Butterworth::prototypeAnalogLowPass(int filterOrder) rather than
for(uint32_t k = 0; k < (filterOrder + 1) / 2; k++){
double theta = (double)(2 * k + 1) * M_PI / (2 * filterOrder);
double real = -sin(theta);
double imag = cos(theta);
poles.push_back(complex_double(real, imag));
poles.push_back(complex_double(real, -imag)); // conjugate
}
might need something like
for(uint32_t k = 0; k < filterOrder / 2; k++){
double theta = (double)(2 * k + 1) * M_PI / (2 * filterOrder);
double real = -sin(theta);
double imag = cos(theta);
poles.push_back(complex_double(real, imag));
poles.push_back(complex_double(real, -imag)); // conjugate
}
if (filterOrder % 2 == 1){
poles.push_back(complex_double(-1, 0);
}
`