Mercurial > hg > aim92
comparison tools/header.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 Utilities for model output headers. | |
3 | |
4 A header is an ASCII desciption which summarises the state of | |
5 a process by giving a list of parameter values etc etc.. | |
6 Each parameter is described on a separate line, and the header consists | |
7 of several lines of the general form: | |
8 | |
9 <ASCII description> = <value>\n | |
10 | |
11 For example, the first five lines of the header generated by a command | |
12 line "gensai -header fname" is as follows: | |
13 | |
14 header_bytes=0000532 | |
15 scale_sai=0.25 | |
16 imagedurn_sai=16 | |
17 decayrate_sai=10 | |
18 cgmdecay=24 | |
19 ... | |
20 date=Thu Jan 11 00:19:41 WET 1990\n | |
21 \000 | |
22 | |
23 This string is written onto the front of the file with padding if | |
24 desired before any data is written. The header can be of any length | |
25 and contain any combination of non null characters. Header items are | |
26 identified by the string on the left of the equals symbol and their | |
27 value is represented by the string on the remainder of that line. | |
28 | |
29 The first line is always the HEADER_STRING (ie. header_bytes=....\n) | |
30 which gives the length of the header. | |
31 | |
32 Synopsis of utilities: | |
33 ---------------------- | |
34 | |
35 char *ReadHeader( fp ) | |
36 FILE *fp ; | |
37 | |
38 WriteHeader(header,fp) | |
39 char *header; | |
40 FILE *fp; | |
41 | |
42 char *HeaderString( header, name ) | |
43 char *header, *name ; | |
44 | |
45 char *HeaderStringOnly( header, name ) | |
46 char *header, *name ; | |
47 | |
48 double HeaderDouble( header, name ) | |
49 char *header, *name ; | |
50 | |
51 double HeaderInt( header, name ) | |
52 char *header, *name ; | |
53 | |
54 void FreeHeader( header ) | |
55 char *header ; | |
56 | |
57 ReadHeader() reads a header (if it exists ) from the file into | |
58 memory and returns a pointer to the header in memory allocated for | |
59 storing the header. It returns a null pointer if no header is found. | |
60 It leaves the fp pointing to the data which follows the header. | |
61 WriteHeader() writes the given header on the given file stream. | |
62 HeaderString() simply searches through the header for values the user | |
63 requests and returns a pointer to the beginning of the value. | |
64 It returns a null pointer if the required string is not found. | |
65 HeaderStringOnly() returns a pointer to an allocated string that | |
66 contains only the value rather than a pointer to a string that | |
67 includes the all the rest of the header (which is what HeaderString() | |
68 returns). It returns a null pointer if the required string is not found. | |
69 HeaderDouble() converts values to Doubles. | |
70 HeaderInt() converts values to Ints. | |
71 FreeHeader() frees the space allocated for a header by ReadHeader. | |
72 | |
73 Example: | |
74 ------- | |
75 A simple example of the use of the header utility routines to read the | |
76 sai dimensions from a header would be: | |
77 (This assumes a ".sai" file generated by a command like "gensai -header") | |
78 | |
79 #include <stdio.h> | |
80 #include <math.h> | |
81 #include "header.c" | |
82 char *header = ReadHeader(fp); fp is file-pointer to ".sai" file | |
83 int frameheight = HeaderInt(header,"frameheight"); num chans | |
84 int framewidth = HeaderInt(header,"framewidth"); sai duration | |
85 | |
86 char *name = "frameheight"; | |
87 printf( "%s=%s\n", name, HeaderStringOnly( header, name ) ) ; | |
88 | |
89 ****************************************************************************/ | |
90 | |
91 #include <stdio.h> | |
92 /* #include <strings.h> */ | |
93 #include <string.h> | |
94 #include <malloc.h> | |
95 #include "header.h" | |
96 #include "units.h" | |
97 | |
98 | |
99 /*************************************************************************** | |
100 ReadHeader() reads a header (if it exists ) from the file into | |
101 memory and returns a pointer to the header in memory allocated for | |
102 storing the header. It returns a null pointer if no header is found. | |
103 ****************************************************************************/ | |
104 char *ReadHeader( fp ) | |
105 FILE *fp ; | |
106 { | |
107 static char header_string[] = HEADER_STRING ; | |
108 static char header_start[] = HEADER_START ; | |
109 unsigned header_length ; | |
110 char *header ; | |
111 | |
112 if( fread( header_string, sizeof ( *header_string ), STRSIZE( header_string ), fp ) == STRSIZE( header_string ) | |
113 && strncmp( header_string, header_start, STRSIZE( header_start ) ) == 0 ) { | |
114 | |
115 /* header located - remove carriage return */ | |
116 | |
117 header_length = atoi( header_string + STRSIZE( header_start ) ) ; | |
118 | |
119 header = malloc( header_length ) ; | |
120 | |
121 if( header != (char *) 0 ) { | |
122 (void) strcpy( header, header_string ) ; | |
123 (void) fread( header + STRSIZE( header_string ), sizeof ( *header_string ), (int) header_length - STRSIZE( header_string ), fp ) ; | |
124 } | |
125 | |
126 return ( header ) ; | |
127 } | |
128 else { | |
129 /* header not present */ | |
130 | |
131 (void) fseek( fp, 0l, 0 ) ; | |
132 | |
133 return ( (char *) 0 ) ; | |
134 } | |
135 } | |
136 | |
137 /*************************************************************************** | |
138 WriteHeader() writes the given header on the given file stream. | |
139 ****************************************************************************/ | |
140 WriteHeader(header,fp) | |
141 char *header; | |
142 FILE *fp; | |
143 { | |
144 int header_length, HeaderInt(); | |
145 | |
146 header_length = HeaderInt(header,"header_bytes"); | |
147 fwrite(header,sizeof(char),header_length,fp); | |
148 } | |
149 | |
150 | |
151 /*************************************************************************** | |
152 HeaderString() simply searches through the header for values the user | |
153 requests and returns a pointer to the begining of the value. | |
154 ****************************************************************************/ | |
155 char *HeaderString( header, name ) | |
156 char *header, *name ; | |
157 { | |
158 register char *next_line = header ; | |
159 register int name_len = strlen( name ) ; | |
160 | |
161 do | |
162 if( strncmp( next_line, name, name_len ) == 0 ) { | |
163 | |
164 next_line+=name_len ; | |
165 | |
166 if( *next_line++ == '=' ) | |
167 return ( next_line ) ; | |
168 } | |
169 | |
170 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; | |
171 | |
172 return ( (char *) 0 ) ; | |
173 } | |
174 | |
175 | |
176 /*************************************************************************** | |
177 HeaderStringOnly() returns a pointer to an allocated string that | |
178 contains only the value rather than a pointer to a string that | |
179 includes the all the rest of the header which is what HeaderString() | |
180 returns. | |
181 ****************************************************************************/ | |
182 char *HeaderStringOnly( header, name ) | |
183 char *header, *name ; | |
184 { | |
185 char *value = HeaderString( header, name ) ; | |
186 unsigned value_length ; | |
187 | |
188 if( value != (char *) 0 ) { | |
189 value_length = strchr( value, '\n' ) - value ; | |
190 return ( strncpy( malloc( value_length+1 ), value, (int) value_length ) ) ; | |
191 } | |
192 else | |
193 return ( (char *) 0 ) ; | |
194 } | |
195 | |
196 | |
197 /*************************************************************************** | |
198 HeaderStrings() searches through the header for values the user | |
199 requests and returns a pointer to the begining of the value. | |
200 This is a version of HeaderString() which allows abbreviated names, | |
201 return null ptr if not found or ambiguous. | |
202 ****************************************************************************/ | |
203 char *HeaderStrings( header, name ) | |
204 char *header, *name ; | |
205 { | |
206 register char *next_line = header ; | |
207 register int name_len = strlen( name ) ; | |
208 char *valptr ; | |
209 int count = 0 ; | |
210 | |
211 do | |
212 if( strncmp( next_line, name, name_len ) == 0 ) { | |
213 | |
214 next_line+=name_len ; | |
215 | |
216 if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) { | |
217 | |
218 /* return directly if name matches exactly otherwise wait to check ambiguity */ | |
219 if ( valptr == next_line ) return ( valptr + 1 ) ; | |
220 | |
221 valptr++ ; | |
222 count++ ; | |
223 } | |
224 } | |
225 | |
226 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; | |
227 | |
228 if( count == 1 ) | |
229 return ( valptr ) ; | |
230 else | |
231 return ( (char *) 0 ) ; /* not found or ambiguous */ | |
232 } | |
233 | |
234 | |
235 /*************************************************************************** | |
236 HeaderNameString() returns a pointer to an allocated string that | |
237 contains the full name corresponding to the given name, which can be | |
238 given in abbreviated form provided this is unambiguous. | |
239 Return a null ptr if the name is not found or is ambiguous. | |
240 (This is an amalgam of HeaderString() and HeaderStringOnly() which also | |
241 checks for ambiguity) | |
242 ****************************************************************************/ | |
243 | |
244 char *HeaderNameString( header, name ) | |
245 char *header, *name ; | |
246 { | |
247 register char *next_line = header ; | |
248 register int name_len = strlen( name ) ; | |
249 unsigned name_length ; | |
250 char *nameptr ; | |
251 int count = 0 ; | |
252 | |
253 do | |
254 if( strncmp( next_line, name, name_len ) == 0 ) { | |
255 if ( strchr( next_line, '=' ) != (char *)0 ) { | |
256 nameptr = next_line ; | |
257 | |
258 /* return directly if name matches exactly otherwise wait to check ambiguity */ | |
259 if ( name_len == ( name_length = strchr( next_line, '=' ) - next_line ) ) | |
260 return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ; | |
261 count++ ; | |
262 } | |
263 } | |
264 | |
265 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; | |
266 | |
267 if( count == 1 ) { | |
268 name_length = strchr( nameptr, '=' ) - nameptr ; | |
269 return ( strncpy( malloc( name_length+1 ), nameptr, (int) name_length ) ) ; | |
270 } | |
271 else | |
272 return ( (char *) 0 ) ; /* not found or ambiguous */ | |
273 } | |
274 | |
275 | |
276 /*************************************************************************** | |
277 HeaderValueString() returns a pointer to an allocated string that | |
278 contains the value corresponding to the given name, which can be given | |
279 in abbreviated form provided this is unambiguous. | |
280 Return a null ptr if the name is not found or is ambiguous. | |
281 (This is an amalgam of HeaderString() and HeaderStringOnly() which also | |
282 checks for ambiguity) | |
283 ****************************************************************************/ | |
284 | |
285 char *HeaderValueString( header, name ) | |
286 char *header, *name ; | |
287 { | |
288 register char *next_line = header ; | |
289 register int name_len = strlen( name ) ; | |
290 unsigned value_length ; | |
291 char *valptr ; | |
292 int count = 0 ; | |
293 | |
294 do | |
295 if( strncmp( next_line, name, name_len ) == 0 ) { | |
296 | |
297 next_line+=name_len ; | |
298 | |
299 if ( ( valptr = strchr( next_line, '=' ) ) != (char *)0 ) { | |
300 | |
301 /* return directly if name matches exactly otherwise wait to check ambiguity */ | |
302 if ( valptr == next_line ) { | |
303 valptr++ ; | |
304 value_length = strchr( valptr, '\n' ) - valptr ; | |
305 return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ; | |
306 } | |
307 | |
308 valptr++ ; | |
309 count++ ; | |
310 } | |
311 } | |
312 | |
313 while( ( next_line = strchr( next_line, '\n' ) + 1 ) != (char *) 0 + 1 ) ; | |
314 | |
315 if( count == 1 ) { | |
316 value_length = strchr( valptr, '\n' ) - valptr ; | |
317 return ( strncpy( malloc( value_length+1 ), valptr, (int) value_length ) ) ; | |
318 } | |
319 else | |
320 return ( (char *) 0 ) ; /* not found or ambiguous */ | |
321 } | |
322 | |
323 | |
324 /*************************************************************************** | |
325 HeaderDouble() converts values to Doubles. | |
326 ****************************************************************************/ | |
327 double HeaderDouble( header, name ) | |
328 char *header, *name ; | |
329 { | |
330 char *valuestr ; | |
331 | |
332 if ( (valuestr = HeaderString( header, name )) == (char *) 0) { | |
333 fprintf(stderr,"option %s not found in header\n", name); | |
334 exit(1); | |
335 } | |
336 return ( atof( HeaderString( header, name ) ) ) ; | |
337 } | |
338 | |
339 | |
340 /*************************************************************************** | |
341 HeaderInt() converts values to Ints. | |
342 ****************************************************************************/ | |
343 int HeaderInt( header, name ) | |
344 char *header, *name ; | |
345 { | |
346 char *valuestr ; | |
347 | |
348 if ( (valuestr = HeaderString( header, name )) == (char *) 0) { | |
349 fprintf(stderr,"option %s not found in header\n", name); | |
350 exit(1); | |
351 } | |
352 return ( atoi( valuestr ) ) ; | |
353 } | |
354 | |
355 | |
356 /*************************************************************************** | |
357 HeaderSamplerate() returns the samplerate | |
358 ****************************************************************************/ | |
359 HeaderSamplerate( header ) | |
360 char *header ; | |
361 { | |
362 char *valuestr ; | |
363 | |
364 if ( (valuestr = HeaderStringOnly( header, "samplerate" )) == (char *) 0) { | |
365 fprintf(stderr,"samplerate not found in header\n"); | |
366 exit(1); | |
367 } | |
368 return ( (int)to_Hz( valuestr, 1 ) ) ; | |
369 } | |
370 | |
371 | |
372 /*************************************************************************** | |
373 FreeHeader frees the space allocated for a header by ReadHeader | |
374 ****************************************************************************/ | |
375 void FreeHeader( header ) | |
376 char *header ; | |
377 { | |
378 free( header ) ; | |
379 return ; | |
380 } | |
381 | |
382 | |
383 /*************************************************************************** | |
384 ApplicString() return a ptr to the rest of the header which starts with | |
385 the 3-char application name of the program. | |
386 ***************************************************************************/ | |
387 | |
388 char *ApplicString( header ) | |
389 char *header ; | |
390 { | |
391 char *versionstr, *progname ; | |
392 | |
393 if ( ( versionstr = HeaderString( header, "Version" ) ) == (char *)0 ) | |
394 return (char *)( 0 ) ; /* version string not found in header */ | |
395 | |
396 if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 ) | |
397 return (char *)( 0 ) ; /* program name not found in version string */ | |
398 if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 ) | |
399 return (char *)( 0 ) ; /* application name not found in version string */ | |
400 | |
401 return ( progname ) ; | |
402 } | |
403 | |
404 | |
405 /*************************************************************************** | |
406 Applic() returns the index number to the gen_applics list (see header.h) | |
407 of the application name of the program (the last three letters of its name). | |
408 This is assumed to be delimited by [ ] in the version string in the header. | |
409 Return a -ve number on error. | |
410 ***************************************************************************/ | |
411 | |
412 Applic( header ) | |
413 char *header ; | |
414 { | |
415 char *versionstr, *progname ; | |
416 int i ; | |
417 | |
418 if ( ( versionstr = HeaderStringOnly( header, "Version" ) ) == (char *)0 ) | |
419 return ( -2 ) ; /* version string not found in header */ | |
420 | |
421 if ( ( progname = strchr( versionstr, '[' ) ) == (char *)0 ) | |
422 return ( -3 ) ; /* program name not found in version string */ | |
423 if ( strchr( versionstr, ']' ) - ( progname += 4 ) != 3 ) | |
424 return ( -4 ) ; /* application name not found in version string */ | |
425 for ( i = 0 ; gen_applics[i] != (char *)0 ; i++ ) | |
426 if ( strncmp( gen_applics[i], progname, 3 ) == 0 ) | |
427 return i ; | |
428 | |
429 return ( -1 ) ; /* application name not found in version string */ | |
430 } | |
431 | |
432 | |
433 /************************************************************************** | |
434 | |
435 The table below gives the meaning of the frame parameters for each gen | |
436 program. The frame parameters are frameheight, framewidth, and frames. | |
437 Depending upon the program and the "view", they can mean: | |
438 | |
439 chans = number of filterbank channels. | |
440 length = duration in samples. | |
441 num frames = number of cartoon frames. | |
442 pwidth = "positive width" of auditory image. | |
443 nwidth = "negative width" of auditory image. | |
444 | |
445 In all cases framebytes = frameheight * framewidth * sizeof(short) | |
446 | |
447 The table also shows how the frame parameters relate to the format of the | |
448 display, where each of "num frames" frames of a cartoon is described as a | |
449 matrix of "rows" * "cols". The number of rows describes the vertical direction | |
450 and the number of cols describes the horizontal direction. | |
451 | |
452 | |
453 gen Frame parameters in header Format of display matrix | |
454 --- ------------------------------------- ---------------------------------- | |
455 view height width frames rows cols num frames | |
456 ---- ------ ----- ------ ---- ---- ---------- | |
457 | |
458 wav wave 1 1 length frameheight frames 1 | |
459 | |
460 bmm landscape chans 1 length frameheight frames 1 | |
461 nap landscape chans 1 length frameheight frames 1 | |
462 | |
463 sgm greyscale chans 1 length frameheight frames 1 | |
464 cgm greyscale chans 1 length frameheight frames 1 | |
465 sas greyscale chans 1 length frameheight frames 1 | |
466 | |
467 asa excitation chans 1 num frames framewidth frameheight frames | |
468 epn excitation chans 1 num frames framewidth frameheight frames | |
469 sep excitation chans 1 num frames framewidth frameheight frames | |
470 | |
471 sai landscape chans p+nwidth num frames frameheight framewidth frames | |
472 | |
473 spl spiral chans pwidth num frames frameheight framewidth frames | |
474 | |
475 | |
476 The table below shows the format of the AIM output array for each gen program | |
477 in terms of the frame parameters. | |
478 | |
479 | |
480 gen Output array format Comment | |
481 --- ---------------------------------- ----------------------------- | |
482 wav frames sets of frameheight (=1) array of time samples. | |
483 | |
484 ----------------------------- | |
485 bmm frames sets of frameheight 2-D array by columns, | |
486 nap frames sets of frameheight with lowest centre-frequency | |
487 first in each column. | |
488 sgm frames sets of frameheight | |
489 cgm frames sets of frameheight | |
490 sas frames sets of frameheight | |
491 | |
492 ----------------------------- | |
493 asa frameheight sets of framewidth (=1) array of frequency samples. | |
494 epn frameheight sets of framewidth (=1) | |
495 sep frameheight sets of framewidth (=1) | |
496 | |
497 ----------------------------- | |
498 sai frameheight sets of framewidth 2-D array by rows, | |
499 with lowest centre-frequency | |
500 spl frameheight sets of framewidth row first in each frame. | |
501 | |
502 | |
503 The gen programs group into five format types each with a particular | |
504 interpretation of it's frame parameters, it's output array format, and it's | |
505 "view". These are defined (in header.h) as: | |
506 | |
507 Format gen programs | |
508 ------ -------------- | |
509 WAV wav | |
510 NAP bmm, nap | |
511 SGM sgm, cgm, sas | |
512 EPN asa, epn, sep | |
513 SAI sai, spl | |
514 | |
515 | |
516 | |
517 | |
518 | |
519 ***************************************************************************/ | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 /************************************************************************** | |
526 Format() returns the index number to the gen_formats list (see header.h) | |
527 of the given application number (eg returned by Applic()). | |
528 0 = wave format (array of time points) | |
529 1 = nap format (by columns, lowest centre-frequency first in each column) | |
530 2 = sgm format (by columns, lowest centre-frequency first in each column) | |
531 3 = epn format (array of frequency points per frame) | |
532 4 = sai format (by rows, lowest centre-frequency row first per frame) | |
533 ***************************************************************************/ | |
534 | |
535 Format( applic ) | |
536 int applic ; | |
537 { | |
538 switch ( applic ) { | |
539 | |
540 case 0 : return ( 0 ) ; | |
541 | |
542 case 1 : case 2 : case 3 : | |
543 case 4 : case 5 : case 6 : | |
544 case 7 : return ( 1 ) ; | |
545 | |
546 case 8 : case 9 : case 10: return ( 2 ) ; | |
547 | |
548 case 11: case 12: case 13: return ( 3 ) ; | |
549 | |
550 case 14: case 15: return ( 4 ) ; | |
551 | |
552 default : fprintf( stderr,"unknown application index number\n" ) ; | |
553 exit( 1 ) ; | |
554 } | |
555 } | |
556 | |
557 | |
558 /************************************************************************** | |
559 frame_to_matrix() | |
560 Given the format number (see: Format(), Applic() and the gen_formats list | |
561 in header.h), and the frameheight, framewidth, and frames, | |
562 return the format of the frames in terms of the number of rows | |
563 (ie. channels) and columns (ie. samples) per frame, and the number of | |
564 such frames, via the given addresses. | |
565 The number of bytes per frame is then = rows * cols * 2. | |
566 ***************************************************************************/ | |
567 | |
568 frame_to_matrix( format, rows, cols, numframes, frameheight, framewidth, frames ) | |
569 int format, *rows, *cols, *numframes, frameheight, framewidth, frames ; | |
570 { | |
571 switch ( format ) { | |
572 case 0 : *rows = 1 ; /* wav format */ | |
573 *cols = frames ; | |
574 *numframes = 1 ; | |
575 break ; | |
576 | |
577 case 1 : *rows = frameheight ; /* nap format */ | |
578 *cols = frames ; | |
579 *numframes = 1 ; | |
580 break ; | |
581 | |
582 case 2 : *rows = frameheight ; /* sgm format */ | |
583 *cols = frames ; | |
584 *numframes = 1 ; | |
585 break ; | |
586 | |
587 case 3 : *rows = 1 ; /* epn format */ | |
588 *cols = frameheight ; | |
589 *numframes = frames ; | |
590 break ; | |
591 | |
592 case 4 : *rows = frameheight ; /* sai format */ | |
593 *cols = framewidth ; | |
594 *numframes = frames ; | |
595 break ; | |
596 | |
597 default : fprintf( stderr,"unknown format number\n" ) ; | |
598 exit( 1 ) ; | |
599 } | |
600 } | |
601 | |
602 | |
603 /************************************************************************** | |
604 matrix_to_frame() | |
605 Inverse of frame_to_matrix(). | |
606 Given the format number and the format in terms of the number of rows and | |
607 columns per frame and the number of such frames, return the frameheight, | |
608 framewidth and frames via the given addresses. | |
609 ***************************************************************************/ | |
610 | |
611 matrix_to_frame( format, rows, cols, numframes, frameheight, framewidth, frames ) | |
612 int format, rows, cols, numframes, *frameheight, *framewidth, *frames ; | |
613 { | |
614 switch ( format ) { | |
615 case 0 : *frameheight = 1 ; /* wav format */ | |
616 *framewidth = 1 ; | |
617 *frames = cols ; | |
618 break ; | |
619 | |
620 case 1 : *frameheight = rows ; /* nap format */ | |
621 *framewidth = 1 ; | |
622 *frames = cols ; | |
623 break ; | |
624 | |
625 case 2 : *frameheight = rows ; /* sgm format */ | |
626 *framewidth = 1 ; | |
627 *frames = cols ; | |
628 break ; | |
629 | |
630 case 3 : *frameheight = cols ; /* epn format */ | |
631 *framewidth = 1 ; | |
632 *frames = numframes ; | |
633 break ; | |
634 | |
635 case 4 : *frameheight = rows ; /* sai format */ | |
636 *framewidth = cols ; | |
637 *frames = numframes ; | |
638 break ; | |
639 | |
640 default : fprintf( stderr,"unknown format number\n" ) ; | |
641 exit( 1 ) ; | |
642 } | |
643 } | |
644 |