Mercurial > hg > aim92
comparison tools/edframe.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 edframe.c Edit (ie. partition) AIM output files. | |
3 ---------- | |
4 | |
5 The input file must have a model header. | |
6 | |
7 Usage: edframe [[-]frame=a[-b]] [[-]time=a[-b]] [[-]freq=a[-b]] [file] | |
8 | |
9 Special arguments: | |
10 | |
11 -help Print help on stderr. | |
12 -info Print frame size information on the stdout. | |
13 info=fbank Print channel centre-frequency information for the selected | |
14 range of frequencies on the stdout. (This information is based | |
15 on the filterbank parameters given in the input header). | |
16 | |
17 Each input frame is a matrix with (0,0) in the bottom left. | |
18 The partition, output for each frame, is a sub-matrix indexed by rows a-to-b | |
19 and columns a-to-b inclusive. | |
20 The partition is specified using args: freq=a-b (rows) and time=a-b (cols). | |
21 A single row or col is specified using a single number: freq=a or time=a. | |
22 Rows (channels) are numbered 0,1,...,frameheight-1 -(lowest freq first). | |
23 Cols (samples) are numbered 0,1,...,framewidth-1. | |
24 The strings "min" and "max" can be used as selectors, meaning eg: | |
25 freq=a-max rows a to frameheight-1 | |
26 freq=min-b rows 0 to b | |
27 time=a-max cols a to framewidth-1 | |
28 time=min-b cols 0 to b | |
29 The default selector specifies the whole matrix: | |
30 freq=min-max time=min-max | |
31 | |
32 Expressing time as cols (along the horizontal axis) and frequency as rows | |
33 (up the vertical axis) applies to most gen programs with the exception of | |
34 genwav (where the vertical axis contains just one wave), and the excitation | |
35 patterns genasa, genepn, and gensep (where frequency is measured as cols | |
36 along the horizontal axis). The horizontal dimension is controlled by the | |
37 "freq" parameter for excitation patterns. | |
38 | |
39 The units of the freq selector are Hz or kHz, specifying a range of channels | |
40 in terms of frequency, or if no units are appended, then the selector is | |
41 interpreted as a channel number in the range 0 to frameheight-1. | |
42 When the freq selector is given with frequency units, then the "closest" | |
43 corresponding channel number is used. (This depends upon the parameters | |
44 mincf_afb, maxcf_afb, and dencf_afb as given in the header). | |
45 | |
46 The units of the time selector are s or ms, specifying a range of samples | |
47 in terms of time, (seconds and milliseconds respectively), or if no units | |
48 are appended, then the selector is interpreted as a sample number in the | |
49 range 0 to framewidth-1. | |
50 | |
51 | |
52 When the input consists of a cartoon of multiple frames (eg gensai output) | |
53 then individual frames or subsequences of frames may be selected from the | |
54 input using [[-]frame=a[-b]]. | |
55 Input frames are numbered 0,1,2,...,frames-1 | |
56 frame=a Select just the a'th frame. | |
57 frame=a-b Select frames from the a'th to b'th inclusive. | |
58 The strings "min" and "max" can be used as selectors, meaning eg: | |
59 frame=min Select the first frame. | |
60 frame=max Select the last frame. | |
61 frame=a-max Select frames from the a'th to the last inclusive. | |
62 frame=min-b Select frames from the first to the b'th inclusive. | |
63 The default selector is for all frames, (ie frame=min-max). | |
64 | |
65 The units of the frame selector are s or ms, each specifying a frame which | |
66 is "closest" to the given time, being the frame number which is the greatest | |
67 integer multiple of the framestep (frstep_aid) which does not exceed the | |
68 given time, measured from the start of the input file. | |
69 If no units are appended, then the selector is interpreted as a frame number. | |
70 | |
71 The output frames are preceded by a model header, so that the partition for | |
72 each frame can be plotted using the option "useprevious=on". | |
73 | |
74 The "Header" option controls the output of the modified header. When it is | |
75 set Header=off then a header is not output. | |
76 | |
77 The "Transpose" option is a matrix transpose (swap rows and columns) of the | |
78 output partition of each input frame. | |
79 When a frame partition has a height greater than it's width (ie. cols < rows) | |
80 then setting Transpose=on may provide a preferable display orientation. | |
81 For example, this enables a very narrow (eg. single column) time-slice to be | |
82 plotted horizontally, so that a time-slice of filterbank output may be | |
83 plotted as a spectrum on a horizontal frequency axis. | |
84 | |
85 | |
86 Examples: | |
87 --------- | |
88 | |
89 Edited output may be displayed using the "useprevious" option, for example: | |
90 | |
91 genXXX ... output=stdout file1 | edframe ... > file2.XXX | |
92 genXXX useprevious=on file2 | |
93 | |
94 Note that that file2.XXX must have a different base-name to the genXXX input | |
95 (file1) because genXXX will remove any file1.XXX as a side-effect. | |
96 | |
97 | |
98 Information on the output is printed on the stdout. For example: | |
99 Print size information for gensai output for all frames. | |
100 | |
101 gensai output=stdout ... | edframe -info | |
102 | |
103 Print channel centre-frequency information for genbmm output for the 1kHz | |
104 channel, and then for channel numbers 37 to 50. | |
105 (To print the exact centre-frequency occupied by a given channel). | |
106 | |
107 genbmm output=stdout ... | edframe info=fbank freq=1kHz | |
108 genbmm output=stdout ... | edframe info=fbank freq=37-50 | |
109 | |
110 | |
111 Selecting particular frames from AIM output. | |
112 ------------------------------------------- | |
113 | |
114 1. Plot gennap output and its transpose. | |
115 | |
116 gennap output=stdout ... | edframe > file1.sai | |
117 gennap output=stdout ... | edframe Tran=on > file2.sai | |
118 gensai useprevious=on file1 | |
119 gensai useprevious=on file2 | |
120 | |
121 2. Select and plot frame 2 (ie. the 3rd frame) of gensai output. | |
122 | |
123 gensai output=stdout ... | edframe frame=2 > file.sai | |
124 gensai useprevious=on file | |
125 | |
126 3. Select the frames of gensai output which start between 16ms and 47ms from | |
127 the start of it's input. (When the option frstep_aid=16ms then this would | |
128 select the 2nd and 3rd frames). | |
129 | |
130 gensai output=stdout ... | edframe frame=16ms-47ms > file.sai | |
131 | |
132 4. Select the 5th to the last frame inclusively of gensai output. | |
133 | |
134 gensai output=stdout ... | edframe frame=4-max > file.sai | |
135 | |
136 5. Select the first frame of genepn output and plot the spectrum. | |
137 | |
138 genepn output=stdout ... | edframe frame=min > file1.epn | |
139 genepn useprevious=on file1 | |
140 | |
141 | |
142 Editing frames to select particular frequency ranges or channels (ie rows). | |
143 -------------------------------------------------------------------------- | |
144 | |
145 6. Select and plot the channel with centre-frequency closest to 1kHz from | |
146 gennap output. | |
147 | |
148 gennap output=stdout ... | edframe freq=1kHz > file.nap | |
149 gennap useprevious=on file | |
150 | |
151 7. Select and plot channel 40 then the channel with the lowest and then | |
152 the highest centre-frequency over all frames of gensai output. | |
153 | |
154 gensai output=stdout ... | edframe freq=40 > file.sai | |
155 gensai useprevious=on file | |
156 | |
157 gensai output=stdout ... | edframe freq=min > file.sai | |
158 gensai useprevious=on file | |
159 | |
160 gensai output=stdout ... | edframe freq=max > file.sai | |
161 gensai useprevious=on file | |
162 | |
163 8. Select and plot all channels of genbmm output from channel 10 to | |
164 the channel with centre-frequency closest to 1kHz inclusively. | |
165 | |
166 genbmm output=stdout ... | edframe freq=10-1000Hz > file.bmm | |
167 genbmm useprevious=on file | |
168 | |
169 9. Select and plot a portion of the spectrum from the first frame of genepn | |
170 output between 1kHz and 2kHz. | |
171 Note: frequency controls the horizontal (ie cols) dimension for genepn. | |
172 | |
173 genepn output=stdout ... | edframe frame=min freq=1kHz-2kHz > file.epn | |
174 genepn useprevious=on file | |
175 | |
176 | |
177 Editing frames to select particular time slices (ie cols). | |
178 --------------------------------------------------------- | |
179 | |
180 10. Plot column (ie sample) 100 of the 3rd frame of gensai output as a row. | |
181 | |
182 gensai output=stdout ... | edframe frame=2 time=100 Tran=on > file.sai | |
183 gensai useprevious=on file | |
184 | |
185 11. Plot column of sample at 20ms from start of gennap output as a row | |
186 | |
187 gennap output=stdout ... | edframe time=20ms Tran=on > file.nap | |
188 gennap useprevious=on file | |
189 | |
190 12. Edit a wave to select the stretch between 4ms and 16ms, strip the | |
191 header and plot the resulting wave. | |
192 | |
193 genwav output=stdout ... | edframe time=4ms-16ms Header=off > file | |
194 genwav file | |
195 | |
196 | |
197 Editing frames to select partitions. | |
198 ----------------------------------- | |
199 | |
200 13. Plot a partition of channels 40 to 44 over the last 5ms (ie near the | |
201 trigger point on the right of the image) of all frames of gensai output. | |
202 Then plot a partition of frequency range 1kHz to 1.5kHz over the first | |
203 20ms (on the left of the image) of all frames of gensai output. | |
204 | |
205 gensai pwidth=35ms nwidth=0 output=stdout ... | edframe time=30ms-max > file.sai | |
206 gensai useprevious=on file | |
207 gensai output=stdout ... | edframe freq=1kHz-1.5kHz time=min-20ms > file.sai | |
208 gensai useprevious=on file | |
209 | |
210 14. Plot the highest-frequency channel over the last 20ms of gennap output. | |
211 | |
212 gennap output=stdout ... | edframe freq=max time=20ms-max > file.sai | |
213 gennap useprevious=on file | |
214 | |
215 | |
216 */ | |
217 | |
218 | |
219 #include <stdio.h> | |
220 #include <math.h> | |
221 #include "header.h" | |
222 #include "options.h" | |
223 #include "units.h" | |
224 #include "strmatch.h" | |
225 #include "freqs.c" | |
226 | |
227 char application[] = "Edit AIM output frames. " ; | |
228 | |
229 static char *helpstr, *debugstr, *fstr, *tstr, *cfstr, *infostr, *transtr, *headstr ; | |
230 | |
231 static Options option[] = { | |
232 { "help" , "off" , &helpstr , "help" , DEBUG }, | |
233 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, | |
234 { "frame" , "min-max" , &fstr , "select frames inclusively" , VAL }, | |
235 { "time" , "min-max" , &tstr , "time (or sample number) partition" , VAL }, | |
236 { "freq" , "min-max" , &cfstr , "frequency (or channel number) partition" , VAL }, | |
237 { "Transpose" , "off" , &transtr , "transpose each output partition" , SETFLAG }, | |
238 { "Header" , "on" , &headstr , "output header" , SETFLAG }, | |
239 { "info" , "off" , &infostr , "print size and channel centre-frequency information" , SETFLAG }, | |
240 ( char * ) 0 } ; | |
241 | |
242 | |
243 char *limitstr ; | |
244 char *qualstr ; | |
245 char *minstr ; | |
246 char *maxstr ; | |
247 char *denstr ; | |
248 char *chansstr ; | |
249 | |
250 double *frequencies ; | |
251 | |
252 | |
253 int frameheight, framewidth ; /* Parameters read from header */ | |
254 int frames, framebytes ; | |
255 int frstep ; | |
256 int samplerate ; | |
257 | |
258 int applic ; | |
259 int format ; | |
260 int rows, cols, numframes ; | |
261 int Newrows, Newcols, Newnumframes ; | |
262 | |
263 int Newframeheight, Newframewidth ; | |
264 int Newframes, Newframebytes ; | |
265 | |
266 int Transpose ; | |
267 | |
268 | |
269 main(argc, argv) | |
270 int argc ; | |
271 char *argv[] ; | |
272 { | |
273 FILE *fopen(), *fp = (FILE *) 0 ; | |
274 char *header, *Header(); | |
275 char *val1, *val2, *headerstring() ; | |
276 short *frame ; | |
277 int i,j,k, a,b, xa,xb, ya,yb; | |
278 char c, Info=0 ; | |
279 | |
280 fp = openopts( option,argc,argv ) ; | |
281 if ( !isoff( helpstr ) ) | |
282 helpopts( helpstr, argv[0], application, option ) ; | |
283 | |
284 Transpose = ison( transtr ) ; | |
285 | |
286 if ( (header = ReadHeader(fp)) == (char *) 0 ) { | |
287 fprintf(stderr,"edframe: header not found\n"); | |
288 exit(1); | |
289 } | |
290 frameheight = HeaderInt( header, "frameheight" ); | |
291 framewidth = HeaderInt( header, "framewidth" ); | |
292 frames = HeaderInt( header, "frames" ); | |
293 samplerate = HeaderSamplerate( header ); | |
294 | |
295 if ( ( applic = Applic( header) ) < 0 ) { | |
296 fprintf(stderr,"edframe: application name not found in header\n" ) ; | |
297 exit( 1 ) ; | |
298 } | |
299 format = Format( applic ) ; | |
300 frame_to_matrix( format, &rows, &cols, &numframes, frameheight, framewidth, frames ) ; | |
301 framebytes = rows * cols * sizeof(short) ; | |
302 | |
303 if ( format > WAV ) { /* if not genwav */ | |
304 limitstr = headerstring( header, "bwmin_afb" ); | |
305 qualstr = headerstring( header, "quality_afb" ); | |
306 minstr = headerstring( header, "mincf_afb" ); | |
307 maxstr = headerstring( header, "maxcf_afb" ); | |
308 denstr = headerstring( header, "dencf_afb" ); | |
309 chansstr = headerstring( header, "channels_afb" ); | |
310 | |
311 SetErbParameters( to_Hz( limitstr, samplerate ), atof( qualstr ) ) ; | |
312 if( OptionInt( chansstr ) == 0 ) | |
313 frequencies = GenerateCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ; | |
314 else | |
315 frequencies = NumberedCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), OptionInt( chansstr ) ) ; | |
316 } | |
317 else frequencies = (double *)0 ; | |
318 | |
319 | |
320 if ( format == SAI ) /* if gensai or genspl */ | |
321 frstep = to_p( headerstring( header, "frstep_aid" ), samplerate ) ; | |
322 else | |
323 frstep = 1 ; | |
324 | |
325 | |
326 /* Get limits on specified number of frames */ | |
327 | |
328 if ( getvals( fstr, &val1, &val2, "-" ) == BADVAL ) { | |
329 fprintf(stderr,"edframe: bad frame selector [%s]\n", fstr ) ; | |
330 exit( 1 ) ; | |
331 } | |
332 if ( ismin( val1 ) ) a = 0 ; | |
333 else if ( ismax( val1 ) ) a = numframes - 1 ; | |
334 else if ( Units( val1 ) ) a = (int)to_p( val1, samplerate ) / frstep ; | |
335 else a = atoi( val1 ) ; | |
336 | |
337 if ( isempty( val2 ) ) b = a ; | |
338 else if ( ismin( val2 ) ) b = 0 ; | |
339 else if ( ismax( val2 ) ) b = numframes - 1 ; | |
340 else if ( Units( val2 ) ) b = (int)to_p( val2, samplerate ) / frstep ; | |
341 else b = atoi( val2 ) ; | |
342 | |
343 if ( ison( debugstr ) ) { | |
344 printf("samplerate=%d val1=[%s] val2=[%s] a=%d b=%d numframes=%d\n", samplerate, val1,val2,a,b,numframes); | |
345 } | |
346 | |
347 if ( a<0 || a>b || b>numframes ) { | |
348 if ( b>numframes ) fprintf(stderr,"edframe: bad frame selector [just %d frames available]\n", numframes ); | |
349 else fprintf(stderr,"edframe: bad frame selector \n" ); | |
350 exit(1); | |
351 } | |
352 | |
353 | |
354 if ( format == EPN ) /* kludge for excitation patterns with horizontal freq axis */ | |
355 swap( &rows, &cols ) ; | |
356 | |
357 | |
358 /* Get limits on specified time (ie samples or cols) */ | |
359 | |
360 if ( getvals( tstr, &val1, &val2, "-" ) == BADVAL ) { | |
361 fprintf(stderr,"edframe: bad time selector [%s]\n", tstr ) ; | |
362 exit( 1 ) ; | |
363 } | |
364 if ( ismin( val1 ) ) xa = 0 ; | |
365 else if ( ismax( val1 ) ) xa = cols-1 ; | |
366 else if ( Units( val1 ) ) xa = to_p( val1, samplerate ) ; | |
367 else xa = atoi( val1 ) ; | |
368 | |
369 if ( isempty( val2 ) ) xb = xa ; | |
370 else if ( ismin( val2 ) ) xb = 0 ; | |
371 else if ( ismax( val2 ) ) xb = cols-1 ; | |
372 else if ( Units( val2 ) ) xb = to_p( val2, samplerate ) ; | |
373 else xb = atoi( val2 ) ; | |
374 | |
375 /* Get limits on specified freqency (ie channels or rows) */ | |
376 | |
377 if ( getvals( cfstr, &val1, &val2, "-" ) == BADVAL ) { | |
378 fprintf(stderr,"edframe: bad frequency selector [%s]\n", cfstr ) ; | |
379 exit( 1 ) ; | |
380 } | |
381 if ( ismin( val1 ) ) ya = 0 ; | |
382 else if ( ismax( val1 ) ) ya = rows-1 ; | |
383 else if ( Units( val1 ) ) ya = closest( to_Hz( val1, samplerate ), frequencies, rows ) ; | |
384 else ya = atoi( val1 ) ; | |
385 | |
386 if ( isempty( val2 ) ) yb = ya ; | |
387 else if ( ismin( val2 ) ) yb = 0 ; | |
388 else if ( ismax( val2 ) ) yb = rows-1 ; | |
389 else if ( Units( val2 ) ) yb = closest( to_Hz( val2, samplerate ), frequencies, rows ) ; | |
390 else yb = atoi( val2 ) ; | |
391 | |
392 | |
393 if ( format == EPN ) { /* excitation patterns have horizontal freq axis */ | |
394 swap( &xa, &ya ) ; | |
395 swap( &xb, &yb ) ; | |
396 swap( &rows, &cols ) ; | |
397 } | |
398 | |
399 if ( ya<0 || yb>=rows || ya>yb || xa<0 || xb>=cols || xa>xb ) { | |
400 fprintf(stderr,"edframe: bad specifiers [xa=%d xb=%d ya=%d yb=%d]\n", xa,xb,ya,yb ) ; | |
401 fprintf(stderr," input frames have %d rows and %d columns \n", rows, cols ) ; | |
402 exit(1); | |
403 } | |
404 | |
405 Newrows = yb - ya + 1 ; | |
406 Newcols = xb - xa + 1 ; | |
407 Newnumframes = b - a + 1 ; | |
408 | |
409 if ( Transpose ) swap( &Newrows, &Newcols ) ; | |
410 | |
411 matrix_to_frame( format, Newrows, Newcols, Newnumframes, &Newframeheight, &Newframewidth, &Newframes ) ; | |
412 Newframebytes = Newframewidth * Newframeheight * sizeof(short) ; | |
413 | |
414 if ( !isoff( infostr ) ) { | |
415 if ( ison( infostr ) ) printinfo() ; | |
416 if ( isstr( infostr, "fbank" ) ) printfbank( xa, xb, ya, yb ) ; | |
417 exit( 0 ) ; | |
418 } | |
419 if ( ison( debugstr ) ) { | |
420 printf( "rows=%d cols=%d numframes=%d\n", rows,cols,numframes); | |
421 printf( "a=%d b=%d ya=%d yb=%d xa=%d xb=%d\n", a,b,ya,yb,xa,xb ) ; | |
422 printf( "Newrows=%d Newcols=%d Newnumframes=%d\n", Newrows,Newcols,Newnumframes); | |
423 printf( "Newframeheight=%d Newframewidth=%d Newframes=%d\n", Newframeheight, Newframewidth, Newframes ) ; | |
424 printf( "framebytes=%d Newframebytes=%d\n", framebytes, Newframebytes ) ; | |
425 exit( 1 ) ; | |
426 } | |
427 | |
428 if ( ison( headstr ) ) | |
429 WriteHeader( Header(header, ya,yb), stdout ); | |
430 | |
431 | |
432 /* Allocate space for framebytes of data */ | |
433 | |
434 if ( (frame = (short *)malloc( framebytes )) == NULL ) { | |
435 fprintf(stderr,"edframe: malloc out of space\n"); | |
436 exit(1); | |
437 } | |
438 | |
439 /* seeks past `a' frames */ | |
440 | |
441 for ( i = 0 ; i < a && fread( frame,framebytes,1,fp ) ; i++ ) | |
442 ; | |
443 | |
444 /* edit frames `a' to `b' */ | |
445 | |
446 if ( Transpose ) { | |
447 | |
448 for ( ; i <= b && fread( frame,framebytes,1,fp ) ; i++ ) { | |
449 | |
450 if ( format == SAI || format == EPN ) | |
451 for ( j=xa ; j<=xb ; j++ ) | |
452 for ( k=ya ; k<=yb ; k++ ) | |
453 fwrite( frame + k*framewidth + j, sizeof(short), 1, stdout ) ; | |
454 else | |
455 for ( j=ya ; j<=yb ; j++ ) | |
456 for ( k=xa ; k<=xb ; k++ ) | |
457 fwrite( frame + k*frameheight + j, sizeof(short), 1, stdout ) ; | |
458 } | |
459 } | |
460 else { /* direct (un-transposed) output */ | |
461 | |
462 for ( ; i <= b && fread( frame,framebytes,1,fp ) ; i++ ) { | |
463 | |
464 if ( format == SAI || format == EPN ) | |
465 for ( j=ya ; j<=yb ; j++ ) | |
466 fwrite( frame + j*framewidth + xa, sizeof(short), Newcols, stdout ) ; | |
467 else | |
468 for ( j=xa ; j<=xb ; j++ ) | |
469 fwrite( frame + j*frameheight + ya, sizeof(short), Newrows, stdout ) ; | |
470 } | |
471 } | |
472 | |
473 fclose(fp); | |
474 | |
475 } | |
476 | |
477 | |
478 /* | |
479 Return an allocated string to the value part of an option in the header | |
480 with the given name. Exit if option not found in header. | |
481 */ | |
482 | |
483 char *headerstring( header, name ) | |
484 char *header, *name ; | |
485 { | |
486 char *valuestr ; | |
487 | |
488 if ( (valuestr = HeaderStringOnly( header, name )) == (char *) 0) { | |
489 fprintf(stderr,"edframe: option %s not found in header\n", name); | |
490 exit( 1 ) ; | |
491 } | |
492 return ( valuestr ) ; | |
493 } | |
494 | |
495 | |
496 int OptionInt( str ) | |
497 char *str ; | |
498 { | |
499 if( strcmp( str, "on" ) == 0 ) | |
500 return( 1 ) ; | |
501 else if( strcmp( str, "Not_used" ) == 0 ) | |
502 return( 0 ) ; | |
503 else | |
504 return( atoi( str ) ) ; | |
505 } | |
506 | |
507 | |
508 /* | |
509 Copy the original nap header to a new sai header, changing in order: | |
510 maxcf_afb | |
511 mincf_afb | |
512 channels_afb | |
513 frames | |
514 framewidth | |
515 frameheight | |
516 framebytes | |
517 view | |
518 Finally, update the new header_bytes, and return the new header. | |
519 */ | |
520 | |
521 char *Header( oldheader, ya,yb ) | |
522 char *oldheader ; | |
523 int ya,yb ; | |
524 { | |
525 char *saiheader; | |
526 char *p0, *p1, *p2, *s, str[64]; | |
527 | |
528 saiheader = (char *)malloc( strlen(oldheader) + 64 ) ; | |
529 | |
530 p0 = saiheader ; | |
531 p1 = oldheader ; | |
532 | |
533 | |
534 if ( format > WAV ) { /* if not genwav */ | |
535 | |
536 /** copy up to maxcf_afb **/ | |
537 | |
538 p2 = HeaderString( oldheader , "maxcf_afb" ) ; | |
539 while( p1 < p2 ) | |
540 *p0++ = *p1++ ; | |
541 | |
542 sprintf(str,"%.2fHz\n", frequencies[yb]); | |
543 for (s = str ; *s != '\n' ; ) | |
544 *p0++ = *s++; | |
545 *p0++ = *s; | |
546 while (*p1 != '\n') | |
547 *p1++; | |
548 *p1++; | |
549 | |
550 | |
551 /** copy up to mincf_afb **/ | |
552 | |
553 p2 = HeaderString( oldheader , "mincf_afb" ) ; | |
554 while( p1 < p2 ) | |
555 *p0++ = *p1++ ; | |
556 | |
557 sprintf(str,"%.2fHz\n", frequencies[ya]); | |
558 for (s = str ; *s != '\n' ; ) | |
559 *p0++ = *s++; | |
560 *p0++ = *s; | |
561 while (*p1 != '\n') | |
562 *p1++; | |
563 *p1++; | |
564 | |
565 | |
566 /** copy up to channels_afb **/ | |
567 | |
568 p2 = HeaderString( oldheader , "channels_afb" ) ; | |
569 while( p1 < p2 ) | |
570 *p0++ = *p1++ ; | |
571 | |
572 sprintf(str,"%d\n", Newframeheight); | |
573 for (s = str ; *s != '\n' ; ) | |
574 *p0++ = *s++; | |
575 *p0++ = *s; | |
576 while (*p1 != '\n') | |
577 *p1++; | |
578 *p1++; | |
579 | |
580 } | |
581 | |
582 /** copy up to frames **/ | |
583 | |
584 p2 = HeaderString( oldheader , "frames" ) ; | |
585 while( p1 < p2 ) | |
586 *p0++ = *p1++ ; | |
587 | |
588 sprintf(str,"%d\n", Newframes); | |
589 for (s = str ; *s != '\n' ; ) | |
590 *p0++ = *s++; | |
591 *p0++ = *s; | |
592 while (*p1 != '\n') | |
593 *p1++; | |
594 *p1++; | |
595 | |
596 | |
597 /** copy up to framewidth **/ | |
598 | |
599 p2 = HeaderString( oldheader , "framewidth" ) ; | |
600 while ( p1 < p2 ) | |
601 *p0++ = *p1++ ; | |
602 | |
603 sprintf(str,"%d\n", Newframewidth); | |
604 for (s = str ; *s != '\n' ; ) | |
605 *p0++ = *s++; | |
606 *p0++ = *s; | |
607 while (*p1 != '\n') | |
608 *p1++; | |
609 *p1++; | |
610 | |
611 | |
612 /** copy up to frameheight **/ | |
613 | |
614 p2 = HeaderString( oldheader , "frameheight" ) ; | |
615 while ( p1 < p2 ) | |
616 *p0++ = *p1++ ; | |
617 | |
618 sprintf(str,"%d\n", Newframeheight); | |
619 for (s = str ; *s != '\n' ; ) | |
620 *p0++ = *s++; | |
621 *p0++ = *s; | |
622 while (*p1 != '\n') | |
623 *p1++; | |
624 *p1++; | |
625 | |
626 | |
627 /** copy up to framebytes **/ | |
628 | |
629 p2 = HeaderString( oldheader , "framebytes" ) ; | |
630 while ( p1 < p2 ) | |
631 *p0++ = *p1++ ; | |
632 | |
633 sprintf(str,"%d\n", Newframebytes); | |
634 for (s = str ; *s != '\n' ; ) | |
635 *p0++ = *s++; | |
636 *p0++ = *s; | |
637 while (*p1 != '\n') | |
638 *p1++; | |
639 *p1++; | |
640 | |
641 | |
642 /** copy rest of header **/ | |
643 | |
644 p2 = HeaderString( oldheader , "Version" ) ; | |
645 while ( p1 < p2 ) | |
646 *p0++ = *p1++ ; | |
647 | |
648 while (*p1 != '\n') | |
649 *p0++ = *p1++ ; | |
650 *p0++ = *p1++ ; | |
651 | |
652 | |
653 /** update header_bytes **/ | |
654 | |
655 sprintf(str, "%0*d", 7, p0-saiheader); | |
656 p0 = HeaderString( saiheader , "header_bytes" ) ; | |
657 s = str; | |
658 while(*p0 != '\n') | |
659 *p0++ = *s++ ; | |
660 | |
661 | |
662 return saiheader; | |
663 } | |
664 | |
665 | |
666 | |
667 | |
668 /* Return the index of the frequency closest to the given "freq" */ | |
669 | |
670 int closest( freq, frequencies, channels ) | |
671 double freq, *frequencies ; | |
672 int channels ; | |
673 { | |
674 int i; | |
675 | |
676 if ( frequencies == (double *)0 ) return 0 ; | |
677 | |
678 for (i=0 ; i<channels && frequencies[i]<freq ; i++) | |
679 ; | |
680 if (i==channels) return ( i-1 ) ; | |
681 if (i==0) return i ; | |
682 if ( frequencies[i]-freq < freq-frequencies[i-1] ) return i ; | |
683 else return ( i-1 ) ; | |
684 } | |
685 | |
686 | |
687 /* Return 1 if the str has appended units. Otherwise return 0. */ | |
688 /* (A freqency specifier with no units is interpreted as a channel number) */ | |
689 Units(str) | |
690 char *str ; | |
691 { | |
692 char *eptr = str + strlen( str ) ; | |
693 | |
694 if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */ | |
695 else return 1 ; | |
696 } | |
697 | |
698 | |
699 printinfo() | |
700 { | |
701 printf( "gen%s output file\n", gen_applics[ applic ] ) ; | |
702 switch ( format ) { | |
703 case WAV : printf( " wave format (array of time points)\n" ) ; | |
704 break ; | |
705 case NAP : printf( " activity-pattern format (by columns, lowest centre-frequency first in each)\n" ) ; | |
706 break ; | |
707 case SGM : printf( " spectrogram format (by columns, lowest centre-frequency first in each)\n" ) ; | |
708 break ; | |
709 case EPN : printf( " excitation-pattern format (array of frequency points per frame)\n" ) ; | |
710 break ; | |
711 case SAI : printf( " auditory-image format (by rows, lowest centre-frequency first per frame)\n" ) ; | |
712 break ; | |
713 } | |
714 | |
715 if ( format != WAV && format != EPN ) /* frameheight meaningless for wav and epn */ | |
716 printf( " frameheight = %4d channels (%.2fHz to %.2fHz) \n", rows, to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ) ) ; | |
717 | |
718 if ( format == EPN ) /* horiz axis is freq for epn, otherwise is time */ | |
719 printf( " framewidth = %4d channels (%.2fHz to %.2fHz) \n", cols, to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ) ) ; | |
720 else | |
721 printf( " framewidth = %4d samples (%d ms at %dHz samplerate) \n", cols, (int)to_ms( itoa( cols ), samplerate ), samplerate ) ; | |
722 | |
723 printf( " frames = %4d \n", numframes ) ; | |
724 printf( " framesize = %4d bytes \n", rows*cols*2 ) ; | |
725 } | |
726 | |
727 | |
728 printfbank( xa, xb, ya, yb ) /* print filterbank info */ | |
729 int xa, xb, ya, yb ; | |
730 { | |
731 int i ; | |
732 | |
733 if ( format > WAV ) { /* no filterbank for genwav */ | |
734 if ( format == EPN ) /* freq axis is horiz for epn */ | |
735 for (i=xa ; i<=xb ; i++) | |
736 printf( "channel %2d. %7.2fHz, %4.2fms, %5.2f samples \n", i, frequencies[i], 1000./frequencies[i], (double)samplerate/frequencies[i] ); | |
737 else | |
738 for (i=ya ; i<=yb ; i++) | |
739 printf( "channel %2d. %7.2fHz, %4.2fms, %5.2f samples \n", i, frequencies[i], 1000./frequencies[i], (double)samplerate/frequencies[i] ); | |
740 } | |
741 } | |
742 | |
743 | |
744 /* Swap the values in integer addresses p1 and p2 */ | |
745 | |
746 swap( p1, p2 ) | |
747 int *p1 , *p2 ; | |
748 { | |
749 int tmp ; | |
750 | |
751 tmp = *p1 ; | |
752 *p1 = *p2 ; | |
753 *p2 = tmp ; | |
754 } |