annotate 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
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 bufwave.c a shifting waveform buffer.
tomwalters@0 3 ---------
tomwalters@0 4
tomwalters@0 5 A buffer (or window) is shifted along the input, and the
tomwalters@0 6 contents of the buffer are written to the stdout on each shift.
tomwalters@0 7
tomwalters@0 8 Input is buffered in frames of size `width' samples, and the buffer is
tomwalters@0 9 shifted along the input in steps of `frstep' samples.
tomwalters@0 10 Both `width' and `frstep' may be given with time units (s or ms), in which
tomwalters@0 11 case the they are converted to a number of samples using the given
tomwalters@0 12 `samplerate' option.
tomwalters@0 13
tomwalters@0 14 The `type' option sets the size of a binary sample in bytes.
tomwalters@0 15 Standard type names are recognised (char, short, int, float, double).
tomwalters@0 16 For example, type=1 is synonymous with type=char, both specifying a
tomwalters@0 17 binary sample of 1 byte.
tomwalters@0 18
tomwalters@0 19 The special case of type=ASCII sets a sample to be a line of ASCII text
tomwalters@0 20 (delimited by a CR), of size up to a maximum number of characters set by
tomwalters@0 21 the `length' option.
tomwalters@0 22
tomwalters@0 23 The `frame' option selects a sequence of contiguous frames for output by:
tomwalters@0 24 frame=a[-b]
tomwalters@0 25 where `a' and `b' are frame numbers: 1,2,3,...
tomwalters@0 26 The upper limit `b' is optional, and when it is missing then the frame
tomwalters@0 27 sequence is a single frame, otherwise `a' and `b' are inclusive limits.
tomwalters@0 28 The strings "min" and "max" are recognised as extreme limits.
tomwalters@0 29
tomwalters@0 30 The `start' option is an offset to the start of the first frame in samples.
tomwalters@0 31 If given with time units, the start is converted to samples using the
tomwalters@0 32 given `samplerate' option.
tomwalters@0 33
tomwalters@0 34 The `reverse' option causes each buffer to be written out in reverse order
tomwalters@0 35 of its samples.
tomwalters@0 36
tomwalters@0 37 For example, if a file foo contains a sequence of frames, each 75 samples
tomwalters@0 38 long, then to reverse the contents of each frame do:
tomwalters@0 39
tomwalters@0 40 bufwave rev=on width=75 frstep=75 foo
tomwalters@0 41
tomwalters@0 42 */
tomwalters@0 43
tomwalters@0 44 #include <stdio.h>
tomwalters@0 45 #include <math.h>
tomwalters@0 46 #include "options.h"
tomwalters@0 47 #include "units.h"
tomwalters@0 48 #include "strmatch.h"
tomwalters@0 49
tomwalters@0 50 char applic[] = "shifting waveform buffer." ;
tomwalters@0 51
tomwalters@0 52 static char *helpstr, *debugstr, *fstr, *bstr, *nstr, *ostr, *sstr, *sampstr, *rstr, *lenstr ;
tomwalters@0 53
tomwalters@0 54 static Options option[] = {
tomwalters@0 55 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 56 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 57 { "samplerate", "20kHz" , &sampstr , "samplerate " , VAL },
tomwalters@0 58 { "frame" , "1-max" , &fstr , "select frames inclusively" , VAL },
tomwalters@0 59 { "width" , "10ms" , &nstr , "frame width" , VAL },
tomwalters@0 60 { "frstep" , "0" , &ostr , "frame step (ie. shift)" , VAL },
tomwalters@0 61 { "start" , "0" , &sstr , "offset to start first frame" , VAL },
tomwalters@0 62 { "type" , "short" , &bstr , "data type or size in bytes" , VAL },
tomwalters@0 63 { "reverse" , "off" , &rstr , "write each frame in reverse" , SETFLAG },
tomwalters@0 64 { "length" , "256" , &lenstr , "max line length in chars" , SVAL },
tomwalters@0 65 ( char * ) 0 } ;
tomwalters@0 66
tomwalters@0 67
tomwalters@0 68 int samplerate ;
tomwalters@0 69 int width ;
tomwalters@0 70 int frstep ;
tomwalters@0 71 int overlap ;
tomwalters@0 72 int start ;
tomwalters@0 73 int reverse ;
tomwalters@0 74
tomwalters@0 75 main (argc, argv)
tomwalters@0 76 int argc;
tomwalters@0 77 char **argv;
tomwalters@0 78 {
tomwalters@0 79 FILE *fp ;
tomwalters@0 80 char *buf, **linebuf ;
tomwalters@0 81 int m, bytes ;
tomwalters@0 82 int a, b, f, i, j, k0, k1 ;
tomwalters@0 83 int helpdatatype() ;
tomwalters@0 84
tomwalters@0 85 fp = openopts( option,argc,argv ) ;
tomwalters@0 86 if ( !isoff( helpstr ) )
tomwalters@0 87 helpopts1( helpstr, argv[0], applic, option, helpdatatype ) ;
tomwalters@0 88
tomwalters@0 89 samplerate = to_Hz( sampstr ) ;
tomwalters@0 90 width = to_p( nstr, samplerate ) ;
tomwalters@0 91 frstep = to_p( ostr, samplerate ) ;
tomwalters@0 92 start = to_p( sstr, samplerate ) ;
tomwalters@0 93 reverse = ison( rstr ) ;
tomwalters@0 94 overlap = width - frstep ;
tomwalters@0 95
tomwalters@0 96 if ( ( bytes = databytes( bstr ) ) < 0 ) {
tomwalters@0 97 fprintf( stderr, "bufwave: bad type [%s]\n", bstr ) ;
tomwalters@0 98 exit( 1 ) ;
tomwalters@0 99 }
tomwalters@0 100
tomwalters@0 101 if ( selector( fstr, &a, &b ) == 0 ) {
tomwalters@0 102 fprintf(stderr,"bufwave: bad frame selector [%s]\n", fstr ) ;
tomwalters@0 103 exit( 1 ) ;
tomwalters@0 104 }
tomwalters@0 105
tomwalters@0 106 if ( ison( debugstr ) ) {
tomwalters@0 107 printf("width=%d frstep=%d start=%d bytes=%d samplerate=%d reverse=%d a=%d b=%d \n",
tomwalters@0 108 width, frstep, start, bytes, samplerate, reverse, a, b );
tomwalters@0 109 exit(0);
tomwalters@0 110 }
tomwalters@0 111
tomwalters@0 112
tomwalters@0 113 if (bytes > 0) { /* binary objects of size `bytes' */
tomwalters@0 114
tomwalters@0 115 /* Allocate space for frame buffer */
tomwalters@0 116 if ( ( buf = (char *)malloc( width*bytes ) ) == (char *)0 ) {
tomwalters@0 117 fprintf( stderr, "bufwave: cannot allocate %d * %d bytes\n", width, bytes ) ;
tomwalters@0 118 exit( 1 ) ;
tomwalters@0 119 }
tomwalters@0 120
tomwalters@0 121 /* Seek to start, past start*bytes and a-1 frame shifts of frstep*bytes */
tomwalters@0 122
tomwalters@0 123 if ( start>0 && seekstart( start, bytes, fp ) < start ) {
tomwalters@0 124 fprintf(stderr,"bufwave: seek overshot end-of-file\n");
tomwalters@0 125 exit(1);
tomwalters@0 126 }
tomwalters@0 127 for (f=1 ; f<a && fread(buf,bytes,frstep,fp) ; f++)
tomwalters@0 128 ;
tomwalters@0 129
tomwalters@0 130 /* Buffer b-a+1 frames (or the remainder if b==0) */
tomwalters@0 131 m = fread(buf, bytes, width, fp); /* m enables oversizing single frames for direct reversing */
tomwalters@0 132 if ( reverse )
tomwalters@0 133 for (k0=m-1 ; k0>=0 && fwrite(&buf[(k0)*bytes], bytes, 1, stdout) ; --k0)
tomwalters@0 134 ;
tomwalters@0 135 else
tomwalters@0 136 fwrite(buf, bytes, m, stdout);
tomwalters@0 137
tomwalters@0 138 k0 = k1 = 0;
tomwalters@0 139 for (i=width, f++ ; k0 == k1 && (f<=b || b==0) ; i+=width, f++) {
tomwalters@0 140 for (k0=i, k1=i+frstep ; k0<k1 && fread(&buf[(k0%width)*bytes], bytes, 1, fp) ; k0++)
tomwalters@0 141 ;
tomwalters@0 142 i -= overlap ;
tomwalters@0 143 if (k0 == k1) {
tomwalters@0 144 if ( reverse ) /* write out in reverse */
tomwalters@0 145 for (k0=i+width-1, k1=i-1 ; k0>k1 && fwrite(&buf[(k0%width)*bytes], bytes, 1, stdout) ; --k0)
tomwalters@0 146 ;
tomwalters@0 147 else /* write out correct order */
tomwalters@0 148 for (k0=i, k1=i+width ; k0<k1 && fwrite(&buf[(k0%width)*bytes], bytes, 1, stdout) ; k0++)
tomwalters@0 149 ;
tomwalters@0 150 }
tomwalters@0 151 }
tomwalters@0 152 }
tomwalters@0 153
tomwalters@0 154 else { /* ASCII objects of size lines up to lenstr chars */
tomwalters@0 155
tomwalters@0 156 /* Allocate space for `width' lines */
tomwalters@0 157 bytes = atoi( lenstr ) ;
tomwalters@0 158 if ( ( linebuf = (char **)malloc( width * sizeof( char * ) ) ) == (char **)0 ) {
tomwalters@0 159 fprintf( stderr, "bufwave: cannot allocate %d * sizeof( char * )\n", width ) ;
tomwalters@0 160 exit( 1 ) ;
tomwalters@0 161 }
tomwalters@0 162 for ( i = 0 ; i < width ; i++)
tomwalters@0 163 if ( ( linebuf[i] = (char *)malloc( bytes ) ) == (char *)0 ) {
tomwalters@0 164 fprintf( stderr, "bufwave: cannot allocate %d bytes %d times\n", bytes, i+1 ) ;
tomwalters@0 165 exit( 1 ) ;
tomwalters@0 166 }
tomwalters@0 167
tomwalters@0 168 /* Seek to start, past start*bytes and frstep*a-1 lines */
tomwalters@0 169 for (i=0 ; i<start && fgets( *linebuf, bytes, fp ) ; i++)
tomwalters@0 170 ;
tomwalters@0 171 if (i<start) {
tomwalters@0 172 fprintf(stderr,"bufwave: seek overshot end-of-file\n");
tomwalters@0 173 exit(1);
tomwalters@0 174 }
tomwalters@0 175 m = frstep * ( a-1 ) ;
tomwalters@0 176 for (i=0 ; i<m && fgets( *linebuf, bytes, fp ) ; i++)
tomwalters@0 177 ;
tomwalters@0 178 if ( m > 0 ) f = m/frstep + 1 ;
tomwalters@0 179 else f = 1 ;
tomwalters@0 180
tomwalters@0 181 /* Buffer b-a+1 lines (or the remainder if b==0) */
tomwalters@0 182 /* (m enables oversizing single frames for direct reversing) */
tomwalters@0 183 for ( m = 0 ; m < width && fgets( linebuf[m], bytes, fp ) ; m++ )
tomwalters@0 184 ;
tomwalters@0 185 if ( reverse )
tomwalters@0 186 for (k0=m-1 ; k0>=0 ; --k0)
tomwalters@0 187 fputs( linebuf[k0], stdout ) ;
tomwalters@0 188 else
tomwalters@0 189 for (k0=0 ; k0<m ; k0++)
tomwalters@0 190 fputs( linebuf[k0], stdout ) ;
tomwalters@0 191
tomwalters@0 192 k0 = k1 = 0;
tomwalters@0 193 for (i=width, f++ ; k0 == k1 && (f<=b || b==0) ; i+=width, f++) {
tomwalters@0 194 for (k0=i, k1=i+frstep ; k0<k1 && fgets( linebuf[k0%width], bytes, fp ) ; k0++)
tomwalters@0 195 ;
tomwalters@0 196 i -= overlap ;
tomwalters@0 197 if (k0 == k1) {
tomwalters@0 198 if ( reverse ) /* write out in reverse */
tomwalters@0 199 for (k0=i+width-1, k1=i-1 ; k0>k1 ; --k0)
tomwalters@0 200 fputs( linebuf[k0%width], stdout ) ;
tomwalters@0 201 else /* write out correct order */
tomwalters@0 202 for (k0=i, k1=i+width ; k0<k1 ; k0++)
tomwalters@0 203 fputs( linebuf[k0%width], stdout) ;
tomwalters@0 204 }
tomwalters@0 205 }
tomwalters@0 206 }
tomwalters@0 207
tomwalters@0 208 }
tomwalters@0 209
tomwalters@0 210
tomwalters@0 211 helpdatatype()
tomwalters@0 212 {
tomwalters@0 213 fprintf(stderr,"\ndata types: \n");
tomwalters@0 214 fprintf(stderr," char \n");
tomwalters@0 215 fprintf(stderr," short \n");
tomwalters@0 216 fprintf(stderr," int \n");
tomwalters@0 217 fprintf(stderr," float \n");
tomwalters@0 218 fprintf(stderr," double \n");
tomwalters@0 219 fprintf(stderr," <number> (sizeof binary object in bytes) \n" ) ;
tomwalters@0 220 fprintf(stderr," ASCII (lines of up to %d characters) \n", atoi( lenstr ) ) ;
tomwalters@0 221 exit( 1 ) ;
tomwalters@0 222 }