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