Mercurial > hg > aim92
comparison model/gen.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 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 | |
3 =========================================================================== | |
4 | |
5 Permission to use, copy, modify, and distribute this software without fee | |
6 is hereby granted for research purposes, provided that this copyright | |
7 notice appears in all copies and in all supporting documentation, and that | |
8 the software is not redistributed for any fee (except for a nominal shipping | |
9 charge). Anyone wanting to incorporate all or part of this software in a | |
10 commercial product must obtain a license from the Medical Research Council. | |
11 | |
12 The MRC makes no representations about the suitability of this | |
13 software for any purpose. It is provided "as is" without express or implied | |
14 warranty. | |
15 | |
16 */ | |
17 | |
18 /* | |
19 gen.c | |
20 ===== | |
21 | |
22 APU, ASP model demonstration program. | |
23 | |
24 | |
25 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. | |
26 | |
27 | |
28 Authors : John Holdsworth (1989), Mike Allerhand (1990) | |
29 | |
30 | |
31 Edited : M.Akeroyd 22-1-1993 | |
32 Removed the conditional of `if (centering) Clear (w)' | |
33 (in plot_frame), so that Clear may be called for | |
34 PostScriptWindows that AREN'T centered, so allowing | |
35 showpages to be generated. | |
36 See also edit to ps.c | |
37 | |
38 : M Akeroyd 3-8-1993 | |
39 Added new options: | |
40 erbscale_efb (InputOption) mono_ctn (SilentOption) | |
41 colour_ctn (SilentOption) planemask_ctn (SilentOption) | |
42 Allowed "bitmap=stdout". | |
43 | |
44 : MAA 3rd August 1993 | |
45 Extra options | |
46 framenumber (SilentOption), review (SilentOption) | |
47 | |
48 : MAA 22nd July 1994. | |
49 Extra postscript options ALl silent | |
50 xstart_ps xend_ps ystart_ps yend_ps | |
51 xtitle_ps ytitle_ps | |
52 Extra X options | |
53 fg_col bg_col | |
54 | |
55 : MAA Summer 1984. Lots of postscript options. All silent | |
56 portraitstr, landscapestr; | |
57 fontnamestr, fontsizestr; | |
58 xmajorticksstr, xminorticksstr, ymajorticksstr, yminorticksstr; | |
59 axistop, axisbottom, axisleft, axisright; | |
60 | |
61 : AJD Spring 1995. | |
62 Added a new argument 'nwid' to the function SourceDraw, so that genspl | |
63 can have the necessary information. | |
64 | |
65 : AJD May, 1995. | |
66 Made options overlap, headroom, perspective, bytemax and type silent. | |
67 */ | |
68 | |
69 | |
70 #ifndef lint | |
71 static char *sccs_id = "@(#)gen.c 1.66 John Holdsworth, Mike Allerhand, Roy Patterson, Paul Manson (MRC-APU) 6/6/91" ; | |
72 #endif | |
73 | |
74 | |
75 /**************************************************************************** | |
76 * This module contains: | |
77 * Display option parameter strings. | |
78 * Model option parameter strings. | |
79 * File-format strings. | |
80 * X windows interface, (included from windows.h). | |
81 * Options handler routines, (included from options.h). | |
82 * Option defaults, (application specific). | |
83 * Strings for generic option types, (OnOption etc). | |
84 * Display options table, (displayopts[]). | |
85 * Model option tables, (included from table.c). | |
86 * Model entry-point functions, (included from model.c). | |
87 * Display drawing routines, (included from draw.h and fill.h). | |
88 * Options table construction, (constructOptions(), and mapOptions()). | |
89 * Main. | |
90 ****************************************************************************/ | |
91 | |
92 #include <string.h> | |
93 #include <ctype.h> | |
94 #include <stdio.h> | |
95 #include <math.h> | |
96 | |
97 #if defined(THINK_C) || defined(NeXT) | |
98 #include <stdlib.h> | |
99 #endif | |
100 | |
101 /********************* Display option parameter strings ********************* | |
102 * The strings defined here are pointers referenced by the "value" field in | |
103 * the display options table, displayopts. They are assigned to space which | |
104 * initially contains defaults in the "defaultValue" field of the display | |
105 * options table. | |
106 ****************************************************************************/ | |
107 | |
108 static char *bmaxstr, *topstr, *botstr, *overstr ; | |
109 static char *headstr, *downcstr, *heightstr, *helpstr ; | |
110 static char *invertstr, *lengthstr, *linstr, *outstr ; | |
111 static char *reusestr, *startstr, *envstr, *typestr ; | |
112 #ifdef X11 | |
113 static char *dispstr, *erasestr, *hiddenstr, *bitmapstr ; | |
114 static char *kludgestr, *magstr, *penstr, *psfilestr ; | |
115 static char *psstr, *animstr, *titlestr, *viewstr ; | |
116 static char *widthstr, *xstr, *ystr ; | |
117 /* All these MAA. */ | |
118 char *monostr, *colourstr, *planemaskstr, *rotateaxesstr; | |
119 char *fgcolourstr, *bgcolourstr; | |
120 char *xstartstr, *ystartstr, *xendstr, *yendstr; | |
121 char *xnewtitlestr, *ynewtitlestr; | |
122 char *portraitstr, *landscapestr; | |
123 char *fontnamestr, *fontsizestr, *titlesizestr; | |
124 char *xticksstr, *yticksstr, *outsidestr; | |
125 char *axistopstr, *axisbottomstr, *axisleftstr, *axisrightstr; | |
126 char *xmajorticksstr, *xminorticksstr, *ymajorticksstr, *yminorticksstr; | |
127 char *axislinewidthstr, *figurelinewidthstr; | |
128 char *boxstr; | |
129 #endif /* X11 */ | |
130 | |
131 char *framenumberstr, *reviewstr; /* MAA: 3-8-1993 */ | |
132 | |
133 static char *test1str, *test2str, *test3str, *test4str ; | |
134 | |
135 char headerstr[64] ; | |
136 | |
137 char *filestr ; | |
138 | |
139 /* application display parameters */ | |
140 | |
141 #ifdef X11 | |
142 static char *tiltstr = "0." ; | |
143 static char *diststr = "0.5" ; | |
144 static char *roomstr = "0%" ; | |
145 #endif /* X11 */ | |
146 | |
147 /*************** Included from glib (graphics library) directory ***********/ | |
148 | |
149 #include "options.h" | |
150 #include "defaults.h" | |
151 | |
152 #ifdef X11 | |
153 #include "windows.h" | |
154 #endif /* X11 */ | |
155 | |
156 /******************* Strings for generic option values ********************** | |
157 * Generic option values, (ON_OPTION etc), are defined in options.h. | |
158 * Convenience routines used to test or convert option values are: | |
159 * OptionStringsEqual( str1, str2 ) -(defined in options.c). | |
160 * isON( str ) -(defined in options.h). | |
161 * isOFF( str ) -(defined in options.c). | |
162 * isNULL( str ) -(defined in options.c). | |
163 * OptionInt( str ) -(defined in model.c). | |
164 * OptionDouble( str ) -(defined in model.c). | |
165 * Samples( str ) -(defined in model.c). | |
166 * Cycles( str, cfreq ) -(defined in model.c). | |
167 * Scalar( str ) -(defined in model.c). | |
168 * Freq( str ) -(defined in model.c). | |
169 * | |
170 ****************************************************************************/ | |
171 | |
172 | |
173 static char helpstring[200] = "no help initially" ; | |
174 static char OnOption[] = ON_OPTION ; /* "on" */ | |
175 static char OffOption[] = OFF_OPTION ; /* "off" */ | |
176 static char NullOption[] = NULL_OPTION ; /* "none" */ | |
177 static char CenterStr[] = "center" ; | |
178 static char LengthStr[] = "remainder" ; | |
179 static char LandStr[] = "landscape" ; | |
180 | |
181 static int isEXCITE( str ) | |
182 char *str ; | |
183 { | |
184 return ( strncmp( str, "excitation", strlen( str ) ) == 0 ) ; | |
185 } | |
186 | |
187 static int isWATERFALL( str ) | |
188 char *str ; | |
189 { | |
190 return ( strncmp( str, "waterfall", strlen( str ) ) == 0 ) ; | |
191 } | |
192 | |
193 static int isGREYSCALE( str ) | |
194 char *str ; | |
195 { | |
196 return ( strncmp( str, "greyscale", strlen( str ) ) == 0 || | |
197 strncmp( str, "grayscale", strlen( str ) ) == 0 ) ; | |
198 } | |
199 | |
200 | |
201 | |
202 /************************* Options table *********************************** | |
203 * The complete options table is built by constructOptions() according to the | |
204 * application. It is composed of the display options, (displayopts[], below), | |
205 * and the model option tables (from table.c) which are appropriate for the | |
206 * application. The sequence of processing stages, (and hence model option | |
207 * tables), for an application is determined by FindStage() in model.c. | |
208 * | |
209 * The complete options table is an array of Option structs. | |
210 * The Option struct is defined in options.h as: | |
211 * | |
212 * typedef struct { | |
213 * char *name ; The name of the option. | |
214 * char *defaultValue ; Default value. | |
215 * char **value ; Address of current value. | |
216 * char *comment ; Something to print when the user types "-help". | |
217 * short classification ; Type of option it is. | |
218 * } Option; | |
219 * | |
220 * The classification of options uses names defined in options.h: | |
221 * InputOption | |
222 * OutputOption | |
223 * InOutOption | |
224 * SilentOption | |
225 * | |
226 * Routines which access the option table: | |
227 * Note: Some routines are called to supply arguments to other routines. | |
228 * Routines which access the option table in some way are denoted (*). | |
229 * Most of these routines are defined in options.c. | |
230 * | |
231 * main() | |
232 * | | |
233 * +-----------------+-----------+----+-------+-----------------+ | |
234 * | | | | | | |
235 * | | | ModeledSource() | | |
236 * | | | | | | |
237 * | | | checkForFile() | | |
238 * helpopts() | | | | | |
239 * | | +---+---+ | | |
240 * | | | | | |
241 * | getopts() readopts() writeopts() | |
242 * | | | | | |
243 * | getnopts(*) readnopts() writenopts(*) | |
244 * | [arg countOptions(*)] [arg countOptions(*)] [arg countOptions(*)] | |
245 * | | | | | |
246 * | +-------+------+ | countBytesToWrite(*) | |
247 * | | | | | | |
248 * | | | +------+------+ | |
249 * | | | | | |
250 * | | | processOptionFile() | |
251 * | | | | | |
252 * | | +------+------+ | |
253 * | | | | |
254 * | | LookUpAndStore(*) | |
255 * | | | | |
256 * | | +---+---+----------+ | |
257 * | | | | | | |
258 * | +-----+----+ LookUp(*) Ambiguity(*) | |
259 * | | | | |
260 * +----+----+ updateOptionsFile(*) | |
261 * | | |
262 * defaultHelpHandler(*) | |
263 * | |
264 * | |
265 * getopts() | |
266 * Operates on the options table given to it as an argument. | |
267 * a) Each "value" field is initialized to its "defaultValue" field. | |
268 * b) The "value" fields are re-initialized by any corresponding values found | |
269 * in the options ("rc") file, (overriding the "defaultValue"). | |
270 * c) The "value" fields are re-initialized again by any corresponding values | |
271 * found in command-line arguments. | |
272 * d) Special arguments are dealt with: | |
273 * "help" calls the onLineHelpHandler() routine, (see below). | |
274 * "update" calls the updateOptionsFile() routine. | |
275 * e) Return the remainder of the command-line (argc and argv) for use in | |
276 * main(). | |
277 * | |
278 * helpopts() | |
279 * Is called to print the help menu if no input file has been found by | |
280 * getopts(), (in the "rc" file), and none remains on the command-line. | |
281 * An alias for the onLineHelpHandler() function, which is in turn an | |
282 * alias for the defaultHelpHandler() routine, (see options.c). | |
283 * | |
284 * readopts() | |
285 * Read any options header which may be at the start of the input file. | |
286 * Interpret the header like an options ("rc") file, and re-initialize any | |
287 * corresponding "value" fields in the given options table, (as in getopts()). | |
288 * Skip to the start of the input data, allowing for any offset (ie startstr). | |
289 * | |
290 * writeopts() | |
291 * Write the given options table as an options header at the start of an o/p | |
292 * file, if the "header" option is "on". | |
293 * | |
294 ****************************************************************************/ | |
295 | |
296 static Option *options; | |
297 | |
298 /******************** Display options table ******************************** | |
299 * Options table for application display parameters. | |
300 ****************************************************************************/ | |
301 | |
302 static Option displayopts[] = { | |
303 | |
304 /* Miscellaneous Silent Parameters (hidden from users) */ | |
305 | |
306 | |
307 { "Version", headerstr, &versionstr, "Version number and date", OutputOption}, | |
308 | |
309 { "test1", "0", &test1str, "Dummy option for test and development", SilentOption}, | |
310 { "test2", "0", &test2str, "Dummy option for test and development", SilentOption}, | |
311 { "test3", "0", &test3str, "Dummy option for test and development", SilentOption}, | |
312 { "test4", "0", &test4str, "Dummy option for test and development", SilentOption}, | |
313 | |
314 { "linear_sgm", OffOption, &linstr, "Linear frequency axis for spectrograms",SilentOption}, | |
315 { "useprevious", OffOption, &reusestr, "Use previously stored output", SilentOption}, | |
316 | |
317 /* MAA: 21-8-1993 | |
318 * These next two options are here, because otherwise "gensgm -use ..." (at least) core dumps. | |
319 */ | |
320 { "framenumber", OffOption, &framenumberstr, "Index of current frame (to stderr)\n", SilentOption}, | |
321 { "review", OffOption, &reviewstr, "Wait for keyboard <return> between frames",SilentOption}, | |
322 | |
323 #ifdef X11 | |
324 { "pstofile", OffOption, &psfilestr, "Send PostScript output to .ps file", SilentOption}, | |
325 { "invert", OffOption, &invertstr, "Invert axis of sai image", SilentOption}, | |
326 { "fast", OffOption, &kludgestr, "Speed up image generation", SilentOption}, | |
327 #endif /* X11 */ | |
328 | |
329 /* ( The order of the "help" option members is strange due to the way */ | |
330 /* it was originally used. See options.c: defaultHelpHandler() and */ | |
331 /* updateOptionsFile() ). */ | |
332 | |
333 /* Input Parameters */ | |
334 | |
335 { "envelope", OffOption, &envstr, "Type of model to use required", SilentOption}, | |
336 { "help", "not used", &helpstr, helpstring, SilentOption}, | |
337 | |
338 #ifdef X11 | |
339 | |
340 /* Screen Output Parameters */ | |
341 | |
342 { "title", "filename", &titlestr, "Title of picture, or input filename", InputOption}, | |
343 #ifdef THINK_C | |
344 { "x0_win", "10", &xstr, "Left edge of window (pixels)", InOutOption}, | |
345 { "y0_win", "50", &ystr, "Lower edge of window (pixels)", InOutOption}, | |
346 #else | |
347 { "x0_win", CenterStr, &xstr, "Left edge of window (pixels)", InOutOption}, | |
348 { "y0_win", CenterStr, &ystr, "Lower edge of window (pixels)", InOutOption}, | |
349 #endif | |
350 #ifdef PC | |
351 { "width_win", "400", &widthstr, "Window width (pixels)", InOutOption}, | |
352 { "height_win", "300", &heightstr, "Window height (pixels)\n", InOutOption}, | |
353 #else /* UNIX */ | |
354 { "width_win", "540", &widthstr, "Window width (pixels)", InOutOption}, | |
355 { "height_win", "400", &heightstr, "Window height (pixels)\n", InOutOption}, | |
356 #endif | |
357 { "display", OnOption, &dispstr, "Select display of output image", InOutOption}, | |
358 { "view", LandStr, &viewstr, "Select display format", InOutOption}, | |
359 { "top", "1024", &topstr, "Maximum of plotted range", InputOption}, | |
360 { "bottom", "-1024", &botstr, "Minimum of plotted range", InputOption}, | |
361 { "overlap", "50%", &overstr, "Overlap between channels", SilentOption}, /* AJD 16-5-95 */ | |
362 { "headroom", "0%", &roomstr, "Headroom at top of picture", SilentOption}, /* AJD 16-5-95 */ | |
363 { "magnification", "1", &magstr, "Magnification of image in display", InputOption}, | |
364 { "pensize", "1", &penstr, "Size of plotted lines and dots", InputOption}, | |
365 { "hiddenline", OnOption, &hiddenstr, "Hidden line removal\n", InputOption}, | |
366 { "perspective", "0", &tiltstr, "Perspective view of display (degrees)\n", SilentOption}, /* AJD 16-5-95 */ | |
367 #endif /* X11 */ | |
368 | |
369 { "downchannel", OffOption, &downcstr, "Average adjacent frequency channels\n", InOutOption}, | |
370 | |
371 #ifdef X11 | |
372 | |
373 /* Auditory image cartoon parameters */ | |
374 | |
375 { "erase_ctn", OnOption, &erasestr, "Erase display between cartoon frames", InOutOption}, | |
376 { "animate_ctn", OffOption, &animstr, "Animate cartoon", InOutOption}, | |
377 { "bitmap_ctn", OffOption, &bitmapstr, "Produce cartoon output (.ctn)\n", InputOption}, | |
378 { "mono_ctn", OnOption, &monostr, "Force monochrome (single plane) cartoons.", SilentOption}, | |
379 { "colour_ctn", OffOption, &colourstr, "Force colour (multi-plane) cartoons.", SilentOption}, | |
380 {"planemask_ctn", "1", &planemaskstr, "Planemask for creating cartoons.\n", SilentOption}, | |
381 {"fg_col", "black", &fgcolourstr, "Foreground Colour.\n", SilentOption}, | |
382 {"bg_col", "white", &bgcolourstr, "Background Colour.\n", SilentOption}, | |
383 | |
384 | |
385 /* Postscript options */ | |
386 | |
387 { "postscript", OffOption, &psstr, "Produce postscript output", InputOption}, | |
388 { "rotateaxes", OffOption, &rotateaxesstr, "Rotate the axes labels in .ps output", SilentOption}, | |
389 { "xstart_ps", "", &xstartstr, "Postscript x-axis: start point.", SilentOption}, | |
390 { "xend_ps", "", &xendstr, "Postscript x-axis: end point.", SilentOption}, | |
391 { "ystart_ps", "", &ystartstr, "Postscript y-axis: start point.", SilentOption}, | |
392 { "yend_ps", "", ¥dstr, "Postscript y-axis: end point.", SilentOption}, | |
393 { "xtitle_ps", "", &xnewtitlestr, "Postscript x-axis: title.", SilentOption}, | |
394 { "ytitle_ps", "", &ynewtitlestr, "Postscript x-axis: title.", SilentOption}, | |
395 { "portrait_ps", "", &portraitstr, "Use 'portrait' page format", SilentOption}, | |
396 { "landscape_ps", "", &landscapestr, "Use 'landscape' page format (overrides 'portriat)", SilentOption}, | |
397 { "fontname_ps", "Helvetica", &fontnamestr, "Define font", SilentOption}, | |
398 { "fontsize_ps", "12", &fontsizestr, "Define fontsize (points)", SilentOption}, | |
399 { "fonttitlesize_ps", "0", &titlesizestr, "Define fontsize for title (points)", SilentOption}, | |
400 { "axislinewidth_ps", "1", &axislinewidthstr, "Linewidth for axes & tickmarks (points)", SilentOption}, | |
401 { "figurelinewidth_ps", "1", &figurelinewidthstr, "Linewidth for figures (points)", SilentOption}, | |
402 { "xticks_ps", "6", &xticksstr, "Define size of x-axis (big) ticks (points)", SilentOption}, | |
403 { "yticks_ps", "6", &yticksstr, "Define size of y-axis (big) ticks' (points)", SilentOption}, | |
404 { "outsideticks_ps",OnOption, &outsidestr, "Print tick-marks 'outside' figure", SilentOption}, | |
405 { "axistop_ps", OnOption, &axistopstr, "Print tick-marks on top side", SilentOption}, | |
406 { "axisbottom_ps", OnOption, &axisbottomstr, "Print tick-marks on bottom side", SilentOption}, | |
407 { "axisleft_ps", OnOption, &axisleftstr, "Print tick-marks on left side", SilentOption}, | |
408 { "axisright_ps", OnOption, &axisrightstr, "Print tick-marks on right side", SilentOption}, | |
409 { "xmajorticks_ps", "1", &xmajorticksstr, "Relative *spacing* of ticks", SilentOption}, | |
410 { "xminorticks_ps", "1", &xminorticksstr, "Relative *spacing* of ticks", SilentOption}, | |
411 { "ymajorticks_ps", "1", &ymajorticksstr, "Relative *spacing* of ticks", SilentOption}, | |
412 { "yminorticks_ps", "1", &yminorticksstr, "Relative *spacing* of ticks", SilentOption}, | |
413 { "box_ps", OnOption, &boxstr, "Plot a box", SilentOption}, | |
414 #endif /* X11 */ | |
415 | |
416 /* File Output Parameters */ | |
417 { "output", OffOption, &outstr, "Produce output file", InputOption}, | |
418 { "header", OnOption, &headstr, "Add a header to the output file\n", InOutOption}, | |
419 { "bytemax", "255", &bmaxstr, "Maximum value in byte output", SilentOption}, /* AJD 16-5-95 */ | |
420 { "type", "short", &typestr, "Output data type\n", SilentOption}, /* AJD 16-5-95 */ | |
421 | |
422 { "input_wave", NullOption, &filestr, "Default input file name", InputOption}, | |
423 { "start_wave", "0ms", &startstr, "Start point in wave (ms)", InputOption}, | |
424 { "length_wave", LengthStr, &lengthstr, "Length of wave to process (ms)", InputOption}, | |
425 | |
426 ( char * ) 0 } ; | |
427 | |
428 | |
429 /*********************** Included from stitch directory ********************/ | |
430 | |
431 /* interfaces to stitch system */ | |
432 | |
433 #include "stitch.h" | |
434 #include "source.h" | |
435 #include "spiral.h" | |
436 #include "image.h" | |
437 #include "model.h" | |
438 #include "units.h" | |
439 #include "calc.h" | |
440 #include "ops.h" | |
441 #include "io.h" | |
442 | |
443 | |
444 #ifdef X11 | |
445 #include "draw.h" | |
446 #include "fill.h" | |
447 #endif /* X11 */ | |
448 | |
449 /**************************************************************************/ | |
450 | |
451 char *AlterSuffix() ; /* alter suffix of file name. */ | |
452 #ifdef X11 | |
453 void save_frame(), plot_frame() ; /* draw callbacks. */ | |
454 void fast_frame() ; | |
455 #endif /* X11 */ | |
456 | |
457 extern char *genstate() ; | |
458 static char *gen_state ; | |
459 | |
460 Source DownChannel() ; /* reduce channels by averaging. */ | |
461 #ifdef X11 | |
462 Source PackShorts() ; /* pack output into one byte. */ | |
463 #endif /* X11 */ | |
464 Source checkForFile() ; /* create source from file if present. */ | |
465 | |
466 #define POSTSCRIPT_FILE_SUFFIX ".ps" | |
467 #define CARTOON_FILE_SUFFIX ".ctn" | |
468 | |
469 #ifdef X11 | |
470 static WindowObject display = 0 ; | |
471 #endif /* X11 */ | |
472 | |
473 /***************************************************************************/ | |
474 | |
475 /* Return length of the file in bytes */ | |
476 static long fileLength( fp ) | |
477 FILE *fp ; | |
478 { | |
479 long posn = ftell( fp ) ; | |
480 long length = 0 ; | |
481 | |
482 if( fseek( fp, 0l, 2 ) == 0 ) { | |
483 | |
484 length = ftell( fp ) ; | |
485 | |
486 (void) fseek( fp, posn, 0 ) ; | |
487 } | |
488 | |
489 return ( length ) ; | |
490 } | |
491 | |
492 /* per frame image handling */ | |
493 | |
494 static FILE *inputFilePointer = ( FILE * ) 0 ; | |
495 | |
496 #ifdef X11 | |
497 | |
498 static FILE *imageFilePointer = ( FILE * ) 0 ; | |
499 static int images = 0 ; | |
500 static void (*frame_drawer)() ; | |
501 | |
502 /***** axis information *****/ | |
503 /* | |
504 "Axis" is defined in windows.h:143 | |
505 The postscript program for drawing axis stuff is in axis.h | |
506 */ | |
507 | |
508 static int Top() | |
509 { | |
510 return ( atof( topstr ) / atof( magstr ) + 0.5 ) ; | |
511 } | |
512 | |
513 static int Bot() | |
514 { | |
515 if( atof( botstr ) < 0 ) | |
516 return ( atof( botstr ) / atof( magstr ) - 0.5 ) ; | |
517 else | |
518 return ( atof( botstr ) / atof( magstr ) + 0.5 ) ; | |
519 } | |
520 | |
521 static struct { | |
522 double min, max ; | |
523 char *label ; | |
524 } xaxis, yaxis ; | |
525 | |
526 | |
527 | |
528 TimeAxis( min, max, label ) | |
529 double *min, *max ; | |
530 char **label ; | |
531 { | |
532 *min = Samples( startstr, Samplerate() ) / Samplerate() ; | |
533 *max = Samples( startstr, Samplerate() ) / Samplerate() + Frames() * Framestep() / Samplerate() ; | |
534 | |
535 if( *max > 1. ) | |
536 *label = "Time [s]" ; | |
537 else { | |
538 *label = "Time [ms]" ; | |
539 | |
540 *min *= 1000. ; | |
541 *max *= 1000. ; | |
542 } | |
543 } | |
544 | |
545 MagnitudeAxis( min, max, label ) | |
546 double *min, *max ; | |
547 char **label ; | |
548 { | |
549 *min = Bot() ; | |
550 *max = Top() / ( 1. - atof( headstr ) / 100. ) ; | |
551 | |
552 *label = "Magnitude" ; | |
553 } | |
554 | |
555 | |
556 static void DrawAxes( win ) | |
557 WindowObject win ; | |
558 { | |
559 /* frame window with axes */ | |
560 | |
561 Axes( win, titlestr, xaxis.min, xaxis.max, xaxis.label, | |
562 yaxis.min, yaxis.max, yaxis.label ) ; | |
563 return ; | |
564 } | |
565 | |
566 #endif /* X11 */ | |
567 | |
568 /******************************* main ************************************** | |
569 * The following tables are used extensively: | |
570 * stage table Arrays of _stage structs, ("envelope", "fine", etc.), defined | |
571 * in routine FindStage() in model.c. | |
572 * option table Array of Option structs built at run-time by | |
573 * constructOptions() from displayopts, (in gen.c), and tables of | |
574 * model options included from table.c. | |
575 * | |
576 * Compiler switches for model versions are: | |
577 * FLOAT For floating point version, (default uses integer arithmetic). | |
578 * Defined in calc.h. | |
579 * | |
580 * The model version number is the sccs <release-number>.<level-number> of | |
581 * the file version.c. Refer to that file for incrementing the version number. | |
582 * The version number is stored in versionstr in routine getversion(). | |
583 ****************************************************************************/ | |
584 | |
585 int argc_save ; | |
586 char **argv_save ; | |
587 | |
588 main( argc, argv ) | |
589 int argc ; | |
590 char *argv[] ; | |
591 #ifdef THINK_C | |
592 { | |
593 static char *realargv[] = { "prog", "", 0 }; | |
594 static char *progs = { "\pgenwav;-;\ | |
595 genfbm;genfbr;genfbc;genfbt;genfbd;gensai;genspl;gensas;-;\ | |
596 genbmm;gennap;gensai;-;gensgm;gencgm;gensas;-;genasa;genepn;gensep;-;Quit/Q" } ; | |
597 | |
598 extern char *MacMenu(), *MacFile() ; | |
599 | |
600 MacInit() ; | |
601 | |
602 realargv[0] = MacMenu(progs) ; | |
603 realargv[1] = MacFile() ; | |
604 | |
605 return ( real_main( sizeof( realargv ) / sizeof (*realargv) - 1, realargv ) ) ; | |
606 } | |
607 | |
608 real_main( argc, argv ) | |
609 int argc ; | |
610 char *argv[] ; | |
611 #endif | |
612 { | |
613 int i ; | |
614 FILE *ofp = 0 ; | |
615 Source source ; | |
616 char *which, *psfilename ; | |
617 char title[256] ; | |
618 char *programName ; | |
619 int x, y, pixels, image, time ; | |
620 long headerSize, fileFramebytes ; | |
621 double *frequency_scale ; | |
622 #ifdef X11 | |
623 WindowObject psw = 0 ; | |
624 char *imageFileName ; | |
625 #endif /* X11 */ | |
626 | |
627 /************************************************************************** | |
628 * Determine which version of the model is required. | |
629 * Set "which" to the last three chars of the program name, (allowing for | |
630 * a ".exe" extension in the case of a PC version). | |
631 **************************************************************************/ | |
632 | |
633 | |
634 programName = argv[0] ; | |
635 | |
636 which = programName + strlen( programName ) - strlen( "xxx" ) ; | |
637 | |
638 #ifdef PC | |
639 lowerArgs( argv, argc ) ; | |
640 | |
641 which -= strlen( ".exe" ) ; | |
642 #endif | |
643 | |
644 | |
645 /*************************************************************************** | |
646 * Process arguments, (the model options): | |
647 * Set option defaults (from option table in model.c). | |
648 * Then override these by any options in the options file, | |
649 * (the resource control file, eg .gensairc). | |
650 * Finally, override these by any options given as command-line arguments. | |
651 * | |
652 * offsetOptions() finds the first option, (a ptr to one line of the "res" | |
653 * array), required by the program. This gives a place mark in the options | |
654 * table. (Note that the bottom of the options table, a null, corresponds with | |
655 * the top of the help menu). | |
656 * This first option appropriate to the program is found by looking it up in | |
657 * the stage table (in model.c), and then cross-referencing the option name | |
658 * with the names in the options table. | |
659 * | |
660 * Here is an example of an option, showing the members of the Options struct: | |
661 * name: defaultValue: value: comment: classification: | |
662 * {"length_wave", LengthStr, &lengthstr, "Length of wave", InputOption}, | |
663 * | |
664 * getopts() operates on the options between the given place mark and the | |
665 * bottom of the table. | |
666 * This is the only call to routine getopts(), which is defined in options.c. | |
667 * First, each "value" is set to its corresponding "defaultvalue". | |
668 * Then the options file (the "rc" file) is opened, and any options found there | |
669 * are assigned to the corresponding "value", (overriding the "defaultvalue"). | |
670 * Then the command-line arguments are examined, and any options found there | |
671 * are assigned to the corresponding "value", (overriding again). | |
672 * Special arguments are dealt with: | |
673 * "help" calls the onLineHelpHandler() routine, (see below). | |
674 * "update" calls the updateOptionsFile() routine. | |
675 * | |
676 * Finally, leave the remainder of the command line (argc and argv). | |
677 * Anything left on the command line is interpreted as follows: | |
678 * "filestr" is the input data filename, | |
679 * "startstr" is the start point in the data, | |
680 * "lengthstr" is the amount of data to process, | |
681 * "whichstr" is the last 3 chars of the program name (the program version). | |
682 * | |
683 * Note that if no input file has been found by getopts(), (in the "rc" file), | |
684 * and none remains on the command line, then helpopts() is called. | |
685 * This is an alias for the onLineHelpHandler() function, which is in turn an | |
686 * alias for the defaultHelpHandler() routine, (see options.c). | |
687 * | |
688 * | |
689 ***************************************************************************/ | |
690 | |
691 getversion( programName ) ; | |
692 | |
693 /* The helpstring, defined in model.c, is stored as the comment field */ | |
694 /* of the help option (see table.c). It is accessed in options.c in */ | |
695 /* defaultHelpHandler(), using options[help].comment. */ | |
696 | |
697 (void) sprintf( helpstring, " [file_name]\n Generates %s", modelHelp( which ) ) ; | |
698 | |
699 options = constructOptions( which, displayopts ) ; | |
700 | |
701 | |
702 /* Hack to save argc and argv so they don't get mangled by getopts */ | |
703 /* This is so the command line args can override a reused file header */ | |
704 | |
705 argc_save = argc ; | |
706 argv_save = (char **)malloc( ( argc + 1 ) * sizeof( char *) ) ; | |
707 for ( i = 0 ; i < argc ; i++ ) { | |
708 argv_save[i] = (char *)malloc( ( strlen( argv[i] ) + 1 ) * sizeof( char ) ) ; | |
709 strcpy( argv_save[i], argv[i] ) ; | |
710 } | |
711 | |
712 getopts( options, &argc, &argv ) ; | |
713 | |
714 if( argc == 0 && isNULL( filestr ) ) { | |
715 (void) helpopts( options, programName ) ; | |
716 stitch_exit( -1 ) ; | |
717 } | |
718 | |
719 if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) | |
720 filestr = *argv++ ; | |
721 | |
722 if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) | |
723 startstr = *argv++ ; | |
724 | |
725 if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) | |
726 lengthstr = *argv++ ; | |
727 | |
728 if( isNULL( whichstr ) ) | |
729 whichstr = which ; | |
730 | |
731 | |
732 /*************************************************************************** | |
733 * horrrrrrrrible hack for now to try out -envelope option | |
734 ***************************************************************************/ | |
735 | |
736 if( isON( envstr ) ) | |
737 if( whichstr[1] == 'b' ) | |
738 whichstr[1] = 'e' ; | |
739 else { | |
740 /* map sai to sie and sas to sse */ | |
741 | |
742 whichstr[1] = whichstr[2] ; | |
743 whichstr[2] = 'e' ; | |
744 } | |
745 | |
746 | |
747 /*************************************************************************** | |
748 * hack test arguments | |
749 ***************************************************************************/ | |
750 #if 00 | |
751 test1 = atof( test1str ) ; | |
752 test2 = atof( test2str ) ; | |
753 test3 = atof( test3str ) ; | |
754 test4 = atof( test4str ) ; | |
755 #endif | |
756 | |
757 /*************************************************************************** | |
758 * Open input data file, (use stdin if filename "-" is given). | |
759 ***************************************************************************/ | |
760 | |
761 if( strcmp( filestr, "-" ) == 0 ) | |
762 inputFilePointer = stdin ; | |
763 else | |
764 inputFilePointer = fopen( filestr, readBinary ) ; | |
765 | |
766 /*************************************************************************** | |
767 * Position input data file pointer correctly: | |
768 * Read any options header at the start of the input file. Set any options. | |
769 * Skip to the start of the input data, allowing for any offset (ie startstr). | |
770 * Set "framesstr" to the number of frames in the input data file, (here this | |
771 * means the number of shorts remaining in the input file). | |
772 * Create a source for the input data file. | |
773 * Re-set "framesstr" to allow for a given "lengthstr", (ie not the whole file). | |
774 ***************************************************************************/ | |
775 | |
776 if( inputFilePointer != (FILE *) 0 ) { | |
777 | |
778 readopts( options, inputFilePointer ) ; | |
779 | |
780 headerSize = ftell( inputFilePointer ) ; | |
781 | |
782 setFrames( fileLength( inputFilePointer ) / sizeof ( short ) - (long) Samples( startstr, Samplerate() ) ) ; | |
783 | |
784 (void) fseek( inputFilePointer, (long)( headerSize + (long) Samples( startstr, Samplerate() ) * sizeof ( short ) ), 0 ) ; | |
785 | |
786 source = FileSource( inputFilePointer ) ; | |
787 } | |
788 | |
789 /* If a specific processing amount is specifed (other than "remainder") */ | |
790 /* and this amount is less than the remainder of the input file, then */ | |
791 /* override the amount of data to process, (in framesstr). */ | |
792 | |
793 if ( strncmp( lengthstr, LengthStr, strlen(lengthstr) ) != 0 && | |
794 Samples( lengthstr, Samplerate() ) < Frames() ) | |
795 setFrames( (long) ( Samples( lengthstr, Samplerate() ) ) / Framestep() ) ; | |
796 | |
797 | |
798 /*************************************************************************** | |
799 * Create source with data derived from processing file through model. | |
800 * This may involve several stages of callback, and will initialize a chain of | |
801 * objects which will ultimately execute the program, (see SinkSource() below). | |
802 * If reusestr in "on", the "useprevious" option will use a previously | |
803 * generated file, (see checkForFile() routine below). | |
804 * If no input data file is found, report error: "could not open file". | |
805 * | |
806 * The routine ModeledSource() first uses Findstage() to find the appropriate | |
807 * place in the stage table called for by the program, (see model.c). | |
808 * Then it finds the end of the stage table, and works back up the table to | |
809 * the stage called for by the program. Each stage in the table is a process | |
810 * on the way to the program as a whole. The order of the stage table sets the | |
811 * order of processing. | |
812 * Immediately below are the only two calls to routine ModeledSource(). | |
813 ***************************************************************************/ | |
814 | |
815 if( isON( reusestr ) ) | |
816 source = ModeledSource( source, checkForFile ) ; | |
817 else | |
818 if( inputFilePointer != (FILE *) 0 ) | |
819 source = ModeledSource( source, (Source ( * )()) 0 ) ; | |
820 | |
821 if( inputFilePointer == (FILE *) 0 ) | |
822 stitch_error( "Could not open file \"%s\" for input\n", filestr ) ; | |
823 | |
824 /*************************************************************************** | |
825 * If the "downchannel" option is on, reduce channels by averaging. | |
826 * (See DownChannel() routine below). | |
827 * Then updateFramebytes sets "framebytesstr" to the total number of bytes | |
828 * in each frame, (ie the new width * height). | |
829 ***************************************************************************/ | |
830 | |
831 | |
832 for( time=0 ; time<OptionInt( downcstr ) ; time++ ) { | |
833 source = DownChannel( source, Frameheight() ) ; | |
834 setFrameheight( Frameheight() / 2 ) ; | |
835 } | |
836 updateFramebytes() ; | |
837 | |
838 #if 0 /* for debugging */ | |
839 fprintf( stderr, "%d %d %d %d %ld\n", | |
840 Framewidth(), | |
841 Frameheight(), | |
842 Framebytes(), | |
843 Framestep(), | |
844 Frames() ) ; | |
845 #endif | |
846 | |
847 /*************************************************************************** | |
848 * From here on is concerned with setting up for output, then starting the | |
849 * processing, and finally cleaning up. | |
850 ***************************************************************************/ | |
851 | |
852 #ifdef X11 | |
853 /* First sort out window placement. */ | |
854 | |
855 if( strcmp( xstr, CenterStr ) == 0 ) | |
856 x = -1 ; | |
857 else | |
858 x = atoi( xstr ) ; | |
859 | |
860 if( strcmp( ystr, CenterStr ) == 0 ) | |
861 y = -1 ; | |
862 else | |
863 y = atoi( ystr ) ; | |
864 | |
865 if( isGREYSCALE( viewstr ) ) | |
866 pixels = 0 ; | |
867 else { | |
868 pixels = atoi( penstr ) ; | |
869 | |
870 if( isON( hiddenstr ) && Frameheight() > 1 ) | |
871 | |
872 pixels = -abs( pixels ) ; | |
873 | |
874 /* Convert arguments for line-drawing. See draw.ch */ | |
875 drawTilt = atof( tiltstr ) ; | |
876 drawDistance = atof( diststr ) ; | |
877 drawHeadroom = atof( roomstr ) ; | |
878 drawOverlap = atof( overstr ) / 100. ; | |
879 #ifdef mips | |
880 if( pixels == 0 ) | |
881 pixels = 1 ; | |
882 #endif | |
883 } | |
884 #endif /* X11 */ | |
885 | |
886 /* work out title of output */ | |
887 | |
888 (void) strcpy( title, filestr ) ; | |
889 (void) strcat( title, "." ) ; | |
890 (void) strncat( title, whichstr, strlen( "xxx" )+1 ) ; | |
891 | |
892 #ifdef X11 | |
893 | |
894 if( strcmp(titlestr,"filename") == 0) /* was: if(isNULL(titlestr)) */ | |
895 titlestr = title ; | |
896 | |
897 /* calculate axis information */ | |
898 | |
899 if( isEXCITE( viewstr ) ) { | |
900 ChannelAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; | |
901 MagnitudeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; | |
902 } | |
903 else if( isWATERFALL( viewstr ) ) { | |
904 ChannelAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; | |
905 TimeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; | |
906 } /* landscape ones */ | |
907 else if( Framewidth() > 1 ) { | |
908 DelayAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; | |
909 ChannelAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; | |
910 } | |
911 else { | |
912 TimeAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; | |
913 | |
914 if( Frameheight() > 1 ) | |
915 ChannelAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; | |
916 else | |
917 MagnitudeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; | |
918 | |
919 } | |
920 | |
921 | |
922 /* select outputs... */ | |
923 | |
924 | |
925 /* select sai drawing method */ | |
926 | |
927 /* Hack so spiral parameters are independent of stage and option order */ | |
928 /* (Spiral parameters appear late in options list, so are not known */ | |
929 /* when an earlier stage is specified. So don't process unless sai). */ | |
930 | |
931 if( strncmp(whichstr,"spl",strlen("spl")) == 0 ) { | |
932 | |
933 frame_drawer = draw_spiral; | |
934 | |
935 dotthresh_spl = Top() ; | |
936 dotsize_spl = OptionInt( penstr ) ; | |
937 } | |
938 else | |
939 frame_drawer = draw_frame; | |
940 | |
941 /* screen output first */ | |
942 /* (set by option: display=on) */ | |
943 | |
944 if( isON( dispstr ) ) { | |
945 | |
946 display = newDisplayWindow( titlestr, x, y, atoi( widthstr ), atoi( heightstr ), pixels ) ; | |
947 | |
948 if( !isGREYSCALE( viewstr ) /* && OptionInt( penstr ) != 0 */ ) { | |
949 | |
950 if( Top() == Bot() ) | |
951 stitch_error( "error: display top and bottom parameters the same value\n" ); | |
952 | |
953 if( isEXCITE( viewstr ) ) | |
954 source = SourceDraw( source, Bot(), Top(), display, Frameheight(), 1, Nwidth(), Frames(), save_frame, frame_drawer ) ; | |
955 else if( isWATERFALL( viewstr ) ) | |
956 source = SourceDraw( source, Bot(), Top(), display, Frameheight(), Frames(), Nwidth(), 1, save_frame, frame_drawer ) ; | |
957 else if( !isON( kludgestr ) ) | |
958 source = SourceDraw( source, Bot(), Top(), display, Framewidth(), Frameheight(), Nwidth(), Frames(), save_frame, frame_drawer ) ; | |
959 else { /* speed-up for sai */ | |
960 source = SourceDraw( source, Bot(), Top(), display, Framewidth(), Frameheight(), Nwidth(), Frames(), save_frame, fast_frame ) ; | |
961 gen_state = genstate( display, Bot(), Top(), Framewidth(), Frameheight(), Nwidth(), Frames(), pixels ) ; | |
962 frame_drawer=fast_frame ; | |
963 } | |
964 } | |
965 else { | |
966 if( isON( erasestr ) ) | |
967 Clear( display ) ; | |
968 | |
969 DrawAxes( display ) ; | |
970 | |
971 if( isON( linstr ) ) | |
972 frequency_scale = frequencies ; | |
973 else | |
974 frequency_scale = (double *) 0 ; | |
975 | |
976 if( Framewidth() > 1 ) | |
977 source = FillDown( display, source, Top(), Bot(), Framewidth(), Frameheight() ) ; | |
978 else | |
979 source = fillAcross( display, source, Top(), Bot(), Frameheight(),(int)Frames(), frequency_scale ) ; | |
980 } | |
981 } | |
982 | |
983 /* postscript output next */ | |
984 /* (set by option: postscript=on) */ | |
985 | |
986 if( isON( psstr ) ) { | |
987 | |
988 if( isON( psfilestr ) ) | |
989 psfilename = AlterSuffix( filestr, POSTSCRIPT_FILE_SUFFIX ) ; | |
990 else | |
991 psfilename = (char *) 0 ; | |
992 | |
993 /* the extra argument to newPSWindow. MAA> 27-1-1993. */ | |
994 psw = newPSWindow( psfilename, x, y, atoi(widthstr), atoi(heightstr), atoi( penstr ), isON( hiddenstr ) ); | |
995 | |
996 if( !isGREYSCALE( viewstr ) && OptionInt( penstr ) != 0 ) { | |
997 | |
998 if( isEXCITE( viewstr ) ) | |
999 source = SourceDraw( source, Bot(), Top(), psw, Frameheight(), 1, Nwidth(), Frames(), plot_frame, frame_drawer ) ; | |
1000 else if( isWATERFALL( viewstr ) ) | |
1001 source = SourceDraw( source, Bot(), Top(), psw, Frameheight(), Frames(), Nwidth(), 1, plot_frame, frame_drawer ) ; | |
1002 else | |
1003 source = SourceDraw( source, Bot(), Top(), psw, Framewidth(), Frameheight(), Nwidth(), Frames(), plot_frame, frame_drawer ) ; | |
1004 } | |
1005 else { /* greyscale displays */ | |
1006 | |
1007 if( isON( erasestr ) ) | |
1008 Clear( psw ) ; | |
1009 | |
1010 DrawAxes( psw ) ; | |
1011 | |
1012 if( isON( linstr ) ) | |
1013 frequency_scale = frequencies ; | |
1014 else | |
1015 frequency_scale = (double *) 0 ; | |
1016 | |
1017 if( Framewidth() > 1 ) | |
1018 source = FillDown( psw, source, Top(), Bot(), Framewidth(), Frameheight() ) ; | |
1019 else | |
1020 source = fillAcross( psw, source, Top(), Bot(), Frameheight(),(int)Frames(), frequency_scale ) ; | |
1021 } | |
1022 } | |
1023 | |
1024 | |
1025 if( strcmp( typestr, "char" ) == 0 ) { | |
1026 source = PackShorts( source ) ; | |
1027 fileFramebytes = Framebytes() / sizeof ( short ) * sizeof ( char ) ; | |
1028 } | |
1029 else | |
1030 | |
1031 #endif /* X11 */ | |
1032 | |
1033 fileFramebytes = Framebytes() ; | |
1034 | |
1035 /* output to file */ | |
1036 | |
1037 if( !isOFF( outstr ) ) { | |
1038 | |
1039 (void) unlink( title ) ; | |
1040 | |
1041 if( OptionStringsEqual( outstr, OnOption ) ) | |
1042 ofp = fopen( title, writeBinary ) ; | |
1043 else { | |
1044 if( strcmp( outstr, "stdout" ) == 0 ) | |
1045 ofp = stdout; | |
1046 else | |
1047 ofp = fopen( outstr, writeBinary ) ; | |
1048 } | |
1049 | |
1050 if( ofp == (FILE *) 0 ) | |
1051 stitch_error( "Unable to open file %s for output\n", title ) ; | |
1052 else { | |
1053 if( isON( headstr ) ) | |
1054 writeopts( options, ofp ) ; | |
1055 | |
1056 source = FileTap( source, ofp ) ; | |
1057 } | |
1058 } | |
1059 | |
1060 #ifdef X11 | |
1061 | |
1062 /* output of screen "image" files in display format */ | |
1063 if( !isOFF( bitmapstr ) ) { | |
1064 imageFileName = AlterSuffix(filestr, CARTOON_FILE_SUFFIX ) ; | |
1065 | |
1066 if( (strcmp( bitmapstr, "stdout" ) == 0 )){ | |
1067 imageFilePointer = stdout; | |
1068 writeopts( options, imageFilePointer ) ;} | |
1069 else | |
1070 if ( ( imageFilePointer = fopen(imageFileName, writeBinary ) ) == (FILE *) 0) | |
1071 stitch_error( "Unable to open file %s for image output\n", imageFileName ) ; | |
1072 else | |
1073 writeopts( options, imageFilePointer ) ;} | |
1074 | |
1075 if (( ofp == stdout ) && ( imageFilePointer == stdout )) | |
1076 stitch_error( "Both 'output' and 'bitmap' set to stdout.\n", title); | |
1077 | |
1078 #endif /* X11 */ | |
1079 | |
1080 | |
1081 /*************************************************************************** | |
1082 * Execute the program by pulling data from the source. | |
1083 * This is the only call to routine SinkSource(), which is defined in | |
1084 * stitch/source.c as sinkSource(). | |
1085 * (SinkSource is an alias, defined in stitch/source.h, to cast the arguments). | |
1086 * Routine sinkSource() executes: "(void) Pull( source, fileFramebytes ) ;" | |
1087 * for "Frames()" times in succession. | |
1088 * A chain of source objects, linked by callback-function pointers, was setup | |
1089 * earlier, (see call to ModeledSource() above). | |
1090 ***************************************************************************/ | |
1091 | |
1092 | |
1093 SinkSource( source, fileFramebytes, Frames() ) ; | |
1094 | |
1095 | |
1096 /*************************************************************************** | |
1097 * Clean up and close | |
1098 ****************************************************************************/ | |
1099 | |
1100 CloseSource( source ) ; | |
1101 | |
1102 if( ofp != (FILE *) 0 ) | |
1103 (void) fclose( ofp ) ; | |
1104 | |
1105 #ifdef X11 | |
1106 | |
1107 if( psw != (WindowObject) 0 ) | |
1108 Close( psw ) ; | |
1109 | |
1110 if( display != (WindowObject) 0 ) { | |
1111 | |
1112 /* animate sai's if selected */ | |
1113 | |
1114 do | |
1115 { | |
1116 for( image=1 ; image <= images ; image++ ) | |
1117 for( time = OptionInt( animstr ) ; time>0 ; time-- ) | |
1118 Recall( display, image ) ; | |
1119 | |
1120 if( Pause( display ) == 'q' ) | |
1121 break; | |
1122 | |
1123 } while( isON( animstr ) ) ; | |
1124 | |
1125 Close( display ) ; | |
1126 } | |
1127 | |
1128 #endif /* X11 */ | |
1129 | |
1130 stitch_exit( 0 ) ; | |
1131 } | |
1132 | |
1133 /*************************** End main *************************************/ | |
1134 | |
1135 /*************************************************************************** | |
1136 * checkForFile() | |
1137 * Create source from file if present, to be used if reusestr in "on". | |
1138 * This is the "useprevious" option to use previously generated files. | |
1139 ***************************************************************************/ | |
1140 | |
1141 Source checkForFile( which ) | |
1142 char *which ; | |
1143 { | |
1144 static Source noSource = { (struct _source *) 0 } ; | |
1145 long headerSize, fileFramebytes ; | |
1146 char file_name[200] ; | |
1147 FILE *tmp ; | |
1148 | |
1149 (void) strcpy( file_name, filestr ) ; | |
1150 (void) strcat( file_name, "." ) ; | |
1151 (void) strcat( file_name, which ) ; | |
1152 | |
1153 if( ( tmp = fopen( file_name, readBinary ) ) != ( FILE * ) 0 ) { | |
1154 | |
1155 inputFilePointer = tmp ; | |
1156 | |
1157 (void) fprintf( stderr, "Using existing file \"%s\"\n", file_name ) ; | |
1158 | |
1159 readopts( options, inputFilePointer ) ; | |
1160 | |
1161 /* the saved command line overrides options from file header */ | |
1162 | |
1163 if( isON( reusestr ) ) | |
1164 cmd_line_opts( options, &argc_save, &argv_save ) ; | |
1165 | |
1166 headerSize = ftell( inputFilePointer ) ; | |
1167 | |
1168 if( strcmp( typestr, "char" ) == 0 ) | |
1169 fileFramebytes = Framebytes() / 2 ; | |
1170 else | |
1171 fileFramebytes = Framebytes() ; | |
1172 | |
1173 /* | |
1174 If length=remainder then use the whole file. | |
1175 Otherwise the length of the reused file is that given on the command | |
1176 line, or the default length (if no length option is given). | |
1177 */ | |
1178 | |
1179 if ( strncmp( lengthstr, LengthStr, strlen(lengthstr) ) == 0 ) | |
1180 setFrames( ( fileLength( inputFilePointer ) - headerSize ) / fileFramebytes - (long) Samples( startstr, Samplerate() ) / Framestep() ) ; | |
1181 else | |
1182 setFrames( (long) ( Samples( lengthstr, Samplerate() ) ) / Framestep() ) ; | |
1183 | |
1184 | |
1185 (void) fseek( inputFilePointer, headerSize + (long) Samples( startstr, Samplerate() ) / Framestep() * fileFramebytes, 0 ) ; | |
1186 | |
1187 #ifndef PC | |
1188 if( strcmp( typestr, "char" ) == 0 ) | |
1189 return( CharShortSource( FileSource( inputFilePointer ) ) ) ; | |
1190 else | |
1191 #endif | |
1192 return( FileSource( inputFilePointer ) ) ; | |
1193 } | |
1194 else | |
1195 return( noSource ) ; | |
1196 } | |
1197 | |
1198 /*************************************************************************** | |
1199 * AlterSuffix(). | |
1200 * Returns its argument fileName with a newSuffix appended in place of | |
1201 * any previous suffix it may have had. It should be noted that this | |
1202 * suffix must include any DOT it wishes to have appended to the name. | |
1203 ***************************************************************************/ | |
1204 | |
1205 /* File Name Suffix Conversion Parameters */ | |
1206 | |
1207 #define BACKSLASH_CHAR '\\' | |
1208 #define SLASH_CHARACTER '/' | |
1209 #define NULL_CHARACTER '\000' | |
1210 #define DOT_CHARACTER '.' | |
1211 | |
1212 char *AlterSuffix(fileName, newSuffix) | |
1213 char *fileName, *newSuffix; | |
1214 { | |
1215 char *temp, *temp2, *lastPart; | |
1216 #if defined( PC ) | |
1217 int i; | |
1218 #endif | |
1219 | |
1220 temp = stitch_malloc((unsigned) (strlen(fileName) + strlen(newSuffix) + 1), "AlterSuffix" ); | |
1221 | |
1222 temp = strcpy(temp, fileName); | |
1223 | |
1224 #if defined(PC) | |
1225 /* Change all backslashes to forward slashes */ | |
1226 for (i = 0; temp[i] != NULL_CHARACTER; i++) | |
1227 if (temp[i] == BACKSLASH_CHAR) | |
1228 temp[i] = SLASH_CHARACTER; | |
1229 #endif | |
1230 | |
1231 if ((lastPart = strrchr(temp, SLASH_CHARACTER)) == NULL) | |
1232 lastPart = temp; | |
1233 else | |
1234 lastPart++; /* Skip over the actual "/" */ | |
1235 | |
1236 /* lastPart points to the tail name of the path */ | |
1237 | |
1238 if ((temp2 = strchr(lastPart, DOT_CHARACTER)) == NULL) | |
1239 temp = strcat(temp, newSuffix); | |
1240 else | |
1241 temp2 = strcpy(temp2, newSuffix); | |
1242 | |
1243 return (temp); | |
1244 } | |
1245 | |
1246 #ifdef X11 | |
1247 | |
1248 /*************************************************************************** | |
1249 * Interceptions for various combinations of drawing. | |
1250 * An "interception function" is a function inserted into a chain a functions | |
1251 * linked by function pointers. The inserted function "intercepts" the | |
1252 * processing, to perform some transformation. | |
1253 ****************************************************************************/ | |
1254 | |
1255 /* intercept draw to store images for animation */ | |
1256 | |
1257 void save_frame( state, frame, first ) | |
1258 struct _draw_state *state ; | |
1259 short *frame ; | |
1260 int first ; | |
1261 { | |
1262 if( first ) { | |
1263 if( isON( erasestr ) ) | |
1264 Clear( state->window ) ; | |
1265 | |
1266 if( frame_drawer != (void (*)()) draw_spiral && state->framenumber == 1 ) | |
1267 DrawAxes( state->window ) ; | |
1268 } | |
1269 | |
1270 frame_drawer( state, frame ) ; | |
1271 | |
1272 if( isON( animstr ) && isOFF( kludgestr ) ) | |
1273 if( Store( state->window ) ) | |
1274 ++images ; | |
1275 | |
1276 if( isON( bitmapstr ) ) | |
1277 Write( state->window, imageFilePointer ) ; | |
1278 | |
1279 return ; | |
1280 } | |
1281 | |
1282 /* hacky but effective faster frame drawing routine - for sai only! */ | |
1283 | |
1284 void fast_frame( state, frame, first ) | |
1285 struct _draw_state *state ; | |
1286 short *frame ; | |
1287 int first ; | |
1288 { | |
1289 if( isON( animstr ) || images == 0 ) | |
1290 if( Store( state->window ) ) | |
1291 ++images ; | |
1292 | |
1293 /* generate image in current cleared image */ | |
1294 | |
1295 generate( gen_state, frame ) ; | |
1296 | |
1297 /* then recal the window using the modified image */ | |
1298 | |
1299 Recall( state->window, images ); | |
1300 | |
1301 return ; | |
1302 } | |
1303 | |
1304 /* intercept plot to check if page should be output for printing */ | |
1305 | |
1306 static int plot_wanted( state ) | |
1307 struct _draw_state *state ; | |
1308 { | |
1309 #if !defined(PC) | |
1310 if( display != ( WindowObject ) 0 && state->framewidth > 1 && state->frames > 1 ) { | |
1311 (void) fprintf(stderr, "Hit \"y\" to include this image in the PostScript file: "); | |
1312 | |
1313 switch ( Pause( display ) ) { | |
1314 | |
1315 case 'y' : case 'Y' : | |
1316 case 'p' : case 'P' : | |
1317 return 1 ; | |
1318 | |
1319 default : | |
1320 return 0 ; | |
1321 } | |
1322 } | |
1323 #endif | |
1324 return 1 ; | |
1325 } | |
1326 | |
1327 void plot_frame( state, frame, first ) | |
1328 struct _draw_state *state ; | |
1329 short *frame ; | |
1330 int first ; | |
1331 { | |
1332 int centering = state->window->entries->x( state->window ) < 0 && | |
1333 state->window->entries->y( state->window ) < 0 ; | |
1334 | |
1335 if( isOFF( erasestr ) || state->framewidth == 1 || plot_wanted( state ) ) { | |
1336 | |
1337 if( first && ( state->framenumber == 1 || isON( erasestr ) ) ) { | |
1338 /* *** if( centering ) *** removed the conditional. M.Akeroyd. 22-1-1993.*/ | |
1339 Clear( state->window ) ; | |
1340 | |
1341 if( frame_drawer != (void (*)()) draw_spiral ) | |
1342 DrawAxes( state->window ) ; | |
1343 } | |
1344 | |
1345 frame_drawer( state, frame ) ; | |
1346 } | |
1347 | |
1348 return ; | |
1349 } | |
1350 | |
1351 #endif /* X11 */ | |
1352 | |
1353 /*************************************************************************** | |
1354 * downchannel: average across channels for output (with special sai version) | |
1355 ***************************************************************************/ | |
1356 | |
1357 struct _down_channel_state { | |
1358 struct _fillable_source parent ; | |
1359 int channels ; | |
1360 Source input ; | |
1361 } ; | |
1362 | |
1363 | |
1364 static Pointer down_channel_callback( state, bytes, buffer ) | |
1365 struct _down_channel_state *state ; | |
1366 ByteCount *bytes ; | |
1367 short *buffer ; | |
1368 { | |
1369 register int last = *bytes == 0 ; | |
1370 register int chan, outchans = state->channels >> 1 ; | |
1371 long frame, frames = ToPoints( short, *bytes ) / outchans ; | |
1372 register short *iptr = PullItems( state->input, frames * state->channels, short ) ; | |
1373 register short *bptr = buffer ; | |
1374 | |
1375 for( frame=0 ; frame<frames ; frame++ ) { | |
1376 for( chan=0 ; chan<outchans ; chan++ ) | |
1377 *bptr++ = ( *iptr++ + *iptr++ ) / 2 ; | |
1378 | |
1379 if( ( outchans << 1 ) != state->channels ) | |
1380 iptr++ ; | |
1381 } | |
1382 | |
1383 if( !last ) | |
1384 return ( (Pointer) buffer ) ; | |
1385 else | |
1386 return ( DeleteFillableSource( state ) ) ; | |
1387 } | |
1388 | |
1389 static Pointer down_channel_callback_sai( state, bytes, buffer ) | |
1390 struct _down_channel_state *state ; | |
1391 ByteCount *bytes ; | |
1392 short *buffer ; | |
1393 { | |
1394 register int last = *bytes == 0 ; | |
1395 register int chan, outchans = state->channels >> 1 ; | |
1396 long frame, frames = ToPoints( short, *bytes ) / outchans ; | |
1397 register short *iptr = PullItems( state->input, frames * state->channels, short ) ; | |
1398 register short *bptr = buffer ; | |
1399 register short *iptr2 ; | |
1400 | |
1401 iptr2 = iptr + frames ; | |
1402 for( chan=0 ; chan<outchans ; chan++ ) { | |
1403 for( frame=0 ; frame<frames ; frame++ ) | |
1404 *bptr++ = ( *iptr++ + *iptr2++ ) / 2 ; | |
1405 } | |
1406 | |
1407 if( !last ) | |
1408 return ( (Pointer) buffer ) ; | |
1409 else | |
1410 return ( DeleteFillableSource( state ) ) ; | |
1411 } | |
1412 | |
1413 | |
1414 Source DownChannel( source, channels ) | |
1415 Source source ; | |
1416 { | |
1417 DeclareNew( struct _down_channel_state *, state ) ; | |
1418 | |
1419 state->channels = channels ; | |
1420 state->input = source ; | |
1421 | |
1422 | |
1423 /* Hack for special-case downchannel routine to handle format of sai and spl frames (mha: 22/6/93) */ | |
1424 | |
1425 if( strncmp(whichstr,"sai",strlen("sai")) == 0 || | |
1426 strncmp(whichstr,"spl",strlen("spl")) == 0 ) | |
1427 | |
1428 return ( SetFillableSource( state, down_channel_callback_sai, "down channeling sai frames" ) ) ; | |
1429 | |
1430 return ( SetFillableSource( state, down_channel_callback, "down channeling" ) ) ; | |
1431 } | |
1432 | |
1433 | |
1434 #ifdef X11 | |
1435 | |
1436 /*************************************************************************** | |
1437 * Pack model output onto a single byte if required, | |
1438 * using greyscale Top() from display. | |
1439 ***************************************************************************/ | |
1440 | |
1441 typedef struct { struct _fillable_source parent ; Source input ; } *PackSource ; | |
1442 | |
1443 static Pointer pack_callback( state, bytes, buffer ) | |
1444 PackSource state ; | |
1445 ByteCount *bytes ; | |
1446 Pointer buffer ; | |
1447 { | |
1448 register int last = *bytes == 0 ; | |
1449 register short *iptr = PullShorts( state->input, *bytes ) ; | |
1450 register Pointer optr = buffer ; | |
1451 register Pointer eptr = buffer + *bytes ; | |
1452 register int bytemax = atoi( bmaxstr ) ; | |
1453 register int max = Top() ; | |
1454 register int min = Bot() ; | |
1455 | |
1456 while( optr < eptr ) | |
1457 if( *iptr > max ) { | |
1458 *optr++ = bytemax ; | |
1459 iptr++ ; | |
1460 } | |
1461 else if( *iptr < min ) { | |
1462 *optr++ = 0 ; | |
1463 iptr++ ; | |
1464 } | |
1465 else | |
1466 *optr++ = ( ( ( *iptr++ - min ) * bytemax + ( bytemax >> 1 ) ) / ( max - min ) ) & 0xff ; | |
1467 | |
1468 if( !last ) | |
1469 return ( buffer ) ; | |
1470 else | |
1471 return ( DeleteFillableSource( state ) ) ; | |
1472 } | |
1473 | |
1474 | |
1475 Source PackShorts( input ) | |
1476 Source input ; | |
1477 { | |
1478 DeclareNew( PackSource, source ) ; | |
1479 | |
1480 source->input = input ; | |
1481 | |
1482 return ( SetFillableSource( source, pack_callback, "gen.c packing" ) ) ; | |
1483 } | |
1484 | |
1485 #endif /* X11 */ | |
1486 | |
1487 /***************************************************************************/ | |
1488 | |
1489 #ifdef PC | |
1490 static lowerArgs( argv, argc ) | |
1491 char **argv ; | |
1492 int argc ; | |
1493 { | |
1494 register char *ptr ; | |
1495 register int arg ; | |
1496 | |
1497 for( arg=0 ; arg<=argc ; arg++ ) | |
1498 for( ptr=argv[arg] ; *ptr != '\000' ; ptr++ ) | |
1499 if( isupper( *ptr ) ) | |
1500 *ptr = tolower( (int) *ptr ) ; | |
1501 return ; | |
1502 } | |
1503 #endif | |
1504 | |
1505 | |
1506 /*************************************************************************** | |
1507 * Set the value of versionstr to the model version number and current time. | |
1508 * The version number is the sccs <release-number>.<level-number> of the file | |
1509 * version.c. The current time is returned by ctime(time(0)). | |
1510 * This routine initializes the default version-string (headerstr), which is | |
1511 * later copied into the version-string (versionstr) during getopts(). | |
1512 * In this way, the version-string is available for output at the head of | |
1513 * the help and the options (rc) files, and also output as part of the header, | |
1514 * (when output=on). | |
1515 * Note, the versionstr has to be quoted, otherwise the routine | |
1516 * processOptionFile in options.c will report an error (Detected Trailing...) | |
1517 * when it finds blanks within a line. This happens when trying to read an | |
1518 * options file, for example when reviewing. The addition of quotes enables | |
1519 * a line containing blanks to be read complete by the subroutine getName. | |
1520 ***************************************************************************/ | |
1521 | |
1522 #include "version.c" | |
1523 | |
1524 getversion( name ) | |
1525 char *name ; | |
1526 { | |
1527 char releasestr[8] ; | |
1528 char levelstr[8] ; | |
1529 char timestr[32] ; | |
1530 char *namestr ; | |
1531 long int timeval ; | |
1532 | |
1533 sprintf(releasestr, "%d", atoi( version_Id ) ) ; | |
1534 sprintf(levelstr, "%d", atoi( version_Id + strlen(releasestr) + 1 ) ) ; | |
1535 | |
1536 if ( ( namestr = strrchr( name, '/' ) ) == (char *)0 ) namestr = name ; | |
1537 else namestr++ ; | |
1538 | |
1539 #if defined( PC ) || defined( THINK_C ) | |
1540 sprintf(headerstr, "\"AIM MRC-APU Release R%s.%s [%s]\"", releasestr, levelstr, namestr ) ; | |
1541 #else | |
1542 timeval = time(0); | |
1543 sprintf(timestr,"%s", ctime(&timeval) ) ; | |
1544 timestr[strlen(timestr) - 1] = '\0'; /* remove newline */ | |
1545 sprintf(headerstr, "\"AIM MRC-APU Release R%s.%s [%s] %s\"", releasestr, levelstr, namestr, timestr ) ; | |
1546 #endif | |
1547 | |
1548 } |