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.;
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;
00068 f->w_alpha2 = tan( PI * f->alpha2 ) / PI;
00069 }
00070 } else {
00071 bpm_error( "Invalid sampling frequency in create_filter(...)", __FILE__, __LINE__ );
00072 free(f);
00073 return NULL;
00074 }
00075
00076
00077
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
00090
00091
00092 if ( f->options & ( BUTTERWORTH | BESSEL | CHEBYSHEV ) ) {
00093
00094 f->options |= CAUSAL;
00095
00096
00097
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
00106 f->options |= CAUSAL;
00107
00108
00109 f->alpha2 = f->alpha1;
00110 f->w_alpha2 = f->w_alpha1;
00111
00112
00113 f->cplane = create_resonator_representation( f );
00114 }
00115
00116
00117
00118
00119
00120 if ( f->options & GAUSSIAN ) {
00121
00122 f->options |= NONCAUSAL;
00123
00124 f->cplane = NULL;
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
00133 f->options |= FIR;
00134 f->options &= ~IIR;
00135 } else {
00136
00137 calculate_filter_coefficients( f );
00138
00139
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 }