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