tomwalters@0: /************************************************************************** tomwalters@0: tomwalters@0: Filter-bank routines. tomwalters@0: ====================== tomwalters@0: tomwalters@0: Filter-bank parameters in model headers are as follows: tomwalters@0: (These may be converted, using the given routines, into values which are then tomwalters@0: passed as args into the routines below. All the values are double except for tomwalters@0: the number of channels which is an int. Remember to cast Freq as double). tomwalters@0: tomwalters@0: String name Conversion Value Comment tomwalters@0: ------------- ----------- --------- ------------------------------------- tomwalters@0: channels_afb Optionint() channels Number of channels in filter tomwalters@0: mincf_afb Freq() mincf Minimum center frequency (Hz) tomwalters@0: maxcf_afb Freq() maxcf Maximum center frequency (Hz) tomwalters@0: dencf_afb atof() dencf Filter density (filters/critical band) tomwalters@0: bwmin_afb Freq() bwmin Minimum filter bandwith tomwalters@0: quality_afb Freq() quality Ultimate qualtity factor of filters tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: Initialize global filter parameters. tomwalters@0: tomwalters@0: SetErbParameters( bwmin, quality ) tomwalters@0: double bwmin, quality ; tomwalters@0: tomwalters@0: Return array of centre frequencies for given density. tomwalters@0: tomwalters@0: double *GenerateCenterFrequencies( mincf, maxcf, dencf ) tomwalters@0: double mincf, maxcf, dencf ; tomwalters@0: tomwalters@0: (This uses routine GenerateScale() to compute the scale, and uses tomwalters@0: routine ErbScale() to convert the parameters (mincf etc) into Erbs). tomwalters@0: tomwalters@0: Return array of centre frequencies for given number of channels. tomwalters@0: tomwalters@0: double *NumberedCenterFrequencies( mincf, maxcf, channels ) tomwalters@0: double mincf, maxcf ; tomwalters@0: int channels ; tomwalters@0: tomwalters@0: (This uses routine NumberedScale() to compute the scale, and uses tomwalters@0: routine ErbScale() to convert the parameters (mincf etc) into Erbs). tomwalters@0: tomwalters@0: Return number of channels for given density. tomwalters@0: tomwalters@0: int NumberCenterFrequencies( mincf, maxcf, dencf ) tomwalters@0: double mincf, maxcf, dencf ; tomwalters@0: tomwalters@0: Basic utilities: tomwalters@0: tomwalters@0: ErbScale() Convert freq in Hz to Erbs. tomwalters@0: tomwalters@0: tomwalters@0: Example of application tomwalters@0: ---------------------- tomwalters@0: tomwalters@0: #include "freqs.c" tomwalters@0: tomwalters@0: int channels = 0 ; tomwalters@0: double mincf = 220. ; tomwalters@0: double maxcf = 4400. ; tomwalters@0: double dencf = 4. ; tomwalters@0: double bwmin = 24.7 ; tomwalters@0: double quality = 9.265 ; tomwalters@0: tomwalters@0: SetErbParameters( bwmin, quality ) ; tomwalters@0: tomwalters@0: if (channels==0) { tomwalters@0: frequencies = GenerateCenterFrequencies( mincf, maxcf, dencf ) ; tomwalters@0: channels = NumberCenterFrequencies( mincf, maxcf, dencf ) ; tomwalters@0: } tomwalters@0: else tomwalters@0: frequencies = NumberedCenterFrequencies( mincf, maxcf, channels ) ; tomwalters@0: tomwalters@0: tomwalters@0: **************************************************************************/ tomwalters@0: tomwalters@0: extern void SetErbParameters() ; tomwalters@0: tomwalters@0: extern double Erb(), ErbScale(), FofErbScale() ; tomwalters@0: tomwalters@0: extern double *GenerateCenterFrequencies() ; tomwalters@0: extern int NumberCenterFrequencies() ; tomwalters@0: extern double *NumberedCenterFrequencies() ; tomwalters@0: extern double *GenerateScale() ; tomwalters@0: extern int NumberOnScale() ; tomwalters@0: extern double *NumberedScale() ; tomwalters@0: tomwalters@0: /* Defaults */ tomwalters@0: tomwalters@0: static double limit = 24.7 ; tomwalters@0: static double Q = 9.265 ; tomwalters@0: tomwalters@0: /********************** filter/gamma_tone.c *******************************/ tomwalters@0: tomwalters@0: double bankBaseFrequency = 1000. ; tomwalters@0: tomwalters@0: double *GenerateCenterFrequencies( min_cf, max_cf, erb_density ) tomwalters@0: double min_cf, max_cf, erb_density ; tomwalters@0: { tomwalters@0: return ( GenerateScale( ErbScale( min_cf ), ErbScale( max_cf ), erb_density, ErbScale( bankBaseFrequency ), FofErbScale ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: int NumberCenterFrequencies( min_cf, max_cf, erb_density ) tomwalters@0: double min_cf, max_cf, erb_density ; tomwalters@0: { tomwalters@0: return ( NumberOnScale( ErbScale( min_cf ), ErbScale( max_cf ), erb_density, ErbScale( bankBaseFrequency ) ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: double *NumberedCenterFrequencies( min_cf, max_cf, channels ) tomwalters@0: double min_cf, max_cf ; tomwalters@0: int channels ; tomwalters@0: { tomwalters@0: return ( NumberedScale( ErbScale( min_cf ), ErbScale( max_cf ), channels, FofErbScale ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /********************** filter/scales.c ************************************/ tomwalters@0: tomwalters@0: double *GenerateScale( min, max, density, base, inverse ) tomwalters@0: double min, max, density, base, (*inverse)() ; tomwalters@0: { tomwalters@0: unsigned n_scale = NumberOnScale( min, max, density, base ) ; tomwalters@0: double *scale ; tomwalters@0: double scale_start ; tomwalters@0: int i ; tomwalters@0: tomwalters@0: scale = (double *)malloc( (n_scale+1) * sizeof(double) ) ; tomwalters@0: tomwalters@0: if( min != max ) { tomwalters@0: tomwalters@0: scale_start = base - floor( ( base - min ) * density ) / density ; tomwalters@0: tomwalters@0: /* fill array scale points 1./density apart */ tomwalters@0: tomwalters@0: for( i=0 ; i < n_scale ; i++ ) tomwalters@0: scale[ i ] = scale_start + i / density ; tomwalters@0: tomwalters@0: scale[ i++ ] = 0. ; tomwalters@0: } tomwalters@0: else { tomwalters@0: scale[0] = min ; tomwalters@0: scale[1] = 0. ; tomwalters@0: } tomwalters@0: tomwalters@0: /* convert scale space back to units required */ tomwalters@0: tomwalters@0: if( inverse != (double ( * )()) 0 ) tomwalters@0: for( i=0 ; i < n_scale ; i++ ) tomwalters@0: scale[ i ] = inverse( scale[ i ] ) ; tomwalters@0: tomwalters@0: return ( scale ) ; tomwalters@0: } tomwalters@0: tomwalters@0: int NumberOnScale( min, max, density, base ) tomwalters@0: double min, max, density, base ; tomwalters@0: { tomwalters@0: if( min != max ) tomwalters@0: return ( ( int ) ( ( floor( ( base - min ) * density ) + 1. + ( floor( ( max - base ) * density ) ) ) ) ) ; tomwalters@0: else tomwalters@0: return ( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: double *NumberedScale( min, max, channels, inverse ) tomwalters@0: double min, max ; tomwalters@0: int channels ; tomwalters@0: double (*inverse)() ; tomwalters@0: { tomwalters@0: double *scale ; tomwalters@0: int chan ; tomwalters@0: tomwalters@0: scale = (double *)malloc( (channels+1) * sizeof(double) ) ; tomwalters@0: tomwalters@0: scale[ 0 ] = min ; tomwalters@0: for( chan=1 ; chan < channels ; chan++ ) tomwalters@0: scale[ chan ] = min + chan * (max-min) / ( channels - 1 ) ; tomwalters@0: tomwalters@0: if( inverse != (double ( * )()) 0 ) tomwalters@0: for( chan=0 ; chan < channels ; chan++ ) tomwalters@0: scale[ chan ] = inverse( scale[ chan ] ) ; tomwalters@0: tomwalters@0: scale[ channels ] = 0. ; tomwalters@0: tomwalters@0: return ( scale ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /********************** filter/formulae.c ************************************/ tomwalters@0: tomwalters@0: tomwalters@0: void SetErbParameters( new_limit, new_Q ) tomwalters@0: double new_limit, new_Q ; tomwalters@0: { tomwalters@0: limit = new_limit ; tomwalters@0: Q = new_Q ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: double ErbScale( frequency ) tomwalters@0: double frequency ; tomwalters@0: { tomwalters@0: return ( log( 1. + frequency / Q / limit ) * Q ) ; tomwalters@0: } tomwalters@0: tomwalters@0: double FofErbScale( E ) tomwalters@0: double E ; tomwalters@0: { tomwalters@0: return ( ( exp( E / Q ) - 1 ) * Q * limit ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: