00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <spuc.h>
00022 #include <complex.h>
00023 #include <iir_1st.h>
00024 #include <iir_2nd.h>
00025 namespace SPUC {
00033
00034
00035
00036 template <class Numeric> class butterworth
00037 {
00038 private:
00039 long order;
00040 long odd;
00041 long n2;
00042 complex<double>* roots;
00043 iir_2nd< Numeric>* iir;
00044 iir_1st< Numeric>* iir_1;
00045 double gain;
00046 double* coeff;
00047
00048 public:
00052 butterworth(double fcd, long ord=1, double amax=3.0) {
00053
00054 gain = 1;
00055 order = ord;
00056 double epi = pow( (pow(10.0,(amax/10.)) - 1.0) ,(1./(2.0*ord)));
00057
00058 double wca = 2.0*tan(PI*fcd)/epi;
00059
00060 n2 = (order+1)/2;
00061 odd = (order%2);
00062 roots = new complex<double>[n2];
00063 if (odd) iir_1 = new iir_1st< Numeric >;
00064 get_roots(wca,order,n2);
00065 bilinear(n2);
00066 iir = new iir_2nd< Numeric >[order/2];
00067 get_coeff(n2);
00068 }
00070 ~butterworth() {
00071 delete [] roots;
00072 if (odd) delete iir_1;
00073 delete [] iir;
00074 }
00076 void reset() {
00077 for (int j=odd;j<n2;j++) {
00078 iir[j-odd].reset();
00079 if (odd) iir_1->reset();
00080 }
00081 }
00083 void print() {
00084 for (int j=odd;j<n2;j++) {
00085 iir[j-odd].print();
00086 }
00087 }
00089 Numeric clock(Numeric in) {
00090 Numeric tmp = in;
00091 for (int i=odd;i<n2;i++) {
00092 tmp = iir[i-odd].clock(tmp);
00093 }
00094 if (odd) tmp = iir_1->clock(tmp);
00095 return(gain*tmp);
00096 }
00097 private:
00099 void get_roots(double wp, long n, long n2) {
00100 long l = 0;
00101 if (n%2 == 0) l = 1;
00102 double arg;
00103 for (int j=0;j<n2;j++) {
00104 arg = -0.5*PI*l/float(n);
00105 roots[j] = wp*expj(arg);
00106 l += 2;
00107 }
00108 }
00110 void bilinear(long n2) {
00111 double td;
00112 int j;
00113 const double a = 2.;
00114 if (odd) {
00115
00116
00117 double tmp = (roots[0].real()-a)/(a+roots[0].real());
00118 iir_1->set_coeff(-tmp);
00119 gain *= 0.5*(1+tmp);
00120 }
00121 for (j=odd;j<n2;j++) {
00122 td = a*a - 2*a*roots[j].real() + magsq(roots[j]);
00123 roots[j] = complex<double>((a*a - magsq(roots[j])),
00124 2.0*a*roots[j].imag())/td;
00125 }
00126 }
00128 void get_coeff(long n2) {
00129 for (int j=odd;j<n2;j++) {
00130 iir[j-odd].set_coeff(-2*roots[j].real()/magsq(roots[j]),1.0/magsq(roots[j]));
00131 gain *= (magsq(roots[j]) - 2*roots[j].real() + 1.0)/(4*magsq(roots[j]));
00132 }
00133 }
00134 };
00135 }