annotate 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
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 fbank.c Print parameters and misc info of a filterbank.
tomwalters@0 3 -------
tomwalters@0 4
tomwalters@0 5 The filterbank parameters are read from defaults or overriding options.
tomwalters@0 6 If the "input" option is set, then the parameters are read from a model
tomwalters@0 7 header, which can be given as a model output filename, or piped in.
tomwalters@0 8
tomwalters@0 9 Channels may be specified using option: freq=a-b
tomwalters@0 10 where "a" and "b" may be numbers with optional units of Hz or kHz appended,
tomwalters@0 11 or may be the strings "min" or "max".
tomwalters@0 12
tomwalters@0 13 With no units, the specifier is interpreted as channel (ie row) numbers.
tomwalters@0 14 These must be in the range 0 to channels-1, (where the lowest centre-freq
tomwalters@0 15 channel has the lowest channel number, 0, and `channels' is the max number
tomwalters@0 16 of channels, depending upon the parameters of the filterbank).
tomwalters@0 17
tomwalters@0 18 "min" is interpreted as the lowest frequency channel (number 0).
tomwalters@0 19 "max" is interpreted as the highest frequency channel (number channels-1).
tomwalters@0 20
tomwalters@0 21 With frequency units, the specifier is interpreted as centre-frequencies.
tomwalters@0 22 These are converted to channel numbers using the "closest" channel number
tomwalters@0 23 in the filterbank to each specified centre-frequency.
tomwalters@0 24
tomwalters@0 25 Single channels or ranges can be specified.
tomwalters@0 26 The default specifier is freq=min-max
tomwalters@0 27 Eg:
tomwalters@0 28 specifier channel number
tomwalters@0 29 ---------- ---------------
tomwalters@0 30 freq=5 5
tomwalters@0 31 freq=1kHz channel number with centre-freq closest to 1kHz
tomwalters@0 32 freq=max max channel number (channels-1)
tomwalters@0 33 freq=10-max 10 to channels-1
tomwalters@0 34 freq=min-15 0 to 15
tomwalters@0 35
tomwalters@0 36 */
tomwalters@0 37
tomwalters@0 38
tomwalters@0 39 #include <stdio.h>
tomwalters@0 40 #include <math.h>
tomwalters@0 41 #include "header.h"
tomwalters@0 42 #include "options.h"
tomwalters@0 43 #include "units.h"
tomwalters@0 44 #include "strmatch.h"
tomwalters@0 45 #include "freqs.c"
tomwalters@0 46
tomwalters@0 47 char applic[] = "Print parameters of a filterbank. " ;
tomwalters@0 48
tomwalters@0 49 static char *helpstr, *debugstr, *instr, *cfstr, *sampstr, *chanstr, *minstr, *maxstr, *denstr, *bwstr, *qualstr ;
tomwalters@0 50
tomwalters@0 51 static Options option[] = {
tomwalters@0 52 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 53 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 54 { "input" , "off" , &instr , "Input (off/on)" , FLAG },
tomwalters@0 55 { "freq" , "min-max" , &cfstr , "Frequency (or channel number)" , VAL },
tomwalters@0 56 { "samplerate", "20000." , &sampstr , "Input wave sample rate (Hz)" , VAL },
tomwalters@0 57 { "channels" , "75" , &chanstr , "Number of channels in filter" , VAL },
tomwalters@0 58 { "mincf" , "100Hz" , &minstr , "Minimum center frequency (Hz)" , VAL },
tomwalters@0 59 { "maxcf" , "6000Hz" , &maxstr , "Maximum center frequency (Hz)" , VAL },
tomwalters@0 60 { "dencf" , "off" , &denstr , "Filter density (filters/critical band)" , VAL },
tomwalters@0 61 { "bwmin" , "24.7Hz" , &bwstr , "Minimum filter bandwith" , VAL },
tomwalters@0 62 { "quality" , "9.265" , &qualstr , "Ultimate qualtity factor of filters" , VAL },
tomwalters@0 63 ( char * ) 0 } ;
tomwalters@0 64
tomwalters@0 65
tomwalters@0 66 int samplerate ;
tomwalters@0 67 int channels ;
tomwalters@0 68 double *frequencies ;
tomwalters@0 69
tomwalters@0 70
tomwalters@0 71 main(argc, argv)
tomwalters@0 72 int argc ;
tomwalters@0 73 char *argv[] ;
tomwalters@0 74 {
tomwalters@0 75 FILE *fp ;
tomwalters@0 76 char *header ;
tomwalters@0 77 char *val1, *val2, *headerstring() ;
tomwalters@0 78 int i, cf1, cf2 ;
tomwalters@0 79
tomwalters@0 80 fp = openopts( option,argc,argv ) ;
tomwalters@0 81 if ( !isoff( helpstr ) )
tomwalters@0 82 helpopts( helpstr, argv[0], applic, option ) ;
tomwalters@0 83
tomwalters@0 84 if ( !isoff( instr ) ) {
tomwalters@0 85
tomwalters@0 86 if ( (header = ReadHeader(fp)) == (char *) 0 ) {
tomwalters@0 87 fprintf(stderr,"fbank: header not found\n");
tomwalters@0 88 exit(1);
tomwalters@0 89 }
tomwalters@0 90 sampstr = headerstring( header, "samplerate" ) ;
tomwalters@0 91 chanstr = headerstring( header, "channels_afb" ) ;
tomwalters@0 92 minstr = headerstring( header, "mincf_afb" ) ;
tomwalters@0 93 maxstr = headerstring( header, "maxcf_afb" ) ;
tomwalters@0 94 denstr = headerstring( header, "dencf_afb" ) ;
tomwalters@0 95 bwstr = headerstring( header, "bwmin_afb" ) ;
tomwalters@0 96 qualstr = headerstring( header, "quality_afb" ) ;
tomwalters@0 97 }
tomwalters@0 98
tomwalters@0 99 samplerate = to_Hz( sampstr, 0 ) ;
tomwalters@0 100 channels = OptionInt( chanstr ) ;
tomwalters@0 101
tomwalters@0 102 SetErbParameters( to_Hz( bwstr, samplerate ), atof( qualstr ) ) ;
tomwalters@0 103 if( channels == 0 ) {
tomwalters@0 104 frequencies = GenerateCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ;
tomwalters@0 105 channels = NumberCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ;
tomwalters@0 106 }
tomwalters@0 107 else
tomwalters@0 108 frequencies = NumberedCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), OptionInt( chanstr ) ) ;
tomwalters@0 109
tomwalters@0 110
tomwalters@0 111 /* Get limits on specified frequency (ie channels or rows) */
tomwalters@0 112
tomwalters@0 113 if ( getvals( cfstr, &val1, &val2, "-" ) == BADVAL ) {
tomwalters@0 114 fprintf(stderr,"fbank: bad frequency selector [%s]\n", cfstr ) ;
tomwalters@0 115 exit( 1 ) ;
tomwalters@0 116 }
tomwalters@0 117 if ( ismin( val1 ) ) cf1 = 0 ;
tomwalters@0 118 else if ( ismax( val1 ) ) cf1 = channels-1 ;
tomwalters@0 119 else if ( Units( val1 ) ) cf1 = closest( to_Hz( val1, samplerate ), frequencies, channels ) ;
tomwalters@0 120 else cf1 = atoi( val1 ) ;
tomwalters@0 121
tomwalters@0 122 if ( isempty( val2 ) ) cf2 = cf1 ;
tomwalters@0 123 else if ( ismin( val2 ) ) cf2 = 0 ;
tomwalters@0 124 else if ( ismax( val2 ) ) cf2 = channels-1 ;
tomwalters@0 125 else if ( Units( val2 ) ) cf2 = closest( to_Hz( val2, samplerate ), frequencies, channels ) ;
tomwalters@0 126 else cf2 = atoi( val2 ) ;
tomwalters@0 127
tomwalters@0 128 if ( cf1<0 || cf1>cf2 || cf2>channels ) {
tomwalters@0 129 fprintf( stderr,"fbank: incorrect frequency specifier [%s] for %d channel filterbank\n", cfstr, channels ) ;
tomwalters@0 130 exit( 1 ) ;
tomwalters@0 131 }
tomwalters@0 132
tomwalters@0 133 printf("channel cf period ERB \n");
tomwalters@0 134 printf("number (Hz) (ms) (samples) (Hz) \n");
tomwalters@0 135 printf("------- ------ --------------- ------ \n");
tomwalters@0 136
tomwalters@0 137 for (i=cf1 ; i<=cf2 ; i++)
tomwalters@0 138 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 139
tomwalters@0 140 }
tomwalters@0 141
tomwalters@0 142
tomwalters@0 143 /* Return the index of the frequency closest to the given "freq" */
tomwalters@0 144
tomwalters@0 145 int closest( freq, frequencies, channels )
tomwalters@0 146 double freq, *frequencies ;
tomwalters@0 147 int channels ;
tomwalters@0 148 {
tomwalters@0 149 int i;
tomwalters@0 150
tomwalters@0 151 for (i=0 ; i<channels && frequencies[i]<freq ; i++)
tomwalters@0 152 ;
tomwalters@0 153 if (i==channels) return ( i-1 ) ;
tomwalters@0 154 if (i==0) return i ;
tomwalters@0 155 if ( frequencies[i]-freq < freq-frequencies[i-1] ) return i ;
tomwalters@0 156 else return ( i-1 ) ;
tomwalters@0 157 }
tomwalters@0 158
tomwalters@0 159 /* Return 1 if the str has appended units. Otherwise return 0. */
tomwalters@0 160 /* (A freqency specifier with no units is interpreted as a channel number) */
tomwalters@0 161
tomwalters@0 162 Units(str)
tomwalters@0 163 char *str ;
tomwalters@0 164 {
tomwalters@0 165 char *eptr = str + strlen( str ) ;
tomwalters@0 166
tomwalters@0 167 if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */
tomwalters@0 168 else return 1 ;
tomwalters@0 169 }
tomwalters@0 170
tomwalters@0 171
tomwalters@0 172 int OptionInt( str )
tomwalters@0 173 char *str ;
tomwalters@0 174 {
tomwalters@0 175 if( strcmp( str, "on" ) == 0 )
tomwalters@0 176 return( 1 ) ;
tomwalters@0 177 else if( strcmp( str, "Not_used" ) == 0 )
tomwalters@0 178 return( 0 ) ;
tomwalters@0 179 else
tomwalters@0 180 return( atoi( str ) ) ;
tomwalters@0 181 }
tomwalters@0 182
tomwalters@0 183
tomwalters@0 184 /*
tomwalters@0 185 Return an allocated string to the value part of an option in the header
tomwalters@0 186 with the given name. Exit if option not found in header.
tomwalters@0 187 */
tomwalters@0 188
tomwalters@0 189 char *headerstring( header, name )
tomwalters@0 190 char *header, *name ;
tomwalters@0 191 {
tomwalters@0 192 char *valuestr ;
tomwalters@0 193
tomwalters@0 194 if ( (valuestr = HeaderStringOnly( header, name )) == (char *) 0) {
tomwalters@0 195 fprintf(stderr,"edframe: option %s not found in header\n", name);
tomwalters@0 196 exit(1);
tomwalters@0 197 }
tomwalters@0 198 return ( valuestr ) ;
tomwalters@0 199 }