Mercurial > hg > aim92
diff tools/naptosai.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/naptosai.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,362 @@ +/* + naptosai.c NAP to SAI format conversion. + ------------ + + Read a NAP header and frame. + Write a SAI header, (created from the NAP header). + Write a succession of SAI frames. + + The options "start" and "length" specify the NAP which is input. + The options "width" and "frstep" specify the SAI frames which are output. + + Special option values are: + + length=max Input all the NAP from the given start to its end. + width=max Output framewidth is set equal to the given NAP length, + and if this is also "max", then the framewidth is the + remainder of the NAP. + frstep=0 Output one frame of given width from the given start of + the NAP. + + For example, use naptosai with width=max and frstep=0 to produce one SAI + frame the same size as the input NAP. + +Examples: + + +1. To convert a nap or a bmm output to a single frame of sai output: + +gennap length=64 output=stdout file | naptosai width=32 frstep=0 > file.sai +gensai top=1000 useprevious=on file + +genbmm output=stdout file | naptosai > file.sai +gensai bottom=-100 useprevious=on file + + This uses special case of zero frstep to generate one frame of output with + the given width. The default width is the given length, and the default + length is the remainder of the input file. If the width=length, then the + frstep is zero by default, and therefore the default process, (ie with no + arguments), converts the whole of the input to a single SAI frame. + + Note, certain display parameters have different default values for different + applications. The SAI display parameters should be set to the appropriate + values, in order to plot the SAI on the same scale. For example: + When the source application is NAP, set gensai top=1000 + When the source application is BMM, set gensai bottom=-100 + + +2. To convert a nap output to multiple frames of sai output: + +gennap length=40 output=stdout file | naptosai width=32 frstep=0.2 > file.sai +gensai top=1000 useprevious=on file + + The sai output can be plotted as a spiral, but it is best to set the + display parameters as follows: + +gennap length=40 output=stdout dencf=1 width=500 height=500 file | \ + naptosai width=32 frstep=0.2 > file.sai +genspl useprevious=on pensize=2 file + + +3. To convert a nap output to a sai format bitmap, to display an animated + stream: + +gennap length=40 output=stdout file | naptosai width=32 frstep=0.2 > file.sai +gensai top=1000 useprevious=on bitmap=on file +review file + + The same can be done for the spiral display: + +gennap length=40 output=stdout dencf=1 width=500 height=500 file | \ + naptosai width=32 frstep=0.2 > file.sai +genspl useprevious=on pensize=2 bitmap=on file +review file + + The plots show the nap moving though 8ms (40-32), in steps of 0.2ms, + first in rectangular display, then in spiral-mapped display. + +*/ + + +#include <stdio.h> +#include <math.h> +#include "header.h" +#include "options.h" +#include "units.h" +#include "strmatch.h" + +char applic[] = "NAP to SAI format conversion. " ; + +static char *helpstr, *debugstr, *startstr, *lengthstr, *widthstr, *shiftstr, *headerstr ; + +static Options option[] = { + { "help" , "off" , &helpstr , "help" , DEBUG }, + { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, + { "start" , "0" , &startstr , "Start point in i/p NAP" , VAL }, + { "length" , "max" , &lengthstr , "Length of i/p NAP to process." , VAL }, + { "header" , "on" , &headerstr , "sai header" , VAL }, + { "width" , "max" , &widthstr , "Width of o/p SAI frame." , VAL }, + { "frstep" , "1ms" , &shiftstr , "Step between o/p frames of SAI.\n(frstep=0 gets 1 frame of given width)." , VAL }, + ( char * ) 0 } ; + + +int frameheight, framewidth ; /* Nap parameters read from header */ +int frames, samplerate ; + +int start, length ; + +int Newframeheight, Newframewidth ; /* Sai parameters to write */ +int Newframes ; +int Newframeshift ; +int Newframebytes ; + + +main(argc, argv) +int argc ; +char *argv[] ; +{ + FILE *fp ; + int i, framebytes, startbytes, frameshift; + char *header, *SaiHeader(); + short *nap, *frame, *endframe; + + fp = openopts( option,argc,argv ) ; + if ( !isoff( helpstr ) ) + helpopts( helpstr, argv[0], applic, option ) ; + + if ( ison( debugstr ) ) { + printf("start=%s length=%s width=%s shift=%s\n", + startstr, lengthstr, widthstr, shiftstr ); + exit(0); + } + + if ( (header = ReadHeader(fp)) == (char *) 0 ) { + fprintf(stderr,"naptosai: header not found\n"); + exit(1); + } + + frameheight = HeaderInt( header, "frameheight" ); + framewidth = HeaderInt( header, "framewidth" ); + frames = HeaderInt( header, "frames" ); + samplerate = HeaderSamplerate( header, "samplerate" ); + + start = to_p( startstr, samplerate ); + if ( ismax( lengthstr ) ) /* Special case for remainder of input */ + length = frames - start ; + else + length = to_p( lengthstr, samplerate ); + + if ( start + length > frames ) { + fprintf(stderr,"naptosai: nap too small (%d ms) for requested start and length \n", to_ms( frames, samplerate ) ); + exit(1); + } + + framebytes = frameheight * length * sizeof(short) ; + startbytes = frameheight * start * sizeof(short) ; + + Newframeheight = frameheight ; + if ( ismax( widthstr ) ) /* Special case for single frame of max width */ + Newframewidth = length ; + else + Newframewidth = to_p( widthstr, samplerate ) ; + Newframeshift = to_p( shiftstr, samplerate ) ; + Newframebytes = Newframeheight * Newframewidth * sizeof(short) ; + if ( Newframeshift > 0 ) + Newframes = 1 + ( length - Newframewidth ) / Newframeshift ; + else { /* Special case of zero shift */ + Newframes = 1 ; + Newframeshift = 1 ; + } + + if ( length < Newframewidth ) { + fprintf(stderr,"naptosai: nap too small (%d ms) for requested width\n", to_ms( length, samplerate ) ); + exit(1); + } + + fprintf(stderr,"Output %d sai frames, each %d bytes\n", Newframes, Newframebytes ); + + if ( ison( headerstr ) ) + WriteHeader( SaiHeader(header), stdout ); + + /* Allocate space for framebytes of nap data */ + + if ( (nap = (short *)malloc( framebytes )) == NULL ) { + fprintf(stderr,"naptosai: malloc out of space\n"); + exit(1); + } + + /* Seek to start in blocks of framebytes */ + + for (i=framebytes ; i < startbytes ; i += framebytes) + if ( fread( nap, framebytes, 1, fp ) == NULL ) { + fprintf(stderr,"naptosai: missing data after header\n"); + exit(1); + } + if ( (startbytes -= (i - framebytes)) > 0 ) + if ( fread( nap, startbytes, 1, fp ) == NULL ) { + fprintf(stderr,"naptosai: missing data after header\n"); + exit(1); + } + + /* Read framebytes of i/p nap data */ + + if ( fread( nap, framebytes, 1, fp ) == NULL ) { + fprintf(stderr,"naptosai: missing data after header\n"); + exit(1); + } + + frameshift = Newframeshift * Newframeheight ; + endframe = nap + Newframes * frameshift ; + + for ( frame = nap ; frame < endframe ; frame += frameshift ) + writeframe( frame, stdout ) ; + + fprintf(stderr,"naptosai done\n" ) ; + +} + + + +/* Write a frame in sai format */ + +writeframe( frame, fp ) +short *frame ; +FILE *fp ; +{ + int i, row, col; + + for (row=0 ; row < Newframeheight ; row++) + for (col=0 , i=row ; col < Newframewidth ; col++, i+=Newframeheight) + fwrite( &frame[i], sizeof(short), 1, fp ); +} + + +/*********************** Read header and build new header *****************/ + +/* + Copy the original nap header to a new sai header, changing in order: + frames + frameshift + framewidth + frameheight + framebytes + Then change applic name [gennap] to [gensai] in the Version string. + Finally, update the new header_bytes, and return the new header. +*/ + +char *SaiHeader( napheader ) +char *napheader ; +{ + char *saiheader; + char *p0, *p1, *p2, *s, str[64]; + + saiheader = (char *)malloc( strlen(napheader) + 64 ) ; + + p0 = saiheader ; + p1 = napheader ; + + + /** copy up to frames **/ + + p2 = HeaderString( napheader , "frames" ) ; + while( p1 < p2 ) + *p0++ = *p1++ ; + + sprintf(str,"%d\n", Newframes); + for (s = str ; *s != '\n' ; ) + *p0++ = *s++; + *p0++ = *s; + while (*p1 != '\n') + *p1++; + *p1++; + + + /** copy up to frameshift **/ + + p2 = HeaderString( napheader , "frameshift" ) ; + while ( p1 < p2 ) + *p0++ = *p1++ ; + + sprintf(str,"%d\n", Newframeshift); + for (s = str ; *s != '\n' ; ) + *p0++ = *s++; + *p0++ = *s; + while (*p1 != '\n') + *p1++; + *p1++; + + + /** copy up to framewidth **/ + + p2 = HeaderString( napheader , "framewidth" ) ; + while ( p1 < p2 ) + *p0++ = *p1++ ; + + sprintf(str,"%d\n", Newframewidth); + for (s = str ; *s != '\n' ; ) + *p0++ = *s++; + *p0++ = *s; + while (*p1 != '\n') + *p1++; + *p1++; + + + /** copy up to frameheight **/ + + p2 = HeaderString( napheader , "frameheight" ) ; + while ( p1 < p2 ) + *p0++ = *p1++ ; + + sprintf(str,"%d\n", Newframeheight); + for (s = str ; *s != '\n' ; ) + *p0++ = *s++; + *p0++ = *s; + while (*p1 != '\n') + *p1++; + *p1++; + + + /** copy up to framebytes **/ + + p2 = HeaderString( napheader , "framebytes" ) ; + while ( p1 < p2 ) + *p0++ = *p1++ ; + + sprintf(str,"%d\n", Newframebytes); + for (s = str ; *s != '\n' ; ) + *p0++ = *s++; + *p0++ = *s; + while (*p1 != '\n') + *p1++; + *p1++; + + + /** copy rest of header **/ + + p2 = HeaderString( napheader , "Version" ) ; + while ( p1 < p2 ) + *p0++ = *p1++ ; + + while (*p1 != ']') /* change applic name [gennap] to [gensai] */ + *p0++ = *p1++ ; + *(p0-3) = 's' ; + *(p0-2) = 'a' ; + *(p0-1) = 'i' ; + while (*p1 != '\n') + *p0++ = *p1++ ; + *p0++ = *p1++ ; + + + /** update header_bytes **/ + + sprintf(str, "%0*d", 7, p0-saiheader); + p0 = HeaderString( saiheader , "header_bytes" ) ; + s = str; + while(*p0 != '\n') + *p0++ = *s++ ; + + + return saiheader; +} + +