Mercurial > hg > aim92
comparison tools/acgram.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 acgram.c Autocorrelogram program by Michael Allerhand. | |
3 ---------- | |
4 | |
5 Short-time autocorrelation function applied to each row of input frames. | |
6 Output frames consist of row-wise autocorrelation coefficients. | |
7 The routine acf() uses an fft to compute the array of lagged products | |
8 which is the autocovariance function. An optional normalization (dividing | |
9 each coefficient by the zeroth coefficient) produces the autocorrelation | |
10 function, (and this is then scaled up to the range [0-5000]). | |
11 | |
12 Input/output: | |
13 Read a header and frame in NAP format. | |
14 Write a header, (constructed from the original input header), and a | |
15 succession of frames in SAI format. | |
16 | |
17 The input file is interpreted as one large frame in NAP format to be | |
18 divided into input frames, each to be processed and output in SAI format. | |
19 | |
20 The options "start" and "length" specify the input file. | |
21 The special option value length=max specifies all the input file from | |
22 the given start to its end. | |
23 | |
24 The options "width" and "frstep" specify the input frames. | |
25 The width option is the framewidth of each input frame) and the frstep | |
26 option is the frameshift between input frames in the input file. | |
27 The special option value width=max specifies the input framewidth as equal | |
28 to the given input file length, (and if this is also "max", then the | |
29 input framewidth is the remainder of the input file). | |
30 | |
31 Most options in the input header are copied to the output header. | |
32 This enables options which are needed for the eventual display | |
33 to pass straight through. Some options are set so that they can override | |
34 the input header. For example, the display option is set on to enable | |
35 display even when input has display=off. The animate option can be set on | |
36 even when the input has animate=off. | |
37 Parts of the header are changed for the new sai format: | |
38 (frames, frameshift, framewidth, frameheight, framebytes). | |
39 | |
40 Padding: | |
41 The output framewidth is the given maximum acf lag, which is also the | |
42 number of acf coefficients computed from each row of each input frame. | |
43 The rows of each input frame are padded with zeroes so that the input | |
44 framewidth is at least twice the required output framewidth (max acf lag), | |
45 and also a power of 2. This is because the fft method is "radix-2", and | |
46 because the output acf is symmetrical so that just half the points are | |
47 unique. It is advisable to pad input frames for the additional reason that | |
48 padding counters end-effects (which can be significant with the fft method | |
49 for computing acf). | |
50 | |
51 Therefore each row of each input frame is padded with zeroes to the next | |
52 power of 2 larger than either the original input framewidth or twice the | |
53 max acf lag (whichever is the larger). | |
54 If necessary, extra padding can be enforced using the padding option to | |
55 add extra zeroes, padding to a larger power of 2. | |
56 The amount of extra padding is "exponential" since if the basic padded | |
57 framesize is N, and the padding option is n, then extra padding is to: | |
58 N * 2**n. | |
59 (n=0 by default, so that N is not changed. When n=1 then N is doubled, and | |
60 when n=2 then N is quadrupled, etc.). | |
61 | |
62 | |
63 Examples: | |
64 | |
65 1. Autocorrelogram of a NAP, animated and normalized, with max lag 16ms: | |
66 | |
67 gennap len=128ms output=stdout display=off file | acgram lag=16ms norm=on anim=on > file.sai | |
68 gensai useprev=on headr=5 top=1000 file -(for landscape plot) | |
69 genspl useprev=on headr=5 top=1000 pensize=2 file -(for spiral plot) | |
70 | |
71 2. Autocorrelogram of an SAI: | |
72 (Note that gensai removes file.sai, so you must use some other name, eg foo.sai). | |
73 | |
74 gensai len=64 pwidth=64 nwidth=0 output=stdout display=off file | \ | |
75 saitonap frame=3 | acgram lag=32ms frame=1 > foo.sai | |
76 gensai useprev=on top=1000 headr=5 mag=2 foo | |
77 | |
78 3. Autocorrelogram of a NAP, followed by a cross-channel summary: | |
79 | |
80 gennap len=128ms output=stdout display=off file | acgram lag=16ms scale=0.001 > file.sai | |
81 edframe frame=1 file.sai | integframe var=freq > file.sum | |
82 | |
83 */ | |
84 | |
85 | |
86 #include <stdio.h> | |
87 #include <math.h> | |
88 #include "header.h" | |
89 #include "options.h" | |
90 #include "units.h" | |
91 #include "strmatch.h" | |
92 #include "sigproc.h" | |
93 | |
94 char applic[] = "Autocorrelogram auditory image." ; | |
95 | |
96 static char *helpstr , *debugstr, *dispstr , *anistr , *startstr ; | |
97 static char *lengthstr, *widthstr, *shiftstr, *headerstr, *framestr ; | |
98 static char *normstr , *wstr , *scalestr, *lagstr , *padstr ; | |
99 static char *negstr , *vstr ; | |
100 | |
101 static Options option[] = { | |
102 { "help" , "off" , &helpstr , "help" , DEBUG }, | |
103 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, | |
104 { "display" , "on" , &dispstr , "Display output image." , SETFLAG }, | |
105 { "animate" , "off" , &anistr , "Animate cartoon." , SETFLAG }, | |
106 { "frames" , "1-max" , &framestr , "Select frames inclusively" , VAL }, | |
107 { "Header" , "on" , &headerstr , "Header (for gensai useprevious=on)." , VAL }, | |
108 { "start" , "0" , &startstr , "Start point in i/p file." , VAL }, | |
109 { "length" , "max" , &lengthstr , "Length of i/p file to process." , VAL }, | |
110 { "frstep" , "16ms" , &shiftstr , "Step between input frames." , VAL }, | |
111 { "width" , "32ms" , &widthstr , "Width of input frames." , VAL }, | |
112 { "lag" , "32ms" , &lagstr , "Maximum acf lag (output frame width)." , VAL }, | |
113 { "padding" , "0" , &padstr , "Exponential frame padding" , SVAL }, | |
114 { "window" , "on" , &wstr , "Hamming window" , SETFLAG }, | |
115 { "normalize" , "off" , &normstr , "Normalization" , SETFLAG }, | |
116 { "scale" , "1." , &scalestr , "Scale factor for output" , VAL }, | |
117 { "negative" , "off" , &negstr , "write negative half of acf (zeroth lag on right)", SVAL }, | |
118 { "verbose" , "off" , &vstr , "print at each frame" , SVAL }, | |
119 ( char * ) 0 } ; | |
120 | |
121 | |
122 int samplerate ; | |
123 | |
124 int frameheight, framewidth ; | |
125 int frames, framebytes ; | |
126 int frameshift ; | |
127 | |
128 int Newframeheight, Newframewidth ; | |
129 int Newframes, Newframebytes ; | |
130 int Newframeshift ; | |
131 | |
132 int start, length ; /* Size of input file (num cols) */ | |
133 int frameslength ; /* Length (num cols) of input file to process */ | |
134 | |
135 int zeroes ; | |
136 int window ; /* Flag for Hamming window */ | |
137 float scale ; /* Scale factor for output */ | |
138 int normalize ; /* Flag to normalize acf */ | |
139 int negative ; | |
140 int Verbose ; | |
141 | |
142 short *file ; /* Input file (NAP format) */ | |
143 float *W ; /* Hamming window for fft */ | |
144 float *buf ; /* fft working space */ | |
145 | |
146 | |
147 main(argc, argv) | |
148 int argc ; | |
149 char *argv[] ; | |
150 { | |
151 FILE *fp ; | |
152 char *header, *SaiHeader(); | |
153 char *versionstr, c ; | |
154 int startbytes, framebyteshift ; | |
155 short *frame, *endframe ; | |
156 int i, a, b ; | |
157 float acgram(), f, newscale = 1. ; | |
158 | |
159 fp = openopts( option,argc,argv ) ; | |
160 if ( !isoff( helpstr ) ) | |
161 helpopts( helpstr, argv[0], applic, option ) ; | |
162 | |
163 window = ison( wstr ) ; | |
164 normalize = ison( normstr ) ; | |
165 negative = ison( negstr ) ; | |
166 Verbose = ison( vstr ) ; | |
167 | |
168 | |
169 /**** parse bounds on number of frames ****/ | |
170 | |
171 if ( selector( framestr, &a, &b ) == 0 ) { | |
172 fprintf(stderr,"acgram: bad frame selector [%s]\n", framestr ) ; | |
173 exit( 1 ) ; | |
174 } | |
175 | |
176 | |
177 /**** Input frame dimensions (from header and options) ****/ | |
178 | |
179 if ((header = ReadHeader(fp)) == (char *) 0 ) { | |
180 fprintf(stderr,"acgram: header not found\n"); | |
181 exit(1); | |
182 } | |
183 | |
184 if ( (versionstr = HeaderString( header, "Version" )) == (char *)0 ) { | |
185 fprintf(stderr,"acgram: model version-number not found in header\n"); | |
186 exit(1); | |
187 } | |
188 | |
189 samplerate = HeaderSamplerate( header ); | |
190 | |
191 /* In NAP format, the size of the 2-D image is given by: */ | |
192 /* frameheight = number of rows (filterbank channels) */ | |
193 /* frames = number of columns (sample points) */ | |
194 | |
195 frameheight = HeaderInt( header, "frameheight" ); | |
196 frames = HeaderInt( header, "frames" ); | |
197 | |
198 if ( ( frameshift = to_p( shiftstr, samplerate ) ) <= 0 ) { | |
199 fprintf(stderr,"acgram: non-positive frstep [%d]\n", frameshift); | |
200 exit(1); | |
201 } | |
202 | |
203 /* calculate start of first frame (in cols) */ | |
204 | |
205 if ( ( start = to_p( startstr, samplerate ) + ( a-1 ) * frameshift ) >= frames ) { | |
206 fprintf(stderr,"acgram: input file too small (%dms) for given framing parameters\n", frames * 1000 / samplerate ); | |
207 exit(1); | |
208 } | |
209 | |
210 /* get length of input file (in cols) and framewidth of input frames */ | |
211 | |
212 if ( ismax( lengthstr ) ) length = frames - start ; | |
213 else length = to_p( lengthstr, samplerate ) - start ; | |
214 | |
215 if ( ismax( widthstr ) ) framewidth = length ; | |
216 else framewidth = to_p( widthstr, samplerate ) ; | |
217 | |
218 if ( length < framewidth ) { | |
219 fprintf(stderr,"acgram: input file too small (%dms) for given framing parameters\n", frames * 1000 / samplerate ); | |
220 exit(1); | |
221 } | |
222 | |
223 /* calculate length (num cols) to process, and the number of frames */ | |
224 | |
225 if ( b==0 ) { | |
226 frameslength = length ; | |
227 Newframes = 1 + ( length - framewidth ) / frameshift ; | |
228 } | |
229 else { | |
230 frameslength = framewidth + ( b-a ) * frameshift ; | |
231 Newframes = b - ( a-1 ) ; | |
232 } | |
233 | |
234 if ( start + frameslength > frames ) { | |
235 fprintf(stderr,"acgram: input file too small (%dms) for requested start and length \n", frames * 1000 / samplerate ); | |
236 exit(1); | |
237 } | |
238 | |
239 framebytes = frameheight * frameslength * sizeof(short) ; | |
240 startbytes = frameheight * start * sizeof(short) ; | |
241 | |
242 | |
243 /**** Output frame dimensions ****/ | |
244 | |
245 Newframeheight = frameheight ; | |
246 Newframewidth = to_p( lagstr, samplerate ); /* Max acf lag */ | |
247 Newframeshift = frameshift ; | |
248 Newframebytes = Newframeheight * Newframewidth * sizeof(short) ; | |
249 | |
250 | |
251 /**** Padding and output scale factor ****/ | |
252 | |
253 if ( ( Newframewidth << 1 ) < framewidth ) | |
254 zeroes = ( getpower( framewidth ) << atoi( padstr ) ) - framewidth ; | |
255 else if ( Newframewidth <= framewidth ) | |
256 zeroes = ( getpower( Newframewidth << 1 ) << atoi( padstr ) ) - framewidth ; | |
257 else { | |
258 fprintf(stderr,"acgram: required max lag [%dms] greater than framewidth [%dms]\n", Newframewidth*1000/samplerate, framewidth*1000/samplerate); | |
259 exit( 1 ) ; | |
260 } | |
261 | |
262 if ( normalize == 0 ) /* no normalize, so divide by length to get average of products */ | |
263 scale = 1./(double)(framewidth + zeroes) * atof( scalestr ) ; | |
264 else | |
265 scale = atof( scalestr ) ; | |
266 | |
267 | |
268 /**** Debug ****/ | |
269 | |
270 if ( ison( debugstr ) ) { | |
271 fprintf(stderr, "Input: frames=%d frameheight=%d frameshift=%d\n", frames, frameheight, frameshift ) ; | |
272 fprintf(stderr, "Sizes: start=%d length=%d framewidth=%d frameslength=%d\n", start, length, framewidth, frameslength ) ; | |
273 fprintf(stderr, "Output: zeroes=%d Newframewidth=%d Newframes=%d \n", zeroes, Newframewidth, Newframes ) ; | |
274 exit( 1 ) ; | |
275 } | |
276 | |
277 | |
278 /**** Allocate space (input file, window coeffs, and fft working space) ****/ | |
279 | |
280 if ( ( file = (short *)malloc( framebytes ) ) == NULL ) { | |
281 fprintf(stderr,"acgram: malloc out of space\n"); | |
282 exit(1); | |
283 } | |
284 | |
285 if ( window ) | |
286 W = hamming( framewidth ) ; | |
287 | |
288 buf = (float *)malloc( ( framewidth + zeroes ) * sizeof(float) ); | |
289 | |
290 | |
291 /**** Write new sai header ****/ | |
292 | |
293 if ( ison( headerstr ) ) | |
294 WriteHeader( SaiHeader(header), stdout ); | |
295 | |
296 | |
297 /**** Seek to start of input file in blocks of framebytes ****/ | |
298 | |
299 for (i=framebytes ; i < startbytes ; i += framebytes) | |
300 if ( fread( file, framebytes, 1, fp ) == NULL ) { | |
301 fprintf(stderr,"acgram: missing data after header\n"); | |
302 exit(1); | |
303 } | |
304 if ( (startbytes -= (i - framebytes)) > 0 ) | |
305 if ( fread( file, startbytes, 1, fp ) == NULL ) { | |
306 fprintf(stderr,"acgram: missing data after header\n"); | |
307 exit(1); | |
308 } | |
309 | |
310 | |
311 /**** Read framebytes of i/p file ****/ | |
312 | |
313 if ( fread( file, framebytes, 1, fp ) == NULL ) { | |
314 fprintf(stderr,"acgram: missing data after header\n"); | |
315 exit(1); | |
316 } | |
317 | |
318 | |
319 /**** Process frames ****/ | |
320 | |
321 framebyteshift = frameshift * frameheight ; | |
322 endframe = file + Newframes * framebyteshift ; | |
323 | |
324 for ( frame = file, i=1 ; frame < endframe ; frame += framebyteshift, i++ ) { | |
325 if ( Verbose ) | |
326 fprintf(stderr,"acgram: %d / %d [%dms]\n", i, Newframes, start*1000/samplerate ); | |
327 if ( ( f = acgram( frame ) ) < newscale ) | |
328 newscale = f ; | |
329 start += frameshift ; | |
330 } | |
331 | |
332 fclose(fp); | |
333 | |
334 if ( newscale < 1. ) { | |
335 fprintf( stderr, "Warning: 16-bit overflow during acgram. " ) ; | |
336 if ( normalize == 0 ) | |
337 fprintf( stderr, "Try scale<%f\n", newscale * (float)(framewidth + zeroes) ) ; | |
338 else | |
339 fprintf( stderr, "Try scale<%f\n", newscale ) ; | |
340 } | |
341 | |
342 if ( Verbose ) | |
343 fprintf(stderr,"acgram: done\n" ) ; | |
344 } | |
345 | |
346 | |
347 /************************** Autocorrelation function ***********************/ | |
348 | |
349 /* Call acf for each row in the SAI frame */ | |
350 | |
351 float acgram( frame ) | |
352 short *frame ; | |
353 { | |
354 register int i, j, row, col ; | |
355 float writebuf(), f, newscale = 1. ; | |
356 | |
357 for ( row=0 ; row < frameheight ; row++ ) { | |
358 | |
359 if ( window ) | |
360 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight ) | |
361 buf[col] = frame[i] * W[col] ; | |
362 else | |
363 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight ) | |
364 buf[col] = frame[i] ; | |
365 | |
366 for ( j=0 ; j<zeroes ; j++ ) /* padding */ | |
367 buf[col++] = 0 ; | |
368 | |
369 acf( buf, framewidth+zeroes ) ; | |
370 | |
371 if ( normalize == 0 ) | |
372 f = writebuf( buf, Newframewidth, scale ) ; | |
373 else | |
374 f = writebuf( buf, Newframewidth, scale/buf[0] ) ; | |
375 | |
376 if ( f < newscale ) | |
377 newscale = f ; | |
378 } | |
379 | |
380 return ( newscale ) ; | |
381 } | |
382 | |
383 | |
384 /********************** Write o/p ****************************************/ | |
385 | |
386 float writebuf( buf, n, scale ) /* write buffer as scaled shorts */ | |
387 float *buf ; | |
388 int n ; | |
389 float scale ; | |
390 { | |
391 register int i ; | |
392 short p ; | |
393 float newscale ; | |
394 | |
395 if ( !negative ) { /* usual acf (ie. positive half, with zeroth lag on left) */ | |
396 for (i=0 ; i < n ; i++) { | |
397 | |
398 newscale = check_overflow( buf[i], scale, 1 ) ; | |
399 | |
400 p = (short)( buf[i] * scale ) ; | |
401 fwrite( &p, sizeof(short), 1, stdout ) ; | |
402 } | |
403 } | |
404 | |
405 else { /* write negative half of acf (zeroth lag on right) */ | |
406 for ( i = n-1 ; i >= 0 ; --i ) { | |
407 | |
408 newscale = check_overflow( buf[i], scale, 1 ) ; | |
409 | |
410 p = (short)( buf[i] * scale ) ; | |
411 fwrite( &p, sizeof(short), 1, stdout ) ; | |
412 } | |
413 } | |
414 return ( newscale ) ; | |
415 } | |
416 | |
417 | |
418 | |
419 /************************ Output header ************************************/ | |
420 /* | |
421 First create a new header with | |
422 nwidth_aid | |
423 pwidth_aid | |
424 frstep_aid | |
425 Then copy the original nap header into the sai header, changing in order: | |
426 frames | |
427 frameshift | |
428 framewidth | |
429 frameheight | |
430 framebytes | |
431 animate | |
432 display | |
433 Then change applic name [gennap] to [gensai] in the Version string. | |
434 Finally, update the new header_bytes, and return the new header. | |
435 */ | |
436 | |
437 char *SaiHeader( napheader ) | |
438 char *napheader ; | |
439 { | |
440 char *saiheader; | |
441 char *p0, *p1, *p2, *s, str[64]; | |
442 | |
443 saiheader = (char *)malloc( strlen(napheader) + 128 ) ; | |
444 | |
445 p0 = saiheader ; | |
446 p1 = napheader ; | |
447 | |
448 | |
449 /** copy initial header bytes **/ | |
450 | |
451 p2 = HeaderString( napheader , "header_bytes" ) ; | |
452 while( p1 < p2 ) | |
453 *p0++ = *p1++ ; | |
454 while (*p1 != '\n') | |
455 *p0++ = *p1++ ; | |
456 *p0++ = *p1++ ; | |
457 | |
458 | |
459 /** insert nwidth_aid at top of new header **/ | |
460 | |
461 sprintf(str,"nwidth_aid=0\n"); | |
462 for (s = str ; *s != '\n' ; ) | |
463 *p0++ = *s++; | |
464 *p0++ = *s; | |
465 | |
466 | |
467 /** insert pwidth_aid into new header **/ | |
468 | |
469 sprintf(str,"pwidth_aid=%dms\n", (int)(1000*((float)Newframewidth/samplerate)) ); | |
470 for (s = str ; *s != '\n' ; ) | |
471 *p0++ = *s++; | |
472 *p0++ = *s; | |
473 | |
474 | |
475 /** insert frstep_aid into new header **/ | |
476 | |
477 sprintf(str,"frstep_aid=%dms\n", (int)(1000*((float)frameshift/samplerate)) ); | |
478 for (s = str ; *s != '\n' ; ) | |
479 *p0++ = *s++; | |
480 *p0++ = *s; | |
481 | |
482 | |
483 /** copy up to frames **/ | |
484 | |
485 p2 = HeaderString( napheader , "frames" ) ; | |
486 while( p1 < p2 ) | |
487 *p0++ = *p1++ ; | |
488 | |
489 sprintf(str,"%d\n", Newframes); | |
490 for (s = str ; *s != '\n' ; ) | |
491 *p0++ = *s++; | |
492 *p0++ = *s; | |
493 while (*p1 != '\n') | |
494 *p1++; | |
495 *p1++; | |
496 | |
497 | |
498 /** copy up to frameshift **/ | |
499 | |
500 p2 = HeaderString( napheader , "frameshift" ) ; | |
501 while ( p1 < p2 ) | |
502 *p0++ = *p1++ ; | |
503 | |
504 sprintf(str,"%d\n", Newframeshift); | |
505 for (s = str ; *s != '\n' ; ) | |
506 *p0++ = *s++; | |
507 *p0++ = *s; | |
508 while (*p1 != '\n') | |
509 *p1++; | |
510 *p1++; | |
511 | |
512 | |
513 /** copy up to framewidth **/ | |
514 | |
515 p2 = HeaderString( napheader , "framewidth" ) ; | |
516 while ( p1 < p2 ) | |
517 *p0++ = *p1++ ; | |
518 | |
519 sprintf(str,"%d\n", Newframewidth); | |
520 for (s = str ; *s != '\n' ; ) | |
521 *p0++ = *s++; | |
522 *p0++ = *s; | |
523 while (*p1 != '\n') | |
524 *p1++; | |
525 *p1++; | |
526 | |
527 | |
528 /** copy up to frameheight **/ | |
529 | |
530 p2 = HeaderString( napheader , "frameheight" ) ; | |
531 while ( p1 < p2 ) | |
532 *p0++ = *p1++ ; | |
533 | |
534 sprintf(str,"%d\n", Newframeheight); | |
535 for (s = str ; *s != '\n' ; ) | |
536 *p0++ = *s++; | |
537 *p0++ = *s; | |
538 while (*p1 != '\n') | |
539 *p1++; | |
540 *p1++; | |
541 | |
542 | |
543 /** copy up to framebytes **/ | |
544 | |
545 p2 = HeaderString( napheader , "framebytes" ) ; | |
546 while ( p1 < p2 ) | |
547 *p0++ = *p1++ ; | |
548 | |
549 sprintf(str,"%d\n", Newframebytes); | |
550 for (s = str ; *s != '\n' ; ) | |
551 *p0++ = *s++; | |
552 *p0++ = *s; | |
553 while (*p1 != '\n') | |
554 *p1++; | |
555 *p1++; | |
556 | |
557 | |
558 /** copy up to animate_ctn **/ | |
559 | |
560 p2 = HeaderString( napheader , "animate_ctn" ) ; | |
561 while ( p1 < p2 ) | |
562 *p0++ = *p1++ ; | |
563 | |
564 sprintf(str,"%s\n", anistr ); | |
565 for (s = str ; *s != '\n' ; ) | |
566 *p0++ = *s++; | |
567 *p0++ = *s; | |
568 while (*p1 != '\n') | |
569 *p1++; | |
570 *p1++; | |
571 | |
572 | |
573 /** copy up to display **/ | |
574 | |
575 p2 = HeaderString( napheader , "display" ) ; | |
576 while ( p1 < p2 ) | |
577 *p0++ = *p1++ ; | |
578 | |
579 sprintf(str,"%s\n", dispstr ); | |
580 for (s = str ; *s != '\n' ; ) | |
581 *p0++ = *s++; | |
582 *p0++ = *s; | |
583 while (*p1 != '\n') | |
584 *p1++; | |
585 *p1++; | |
586 | |
587 | |
588 /** copy rest of header **/ | |
589 | |
590 p2 = HeaderString( napheader , "Version" ) ; | |
591 while ( p1 < p2 ) | |
592 *p0++ = *p1++ ; | |
593 | |
594 while (*p1 != ']') /* change applic name [gennap] to [gensai] */ | |
595 *p0++ = *p1++ ; | |
596 *(p0-3) = 's' ; | |
597 *(p0-2) = 'a' ; | |
598 *(p0-1) = 'i' ; | |
599 while (*p1 != '\n') | |
600 *p0++ = *p1++ ; | |
601 *p0++ = *p1++ ; | |
602 | |
603 | |
604 /** update header_bytes **/ | |
605 | |
606 sprintf(str, "%0*d", 7, p0-saiheader); | |
607 p0 = HeaderString( saiheader , "header_bytes" ) ; | |
608 s = str; | |
609 while(*p0 != '\n') | |
610 *p0++ = *s++ ; | |
611 | |
612 | |
613 return saiheader; | |
614 } | |
615 | |
616 |