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;
+}
+
+