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