tomwalters@0
|
1 /*
|
tomwalters@0
|
2 naptosai.c NAP to SAI format conversion.
|
tomwalters@0
|
3 ------------
|
tomwalters@0
|
4
|
tomwalters@0
|
5 Read a NAP header and frame.
|
tomwalters@0
|
6 Write a SAI header, (created from the NAP header).
|
tomwalters@0
|
7 Write a succession of SAI frames.
|
tomwalters@0
|
8
|
tomwalters@0
|
9 The options "start" and "length" specify the NAP which is input.
|
tomwalters@0
|
10 The options "width" and "frstep" specify the SAI frames which are output.
|
tomwalters@0
|
11
|
tomwalters@0
|
12 Special option values are:
|
tomwalters@0
|
13
|
tomwalters@0
|
14 length=max Input all the NAP from the given start to its end.
|
tomwalters@0
|
15 width=max Output framewidth is set equal to the given NAP length,
|
tomwalters@0
|
16 and if this is also "max", then the framewidth is the
|
tomwalters@0
|
17 remainder of the NAP.
|
tomwalters@0
|
18 frstep=0 Output one frame of given width from the given start of
|
tomwalters@0
|
19 the NAP.
|
tomwalters@0
|
20
|
tomwalters@0
|
21 For example, use naptosai with width=max and frstep=0 to produce one SAI
|
tomwalters@0
|
22 frame the same size as the input NAP.
|
tomwalters@0
|
23
|
tomwalters@0
|
24 Examples:
|
tomwalters@0
|
25
|
tomwalters@0
|
26
|
tomwalters@0
|
27 1. To convert a nap or a bmm output to a single frame of sai output:
|
tomwalters@0
|
28
|
tomwalters@0
|
29 gennap length=64 output=stdout file | naptosai width=32 frstep=0 > file.sai
|
tomwalters@0
|
30 gensai top=1000 useprevious=on file
|
tomwalters@0
|
31
|
tomwalters@0
|
32 genbmm output=stdout file | naptosai > file.sai
|
tomwalters@0
|
33 gensai bottom=-100 useprevious=on file
|
tomwalters@0
|
34
|
tomwalters@0
|
35 This uses special case of zero frstep to generate one frame of output with
|
tomwalters@0
|
36 the given width. The default width is the given length, and the default
|
tomwalters@0
|
37 length is the remainder of the input file. If the width=length, then the
|
tomwalters@0
|
38 frstep is zero by default, and therefore the default process, (ie with no
|
tomwalters@0
|
39 arguments), converts the whole of the input to a single SAI frame.
|
tomwalters@0
|
40
|
tomwalters@0
|
41 Note, certain display parameters have different default values for different
|
tomwalters@0
|
42 applications. The SAI display parameters should be set to the appropriate
|
tomwalters@0
|
43 values, in order to plot the SAI on the same scale. For example:
|
tomwalters@0
|
44 When the source application is NAP, set gensai top=1000
|
tomwalters@0
|
45 When the source application is BMM, set gensai bottom=-100
|
tomwalters@0
|
46
|
tomwalters@0
|
47
|
tomwalters@0
|
48 2. To convert a nap output to multiple frames of sai output:
|
tomwalters@0
|
49
|
tomwalters@0
|
50 gennap length=40 output=stdout file | naptosai width=32 frstep=0.2 > file.sai
|
tomwalters@0
|
51 gensai top=1000 useprevious=on file
|
tomwalters@0
|
52
|
tomwalters@0
|
53 The sai output can be plotted as a spiral, but it is best to set the
|
tomwalters@0
|
54 display parameters as follows:
|
tomwalters@0
|
55
|
tomwalters@0
|
56 gennap length=40 output=stdout dencf=1 width=500 height=500 file | \
|
tomwalters@0
|
57 naptosai width=32 frstep=0.2 > file.sai
|
tomwalters@0
|
58 genspl useprevious=on pensize=2 file
|
tomwalters@0
|
59
|
tomwalters@0
|
60
|
tomwalters@0
|
61 3. To convert a nap output to a sai format bitmap, to display an animated
|
tomwalters@0
|
62 stream:
|
tomwalters@0
|
63
|
tomwalters@0
|
64 gennap length=40 output=stdout file | naptosai width=32 frstep=0.2 > file.sai
|
tomwalters@0
|
65 gensai top=1000 useprevious=on bitmap=on file
|
tomwalters@0
|
66 review file
|
tomwalters@0
|
67
|
tomwalters@0
|
68 The same can be done for the spiral display:
|
tomwalters@0
|
69
|
tomwalters@0
|
70 gennap length=40 output=stdout dencf=1 width=500 height=500 file | \
|
tomwalters@0
|
71 naptosai width=32 frstep=0.2 > file.sai
|
tomwalters@0
|
72 genspl useprevious=on pensize=2 bitmap=on file
|
tomwalters@0
|
73 review file
|
tomwalters@0
|
74
|
tomwalters@0
|
75 The plots show the nap moving though 8ms (40-32), in steps of 0.2ms,
|
tomwalters@0
|
76 first in rectangular display, then in spiral-mapped display.
|
tomwalters@0
|
77
|
tomwalters@0
|
78 */
|
tomwalters@0
|
79
|
tomwalters@0
|
80
|
tomwalters@0
|
81 #include <stdio.h>
|
tomwalters@0
|
82 #include <math.h>
|
tomwalters@0
|
83 #include "header.h"
|
tomwalters@0
|
84 #include "options.h"
|
tomwalters@0
|
85 #include "units.h"
|
tomwalters@0
|
86 #include "strmatch.h"
|
tomwalters@0
|
87
|
tomwalters@0
|
88 char applic[] = "NAP to SAI format conversion. " ;
|
tomwalters@0
|
89
|
tomwalters@0
|
90 static char *helpstr, *debugstr, *startstr, *lengthstr, *widthstr, *shiftstr, *headerstr ;
|
tomwalters@0
|
91
|
tomwalters@0
|
92 static Options option[] = {
|
tomwalters@0
|
93 { "help" , "off" , &helpstr , "help" , DEBUG },
|
tomwalters@0
|
94 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
|
tomwalters@0
|
95 { "start" , "0" , &startstr , "Start point in i/p NAP" , VAL },
|
tomwalters@0
|
96 { "length" , "max" , &lengthstr , "Length of i/p NAP to process." , VAL },
|
tomwalters@0
|
97 { "header" , "on" , &headerstr , "sai header" , VAL },
|
tomwalters@0
|
98 { "width" , "max" , &widthstr , "Width of o/p SAI frame." , VAL },
|
tomwalters@0
|
99 { "frstep" , "1ms" , &shiftstr , "Step between o/p frames of SAI.\n(frstep=0 gets 1 frame of given width)." , VAL },
|
tomwalters@0
|
100 ( char * ) 0 } ;
|
tomwalters@0
|
101
|
tomwalters@0
|
102
|
tomwalters@0
|
103 int frameheight, framewidth ; /* Nap parameters read from header */
|
tomwalters@0
|
104 int frames, samplerate ;
|
tomwalters@0
|
105
|
tomwalters@0
|
106 int start, length ;
|
tomwalters@0
|
107
|
tomwalters@0
|
108 int Newframeheight, Newframewidth ; /* Sai parameters to write */
|
tomwalters@0
|
109 int Newframes ;
|
tomwalters@0
|
110 int Newframeshift ;
|
tomwalters@0
|
111 int Newframebytes ;
|
tomwalters@0
|
112
|
tomwalters@0
|
113
|
tomwalters@0
|
114 main(argc, argv)
|
tomwalters@0
|
115 int argc ;
|
tomwalters@0
|
116 char *argv[] ;
|
tomwalters@0
|
117 {
|
tomwalters@0
|
118 FILE *fp ;
|
tomwalters@0
|
119 int i, framebytes, startbytes, frameshift;
|
tomwalters@0
|
120 char *header, *SaiHeader();
|
tomwalters@0
|
121 short *nap, *frame, *endframe;
|
tomwalters@0
|
122
|
tomwalters@0
|
123 fp = openopts( option,argc,argv ) ;
|
tomwalters@0
|
124 if ( !isoff( helpstr ) )
|
tomwalters@0
|
125 helpopts( helpstr, argv[0], applic, option ) ;
|
tomwalters@0
|
126
|
tomwalters@0
|
127 if ( ison( debugstr ) ) {
|
tomwalters@0
|
128 printf("start=%s length=%s width=%s shift=%s\n",
|
tomwalters@0
|
129 startstr, lengthstr, widthstr, shiftstr );
|
tomwalters@0
|
130 exit(0);
|
tomwalters@0
|
131 }
|
tomwalters@0
|
132
|
tomwalters@0
|
133 if ( (header = ReadHeader(fp)) == (char *) 0 ) {
|
tomwalters@0
|
134 fprintf(stderr,"naptosai: header not found\n");
|
tomwalters@0
|
135 exit(1);
|
tomwalters@0
|
136 }
|
tomwalters@0
|
137
|
tomwalters@0
|
138 frameheight = HeaderInt( header, "frameheight" );
|
tomwalters@0
|
139 framewidth = HeaderInt( header, "framewidth" );
|
tomwalters@0
|
140 frames = HeaderInt( header, "frames" );
|
tomwalters@0
|
141 samplerate = HeaderSamplerate( header, "samplerate" );
|
tomwalters@0
|
142
|
tomwalters@0
|
143 start = to_p( startstr, samplerate );
|
tomwalters@0
|
144 if ( ismax( lengthstr ) ) /* Special case for remainder of input */
|
tomwalters@0
|
145 length = frames - start ;
|
tomwalters@0
|
146 else
|
tomwalters@0
|
147 length = to_p( lengthstr, samplerate );
|
tomwalters@0
|
148
|
tomwalters@0
|
149 if ( start + length > frames ) {
|
tomwalters@0
|
150 fprintf(stderr,"naptosai: nap too small (%d ms) for requested start and length \n", to_ms( frames, samplerate ) );
|
tomwalters@0
|
151 exit(1);
|
tomwalters@0
|
152 }
|
tomwalters@0
|
153
|
tomwalters@0
|
154 framebytes = frameheight * length * sizeof(short) ;
|
tomwalters@0
|
155 startbytes = frameheight * start * sizeof(short) ;
|
tomwalters@0
|
156
|
tomwalters@0
|
157 Newframeheight = frameheight ;
|
tomwalters@0
|
158 if ( ismax( widthstr ) ) /* Special case for single frame of max width */
|
tomwalters@0
|
159 Newframewidth = length ;
|
tomwalters@0
|
160 else
|
tomwalters@0
|
161 Newframewidth = to_p( widthstr, samplerate ) ;
|
tomwalters@0
|
162 Newframeshift = to_p( shiftstr, samplerate ) ;
|
tomwalters@0
|
163 Newframebytes = Newframeheight * Newframewidth * sizeof(short) ;
|
tomwalters@0
|
164 if ( Newframeshift > 0 )
|
tomwalters@0
|
165 Newframes = 1 + ( length - Newframewidth ) / Newframeshift ;
|
tomwalters@0
|
166 else { /* Special case of zero shift */
|
tomwalters@0
|
167 Newframes = 1 ;
|
tomwalters@0
|
168 Newframeshift = 1 ;
|
tomwalters@0
|
169 }
|
tomwalters@0
|
170
|
tomwalters@0
|
171 if ( length < Newframewidth ) {
|
tomwalters@0
|
172 fprintf(stderr,"naptosai: nap too small (%d ms) for requested width\n", to_ms( length, samplerate ) );
|
tomwalters@0
|
173 exit(1);
|
tomwalters@0
|
174 }
|
tomwalters@0
|
175
|
tomwalters@0
|
176 fprintf(stderr,"Output %d sai frames, each %d bytes\n", Newframes, Newframebytes );
|
tomwalters@0
|
177
|
tomwalters@0
|
178 if ( ison( headerstr ) )
|
tomwalters@0
|
179 WriteHeader( SaiHeader(header), stdout );
|
tomwalters@0
|
180
|
tomwalters@0
|
181 /* Allocate space for framebytes of nap data */
|
tomwalters@0
|
182
|
tomwalters@0
|
183 if ( (nap = (short *)malloc( framebytes )) == NULL ) {
|
tomwalters@0
|
184 fprintf(stderr,"naptosai: malloc out of space\n");
|
tomwalters@0
|
185 exit(1);
|
tomwalters@0
|
186 }
|
tomwalters@0
|
187
|
tomwalters@0
|
188 /* Seek to start in blocks of framebytes */
|
tomwalters@0
|
189
|
tomwalters@0
|
190 for (i=framebytes ; i < startbytes ; i += framebytes)
|
tomwalters@0
|
191 if ( fread( nap, framebytes, 1, fp ) == NULL ) {
|
tomwalters@0
|
192 fprintf(stderr,"naptosai: missing data after header\n");
|
tomwalters@0
|
193 exit(1);
|
tomwalters@0
|
194 }
|
tomwalters@0
|
195 if ( (startbytes -= (i - framebytes)) > 0 )
|
tomwalters@0
|
196 if ( fread( nap, startbytes, 1, fp ) == NULL ) {
|
tomwalters@0
|
197 fprintf(stderr,"naptosai: missing data after header\n");
|
tomwalters@0
|
198 exit(1);
|
tomwalters@0
|
199 }
|
tomwalters@0
|
200
|
tomwalters@0
|
201 /* Read framebytes of i/p nap data */
|
tomwalters@0
|
202
|
tomwalters@0
|
203 if ( fread( nap, framebytes, 1, fp ) == NULL ) {
|
tomwalters@0
|
204 fprintf(stderr,"naptosai: missing data after header\n");
|
tomwalters@0
|
205 exit(1);
|
tomwalters@0
|
206 }
|
tomwalters@0
|
207
|
tomwalters@0
|
208 frameshift = Newframeshift * Newframeheight ;
|
tomwalters@0
|
209 endframe = nap + Newframes * frameshift ;
|
tomwalters@0
|
210
|
tomwalters@0
|
211 for ( frame = nap ; frame < endframe ; frame += frameshift )
|
tomwalters@0
|
212 writeframe( frame, stdout ) ;
|
tomwalters@0
|
213
|
tomwalters@0
|
214 fprintf(stderr,"naptosai done\n" ) ;
|
tomwalters@0
|
215
|
tomwalters@0
|
216 }
|
tomwalters@0
|
217
|
tomwalters@0
|
218
|
tomwalters@0
|
219
|
tomwalters@0
|
220 /* Write a frame in sai format */
|
tomwalters@0
|
221
|
tomwalters@0
|
222 writeframe( frame, fp )
|
tomwalters@0
|
223 short *frame ;
|
tomwalters@0
|
224 FILE *fp ;
|
tomwalters@0
|
225 {
|
tomwalters@0
|
226 int i, row, col;
|
tomwalters@0
|
227
|
tomwalters@0
|
228 for (row=0 ; row < Newframeheight ; row++)
|
tomwalters@0
|
229 for (col=0 , i=row ; col < Newframewidth ; col++, i+=Newframeheight)
|
tomwalters@0
|
230 fwrite( &frame[i], sizeof(short), 1, fp );
|
tomwalters@0
|
231 }
|
tomwalters@0
|
232
|
tomwalters@0
|
233
|
tomwalters@0
|
234 /*********************** Read header and build new header *****************/
|
tomwalters@0
|
235
|
tomwalters@0
|
236 /*
|
tomwalters@0
|
237 Copy the original nap header to a new sai header, changing in order:
|
tomwalters@0
|
238 frames
|
tomwalters@0
|
239 frameshift
|
tomwalters@0
|
240 framewidth
|
tomwalters@0
|
241 frameheight
|
tomwalters@0
|
242 framebytes
|
tomwalters@0
|
243 Then change applic name [gennap] to [gensai] in the Version string.
|
tomwalters@0
|
244 Finally, update the new header_bytes, and return the new header.
|
tomwalters@0
|
245 */
|
tomwalters@0
|
246
|
tomwalters@0
|
247 char *SaiHeader( napheader )
|
tomwalters@0
|
248 char *napheader ;
|
tomwalters@0
|
249 {
|
tomwalters@0
|
250 char *saiheader;
|
tomwalters@0
|
251 char *p0, *p1, *p2, *s, str[64];
|
tomwalters@0
|
252
|
tomwalters@0
|
253 saiheader = (char *)malloc( strlen(napheader) + 64 ) ;
|
tomwalters@0
|
254
|
tomwalters@0
|
255 p0 = saiheader ;
|
tomwalters@0
|
256 p1 = napheader ;
|
tomwalters@0
|
257
|
tomwalters@0
|
258
|
tomwalters@0
|
259 /** copy up to frames **/
|
tomwalters@0
|
260
|
tomwalters@0
|
261 p2 = HeaderString( napheader , "frames" ) ;
|
tomwalters@0
|
262 while( p1 < p2 )
|
tomwalters@0
|
263 *p0++ = *p1++ ;
|
tomwalters@0
|
264
|
tomwalters@0
|
265 sprintf(str,"%d\n", Newframes);
|
tomwalters@0
|
266 for (s = str ; *s != '\n' ; )
|
tomwalters@0
|
267 *p0++ = *s++;
|
tomwalters@0
|
268 *p0++ = *s;
|
tomwalters@0
|
269 while (*p1 != '\n')
|
tomwalters@0
|
270 *p1++;
|
tomwalters@0
|
271 *p1++;
|
tomwalters@0
|
272
|
tomwalters@0
|
273
|
tomwalters@0
|
274 /** copy up to frameshift **/
|
tomwalters@0
|
275
|
tomwalters@0
|
276 p2 = HeaderString( napheader , "frameshift" ) ;
|
tomwalters@0
|
277 while ( p1 < p2 )
|
tomwalters@0
|
278 *p0++ = *p1++ ;
|
tomwalters@0
|
279
|
tomwalters@0
|
280 sprintf(str,"%d\n", Newframeshift);
|
tomwalters@0
|
281 for (s = str ; *s != '\n' ; )
|
tomwalters@0
|
282 *p0++ = *s++;
|
tomwalters@0
|
283 *p0++ = *s;
|
tomwalters@0
|
284 while (*p1 != '\n')
|
tomwalters@0
|
285 *p1++;
|
tomwalters@0
|
286 *p1++;
|
tomwalters@0
|
287
|
tomwalters@0
|
288
|
tomwalters@0
|
289 /** copy up to framewidth **/
|
tomwalters@0
|
290
|
tomwalters@0
|
291 p2 = HeaderString( napheader , "framewidth" ) ;
|
tomwalters@0
|
292 while ( p1 < p2 )
|
tomwalters@0
|
293 *p0++ = *p1++ ;
|
tomwalters@0
|
294
|
tomwalters@0
|
295 sprintf(str,"%d\n", Newframewidth);
|
tomwalters@0
|
296 for (s = str ; *s != '\n' ; )
|
tomwalters@0
|
297 *p0++ = *s++;
|
tomwalters@0
|
298 *p0++ = *s;
|
tomwalters@0
|
299 while (*p1 != '\n')
|
tomwalters@0
|
300 *p1++;
|
tomwalters@0
|
301 *p1++;
|
tomwalters@0
|
302
|
tomwalters@0
|
303
|
tomwalters@0
|
304 /** copy up to frameheight **/
|
tomwalters@0
|
305
|
tomwalters@0
|
306 p2 = HeaderString( napheader , "frameheight" ) ;
|
tomwalters@0
|
307 while ( p1 < p2 )
|
tomwalters@0
|
308 *p0++ = *p1++ ;
|
tomwalters@0
|
309
|
tomwalters@0
|
310 sprintf(str,"%d\n", Newframeheight);
|
tomwalters@0
|
311 for (s = str ; *s != '\n' ; )
|
tomwalters@0
|
312 *p0++ = *s++;
|
tomwalters@0
|
313 *p0++ = *s;
|
tomwalters@0
|
314 while (*p1 != '\n')
|
tomwalters@0
|
315 *p1++;
|
tomwalters@0
|
316 *p1++;
|
tomwalters@0
|
317
|
tomwalters@0
|
318
|
tomwalters@0
|
319 /** copy up to framebytes **/
|
tomwalters@0
|
320
|
tomwalters@0
|
321 p2 = HeaderString( napheader , "framebytes" ) ;
|
tomwalters@0
|
322 while ( p1 < p2 )
|
tomwalters@0
|
323 *p0++ = *p1++ ;
|
tomwalters@0
|
324
|
tomwalters@0
|
325 sprintf(str,"%d\n", Newframebytes);
|
tomwalters@0
|
326 for (s = str ; *s != '\n' ; )
|
tomwalters@0
|
327 *p0++ = *s++;
|
tomwalters@0
|
328 *p0++ = *s;
|
tomwalters@0
|
329 while (*p1 != '\n')
|
tomwalters@0
|
330 *p1++;
|
tomwalters@0
|
331 *p1++;
|
tomwalters@0
|
332
|
tomwalters@0
|
333
|
tomwalters@0
|
334 /** copy rest of header **/
|
tomwalters@0
|
335
|
tomwalters@0
|
336 p2 = HeaderString( napheader , "Version" ) ;
|
tomwalters@0
|
337 while ( p1 < p2 )
|
tomwalters@0
|
338 *p0++ = *p1++ ;
|
tomwalters@0
|
339
|
tomwalters@0
|
340 while (*p1 != ']') /* change applic name [gennap] to [gensai] */
|
tomwalters@0
|
341 *p0++ = *p1++ ;
|
tomwalters@0
|
342 *(p0-3) = 's' ;
|
tomwalters@0
|
343 *(p0-2) = 'a' ;
|
tomwalters@0
|
344 *(p0-1) = 'i' ;
|
tomwalters@0
|
345 while (*p1 != '\n')
|
tomwalters@0
|
346 *p0++ = *p1++ ;
|
tomwalters@0
|
347 *p0++ = *p1++ ;
|
tomwalters@0
|
348
|
tomwalters@0
|
349
|
tomwalters@0
|
350 /** update header_bytes **/
|
tomwalters@0
|
351
|
tomwalters@0
|
352 sprintf(str, "%0*d", 7, p0-saiheader);
|
tomwalters@0
|
353 p0 = HeaderString( saiheader , "header_bytes" ) ;
|
tomwalters@0
|
354 s = str;
|
tomwalters@0
|
355 while(*p0 != '\n')
|
tomwalters@0
|
356 *p0++ = *s++ ;
|
tomwalters@0
|
357
|
tomwalters@0
|
358
|
tomwalters@0
|
359 return saiheader;
|
tomwalters@0
|
360 }
|
tomwalters@0
|
361
|
tomwalters@0
|
362
|