Mercurial > hg > aim92
diff tools/fbank.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/fbank.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,199 @@ +/* + fbank.c Print parameters and misc info of a filterbank. + ------- + + The filterbank parameters are read from defaults or overriding options. + If the "input" option is set, then the parameters are read from a model + header, which can be given as a model output filename, or piped in. + + Channels may be specified using option: freq=a-b + where "a" and "b" may be numbers with optional units of Hz or kHz appended, + or may be the strings "min" or "max". + + With no units, the specifier is interpreted as channel (ie row) numbers. + These must be in the range 0 to channels-1, (where the lowest centre-freq + channel has the lowest channel number, 0, and `channels' is the max number + of channels, depending upon the parameters of the filterbank). + + "min" is interpreted as the lowest frequency channel (number 0). + "max" is interpreted as the highest frequency channel (number channels-1). + + With frequency units, the specifier is interpreted as centre-frequencies. + These are converted to channel numbers using the "closest" channel number + in the filterbank to each specified centre-frequency. + + Single channels or ranges can be specified. + The default specifier is freq=min-max + Eg: + specifier channel number + ---------- --------------- + freq=5 5 + freq=1kHz channel number with centre-freq closest to 1kHz + freq=max max channel number (channels-1) + freq=10-max 10 to channels-1 + freq=min-15 0 to 15 + +*/ + + +#include <stdio.h> +#include <math.h> +#include "header.h" +#include "options.h" +#include "units.h" +#include "strmatch.h" +#include "freqs.c" + +char applic[] = "Print parameters of a filterbank. " ; + +static char *helpstr, *debugstr, *instr, *cfstr, *sampstr, *chanstr, *minstr, *maxstr, *denstr, *bwstr, *qualstr ; + +static Options option[] = { + { "help" , "off" , &helpstr , "help" , DEBUG }, + { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, + { "input" , "off" , &instr , "Input (off/on)" , FLAG }, + { "freq" , "min-max" , &cfstr , "Frequency (or channel number)" , VAL }, + { "samplerate", "20000." , &sampstr , "Input wave sample rate (Hz)" , VAL }, + { "channels" , "75" , &chanstr , "Number of channels in filter" , VAL }, + { "mincf" , "100Hz" , &minstr , "Minimum center frequency (Hz)" , VAL }, + { "maxcf" , "6000Hz" , &maxstr , "Maximum center frequency (Hz)" , VAL }, + { "dencf" , "off" , &denstr , "Filter density (filters/critical band)" , VAL }, + { "bwmin" , "24.7Hz" , &bwstr , "Minimum filter bandwith" , VAL }, + { "quality" , "9.265" , &qualstr , "Ultimate qualtity factor of filters" , VAL }, + ( char * ) 0 } ; + + +int samplerate ; +int channels ; +double *frequencies ; + + +main(argc, argv) +int argc ; +char *argv[] ; +{ + FILE *fp ; + char *header ; + char *val1, *val2, *headerstring() ; + int i, cf1, cf2 ; + + fp = openopts( option,argc,argv ) ; + if ( !isoff( helpstr ) ) + helpopts( helpstr, argv[0], applic, option ) ; + + if ( !isoff( instr ) ) { + + if ( (header = ReadHeader(fp)) == (char *) 0 ) { + fprintf(stderr,"fbank: header not found\n"); + exit(1); + } + sampstr = headerstring( header, "samplerate" ) ; + chanstr = headerstring( header, "channels_afb" ) ; + minstr = headerstring( header, "mincf_afb" ) ; + maxstr = headerstring( header, "maxcf_afb" ) ; + denstr = headerstring( header, "dencf_afb" ) ; + bwstr = headerstring( header, "bwmin_afb" ) ; + qualstr = headerstring( header, "quality_afb" ) ; + } + + samplerate = to_Hz( sampstr, 0 ) ; + channels = OptionInt( chanstr ) ; + + SetErbParameters( to_Hz( bwstr, samplerate ), atof( qualstr ) ) ; + if( channels == 0 ) { + frequencies = GenerateCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ; + channels = NumberCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ; + } + else + frequencies = NumberedCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), OptionInt( chanstr ) ) ; + + + /* Get limits on specified frequency (ie channels or rows) */ + + if ( getvals( cfstr, &val1, &val2, "-" ) == BADVAL ) { + fprintf(stderr,"fbank: bad frequency selector [%s]\n", cfstr ) ; + exit( 1 ) ; + } + if ( ismin( val1 ) ) cf1 = 0 ; + else if ( ismax( val1 ) ) cf1 = channels-1 ; + else if ( Units( val1 ) ) cf1 = closest( to_Hz( val1, samplerate ), frequencies, channels ) ; + else cf1 = atoi( val1 ) ; + + if ( isempty( val2 ) ) cf2 = cf1 ; + else if ( ismin( val2 ) ) cf2 = 0 ; + else if ( ismax( val2 ) ) cf2 = channels-1 ; + else if ( Units( val2 ) ) cf2 = closest( to_Hz( val2, samplerate ), frequencies, channels ) ; + else cf2 = atoi( val2 ) ; + + if ( cf1<0 || cf1>cf2 || cf2>channels ) { + fprintf( stderr,"fbank: incorrect frequency specifier [%s] for %d channel filterbank\n", cfstr, channels ) ; + exit( 1 ) ; + } + + printf("channel cf period ERB \n"); + printf("number (Hz) (ms) (samples) (Hz) \n"); + printf("------- ------ --------------- ------ \n"); + + for (i=cf1 ; i<=cf2 ; i++) + printf( "%3d %7.2f %6.2f %6.2f %6.2f \n", i, frequencies[i], 1000./frequencies[i], (double)samplerate/frequencies[i], frequencies[i]/9.26449 + 24.7 ); + +} + + +/* Return the index of the frequency closest to the given "freq" */ + +int closest( freq, frequencies, channels ) +double freq, *frequencies ; +int channels ; +{ + int i; + + for (i=0 ; i<channels && frequencies[i]<freq ; i++) + ; + if (i==channels) return ( i-1 ) ; + if (i==0) return i ; + if ( frequencies[i]-freq < freq-frequencies[i-1] ) return i ; + else return ( i-1 ) ; +} + +/* Return 1 if the str has appended units. Otherwise return 0. */ +/* (A freqency specifier with no units is interpreted as a channel number) */ + +Units(str) +char *str ; +{ + char *eptr = str + strlen( str ) ; + + if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */ + else return 1 ; +} + + +int OptionInt( str ) +char *str ; +{ + if( strcmp( str, "on" ) == 0 ) + return( 1 ) ; + else if( strcmp( str, "Not_used" ) == 0 ) + return( 0 ) ; + else + return( atoi( str ) ) ; +} + + +/* +Return an allocated string to the value part of an option in the header +with the given name. Exit if option not found in header. +*/ + +char *headerstring( header, name ) +char *header, *name ; +{ + char *valuestr ; + + if ( (valuestr = HeaderStringOnly( header, name )) == (char *) 0) { + fprintf(stderr,"edframe: option %s not found in header\n", name); + exit(1); + } + return ( valuestr ) ; +}