view 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 source
/**************************************************************************

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