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