tomwalters@0: /* tomwalters@0: acgram.c Autocorrelogram program by Michael Allerhand. tomwalters@0: ---------- tomwalters@0: tomwalters@0: Short-time autocorrelation function applied to each row of input frames. tomwalters@0: Output frames consist of row-wise autocorrelation coefficients. tomwalters@0: The routine acf() uses an fft to compute the array of lagged products tomwalters@0: which is the autocovariance function. An optional normalization (dividing tomwalters@0: each coefficient by the zeroth coefficient) produces the autocorrelation tomwalters@0: function, (and this is then scaled up to the range [0-5000]). tomwalters@0: tomwalters@0: Input/output: tomwalters@0: Read a header and frame in NAP format. tomwalters@0: Write a header, (constructed from the original input header), and a tomwalters@0: succession of frames in SAI format. tomwalters@0: tomwalters@0: The input file is interpreted as one large frame in NAP format to be tomwalters@0: divided into input frames, each to be processed and output in SAI format. tomwalters@0: tomwalters@0: The options "start" and "length" specify the input file. tomwalters@0: The special option value length=max specifies all the input file from tomwalters@0: the given start to its end. tomwalters@0: tomwalters@0: The options "width" and "frstep" specify the input frames. tomwalters@0: The width option is the framewidth of each input frame) and the frstep tomwalters@0: option is the frameshift between input frames in the input file. tomwalters@0: The special option value width=max specifies the input framewidth as equal tomwalters@0: to the given input file length, (and if this is also "max", then the tomwalters@0: input framewidth is the remainder of the input file). tomwalters@0: tomwalters@0: Most options in the input header are copied to the output header. tomwalters@0: This enables options which are needed for the eventual display tomwalters@0: to pass straight through. Some options are set so that they can override tomwalters@0: the input header. For example, the display option is set on to enable tomwalters@0: display even when input has display=off. The animate option can be set on tomwalters@0: even when the input has animate=off. tomwalters@0: Parts of the header are changed for the new sai format: tomwalters@0: (frames, frameshift, framewidth, frameheight, framebytes). tomwalters@0: tomwalters@0: Padding: tomwalters@0: The output framewidth is the given maximum acf lag, which is also the tomwalters@0: number of acf coefficients computed from each row of each input frame. tomwalters@0: The rows of each input frame are padded with zeroes so that the input tomwalters@0: framewidth is at least twice the required output framewidth (max acf lag), tomwalters@0: and also a power of 2. This is because the fft method is "radix-2", and tomwalters@0: because the output acf is symmetrical so that just half the points are tomwalters@0: unique. It is advisable to pad input frames for the additional reason that tomwalters@0: padding counters end-effects (which can be significant with the fft method tomwalters@0: for computing acf). tomwalters@0: tomwalters@0: Therefore each row of each input frame is padded with zeroes to the next tomwalters@0: power of 2 larger than either the original input framewidth or twice the tomwalters@0: max acf lag (whichever is the larger). tomwalters@0: If necessary, extra padding can be enforced using the padding option to tomwalters@0: add extra zeroes, padding to a larger power of 2. tomwalters@0: The amount of extra padding is "exponential" since if the basic padded tomwalters@0: framesize is N, and the padding option is n, then extra padding is to: tomwalters@0: N * 2**n. tomwalters@0: (n=0 by default, so that N is not changed. When n=1 then N is doubled, and tomwalters@0: when n=2 then N is quadrupled, etc.). tomwalters@0: tomwalters@0: tomwalters@0: Examples: tomwalters@0: tomwalters@0: 1. Autocorrelogram of a NAP, animated and normalized, with max lag 16ms: tomwalters@0: tomwalters@0: gennap len=128ms output=stdout display=off file | acgram lag=16ms norm=on anim=on > file.sai tomwalters@0: gensai useprev=on headr=5 top=1000 file -(for landscape plot) tomwalters@0: genspl useprev=on headr=5 top=1000 pensize=2 file -(for spiral plot) tomwalters@0: tomwalters@0: 2. Autocorrelogram of an SAI: tomwalters@0: (Note that gensai removes file.sai, so you must use some other name, eg foo.sai). tomwalters@0: tomwalters@0: gensai len=64 pwidth=64 nwidth=0 output=stdout display=off file | \ tomwalters@0: saitonap frame=3 | acgram lag=32ms frame=1 > foo.sai tomwalters@0: gensai useprev=on top=1000 headr=5 mag=2 foo tomwalters@0: tomwalters@0: 3. Autocorrelogram of a NAP, followed by a cross-channel summary: tomwalters@0: tomwalters@0: gennap len=128ms output=stdout display=off file | acgram lag=16ms scale=0.001 > file.sai tomwalters@0: edframe frame=1 file.sai | integframe var=freq > file.sum tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include "header.h" tomwalters@0: #include "options.h" tomwalters@0: #include "units.h" tomwalters@0: #include "strmatch.h" tomwalters@0: #include "sigproc.h" tomwalters@0: tomwalters@0: char applic[] = "Autocorrelogram auditory image." ; tomwalters@0: tomwalters@0: static char *helpstr , *debugstr, *dispstr , *anistr , *startstr ; tomwalters@0: static char *lengthstr, *widthstr, *shiftstr, *headerstr, *framestr ; tomwalters@0: static char *normstr , *wstr , *scalestr, *lagstr , *padstr ; tomwalters@0: static char *negstr , *vstr ; tomwalters@0: tomwalters@0: static Options option[] = { tomwalters@0: { "help" , "off" , &helpstr , "help" , DEBUG }, tomwalters@0: { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, tomwalters@0: { "display" , "on" , &dispstr , "Display output image." , SETFLAG }, tomwalters@0: { "animate" , "off" , &anistr , "Animate cartoon." , SETFLAG }, tomwalters@0: { "frames" , "1-max" , &framestr , "Select frames inclusively" , VAL }, tomwalters@0: { "Header" , "on" , &headerstr , "Header (for gensai useprevious=on)." , VAL }, tomwalters@0: { "start" , "0" , &startstr , "Start point in i/p file." , VAL }, tomwalters@0: { "length" , "max" , &lengthstr , "Length of i/p file to process." , VAL }, tomwalters@0: { "frstep" , "16ms" , &shiftstr , "Step between input frames." , VAL }, tomwalters@0: { "width" , "32ms" , &widthstr , "Width of input frames." , VAL }, tomwalters@0: { "lag" , "32ms" , &lagstr , "Maximum acf lag (output frame width)." , VAL }, tomwalters@0: { "padding" , "0" , &padstr , "Exponential frame padding" , SVAL }, tomwalters@0: { "window" , "on" , &wstr , "Hamming window" , SETFLAG }, tomwalters@0: { "normalize" , "off" , &normstr , "Normalization" , SETFLAG }, tomwalters@0: { "scale" , "1." , &scalestr , "Scale factor for output" , VAL }, tomwalters@0: { "negative" , "off" , &negstr , "write negative half of acf (zeroth lag on right)", SVAL }, tomwalters@0: { "verbose" , "off" , &vstr , "print at each frame" , SVAL }, tomwalters@0: ( char * ) 0 } ; tomwalters@0: tomwalters@0: tomwalters@0: int samplerate ; tomwalters@0: tomwalters@0: int frameheight, framewidth ; tomwalters@0: int frames, framebytes ; tomwalters@0: int frameshift ; tomwalters@0: tomwalters@0: int Newframeheight, Newframewidth ; tomwalters@0: int Newframes, Newframebytes ; tomwalters@0: int Newframeshift ; tomwalters@0: tomwalters@0: int start, length ; /* Size of input file (num cols) */ tomwalters@0: int frameslength ; /* Length (num cols) of input file to process */ tomwalters@0: tomwalters@0: int zeroes ; tomwalters@0: int window ; /* Flag for Hamming window */ tomwalters@0: float scale ; /* Scale factor for output */ tomwalters@0: int normalize ; /* Flag to normalize acf */ tomwalters@0: int negative ; tomwalters@0: int Verbose ; tomwalters@0: tomwalters@0: short *file ; /* Input file (NAP format) */ tomwalters@0: float *W ; /* Hamming window for fft */ tomwalters@0: float *buf ; /* fft working space */ tomwalters@0: tomwalters@0: tomwalters@0: main(argc, argv) tomwalters@0: int argc ; tomwalters@0: char *argv[] ; tomwalters@0: { tomwalters@0: FILE *fp ; tomwalters@0: char *header, *SaiHeader(); tomwalters@0: char *versionstr, c ; tomwalters@0: int startbytes, framebyteshift ; tomwalters@0: short *frame, *endframe ; tomwalters@0: int i, a, b ; tomwalters@0: float acgram(), f, newscale = 1. ; tomwalters@0: tomwalters@0: fp = openopts( option,argc,argv ) ; tomwalters@0: if ( !isoff( helpstr ) ) tomwalters@0: helpopts( helpstr, argv[0], applic, option ) ; tomwalters@0: tomwalters@0: window = ison( wstr ) ; tomwalters@0: normalize = ison( normstr ) ; tomwalters@0: negative = ison( negstr ) ; tomwalters@0: Verbose = ison( vstr ) ; tomwalters@0: tomwalters@0: tomwalters@0: /**** parse bounds on number of frames ****/ tomwalters@0: tomwalters@0: if ( selector( framestr, &a, &b ) == 0 ) { tomwalters@0: fprintf(stderr,"acgram: bad frame selector [%s]\n", framestr ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /**** Input frame dimensions (from header and options) ****/ tomwalters@0: tomwalters@0: if ((header = ReadHeader(fp)) == (char *) 0 ) { tomwalters@0: fprintf(stderr,"acgram: header not found\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: if ( (versionstr = HeaderString( header, "Version" )) == (char *)0 ) { tomwalters@0: fprintf(stderr,"acgram: model version-number not found in header\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: samplerate = HeaderSamplerate( header ); tomwalters@0: tomwalters@0: /* In NAP format, the size of the 2-D image is given by: */ tomwalters@0: /* frameheight = number of rows (filterbank channels) */ tomwalters@0: /* frames = number of columns (sample points) */ tomwalters@0: tomwalters@0: frameheight = HeaderInt( header, "frameheight" ); tomwalters@0: frames = HeaderInt( header, "frames" ); tomwalters@0: tomwalters@0: if ( ( frameshift = to_p( shiftstr, samplerate ) ) <= 0 ) { tomwalters@0: fprintf(stderr,"acgram: non-positive frstep [%d]\n", frameshift); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: /* calculate start of first frame (in cols) */ tomwalters@0: tomwalters@0: if ( ( start = to_p( startstr, samplerate ) + ( a-1 ) * frameshift ) >= frames ) { tomwalters@0: fprintf(stderr,"acgram: input file too small (%dms) for given framing parameters\n", frames * 1000 / samplerate ); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: /* get length of input file (in cols) and framewidth of input frames */ tomwalters@0: tomwalters@0: if ( ismax( lengthstr ) ) length = frames - start ; tomwalters@0: else length = to_p( lengthstr, samplerate ) - start ; tomwalters@0: tomwalters@0: if ( ismax( widthstr ) ) framewidth = length ; tomwalters@0: else framewidth = to_p( widthstr, samplerate ) ; tomwalters@0: tomwalters@0: if ( length < framewidth ) { tomwalters@0: fprintf(stderr,"acgram: input file too small (%dms) for given framing parameters\n", frames * 1000 / samplerate ); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: /* calculate length (num cols) to process, and the number of frames */ tomwalters@0: tomwalters@0: if ( b==0 ) { tomwalters@0: frameslength = length ; tomwalters@0: Newframes = 1 + ( length - framewidth ) / frameshift ; tomwalters@0: } tomwalters@0: else { tomwalters@0: frameslength = framewidth + ( b-a ) * frameshift ; tomwalters@0: Newframes = b - ( a-1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: if ( start + frameslength > frames ) { tomwalters@0: fprintf(stderr,"acgram: input file too small (%dms) for requested start and length \n", frames * 1000 / samplerate ); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: framebytes = frameheight * frameslength * sizeof(short) ; tomwalters@0: startbytes = frameheight * start * sizeof(short) ; tomwalters@0: tomwalters@0: tomwalters@0: /**** Output frame dimensions ****/ tomwalters@0: tomwalters@0: Newframeheight = frameheight ; tomwalters@0: Newframewidth = to_p( lagstr, samplerate ); /* Max acf lag */ tomwalters@0: Newframeshift = frameshift ; tomwalters@0: Newframebytes = Newframeheight * Newframewidth * sizeof(short) ; tomwalters@0: tomwalters@0: tomwalters@0: /**** Padding and output scale factor ****/ tomwalters@0: tomwalters@0: if ( ( Newframewidth << 1 ) < framewidth ) tomwalters@0: zeroes = ( getpower( framewidth ) << atoi( padstr ) ) - framewidth ; tomwalters@0: else if ( Newframewidth <= framewidth ) tomwalters@0: zeroes = ( getpower( Newframewidth << 1 ) << atoi( padstr ) ) - framewidth ; tomwalters@0: else { tomwalters@0: fprintf(stderr,"acgram: required max lag [%dms] greater than framewidth [%dms]\n", Newframewidth*1000/samplerate, framewidth*1000/samplerate); tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: if ( normalize == 0 ) /* no normalize, so divide by length to get average of products */ tomwalters@0: scale = 1./(double)(framewidth + zeroes) * atof( scalestr ) ; tomwalters@0: else tomwalters@0: scale = atof( scalestr ) ; tomwalters@0: tomwalters@0: tomwalters@0: /**** Debug ****/ tomwalters@0: tomwalters@0: if ( ison( debugstr ) ) { tomwalters@0: fprintf(stderr, "Input: frames=%d frameheight=%d frameshift=%d\n", frames, frameheight, frameshift ) ; tomwalters@0: fprintf(stderr, "Sizes: start=%d length=%d framewidth=%d frameslength=%d\n", start, length, framewidth, frameslength ) ; tomwalters@0: fprintf(stderr, "Output: zeroes=%d Newframewidth=%d Newframes=%d \n", zeroes, Newframewidth, Newframes ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /**** Allocate space (input file, window coeffs, and fft working space) ****/ tomwalters@0: tomwalters@0: if ( ( file = (short *)malloc( framebytes ) ) == NULL ) { tomwalters@0: fprintf(stderr,"acgram: malloc out of space\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: if ( window ) tomwalters@0: W = hamming( framewidth ) ; tomwalters@0: tomwalters@0: buf = (float *)malloc( ( framewidth + zeroes ) * sizeof(float) ); tomwalters@0: tomwalters@0: tomwalters@0: /**** Write new sai header ****/ tomwalters@0: tomwalters@0: if ( ison( headerstr ) ) tomwalters@0: WriteHeader( SaiHeader(header), stdout ); tomwalters@0: tomwalters@0: tomwalters@0: /**** Seek to start of input file in blocks of framebytes ****/ tomwalters@0: tomwalters@0: for (i=framebytes ; i < startbytes ; i += framebytes) tomwalters@0: if ( fread( file, framebytes, 1, fp ) == NULL ) { tomwalters@0: fprintf(stderr,"acgram: missing data after header\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: if ( (startbytes -= (i - framebytes)) > 0 ) tomwalters@0: if ( fread( file, startbytes, 1, fp ) == NULL ) { tomwalters@0: fprintf(stderr,"acgram: missing data after header\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /**** Read framebytes of i/p file ****/ tomwalters@0: tomwalters@0: if ( fread( file, framebytes, 1, fp ) == NULL ) { tomwalters@0: fprintf(stderr,"acgram: missing data after header\n"); tomwalters@0: exit(1); tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /**** Process frames ****/ tomwalters@0: tomwalters@0: framebyteshift = frameshift * frameheight ; tomwalters@0: endframe = file + Newframes * framebyteshift ; tomwalters@0: tomwalters@0: for ( frame = file, i=1 ; frame < endframe ; frame += framebyteshift, i++ ) { tomwalters@0: if ( Verbose ) tomwalters@0: fprintf(stderr,"acgram: %d / %d [%dms]\n", i, Newframes, start*1000/samplerate ); tomwalters@0: if ( ( f = acgram( frame ) ) < newscale ) tomwalters@0: newscale = f ; tomwalters@0: start += frameshift ; tomwalters@0: } tomwalters@0: tomwalters@0: fclose(fp); tomwalters@0: tomwalters@0: if ( newscale < 1. ) { tomwalters@0: fprintf( stderr, "Warning: 16-bit overflow during acgram. " ) ; tomwalters@0: if ( normalize == 0 ) tomwalters@0: fprintf( stderr, "Try scale<%f\n", newscale * (float)(framewidth + zeroes) ) ; tomwalters@0: else tomwalters@0: fprintf( stderr, "Try scale<%f\n", newscale ) ; tomwalters@0: } tomwalters@0: tomwalters@0: if ( Verbose ) tomwalters@0: fprintf(stderr,"acgram: done\n" ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /************************** Autocorrelation function ***********************/ tomwalters@0: tomwalters@0: /* Call acf for each row in the SAI frame */ tomwalters@0: tomwalters@0: float acgram( frame ) tomwalters@0: short *frame ; tomwalters@0: { tomwalters@0: register int i, j, row, col ; tomwalters@0: float writebuf(), f, newscale = 1. ; tomwalters@0: tomwalters@0: for ( row=0 ; row < frameheight ; row++ ) { tomwalters@0: tomwalters@0: if ( window ) tomwalters@0: for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight ) tomwalters@0: buf[col] = frame[i] * W[col] ; tomwalters@0: else tomwalters@0: for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight ) tomwalters@0: buf[col] = frame[i] ; tomwalters@0: tomwalters@0: for ( j=0 ; j= 0 ; --i ) { tomwalters@0: tomwalters@0: newscale = check_overflow( buf[i], scale, 1 ) ; tomwalters@0: tomwalters@0: p = (short)( buf[i] * scale ) ; tomwalters@0: fwrite( &p, sizeof(short), 1, stdout ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: return ( newscale ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /************************ Output header ************************************/ tomwalters@0: /* tomwalters@0: First create a new header with tomwalters@0: nwidth_aid tomwalters@0: pwidth_aid tomwalters@0: frstep_aid tomwalters@0: Then copy the original nap header into the sai header, changing in order: tomwalters@0: frames tomwalters@0: frameshift tomwalters@0: framewidth tomwalters@0: frameheight tomwalters@0: framebytes tomwalters@0: animate tomwalters@0: display tomwalters@0: Then change applic name [gennap] to [gensai] in the Version string. tomwalters@0: Finally, update the new header_bytes, and return the new header. tomwalters@0: */ tomwalters@0: tomwalters@0: char *SaiHeader( napheader ) tomwalters@0: char *napheader ; tomwalters@0: { tomwalters@0: char *saiheader; tomwalters@0: char *p0, *p1, *p2, *s, str[64]; tomwalters@0: tomwalters@0: saiheader = (char *)malloc( strlen(napheader) + 128 ) ; tomwalters@0: tomwalters@0: p0 = saiheader ; tomwalters@0: p1 = napheader ; tomwalters@0: tomwalters@0: tomwalters@0: /** copy initial header bytes **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "header_bytes" ) ; tomwalters@0: while( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p0++ = *p1++ ; tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: tomwalters@0: /** insert nwidth_aid at top of new header **/ tomwalters@0: tomwalters@0: sprintf(str,"nwidth_aid=0\n"); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: tomwalters@0: tomwalters@0: /** insert pwidth_aid into new header **/ tomwalters@0: tomwalters@0: sprintf(str,"pwidth_aid=%dms\n", (int)(1000*((float)Newframewidth/samplerate)) ); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: tomwalters@0: tomwalters@0: /** insert frstep_aid into new header **/ tomwalters@0: tomwalters@0: sprintf(str,"frstep_aid=%dms\n", (int)(1000*((float)frameshift/samplerate)) ); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to frames **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "frames" ) ; tomwalters@0: while( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%d\n", Newframes); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to frameshift **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "frameshift" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%d\n", Newframeshift); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to framewidth **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "framewidth" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%d\n", Newframewidth); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to frameheight **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "frameheight" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%d\n", Newframeheight); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to framebytes **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "framebytes" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%d\n", Newframebytes); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to animate_ctn **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "animate_ctn" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%s\n", anistr ); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy up to display **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "display" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: sprintf(str,"%s\n", dispstr ); tomwalters@0: for (s = str ; *s != '\n' ; ) tomwalters@0: *p0++ = *s++; tomwalters@0: *p0++ = *s; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p1++; tomwalters@0: *p1++; tomwalters@0: tomwalters@0: tomwalters@0: /** copy rest of header **/ tomwalters@0: tomwalters@0: p2 = HeaderString( napheader , "Version" ) ; tomwalters@0: while ( p1 < p2 ) tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: while (*p1 != ']') /* change applic name [gennap] to [gensai] */ tomwalters@0: *p0++ = *p1++ ; tomwalters@0: *(p0-3) = 's' ; tomwalters@0: *(p0-2) = 'a' ; tomwalters@0: *(p0-1) = 'i' ; tomwalters@0: while (*p1 != '\n') tomwalters@0: *p0++ = *p1++ ; tomwalters@0: *p0++ = *p1++ ; tomwalters@0: tomwalters@0: tomwalters@0: /** update header_bytes **/ tomwalters@0: tomwalters@0: sprintf(str, "%0*d", 7, p0-saiheader); tomwalters@0: p0 = HeaderString( saiheader , "header_bytes" ) ; tomwalters@0: s = str; tomwalters@0: while(*p0 != '\n') tomwalters@0: *p0++ = *s++ ; tomwalters@0: tomwalters@0: tomwalters@0: return saiheader; tomwalters@0: } tomwalters@0: tomwalters@0: