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