int fft ( COMPLEX *in, unsigned n, COMPLEX *out ) { unsigned i; for (i = 0; i < n; i++) c_conj (in [i]); if (W_init (n) == -1) return -1; Fourier (in, n, out); for (i = 0; i < n; i++) { c_conj (out [i]); c_realdiv (out [i], n); } return 0; }
filterrep_t* create_resonator_representation( filter_t *f ) { double theta, r, thm, th1, th2, phi; int i, cvg; complex_t z, g; complex_t topco[MAXPZ+1], botco[MAXPZ+1]; filterrep_t *zrep; // allocate memory for the filterrepresentation... zrep = (filterrep_t*) calloc( 1, sizeof( filterrep_t) ); if ( ! zrep ) { bpm_error( "Cannot allocate memory for resonator representation.", __FILE__, __LINE__ ); return NULL; } // for all : zrep->nzeros = 2; zrep->npoles = 2; zrep->zero[0] = complex( 1., 0. ); zrep->zero[1] = complex( -1., 0. ); theta = 2.*PI*f->alpha1; if ( f->Q <= 0. ) { // negative Q, so assume infinte Q : pure oscillator, calculate the poles z = c_exp( complex(0., theta) ); zrep->pole[0] = z; zrep->pole[1] = c_conj( z ); } else { // finite Q factor for the resonator, calculate the poles _expand_complex_polynomial( zrep->zero, zrep->nzeros, topco); r = exp(-theta / (2.0 * f->Q)); thm = theta; th1 = 0.0; th2 = PI; cvg = 0; for ( i=0; ( i<MAX_RESONATOR_ITER ) && ( cvg == 0 ); i++ ) { z = complex( r*cos(thm), r*sin(thm)); zrep->pole[0] = z; zrep->pole[1] = c_conj(z); _expand_complex_polynomial( zrep->pole, zrep->npoles, botco); g = c_div( _eval_complex_polynomial( topco, zrep->nzeros, complex(cos(theta),sin(theta))), _eval_complex_polynomial( botco, zrep->npoles, complex(cos(theta),sin(theta))) ); phi = g.im / g.re; if ( phi > 0.0 ) th2 = thm; else th1 = thm; if ( fabs(phi) < FILT_EPS ) cvg = 1; thm = 0.5 * ( th1 + th2 ); } if ( ! cvg ) { bpm_error( "Finite Q resonator failed to converge on pole/zero calculation.", __FILE__, __LINE__ ); free(zrep); return NULL; } } // adjust the zeros for a bandstop resonator if ( f->options & BANDSTOP ) { theta = 2.*PI*f->alpha1; z = complex( cos(theta), sin(theta) ); zrep->zero[0] = z; zrep->zero[1] = c_conj( z ); } // adjust the zeros for an allpas resonator if ( f->options & ALLPASS ) { zrep->zero[0] = _reflect( zrep->pole[0] ); zrep->zero[1] = _reflect( zrep->pole[1] ); } return zrep; }