bpmdsp/create_filter.c

Go to the documentation of this file.
00001 
00005 #include <string.h>
00006 
00007 #include "bpm/bpm_alloc.h"
00008 #include "bpm/bpm_dsp.h"
00009 
00010 filter_t* create_filter( char name[], unsigned int options, int order, int ns,
00011                          double fs, double f1, double f2, double par ) {
00012   
00013   filterrep_t *s;
00014   int n = 0;
00015 
00016   filter_t *f = (filter_t*) calloc( 1, sizeof(filter_t) );
00017   if ( ! f ) {
00018     bpm_error( "Couldn't reserve memory for filter", __FILE__, __LINE__ );
00019     return NULL;
00020   }
00021 
00022   strncpy( f->name, name, 79 );
00023   f->options = options;
00024   f->order   = order;
00025 
00026   f->ns      = ns;
00027   f->fs      = fs;
00028   f->f1      = f1;
00029   f->f2      = f2;
00030 
00031   f->cheb_ripple  = 0.;
00032   f->gauss_cutoff = 0.001;
00033   f->Q            = -1.;  // initialise to infinite Q, so pure oscillator for resonator filter
00034 
00035   if ( f->options & CHEBYSHEV ) {
00036     if ( par <  0. ) {
00037       f->cheb_ripple = par;
00038     } else {
00039       bpm_warning( "Invalid Chebyshev ripple, setting default !", __FILE__, __LINE__ );
00040     }
00041   }
00042 
00043   if ( f->options & RESONATOR ) {
00044     if ( par > 0. ) {
00045       f->Q = par;
00046     } else {
00047       bpm_warning( "Q factor <= 0, assuming pure oscillator !", __FILE__, __LINE__ );
00048     }
00049   }
00050 
00051   if ( f->options & GAUSSIAN ) {
00052     if ( par <=  0. ) {
00053       bpm_warning( "Invalid gaussian cutoff, setting default !", __FILE__, __LINE__ );
00054     } else {
00055       f->gauss_cutoff = par;
00056     }
00057   }
00058 
00059   if ( f->fs > 0. ) {
00060     f->alpha1   = f->f1 / f->fs;
00061     f->alpha2   = f->f2 / f->fs;
00062 
00063     if ( f->options & NO_PREWARP ) {
00064       f->w_alpha1 = f->alpha1;  
00065       f->w_alpha2 = f->alpha2;  
00066     } else {
00067       f->w_alpha1 = tan( PI * f->alpha1 ) / PI;  // pre-warped alpha1
00068       f->w_alpha2 = tan( PI * f->alpha2 ) / PI;  // pre-warped alpha2
00069     }
00070   } else {
00071     bpm_error( "Invalid sampling frequency in create_filter(...)", __FILE__, __LINE__ );
00072     free(f);
00073     return NULL;
00074   }
00075 
00076 
00077   // setup the waveform buffer
00078 
00079 
00080   f->wfbuffer = alloc_simple_wave_double( ns );
00081   if ( ! f->wfbuffer ) {
00082     bpm_error( "Cannot allocate memory for waveform buffer in create_filter()",
00083                __FILE__, __LINE__ );
00084     free(f);
00085     return NULL;
00086   }
00087  
00088 
00089   // calculate poles and zeros where applicable
00090   
00091 
00092   if ( f->options & ( BUTTERWORTH | BESSEL | CHEBYSHEV ) ) {
00093     // this filter is causal
00094     f->options |= CAUSAL;
00095 
00096     // calculate s plane represenation and transform to z plane for
00097     // butterworth, cheybyshev and bessel filters
00098     s = create_splane_representation( f );
00099     normalise_filter( f, s );
00100     f->cplane = zplane_transform( f, s );
00101     free(s);
00102   } 
00103 
00104   if ( f->options & RESONATOR ) {
00105     // this filter is causal
00106     f->options |= CAUSAL;
00107 
00108     // set some values for the resonator
00109     f->alpha2   = f->alpha1;  // needed when we calculate fc_gain
00110     f->w_alpha2 = f->w_alpha1;
00111 
00112     // Directly create z pole representation for the resonator case
00113     f->cplane = create_resonator_representation( f );
00114   }
00115 
00116 
00117   // calculate the filter coefficients
00118 
00119   
00120   if ( f->options & GAUSSIAN ) {
00121     // this filter is non-causal
00122     f->options |= NONCAUSAL;
00123 
00124     f->cplane = NULL; // set this to 0, no representation for gaussian filter implementation
00125     if ( gaussian_filter_coeffs( f ) == BPM_FAILURE ) {
00126       bpm_error( "Failed to calculate gaussian coefficients",__FILE__, __LINE__ );
00127       free(f->wfbuffer);
00128       free(f);
00129       return NULL;
00130     };
00131 
00132     // filter implementation is FIR
00133     f->options |=  FIR;
00134     f->options &= ~IIR;
00135   } else {
00136     // calculate general filter coefficients from the pole/zero representation
00137     calculate_filter_coefficients( f );
00138 
00139     // set whether filter is FIR/IIR
00140     while (n < f->cplane->npoles && f->yc[n] == 0.0) n++;
00141     if ( n >= f->cplane->npoles ) { 
00142       f->options |=  FIR;
00143       f->options &= ~IIR;
00144     } else {
00145       f->options |=  IIR; 
00146       f->options &= ~FIR; 
00147     }
00148   }
00149   
00150 
00151 
00152   return f;
00153 }

Generated on Thu Jan 10 10:18:04 2008 for libbpm by  doxygen 1.5.1