double *openAFE::dcof_bwlp( int n, double fcf ) { int k; // loop variables double theta; // M_PI * fcf / 2.0 double st; // sine of theta double ct; // cosine of theta double parg; // pole angle double sparg; // sine of the pole angle double cparg; // cosine of the pole angle double a; // workspace variable double *rcof; // binomial coefficients double *dcof; // dk coefficients rcof = (double *)calloc( 2 * n, sizeof(double) ); if( rcof == NULL ) return( NULL ); theta = M_PI * fcf; st = sin(theta); ct = cos(theta); for( k = 0; k < n; ++k ) { parg = M_PI * (double)(2*k+1)/(double)(2*n); sparg = sin(parg); cparg = cos(parg); a = 1.0 + st*sparg; rcof[2*k] = -ct/a; rcof[2*k+1] = -st*cparg/a; } dcof = binomial_mult( n, rcof ); free( rcof ); dcof[1] = dcof[0]; dcof[0] = 1.0; for( k = 3; k <= n; ++k ) dcof[k] = dcof[2*k-2]; return( dcof ); }
void design_butter_lowpass_filter( unsigned int order, float wc, float *b, float *a) { int i, n; double fcd, fca; double *p; double *d; double pmr, pmi; double ppr, ppi; double ppmr, ppmi; double d1, d2; n = order; fcd = M_PI * wc; fca = tan( fcd / 2.0 ); p = (double *)calloc( 2 * n, sizeof(double) ); /* Calculate analog Butterworth coefficients */ for( i = 0; i < n; ++i ) { p[2*i] = -fca * sin(M_PI*((double)i+0.5)/(double)n); p[2*i+1] = fca * cos(M_PI*((double)i+0.5)/(double)n); } ppmr = 1.0; ppmi = 0.0; for( i = 0; i < n; ++i ) { pmr = p[2*i] - 1.0; pmi = p[2*i+1]; ppr = p[2*i] + 1.0; ppi = p[2*i+1]; d1 = pmr * pmr + pmi * pmi; p[2*i] = (ppr * pmr + ppi * pmi) / d1; p[2*i+1] = (ppi * pmr - ppr * pmi) / d1; d1 = ppmr; d2 = ppmi; ppmr = -( d1 * pmr - d2 * pmi ); ppmi = -( d1 * pmi + d2 * pmr ); } ppmr = pow( fca, (double)n ) / ppmr; /* scaling factor */ d = binomial_mult( n, p ); b[0] = (float) ppmr; d1 = (double)n; d2 = 1.0; for( i = 1; i <= n; ++i ) { b[i] = (float) (ppmr*d1/d2); d1 *= (double)(n - i); d2 *= (double)(i + 1); } a[0] = 1.0f; for( i = 0; i < n; ++i ) a[i+1] = (float) (d[2*i]); free( p ); free( d ); }