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