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 ) ;
+}
+
+
+