diff tools/bufwave.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/bufwave.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,222 @@
+/*
+  bufwave.c      a shifting waveform buffer.
+  ---------
+
+  A buffer (or window) is shifted along the input, and the
+  contents of the buffer are written to the stdout on each shift.
+
+  Input is buffered in frames of size `width' samples, and the buffer is
+  shifted along the input in steps of `frstep' samples.
+  Both `width' and `frstep' may be given with time units (s or ms), in which
+  case the they are converted to a number of samples using the given
+  `samplerate' option.
+
+  The `type' option sets the size of a binary sample in bytes.
+  Standard type names are recognised (char, short, int, float, double).
+  For example, type=1 is synonymous with type=char, both specifying a
+  binary sample of 1 byte.
+
+  The special case of type=ASCII sets a sample to be a line of ASCII text
+  (delimited by a CR), of size up to a maximum number of characters set by
+  the `length' option.
+
+  The `frame' option selects a sequence of contiguous frames for output by:
+	frame=a[-b]
+  where `a' and `b' are frame numbers: 1,2,3,...
+  The upper limit `b' is optional, and when it is missing then the frame
+  sequence is a single frame, otherwise `a' and `b' are inclusive limits.
+  The strings "min" and "max" are recognised as extreme limits.
+
+  The `start' option is an offset to the start of the first frame in samples.
+  If given with time units, the start is converted to samples using the
+  given `samplerate' option.
+
+  The `reverse' option causes each buffer to be written out in reverse order
+  of its samples.
+
+  For example, if a file foo contains a sequence of frames, each 75 samples
+  long, then to reverse the contents of each frame do:
+
+	bufwave rev=on width=75 frstep=75 foo
+
+*/
+
+#include <stdio.h>
+#include <math.h>
+#include "options.h"
+#include "units.h"
+#include "strmatch.h"
+
+char applic[]     = "shifting waveform buffer." ;
+
+static char *helpstr, *debugstr, *fstr, *bstr, *nstr, *ostr, *sstr, *sampstr, *rstr, *lenstr ;
+
+static Options option[] = {
+    {   "help"      ,   "off"       ,  &helpstr     ,   "help"                              , DEBUG   },
+    {   "debug"     ,   "off"       ,  &debugstr    ,   "debugging switch"                  , DEBUG   },
+    {   "samplerate",   "20kHz"     ,  &sampstr     ,   "samplerate "                       , VAL     },
+    {   "frame"     ,   "1-max"     ,  &fstr        ,   "select frames inclusively"         , VAL     },
+    {   "width"     ,   "10ms"      ,  &nstr        ,   "frame width"                       , VAL     },
+    {   "frstep"    ,   "0"         ,  &ostr        ,   "frame step (ie. shift)"            , VAL     },
+    {   "start"     ,   "0"         ,  &sstr        ,   "offset to start first frame"       , VAL     },
+    {   "type"      ,   "short"     ,  &bstr        ,   "data type or size in bytes"        , VAL     },
+    {   "reverse"   ,   "off"       ,  &rstr        ,   "write each frame in reverse"       , SETFLAG },
+    {   "length"    ,   "256"       ,  &lenstr      ,   "max line length in chars"          , SVAL    },
+   ( char * ) 0 } ;
+
+
+int   samplerate ;
+int   width      ;
+int   frstep     ;
+int   overlap    ;
+int   start      ;
+int   reverse    ;
+
+main (argc, argv)
+int    argc;
+char **argv;
+{
+    FILE  *fp ;
+    char  *buf, **linebuf ;
+    int    m, bytes ;
+    int    a, b, f, i, j, k0, k1 ;
+    int    helpdatatype() ;
+
+    fp = openopts( option,argc,argv ) ;
+    if ( !isoff( helpstr ) )
+	helpopts1( helpstr, argv[0], applic, option, helpdatatype ) ;
+
+    samplerate = to_Hz( sampstr ) ;
+    width      = to_p( nstr, samplerate ) ;
+    frstep     = to_p( ostr, samplerate ) ;
+    start      = to_p( sstr, samplerate ) ;
+    reverse    = ison( rstr ) ;
+    overlap    = width - frstep ;
+
+    if ( ( bytes = databytes( bstr ) ) < 0 ) {
+	fprintf( stderr, "bufwave: bad type [%s]\n", bstr ) ;
+	exit( 1 ) ;
+    }
+
+    if ( selector( fstr, &a, &b ) == 0 ) {
+	fprintf(stderr,"bufwave: bad frame selector [%s]\n", fstr ) ;
+	exit( 1 ) ;
+    }
+
+    if ( ison( debugstr ) ) {
+	printf("width=%d frstep=%d start=%d bytes=%d samplerate=%d reverse=%d a=%d b=%d \n",
+		width, frstep, start, bytes, samplerate, reverse, a, b );
+	exit(0);
+    }
+
+
+    if (bytes > 0) {    /* binary objects of size `bytes' */
+
+	/* Allocate space for frame buffer */
+	if ( ( buf = (char *)malloc( width*bytes ) ) == (char *)0 ) {
+	    fprintf( stderr, "bufwave: cannot allocate %d * %d bytes\n", width, bytes ) ;
+	    exit( 1 ) ;
+	}
+
+	/* Seek to start, past start*bytes and a-1 frame shifts of frstep*bytes */
+
+	if ( start>0 && seekstart( start, bytes, fp ) < start ) {
+	    fprintf(stderr,"bufwave: seek overshot end-of-file\n");
+	    exit(1);
+	}
+	for (f=1 ; f<a  && fread(buf,bytes,frstep,fp) ; f++)
+	    ;
+
+	/* Buffer b-a+1 frames (or the remainder if b==0) */
+	m = fread(buf, bytes, width, fp);   /* m enables oversizing single frames for direct reversing */
+	if ( reverse )
+	    for (k0=m-1 ; k0>=0 && fwrite(&buf[(k0)*bytes], bytes, 1, stdout) ; --k0)
+		;
+	else
+	    fwrite(buf, bytes, m, stdout);
+
+	k0 = k1 = 0;
+	for (i=width, f++ ; k0 == k1 && (f<=b || b==0) ; i+=width, f++) {
+	    for (k0=i, k1=i+frstep ; k0<k1 && fread(&buf[(k0%width)*bytes], bytes, 1, fp) ; k0++)
+		;
+	    i -= overlap ;
+	    if (k0 == k1) {
+		if ( reverse )  /* write out in reverse */
+		    for (k0=i+width-1, k1=i-1 ; k0>k1 && fwrite(&buf[(k0%width)*bytes], bytes, 1, stdout) ; --k0)
+			;
+		else        /* write out correct order */
+		    for (k0=i, k1=i+width ; k0<k1 && fwrite(&buf[(k0%width)*bytes], bytes, 1, stdout) ; k0++)
+			;
+	    }
+	}
+    }
+
+    else {      /* ASCII objects of size lines up to lenstr chars */
+
+	/* Allocate space for `width' lines */
+	bytes = atoi( lenstr ) ;
+	if ( ( linebuf = (char **)malloc( width * sizeof( char * ) ) ) == (char **)0 ) {
+	    fprintf( stderr, "bufwave: cannot allocate %d * sizeof( char * )\n", width ) ;
+	    exit( 1 ) ;
+	}
+	for ( i = 0 ; i < width ; i++)
+	    if ( ( linebuf[i] = (char *)malloc( bytes ) ) == (char *)0 ) {
+		fprintf( stderr, "bufwave: cannot allocate %d bytes %d times\n", bytes, i+1 ) ;
+		exit( 1 ) ;
+	    }
+
+	/* Seek to start, past start*bytes and frstep*a-1 lines */
+	for (i=0 ; i<start && fgets( *linebuf, bytes, fp ) ; i++)
+	    ;
+	if (i<start) {
+	    fprintf(stderr,"bufwave: seek overshot end-of-file\n");
+	    exit(1);
+	}
+	m = frstep * ( a-1 ) ;
+	for (i=0 ; i<m  && fgets( *linebuf, bytes, fp ) ; i++)
+	    ;
+	if ( m > 0 )  f = m/frstep + 1 ;
+	else          f = 1 ;
+
+	/* Buffer b-a+1 lines (or the remainder if b==0) */
+	/* (m enables oversizing single frames for direct reversing) */
+	for ( m = 0 ; m < width && fgets( linebuf[m], bytes, fp ) ; m++ )
+	    ;
+	if ( reverse )
+	    for (k0=m-1 ; k0>=0 ; --k0)
+		fputs( linebuf[k0], stdout ) ;
+	else
+	    for (k0=0 ; k0<m ; k0++)
+		fputs( linebuf[k0], stdout ) ;
+
+	k0 = k1 = 0;
+	for (i=width, f++ ; k0 == k1 && (f<=b || b==0) ; i+=width, f++) {
+	    for (k0=i, k1=i+frstep ; k0<k1 && fgets( linebuf[k0%width], bytes, fp ) ; k0++)
+		;
+	    i -= overlap ;
+	    if (k0 == k1) {
+		if ( reverse )  /* write out in reverse */
+		    for (k0=i+width-1, k1=i-1 ; k0>k1 ; --k0)
+			fputs( linebuf[k0%width], stdout ) ;
+		else        /* write out correct order */
+		    for (k0=i, k1=i+width ; k0<k1 ; k0++)
+			fputs( linebuf[k0%width], stdout) ;
+	    }
+	}
+    }
+
+}
+
+
+helpdatatype()
+{
+    fprintf(stderr,"\ndata types:       \n");
+    fprintf(stderr,"            char    \n");
+    fprintf(stderr,"            short   \n");
+    fprintf(stderr,"            int     \n");
+    fprintf(stderr,"            float   \n");
+    fprintf(stderr,"            double  \n");
+    fprintf(stderr,"            <number>  (sizeof binary object in bytes)  \n" ) ;
+    fprintf(stderr,"            ASCII     (lines of up to %d characters)   \n", atoi( lenstr ) ) ;
+    exit( 1 ) ;
+}