1 
2 /*
3 #    Sfront, a SAOL to C translator
4 #    This file: Included file in sfront runtime
5 #
6 # Copyright (c) 1999-2006, Regents of the University of California
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 #  Redistributions of source code must retain the above copyright
14 #  notice, this list of conditions and the following disclaimer.
15 #
16 #  Redistributions in binary form must reproduce the above copyright
17 #  notice, this list of conditions and the following disclaimer in the
18 #  documentation and/or other materials provided with the distribution.
19 #
20 #  Neither the name of the University of California, Berkeley nor the
21 #  names of its contributors may be used to endorse or promote products
22 #  derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #
36 #    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
37 */
38 
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <math.h>
43 #include <float.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <time.h>
47 #include <signal.h>
48 
49 /********************************/
50 /* readabiliy-improving defines */
51 /********************************/
52 
53 #define NV(x)   nstate->v[x].f
54 #define NVI(x)  nstate->v[x].i
55 #define NVUI(x) nstate->v[x].ui
56 #define NVU(x)  nstate->v[x]
57 #define NT(x)   nstate->t[x]
58 #define NS(x)   nstate->x
59 #define NSP     nstate
60 #define NP(x)   nstate->v[x].f
61 #define NPI(x)  nstate->v[x].i
62 #define NPUI(x) nstate->v[x].ui
63 #define NG(x)   global[x].f
64 #define NGI(x)  global[x].i
65 #define NGUI(x) global[x].ui
66 #define NGU(x)  global[x]
67 
68 #define TB(x)   bus[x]
69 #define STB(x)  sbus[x]
70 #define ROUND(x) ( ((x) > 0.0F) ? ((int) ((x) + 0.5F)) :  ((int) ((x) - 0.5F)))
71 #define POS(x)   (((x) > 0.0F) ? x : 0.0F)
72 #define RMULT ((float)(1.0F/(RAND_MAX + 1.0F)))
73 
74 #define NOTUSEDYET 0
75 #define TOBEPLAYED 1
76 #define PAUSED     2
77 #define PLAYING    3
78 #define ALLDONE    4
79 
80 #define NOTLAUNCHED 0
81 #define LAUNCHED 1
82 
83 #define ASYS_DONE        0
84 #define ASYS_EXIT        1
85 #define ASYS_ERROR       2
86 
87 #define IPASS 1
88 #define KPASS 2
89 #define APASS 3
90 
91 #define IOERROR_RETRY 256
92 
93 /************************************/
94 /* externs for system functions     */
95 /************************************/
96 
97 extern void epr(int, char *, char *, char *);
98 extern size_t rread(void * ptr, size_t len, size_t nmemb, FILE * stream);
99 extern size_t rwrite(void * ptr, size_t len, size_t nmemb, FILE * stream);
100 
101 /************************************/
102 /*  union for a data stack element  */
103 /************************************/
104 
105 typedef union {
106 
107 float f;
108 long  i;
109 unsigned long ui;
110 
111 } dstack;
112 
113 
114 /************************************/
115 /* ntables: table entries for notes */
116 /************************************/
117 
118 typedef struct tableinfo {
119 
120 int    len;                /* length of table */
121 float  lenf;               /* length of table, as a float */
122 
123 int    start;              /* loop start position */
124 int    end;                /* loop end position */
125 float  sr;                 /* table sampling rate  */
126 float  base;               /* table base frequency */
127 
128                            /* precomputed constants       */
129 int tend;                  /* len -1 if end==0            */
130 float oconst;              /* len*ATIME                   */
131 
132 unsigned long dint;        /* doscil: 64-bit phase incr   */
133 unsigned long dfrac;
134                            /* doscil: sinc interpolation        */
135 unsigned long sfui;        /* scale_factor as unsigned long     */
136 float sffl;                /* scale_factor as a float           */
137 unsigned long dsincr;      /* sinc pointer increment (d=doscil) */
138 
139 float  *t;                 /* pointer to table entries    */
140 float stamp;               /* timestamp on table contents */
141 char llmem;                /* 1 if *t was malloced        */
142 } tableinfo;
143 
144 /********************/
145 /*  control lines   */
146 /********************/
147 
148 typedef struct scontrol_lines {
149 
150 float t;                  /* trigger time */
151 int label;                /* index into label array */
152 int siptr;                /* score instr line to control */
153 struct instr_line *iline; /* pointer to score line */
154 int imptr;                /* position of variable in v[] */
155 float imval;              /* value to import into v[] */
156 
157 } scontrol_lines;
158 
159 /********************/
160 /*   tempo lines    */
161 /********************/
162 
163 typedef struct stempo_lines {
164 
165   float t;          /* trigger time */
166   float newtempo;   /* new tempo */
167 
168 } stempo_lines;
169 
170 /********************/
171 /*   table lines    */
172 /********************/
173 
174 typedef struct stable_lines {
175 
176   float t;          /* trigger time */
177   int gindex;       /* global table to target */
178   int size;         /* size of data */
179   void (*tmake) (); /* function   */
180   void * data;      /* data block */
181 
182 } stable_lines;
183 
184 /********************/
185 /* system variables */
186 /********************/
187 
188 /* audio and control rates */
189 
190 float globaltune = 440.0F;
191 float invglobaltune = 2.272727e-03F;
192 float scorebeats = 0.0F;              /* current score beat */
193 float absolutetime = 0.0F;            /* current absolute time */
194 int kbase = 1;                        /* kcycle of last tempo change */
195 float scorebase = 0.0F;               /* scorebeat of last tempo change */
196 
197 /* counters & bounds acycles and kcycles */
198 
199 int endkcycle;
200 int kcycleidx = 1;
201 int acycleidx = 0;
202 int pass = IPASS;
203 int beginflag;
204 sig_atomic_t graceful_exit;
205 
206 struct instr_line * sysidx;
207 
208 int busidx;        /* counter for buses                   */
209 int nextstate = 0; /* counter for active instrument state */
210 int oldstate;      /* detects loops in nextstate updates  */
211 int tstate;        /* flag for turnoff state machine      */
212 float cpuload;     /* current cpu-time value              */
213 
214 int asys_argc;
215 char ** asys_argv;
216 
217 int csys_argc;
218 char ** csys_argv;
219 
220 
221 int csys_sfront_argc = 7;
222 
223 char * csys_sfront_argv[7] = {
224 "sfront",
225 "-aout",
226 "output.wav",
227 "-orc",
228 "sine.saol",
229 "-sco",
230 "sine.sasl"};
231 
232 
233 #define APPNAME "sfront"
234 #define APPVERSION "--IDSTRING--"
235 #define NSYS_NET 0
236 #define INTERP_LINEAR 0
237 #define INTERP_SINC 1
238 #define INTERP_TYPE INTERP_LINEAR
239 #define ARATE 32000.0F
240 #define ATIME 3.125000e-05F
241 #define KRATE 100.0F
242 #define KTIME 1.000000e-02F
243 #define KMTIME 1.000000e+01F
244 #define KUTIME 10000L
245 #define ACYCLE 320L
246 float tempo = 60.0F;
247 float scoremult = 1.000000e-02F;
248 
249 #define ASYS_RENDER   0
250 #define ASYS_PLAYBACK 1
251 #define ASYS_TIMESYNC 2
252 
253 #define ASYS_SHORT   0
254 #define ASYS_FLOAT   1
255 
256 /* audio i/o */
257 
258 #define ASYS_OCHAN 1L
259 #define ASYS_OTYPENAME  ASYS_FLOAT
260 #define ASYS_OTYPE  float
261 long asys_osize = 0;
262 long obusidx = 0;
263 
264 ASYS_OTYPE * asys_obuf = NULL;
265 
266 #define ASYS_USERLATENCY  0
267 #define ASYS_LOWLATENCY   0
268 #define ASYS_HIGHLATENCY  1
269 #define ASYS_LATENCYTYPE  ASYS_HIGHLATENCY
270 #define ASYS_LATENCY 0.300000F
271 #define ASYS_TIMEOPTION ASYS_RENDER
272 
273 /* AIF or WAV output file wordsize */
274 
275 #define ASYS_OUTFILE_WORDSIZE_8BIT  0
276 #define ASYS_OUTFILE_WORDSIZE_16BIT  1
277 #define ASYS_OUTFILE_WORDSIZE_24BIT  2
278 #define ASYS_OUTFILE_WORDSIZE  1
279 
280 #define MAXPFIELDS 1
281 
282 struct instr_line {
283 
284 float starttime;  /* score start time of note */
285 float endtime;    /* score end time of note */
286 float startabs;   /* absolute start time of note */
287 float endabs;     /* absolute end time of note */
288 float abstime;    /* absolute time extension */
289 float time;       /* time of note start (absolute) */
290 float itime;      /* elapsed time (absolute) */
291 float sdur;       /* duration of note in score time*/
292 
293 int kbirth;       /* kcycleidx for note launch */
294 int released;     /* flag for turnoff*/
295 int turnoff;      /* flag for turnoff */
296 int noteon;       /* NOTYETUSED,TOBEPLAYED,PAUSED,PLAYING,ALLDONE */
297 int notestate;    /* index into state array */
298 int launch;       /* only for dynamic instruments */
299 int numchan;      /* only for MIDI notes */
300 int preset;       /* only for MIDI notes */
301 int notenum;      /* only for MIDI notes */
302 int label;        /* SASL label index + 1, or 0 (no label) */
303 
304                   /* for static MIDI, all-sounds noteoff */
305 
306 float p[MAXPFIELDS];          /* parameters */
307 
308 struct ninstr_types * nstate; /* pointer into state array */
309 
310 };
311 
312 #define BUS_output_bus 0
313 #define ENDBUS_output_bus 1
314 #define ENDBUS 1
315 float bus[ENDBUS];
316 
317 float fakeMIDIctrl[256];
318 
319 #define GBL_STARTVAR 0
320 #define GBL_ENDVAR 0
321 /* global variables */
322 
323 dstack global[GBL_ENDVAR+1];
324 
325 #define GBL_ENDTBL 0
326 struct tableinfo gtables[GBL_ENDTBL+1];
327 
328 #define tone_a 0
329 #define tone_x 1
330 #define tone_y 2
331 #define tone_init 3
332 #define tone_ENDVAR 4
333 
334 #define tone_ENDTBL 0
335 
336 extern void sigint_handler(int);
337 
338 void tone_ipass(struct ninstr_types *);
339 void tone_kpass(struct ninstr_types *);
340 void tone_apass(struct ninstr_types *);
341 
342 
343 
344 
345 #define MAXENDTIME 1E+37
346 
347 float endtime = 4.50F;
348 struct instr_line s_tone[1] = {
349 { 0.25F, MAXENDTIME, MAXENDTIME, MAXENDTIME,  0.0F, 0.0F, 0.0F,  4.0F, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, { 0.0F }, NULL }};
350 
351 #define MAXSTATE 2
352 
353 
354 #define MAXVARSTATE 4
355 #define MAXTABLESTATE 1
356 
357 /* ninstr: used for score, effects, */
358 /* and dynamic instruments          */
359 
360 struct ninstr_types {
361 
362 struct instr_line * iline; /* pointer to score line */
363 dstack v[MAXVARSTATE];     /* parameters & variables*/
364 struct tableinfo t[MAXTABLESTATE]; /* tables */
365 
366 } ninstr[MAXSTATE];
367 
368 #define ASYS_OUTDRIVER_WAV
369 #define ASYS_HASOUTPUT
370 
371 
372 /*
373 #    Sfront, a SAOL to C translator
374 #    This file: WAV audio driver for sfront
375 #
376 # Copyright (c) 1999-2006, Regents of the University of California
377 # All rights reserved.
378 #
379 # Redistribution and use in source and binary forms, with or without
380 # modification, are permitted provided that the following conditions are
381 # met:
382 #
383 #  Redistributions of source code must retain the above copyright
384 #  notice, this list of conditions and the following disclaimer.
385 #
386 #  Redistributions in binary form must reproduce the above copyright
387 #  notice, this list of conditions and the following disclaimer in the
388 #  documentation and/or other materials provided with the distribution.
389 #
390 #  Neither the name of the University of California, Berkeley nor the
391 #  names of its contributors may be used to endorse or promote products
392 #  derived from this software without specific prior written permission.
393 #
394 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
395 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
396 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
397 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
398 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
399 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
400 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
401 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
402 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
403 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
404 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
405 #
406 #    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
407 */
408 
409 
410 /****************************************************************/
411 /****************************************************************/
412 /*             wav file audio driver for sfront                 */
413 /****************************************************************/
414 
415 #include <stdio.h>
416 #include <string.h>
417 
418 #if defined(ASYS_HASOUTPUT)
419 
420 /* default name for output audio file */
421 #define ASYSO_DEFAULTNAME "output.wav"
422 
423 /* global variables, must start with asyso_ */
424 
425 FILE * asyso_fd;     /* output file pointer */
426 char * asyso_name;   /* name of file  */
427 long asyso_srate;    /* sampling rate */
428 long asyso_channels; /* number of channels */
429 long asyso_size;     /* number of float samples _buf */
430 long asyso_nsamp;    /* total number of samples written */
431 long asyso_bps;      /* number of bytes per sample, 1-3 */
432 long asyso_doswap;   /* needs byteswap on write */
433 float * asyso_buf;   /* output floats from sfront */
434 unsigned char * asyso_cbuf;  /* output chars to file */
435 #endif
436 
437 #if defined(ASYS_HASINPUT)
438 
439 /* default name for input audio file */
440 
441 #define ASYSI_DEFAULTNAME "input.wav"
442 
443 /* only used for asysi_soundtypecheck */
444 
445 #define ASYSI_MATCH  0
446 #define ASYSI_EOF 1
447 #define ASYSI_NOMATCH 2
448 
449 /* global variables, must start with asysi_ */
450 
451 FILE * asysi_fd;     /* input file pointer */
452 char * asysi_name;   /* name of file  */
453 long asysi_srate;    /* sampling rate */
454 long asysi_channels; /* number of channels */
455 long asysi_bytes;     /* number of bytes in a buffer */
456 long asysi_nsamp;    /* total number of samples read */
457 long asysi_bps;      /* number of bytes per sample, 1-3 */
458 long asysi_doswap;   /* needs byteswap on read */
459 unsigned char * asysi_cbuf;  /* buffer of WAV file bytes */
460 float * asysi_buf;   /* float buffer for sfront */
461 
462 #endif
463 
464 #if defined(ASYS_HASOUTPUT)
465 
466 /*********************************************************/
467 /*        writes next block of WAV/AIFF bytes            */
468 /*********************************************************/
469 
asyso_putbytes(unsigned char * c,int numbytes)470 int asyso_putbytes(unsigned char * c, int numbytes)
471 
472 {
473   if (rwrite(c, sizeof(char), numbytes, asyso_fd) != numbytes)
474     return ASYS_ERROR;
475   return ASYS_DONE;
476 }
477 
478 /*********************************************************/
479 /*        writes unsigned long to a WAV files            */
480 /*********************************************************/
481 
asyso_putlong(unsigned long val,int numbytes)482 int asyso_putlong(unsigned long val, int numbytes)
483 
484 {
485   unsigned char c[4];
486 
487   if (numbytes > 4)
488     return ASYS_ERROR;
489   switch (numbytes) {
490   case 4:
491     c[0] = (unsigned char) (val&0x000000FF);
492     c[1] = (unsigned char)((val >> 8)&0x000000FF);
493     c[2] = (unsigned char)((val >> 16)&0x000000FF);
494     c[3] = (unsigned char)((val >> 24)&0x000000FF);
495     return asyso_putbytes(c, 4);
496   case 3:
497     c[0] = (unsigned char) (val&0x000000FF);
498     c[1] = (unsigned char)((val >> 8)&0x000000FF);
499     c[2] = (unsigned char)((val >> 16)&0x000000FF);
500     return asyso_putbytes(c, 3);
501   case 2:
502     c[0] = (unsigned char) (val&0x000000FF);
503     c[1] = (unsigned char)((val >> 8)&0x000000FF);
504     return asyso_putbytes(c, 2);
505   case 1:
506     c[0] = (unsigned char) (val&0x000000FF);
507     return asyso_putbytes(c,1);
508   default:
509     return ASYS_ERROR;
510   }
511 
512 }
513 
514 /****************************************************************/
515 /*        core routine for audio output setup                   */
516 /****************************************************************/
517 
asyso_setup(long srate,long ochannels,long osize,char * name)518 int asyso_setup(long srate, long ochannels, long osize, char * name)
519 
520 
521 {
522   short swaptest = 0x0100;
523   char * val;
524 
525   asyso_doswap = *((char *)&swaptest);
526   if (name == NULL)
527     val = ASYSO_DEFAULTNAME;
528   else
529     val = name;
530 
531   switch (ASYS_OUTFILE_WORDSIZE) {
532   case ASYS_OUTFILE_WORDSIZE_8BIT:
533     asyso_bps = 1;
534     break;
535   case ASYS_OUTFILE_WORDSIZE_16BIT:
536     asyso_bps = 3;
537     break;
538   case ASYS_OUTFILE_WORDSIZE_24BIT:
539     asyso_bps = 3;
540     break;
541   }
542 
543   asyso_name = strcpy((char *) calloc((strlen(val)+1),sizeof(char)), val);
544   asyso_fd = fopen(asyso_name,"wb");
545   if (asyso_fd == NULL)
546     return ASYS_ERROR;
547 
548   /* preamble for wav file */
549 
550   asyso_putbytes((unsigned char *) "RIFF",4);
551   asyso_putlong(0,4);       /* patched later */
552   asyso_putbytes((unsigned char *) "WAVEfmt ",8);
553   asyso_putlong(16,4);
554   asyso_putlong(1,2);                          /* PCM  */
555   asyso_putlong(ochannels,2);                  /* number of channels */
556   asyso_putlong(srate,4);                      /* srate */
557   asyso_putlong(srate*ochannels*asyso_bps, 4); /* bytes/sec */
558   asyso_putlong(ochannels*asyso_bps, 2);       /* block align */
559   asyso_putlong(8*asyso_bps, 2);               /* bits per sample */
560   asyso_putbytes((unsigned char *) "data",4);
561   asyso_putlong(0,4);                          /* patched later */
562 
563   asyso_srate = srate;
564   asyso_channels = ochannels;
565   asyso_size = osize;
566   asyso_nsamp = 0;
567   asyso_cbuf = (unsigned char *) malloc(osize*asyso_bps);
568 
569   if (asyso_cbuf == NULL)
570     {
571       fprintf(stderr, "Can't allocate WAV byte output buffer (%s).\n",
572 	      strerror(errno));
573       return ASYS_ERROR;
574     }
575 
576   asyso_buf = (float *)calloc(osize, sizeof(float));
577 
578   if (asyso_buf == NULL)
579     {
580       fprintf(stderr, "Can't allocate WAV float output buffer (%s).\n",
581 	      strerror(errno));
582       return ASYS_ERROR;
583     }
584 
585   return ASYS_DONE;
586 }
587 
588 #endif
589 
590 #if defined(ASYS_HASINPUT)
591 
592 /*********************************************************/
593 /*            gets next block of WAV bytes               */
594 /*********************************************************/
595 
asysi_getbytes(unsigned char * c,int numbytes)596 int asysi_getbytes(unsigned char * c, int numbytes)
597 
598 {
599   if ((int)rread(c, sizeof(char), numbytes, asysi_fd) != numbytes)
600     return ASYS_ERROR;
601   return ASYS_DONE;
602 }
603 
604 /*********************************************************/
605 /*        flushes next block of WAV bytes                */
606 /*********************************************************/
607 
asysi_flushbytes(int numbytes)608 int asysi_flushbytes(int numbytes)
609 
610 {
611   unsigned char c;
612 
613   while (numbytes > 0)
614     {
615       if (rread(&c, sizeof(char), 1, asysi_fd) != 1)
616 	return ASYS_ERROR;
617       numbytes--;
618     }
619   return ASYS_DONE;
620 
621 }
622 
623 /*********************************************************/
624 /*     converts byte stream to an unsigned long          */
625 /*********************************************************/
626 
asysi_getlong(int numbytes,unsigned long * ret)627 long asysi_getlong(int numbytes, unsigned long * ret)
628 
629 {
630   unsigned char c[4];
631 
632   if (numbytes > 4)
633     return ASYS_ERROR;
634   if (ASYS_DONE != asysi_getbytes(&c[0],numbytes))
635     return ASYS_ERROR;
636   switch (numbytes) {
637   case 4:
638     *ret  =  (unsigned long)c[0];
639     *ret |=  (unsigned long)c[1] << 8;
640     *ret |=  (unsigned long)c[2] << 16;
641     *ret |=  (unsigned long)c[3] << 24;
642     return ASYS_DONE;
643   case 3:
644     *ret  =  (unsigned long)c[0];
645     *ret |=  (unsigned long)c[1] << 8;
646     *ret |=  (unsigned long)c[2] << 16;
647     return ASYS_DONE;
648   case 2:
649     *ret  =  (unsigned long)c[0];
650     *ret |=  (unsigned long)c[1] << 8;
651     return ASYS_DONE;
652   case 1:
653     *ret = (unsigned long)c[0];
654     return ASYS_DONE;
655   default:
656     return ASYS_ERROR;
657   }
658 
659 }
660 
661 /***********************************************************/
662 /*  checks byte stream for AIFF/WAV cookie --              */
663 /***********************************************************/
664 
asysi_soundtypecheck(char * d)665 int asysi_soundtypecheck(char * d)
666 
667 {
668   char c[4];
669 
670   if (rread(c, sizeof(char), 4, asysi_fd) != 4)
671     return ASYSI_EOF;
672   if (strncmp(c,d,4))
673     return ASYSI_NOMATCH;
674   return ASYSI_MATCH;
675 }
676 
677 /****************************************************************/
678 /*        core routine for audio input setup                   */
679 /****************************************************************/
680 
asysi_setup(long srate,long ichannels,long isize,char * name)681 int asysi_setup(long srate, long ichannels, long isize, char * name)
682 
683 
684 {
685   short swaptest = 0x0100;
686   unsigned long i, cookie;
687   long len;
688   char * val;
689 
690   asysi_doswap = *((char *)&swaptest);
691 
692   if (name == NULL)
693     val = ASYSI_DEFAULTNAME;
694   else
695     val = name;
696   asysi_name = strcpy((char *) calloc((strlen(val)+1),sizeof(char)), val);
697   asysi_fd = fopen(asysi_name,"rb");
698   if (asysi_fd == NULL)
699     return ASYS_ERROR;
700 
701   if (asysi_soundtypecheck("RIFF")!= ASYSI_MATCH)
702     return ASYS_ERROR;
703   if (asysi_flushbytes(4)!= ASYS_DONE)
704     return ASYS_ERROR;
705   if (asysi_soundtypecheck("WAVE")!= ASYSI_MATCH)
706     return ASYS_ERROR;
707   while ((cookie = asysi_soundtypecheck("fmt "))!=ASYSI_MATCH)
708     {
709       if (cookie == ASYSI_EOF)
710 	return ASYS_ERROR;
711       if (asysi_getlong(4, &i) != ASYS_DONE)
712 	return ASYS_ERROR;
713       if (asysi_flushbytes(i + (i % 2))!= ASYS_DONE)
714 	return ASYS_ERROR;
715     }
716   if (asysi_getlong(4, &i) != ASYS_DONE)
717     return ASYS_ERROR;
718   len = i;
719   if ((len -= 16) < 0)
720     return ASYS_ERROR;
721   if (asysi_getlong(2, &i) != ASYS_DONE)
722     return ASYS_ERROR;
723   if (i != 1)
724     {
725       fprintf(stderr,"Error: Can only handle PCM WAV files\n");
726       return ASYS_ERROR;
727     }
728   if (asysi_getlong(2, &i) != ASYS_DONE)
729     return ASYS_ERROR;
730   if (i != ichannels)
731     {
732       fprintf(stderr,"Error: Inchannels doesn't match WAV file\n");
733       return ASYS_ERROR;
734     }
735   if (asysi_getlong(4, &i) != ASYS_DONE)
736     return ASYS_ERROR;
737   if (srate != i)
738     fprintf(stderr,"Warning: SAOL srate %i mismatches WAV file srate %i\n",
739 	    srate,i);
740   asysi_flushbytes(6);
741   if (asysi_getlong(2, &i) != ASYS_DONE)
742     return ASYS_ERROR;
743   if ((i < 8) || (i > 24))
744     {
745       fprintf(stderr,"Error: Can't handle %i bit data\n",i);
746       return ASYS_ERROR;
747     }
748   asysi_bps = i/8;
749   asysi_flushbytes(len + (len % 2));
750 
751   while ((cookie = asysi_soundtypecheck("data"))!=ASYSI_MATCH)
752     {
753       if (cookie == ASYSI_EOF)
754 	return ASYS_ERROR;
755       if (asysi_getlong(4, &i) != ASYS_DONE)
756 	return ASYS_ERROR;
757       if (asysi_flushbytes(i + (i % 2))!= ASYS_DONE)
758 	return ASYS_ERROR;
759     }
760   if (asysi_getlong(4, &i) != ASYS_DONE)
761     return ASYS_ERROR;
762 
763   asysi_nsamp = i/asysi_bps;
764   asysi_srate = srate;
765   asysi_channels = ichannels;
766   asysi_bytes = isize*asysi_bps;
767   asysi_cbuf = (unsigned char *) malloc(asysi_bytes);
768 
769   if (asysi_cbuf == NULL)
770     {
771       fprintf(stderr, "Can't allocate WAV input byte buffer (%s).\n",
772 	      strerror(errno));
773       return ASYS_ERROR;
774     }
775 
776   asysi_buf = (float *) malloc(sizeof(float)*isize);
777 
778   if (asysi_buf == NULL)
779     {
780       fprintf(stderr, "Can't allocate WAV input float buffer (%s).\n",
781 	      strerror(errno));
782       return ASYS_ERROR;
783     }
784 
785   return ASYS_DONE;
786 }
787 
788 #endif
789 
790 #if (defined(ASYS_HASOUTPUT) && !defined(ASYS_HASINPUT))
791 
792 /****************************************************************/
793 /*        sets up audio output for a given srate/channels       */
794 /****************************************************************/
795 
asys_osetup(long srate,long ochannels,long osample,char * oname,long toption)796 int asys_osetup(long srate, long ochannels, long osample,
797 		char * oname, long toption)
798 
799 {
800   return asyso_setup(srate, ochannels, ASYS_OCHAN*ACYCLE, oname);
801 }
802 
803 #endif
804 
805 
806 #if (!defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))
807 
808 /****************************************************************/
809 /*        sets up audio input for a given srate/channels       */
810 /****************************************************************/
811 
asys_isetup(long srate,long ichannels,long isample,char * iname,long toption)812 int asys_isetup(long srate, long ichannels, long isample,
813 		char * iname, long toption)
814 
815 {
816   return asysi_setup(srate, ichannels, ASYS_ICHAN*ACYCLE, iname);
817 }
818 
819 #endif
820 
821 
822 #if (defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))
823 
824 /****************************************************************/
825 /*   sets up audio input and output for a given srate/channels  */
826 /****************************************************************/
827 
asys_iosetup(long srate,long ichannels,long ochannels,long isample,long osample,char * iname,char * oname,long toption)828 int asys_iosetup(long srate, long ichannels, long ochannels,
829 		 long isample, long osample,
830 		 char * iname, char * oname, long toption)
831 
832 {
833 
834   if (asysi_setup(srate, ichannels, ASYS_ICHAN*ACYCLE, iname) != ASYS_DONE)
835     return ASYS_ERROR;
836   return asyso_setup(srate, ochannels, ASYS_OCHAN*ACYCLE, oname);
837 
838 }
839 
840 #endif
841 
842 #if defined(ASYS_HASOUTPUT)
843 
844 /****************************************************************/
845 /*             shuts down audio output system                   */
846 /****************************************************************/
847 
asyso_shutdown(void)848 void asyso_shutdown(void)
849 
850 {
851 
852   fseek(asyso_fd, 4, SEEK_SET);
853   asyso_putlong(asyso_bps*(unsigned long)asyso_nsamp+36,4);
854   fseek(asyso_fd, 32, SEEK_CUR);
855   asyso_putlong(asyso_bps*(unsigned long)asyso_nsamp,4);
856   fclose(asyso_fd);
857 
858 }
859 
860 #endif
861 
862 #if defined(ASYS_HASINPUT)
863 
864 /****************************************************************/
865 /*               shuts down audio input system                  */
866 /****************************************************************/
867 
asysi_shutdown(void)868 void asysi_shutdown(void)
869 
870 {
871 
872   fclose(asysi_fd);
873 }
874 
875 #endif
876 
877 
878 #if (defined(ASYS_HASOUTPUT)&&(!defined(ASYS_HASINPUT)))
879 
880 /****************************************************************/
881 /*                    shuts down audio output                   */
882 /****************************************************************/
883 
asys_oshutdown(void)884 void asys_oshutdown(void)
885 
886 {
887   asyso_shutdown();
888 }
889 
890 #endif
891 
892 #if (!defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))
893 
894 /****************************************************************/
895 /*              shuts down audio input device                   */
896 /****************************************************************/
897 
asys_ishutdown(void)898 void asys_ishutdown(void)
899 
900 {
901   asysi_shutdown();
902 }
903 
904 #endif
905 
906 #if (defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))
907 
908 /****************************************************************/
909 /*              shuts down audio input and output device        */
910 /****************************************************************/
911 
asys_ioshutdown(void)912 void asys_ioshutdown(void)
913 
914 {
915   asysi_shutdown();
916   asyso_shutdown();
917 }
918 
919 #endif
920 
921 
922 #if defined(ASYS_HASOUTPUT)
923 
924 
925 /****************************************************************/
926 /*        creates buffer, and generates starting silence        */
927 /****************************************************************/
928 
asys_preamble(ASYS_OTYPE * asys_obuf[],long * osize)929 int asys_preamble(ASYS_OTYPE * asys_obuf[], long * osize)
930 
931 {
932   *asys_obuf = asyso_buf;
933   *osize = asyso_size;
934   return ASYS_DONE;
935 }
936 
937 /****************************************************************/
938 /*               sends one frame of audio to output             */
939 /****************************************************************/
940 
asys_putbuf(ASYS_OTYPE * asys_obuf[],long * osize)941 int asys_putbuf(ASYS_OTYPE * asys_obuf[], long * osize)
942 
943 {
944   float * buf = *asys_obuf;
945   float fval;
946   long val;
947   long i = 0;
948   long j = 0;
949 
950   switch (asyso_bps) {
951   case 3:
952     while (i < *osize)
953       {
954 	fval = ((float)(pow(2, 23) - 1))*buf[i++];
955 	val = (long)((fval >= 0.0F) ? (fval + 0.5F) : (fval - 0.5F));
956 	asyso_cbuf[j++] = (unsigned char) (val & 0x000000FF);
957 	asyso_cbuf[j++] = (unsigned char)((val >> 8) & 0x000000FF);
958 	asyso_cbuf[j++] = (unsigned char)((val >> 16) & 0x000000FF);
959       }
960     break;
961   case 2:
962     while (i < *osize)
963       {
964 	fval = ((float)(pow(2, 15) - 1))*buf[i++];
965 	val = (long)((fval >= 0.0F) ? (fval + 0.5F) : (fval - 0.5F));
966 	asyso_cbuf[j++] = (unsigned char) (val & 0x000000FF);
967 	asyso_cbuf[j++] = (unsigned char)((val >> 8) & 0x000000FF);
968       }
969     break;
970   case 1:
971     while (i < *osize)
972       {
973 	fval = ((float)(pow(2, 7) - 1))*buf[i++];
974 	asyso_cbuf[j++] = (unsigned char)
975 	  (128 + ((char)((fval >= 0.0F) ? (fval + 0.5F) : (fval - 0.5F))));
976       }
977     break;
978   }
979 
980   if (rwrite(asyso_cbuf, sizeof(char), j, asyso_fd) != j)
981     return ASYS_ERROR;
982 
983   asyso_nsamp += *osize;
984   *osize = asyso_size;
985   return ASYS_DONE;
986 }
987 
988 #endif
989 
990 
991 #if defined(ASYS_HASINPUT)
992 
993 /****************************************************************/
994 /*               get one frame of audio from input              */
995 /****************************************************************/
996 
asys_getbuf(ASYS_ITYPE * asys_ibuf[],long * isize)997 int asys_getbuf(ASYS_ITYPE * asys_ibuf[], long * isize)
998 
999 {
1000   long i = 0;
1001   long j = 0;
1002 
1003   if (*asys_ibuf == NULL)
1004     *asys_ibuf = asysi_buf;
1005 
1006   if (asysi_nsamp <= 0)
1007     {
1008       *isize = 0;
1009       return ASYS_DONE;
1010     }
1011 
1012   *isize = (long)rread(asysi_cbuf, sizeof(unsigned char), asysi_bytes, asysi_fd);
1013 
1014   switch (asysi_bps) {
1015   case 1:                              /* 8-bit  */
1016     while (i < *isize)
1017       {
1018 	asysi_buf[i] = ((float)pow(2, -7))*(((short) asysi_cbuf[i]) - 128);
1019 	i++;
1020       }
1021     break;
1022   case 2:                              /* 9-16 bit */
1023     *isize = (*isize) / 2;
1024     while (i < *isize)
1025       {
1026 	asysi_buf[i] = ((float)pow(2, -15))*((long)(asysi_cbuf[j]) +
1027 				    (((long)((char)(asysi_cbuf[j+1]))) << 8));
1028 	i++;
1029 	j += 2;
1030       }
1031     break;
1032   case 3:                            /* 17-24 bit */
1033     *isize = (*isize) / 3;
1034     while (i < *isize)
1035       {
1036 	asysi_buf[i] = ((float)pow(2, -23))*((long)(asysi_cbuf[j]) +
1037 				    (((long)(asysi_cbuf[j+1])) << 8) +
1038 				    (((long)((char) asysi_cbuf[j+2])) << 16));
1039 	i++;
1040 	j += 3;
1041       }
1042     break;
1043   }
1044 
1045   asysi_nsamp -= *isize;
1046   return ASYS_DONE;
1047 }
1048 
1049 #endif
1050 
1051 
1052 #undef ASYS_HASOUTPUT
1053 
1054 
ksync()1055 float ksync() { return 0.0F; }
1056 
1057 
ksyncinit(void)1058 void ksyncinit(void) { }
1059 
1060 
1061 
1062 #undef NS
1063 #define NS(x) nstate->x
1064 #undef NSP
1065 #define NSP nstate
1066 #undef NT
1067 #define NT(x)  nstate->t[x]
1068 #undef NV
1069 #define NV(x)  nstate->v[x].f
1070 #undef NVI
1071 #define NVI(x)  nstate->v[x].i
1072 #undef NVUI
1073 #define NVUI(x)  nstate->v[x].ui
1074 #undef NVU
1075 #define NVU(x)  nstate->v[x]
1076 #undef NP
1077 #define NP(x)  nstate->v[x].f
1078 #undef NPI
1079 #define NPI(x)  nstate->v[x].i
1080 #undef NPUI
1081 #define NPUI(x)  nstate->v[x].ui
1082 
tone_ipass(struct ninstr_types * nstate)1083 void tone_ipass(struct ninstr_types * nstate)
1084 {
1085    int i;
1086 
1087 memset(&(NV(0)), 0, tone_ENDVAR*sizeof(float));
1088 memset(&(NT(0)), 0, tone_ENDTBL*sizeof(struct tableinfo));
1089 
1090 }
1091 
1092 
1093 #undef NS
1094 #define NS(x) nstate->x
1095 #undef NSP
1096 #define NSP nstate
1097 #undef NT
1098 #define NT(x)  nstate->t[x]
1099 #undef NV
1100 #define NV(x)  nstate->v[x].f
1101 #undef NVI
1102 #define NVI(x)  nstate->v[x].i
1103 #undef NVUI
1104 #define NVUI(x)  nstate->v[x].ui
1105 #undef NVU
1106 #define NVU(x)  nstate->v[x]
1107 #undef NP
1108 #define NP(x)  nstate->v[x].f
1109 #undef NPI
1110 #define NPI(x)  nstate->v[x].i
1111 #undef NPUI
1112 #define NPUI(x)  nstate->v[x].ui
1113 
tone_kpass(struct ninstr_types * nstate)1114 void tone_kpass(struct ninstr_types * nstate)
1115 {
1116 
1117    int i;
1118 
1119 
1120 }
1121 
1122 
1123 #undef NS
1124 #define NS(x) nstate->x
1125 #undef NSP
1126 #define NSP nstate
1127 #undef NT
1128 #define NT(x)  nstate->t[x]
1129 #undef NV
1130 #define NV(x)  nstate->v[x].f
1131 #undef NVI
1132 #define NVI(x)  nstate->v[x].i
1133 #undef NVUI
1134 #define NVUI(x)  nstate->v[x].ui
1135 #undef NVU
1136 #define NVU(x)  nstate->v[x]
1137 #undef NP
1138 #define NP(x)  nstate->v[x].f
1139 #undef NPI
1140 #define NPI(x)  nstate->v[x].i
1141 #undef NPUI
1142 #define NPUI(x)  nstate->v[x].ui
1143 
tone_apass(struct ninstr_types * nstate)1144 void tone_apass(struct ninstr_types * nstate)
1145 {
1146 
1147  if  ( NV(tone_init) ==  0.0F )
1148  { NV(tone_init) =  1.0F ;
1149  NV(tone_x) =  0.5F ;
1150  }
1151 NV(tone_x) = NV(tone_x) -  0.196307F  * NV(tone_y);
1152  NV(tone_y) = NV(tone_y) +  0.196307F  * NV(tone_x);
1153  TB(BUS_output_bus + 0) += NV(tone_y);
1154 }
1155 
1156 
1157 #undef NS
1158 #define NS(x) nstate->x
1159 #undef NSP
1160 #define NSP nstate
1161 #undef NT
1162 #define NT(x)  nstate->t[x]
1163 #undef NV
1164 #define NV(x)  nstate->v[x].f
1165 #undef NVI
1166 #define NVI(x)  nstate->v[x].i
1167 #undef NVUI
1168 #define NVUI(x)  nstate->v[x].ui
1169 #undef NVU
1170 #define NVU(x)  nstate->v[x]
1171 #undef NP
1172 #define NP(x)  nstate->v[x].f
1173 #undef NPI
1174 #define NPI(x)  nstate->v[x].i
1175 #undef NPUI
1176 #define NPUI(x)  nstate->v[x].ui
1177 
1178 
1179 #undef NS
1180 #define NS(x) 0
1181 #undef NSP
1182 #define NSP NULL
1183 #undef NT
1184 #define NT(x)  gtables[x]
1185 #undef NV
1186 #define NV(x)  global[x].f
1187 #undef NVI
1188 #define NVI(x)  global[x].i
1189 #undef NVUI
1190 #define NVUI(x)  global[x].ui
1191 #undef NVU
1192 #define NVU(x)  global[x]
1193 #undef NP
1194 #define NP(x)  global[x].f
1195 #undef NPI
1196 #define NPI(x)  global[x].i
1197 #undef NPUI
1198 #define NPUI(x)  global[x].ui
1199 
1200 
1201 #undef NS
1202 #define NS(x) nstate->x
1203 #undef NSP
1204 #define NSP nstate
1205 #undef NT
1206 #define NT(x)  nstate->t[x]
1207 #undef NV
1208 #define NV(x)  nstate->v[x].f
1209 #undef NVI
1210 #define NVI(x)  nstate->v[x].i
1211 #undef NVUI
1212 #define NVUI(x)  nstate->v[x].ui
1213 #undef NVU
1214 #define NVU(x)  nstate->v[x]
1215 #undef NP
1216 #define NP(x)  nstate->v[x].f
1217 #undef NPI
1218 #define NPI(x)  nstate->v[x].i
1219 #undef NPUI
1220 #define NPUI(x)  nstate->v[x].ui
1221 
1222 
1223 
1224 #undef NS
1225 #define NS(x) 0
1226 #undef NSP
1227 #define NSP NULL
1228 #undef NT
1229 #define NT(x)  gtables[x]
1230 #undef NV
1231 #define NV(x)  global[x].f
1232 #undef NVI
1233 #define NVI(x)  global[x].i
1234 #undef NVUI
1235 #define NVUI(x)  global[x].ui
1236 #undef NVU
1237 #define NVU(x)  global[x]
1238 #undef NP
1239 #define NP(x)  global[x].f
1240 #undef NPI
1241 #define NPI(x)  global[x].i
1242 #undef NPUI
1243 #define NPUI(x)  global[x].ui
1244 
1245 
1246 
system_init(int argc,char ** argv)1247 void system_init(int argc, char **argv)
1248 {
1249 
1250    int i;
1251 
1252 
1253    srand(((unsigned int)time(0))|1);
1254    asys_argc = argc;
1255    asys_argv = argv;
1256 
1257 
1258    memset(&(NV(GBL_STARTVAR)), 0,
1259           (GBL_ENDVAR-GBL_STARTVAR)*sizeof(float));
1260    memset(&(NT(0)), 0, GBL_ENDTBL*sizeof(struct tableinfo));
1261 
1262 #undef NS
1263 #define NS(x) nstate->x
1264 #undef NSP
1265 #define NSP nstate
1266 #undef NT
1267 #define NT(x)  nstate->t[x]
1268 #undef NV
1269 #define NV(x)  nstate->v[x].f
1270 #undef NVI
1271 #define NVI(x)  nstate->v[x].i
1272 #undef NVUI
1273 #define NVUI(x)  nstate->v[x].ui
1274 #undef NVU
1275 #define NVU(x)  nstate->v[x]
1276 #undef NP
1277 #define NP(x)  nstate->v[x].f
1278 #undef NPI
1279 #define NPI(x)  nstate->v[x].i
1280 #undef NPUI
1281 #define NPUI(x)  nstate->v[x].ui
1282 
1283    for (busidx=0; busidx<ENDBUS;busidx++)
1284       TB(busidx)=0.0F;
1285 
1286 
1287 }
1288 
1289 
1290 #undef NS
1291 #define NS(x) 0
1292 #undef NSP
1293 #define NSP NULL
1294 #undef NT
1295 #define NT(x)  gtables[x]
1296 #undef NV
1297 #define NV(x)  global[x].f
1298 #undef NVI
1299 #define NVI(x)  global[x].i
1300 #undef NVUI
1301 #define NVUI(x)  global[x].ui
1302 #undef NVU
1303 #define NVU(x)  global[x]
1304 #undef NP
1305 #define NP(x)  global[x].f
1306 #undef NPI
1307 #define NPI(x)  global[x].i
1308 #undef NPUI
1309 #define NPUI(x)  global[x].ui
1310 
1311 
1312 
effects_init(void)1313 void effects_init(void)
1314 {
1315 
1316 
1317 
1318 }
1319 
1320 
1321 #undef NS
1322 #define NS(x) nstate->x
1323 #undef NSP
1324 #define NSP nstate
1325 #undef NT
1326 #define NT(x)  nstate->t[x]
1327 #undef NV
1328 #define NV(x)  nstate->v[x].f
1329 #undef NVI
1330 #define NVI(x)  nstate->v[x].i
1331 #undef NVUI
1332 #define NVUI(x)  nstate->v[x].ui
1333 #undef NVU
1334 #define NVU(x)  nstate->v[x]
1335 #undef NP
1336 #define NP(x)  nstate->v[x].f
1337 #undef NPI
1338 #define NPI(x)  nstate->v[x].i
1339 #undef NPUI
1340 #define NPUI(x)  nstate->v[x].ui
1341 
1342 
1343 #undef NS
1344 #define NS(x) 0
1345 #undef NSP
1346 #define NSP NULL
1347 #undef NT
1348 #define NT(x)  gtables[x]
1349 #undef NV
1350 #define NV(x)  global[x].f
1351 #undef NVI
1352 #define NVI(x)  global[x].i
1353 #undef NVUI
1354 #define NVUI(x)  global[x].ui
1355 #undef NVU
1356 #define NVU(x)  global[x]
1357 #undef NP
1358 #define NP(x)  global[x].f
1359 #undef NPI
1360 #define NPI(x)  global[x].i
1361 #undef NPUI
1362 #define NPUI(x)  global[x].ui
1363 
1364 
1365 
shut_down(void)1366 void shut_down(void)
1367    {
1368 
1369   if (graceful_exit)
1370     {
1371       fprintf(stderr, "\nShutting down system ... please wait.\n");
1372       fprintf(stderr, "If no termination in 10 seconds, use Ctrl-C or Ctrl-\\ to force exit.\n");
1373       fflush(stderr);
1374     }
1375    asys_putbuf(&asys_obuf, &obusidx);
1376    asys_oshutdown();
1377 
1378    }
1379 
main_apass(void)1380 void main_apass(void)
1381 
1382 {
1383 
1384   if (s_tone[0].noteon == PLAYING)
1385    tone_apass(s_tone[0].nstate);
1386 
1387 }
1388 
main_kpass(void)1389 int main_kpass(void)
1390 
1391 {
1392 
1393   if (s_tone[0].noteon == PLAYING)
1394    tone_kpass(s_tone[0].nstate);
1395 
1396   return graceful_exit;
1397 }
1398 
main_ipass(void)1399 void main_ipass(void)
1400 
1401 {
1402 
1403 int i;
1404 
1405   sysidx = &s_tone[0];
1406   switch(sysidx->noteon) {
1407    case PLAYING:
1408    if (sysidx->released)
1409     {
1410      if (sysidx->turnoff)
1411       {
1412         sysidx->noteon = ALLDONE;
1413         for (i = 0; i < tone_ENDTBL; i++)
1414          if (sysidx->nstate->t[i].llmem)
1415            free(sysidx->nstate->t[i].t);
1416         sysidx->nstate->iline = NULL;
1417       }
1418      else
1419       {
1420         sysidx->abstime -= KTIME;
1421         if (sysidx->abstime < 0.0F)
1422          {
1423            sysidx->noteon = ALLDONE;
1424            for (i = 0; i < tone_ENDTBL; i++)
1425             if (sysidx->nstate->t[i].llmem)
1426              free(sysidx->nstate->t[i].t);
1427            sysidx->nstate->iline = NULL;
1428          }
1429         else
1430          sysidx->turnoff = sysidx->released = 0;
1431       }
1432     }
1433    else
1434     {
1435      if (sysidx->turnoff)
1436       {
1437        sysidx->released = 1;
1438       }
1439      else
1440       {
1441         if (sysidx->endtime <= scorebeats)
1442          {
1443            if (sysidx->abstime <= 0.0F)
1444              sysidx->turnoff = sysidx->released = 1;
1445            else
1446            {
1447              sysidx->abstime -= KTIME;
1448              if (sysidx->abstime < 0.0F)
1449                sysidx->turnoff = sysidx->released = 1;
1450            }
1451          }
1452         else
1453           if ((sysidx->abstime < 0.0F) &&
1454            (1.666667e-2F*tempo*sysidx->abstime +
1455                sysidx->endtime <= scorebeats))
1456             sysidx->turnoff = sysidx->released = 1;
1457       }
1458     }
1459    break;
1460    case TOBEPLAYED:
1461     if (sysidx->starttime <= scorebeats)
1462      {
1463       sysidx->noteon = PLAYING;
1464       sysidx->notestate = nextstate;
1465       sysidx->nstate = &ninstr[nextstate];
1466       if (sysidx->sdur >= 0.0F)
1467         sysidx->endtime = scorebeats + sysidx->sdur;
1468       sysidx->kbirth = kcycleidx;
1469       ninstr[nextstate].iline = sysidx;
1470       sysidx->time = (kcycleidx-1)*KTIME;
1471        oldstate = nextstate;
1472        nextstate = (nextstate+1) % MAXSTATE;
1473        while ((oldstate != nextstate) &&
1474               (ninstr[nextstate].iline != NULL))
1475          nextstate = (nextstate+1) % MAXSTATE;
1476        if (oldstate == nextstate)
1477        {
1478          nextstate = (nextstate+1) % MAXSTATE;
1479          while ((oldstate != nextstate) &&
1480              (ninstr[nextstate].iline->time == 0.0F) &&
1481              (ninstr[nextstate].iline->noteon == PLAYING))
1482            nextstate = (nextstate+1) % MAXSTATE;
1483          ninstr[nextstate].iline->noteon = ALLDONE;
1484          ninstr[nextstate].iline = NULL;
1485        }
1486       tone_ipass(sysidx->nstate);
1487     }
1488    break;
1489    }
1490 
1491 }
1492 
main_initpass(void)1493 void main_initpass(void)
1494 
1495 {
1496 
1497 
1498    if (asys_osetup((int)ARATE, ASYS_OCHAN, ASYS_OTYPENAME,  "output.wav",
1499 ASYS_TIMEOPTION) != ASYS_DONE)
1500    epr(0,NULL,NULL,"audio output device unavailable");
1501    endkcycle = kbase + (int)
1502       (KRATE*(endtime - scorebase)*(60.0F/tempo));
1503 
1504    if (asys_preamble(&asys_obuf, &asys_osize) != ASYS_DONE)
1505    epr(0,NULL,NULL,"audio output device unavailable");
1506    ksyncinit();
1507 
1508 
1509 }
1510 
main_control(void)1511 void main_control(void)
1512 
1513 {
1514 
1515 }
1516 
1517 /*
1518 #    Sfront, a SAOL to C translator
1519 #    This file: Robust file I/O, termination function
1520 #
1521 # Copyright (c) 1999-2006, Regents of the University of California
1522 # All rights reserved.
1523 #
1524 # Redistribution and use in source and binary forms, with or without
1525 # modification, are permitted provided that the following conditions are
1526 # met:
1527 #
1528 #  Redistributions of source code must retain the above copyright
1529 #  notice, this list of conditions and the following disclaimer.
1530 #
1531 #  Redistributions in binary form must reproduce the above copyright
1532 #  notice, this list of conditions and the following disclaimer in the
1533 #  documentation and/or other materials provided with the distribution.
1534 #
1535 #  Neither the name of the University of California, Berkeley nor the
1536 #  names of its contributors may be used to endorse or promote products
1537 #  derived from this software without specific prior written permission.
1538 #
1539 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1540 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1541 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1542 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1543 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1544 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1545 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1546 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1547 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1548 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1549 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1550 #
1551 #    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
1552 */
1553 
1554 
1555 /* handles termination in case of error */
1556 
epr(int linenum,char * filename,char * token,char * message)1557 void epr(int linenum, char * filename, char * token, char * message)
1558 
1559 {
1560 
1561   fprintf(stderr, "\nRuntime Error.\n");
1562   if (filename != NULL)
1563     fprintf(stderr, "Location: File %s near line %i.\n",filename, linenum);
1564   if (token != NULL)
1565     fprintf(stderr, "While executing: %s.\n",token);
1566   if (message != NULL)
1567     fprintf(stderr, "Potential problem: %s.\n",message);
1568   fprintf(stderr, "Exiting program.\n\n");
1569   exit(-1);
1570 
1571 }
1572 
1573 /* robust replacement for fread() */
1574 
rread(void * ptr,size_t size,size_t nmemb,FILE * stream)1575 size_t rread(void * ptr, size_t size, size_t nmemb, FILE * stream)
1576 
1577 {
1578   long recv;
1579   long len;
1580   long retry;
1581   char * c;
1582 
1583   /* fast path */
1584 
1585   if ((recv = fread(ptr, size, nmemb, stream)) == nmemb)
1586     return nmemb;
1587 
1588   /* error recovery */
1589 
1590   c = (char *) ptr;
1591   len = retry = 0;
1592 
1593   do
1594     {
1595       if (++retry > IOERROR_RETRY)
1596 	{
1597 	  len = recv = 0;
1598 	  break;
1599 	}
1600 
1601       if (feof(stream))
1602 	{
1603 	  clearerr(stream);
1604 	  break;
1605 	}
1606 
1607       /* ANSI, not POSIX, so can't look for EINTR/EAGAIN  */
1608       /* Assume it was one of these and retry.            */
1609 
1610       clearerr(stream);
1611       len += recv;
1612       nmemb -= recv;
1613 
1614     }
1615   while ((recv = fread(&(c[len]), size, nmemb, stream)) != nmemb);
1616 
1617   return (len += recv);
1618 
1619 }
1620 
1621 /* robust replacement for fwrite() */
1622 
rwrite(void * ptr,size_t size,size_t nmemb,FILE * stream)1623 size_t rwrite(void * ptr, size_t size, size_t nmemb, FILE * stream)
1624 
1625 {
1626   long recv;
1627   long len;
1628   long retry;
1629   char * c;
1630 
1631   /* fast path */
1632 
1633   if ((recv = fwrite(ptr, size, nmemb, stream)) == nmemb)
1634     return nmemb;
1635 
1636   /* error recovery */
1637 
1638   c = (char *) ptr;
1639   len = retry = 0;
1640 
1641   do
1642     {
1643       if (++retry > IOERROR_RETRY)
1644 	{
1645 	  len = recv = 0;
1646 	  break;
1647 	}
1648 
1649       /* ANSI, not POSIX, so can't look for EINTR/EAGAIN  */
1650       /* Assume it was one of these and retry.            */
1651 
1652       len += recv;
1653       nmemb -= recv;
1654 
1655     }
1656   while ((recv = fwrite(&(c[len]), size, nmemb, stream)) != nmemb);
1657 
1658   return (len += recv);
1659 
1660 }
1661 
1662 
1663 /*
1664 #    Sfront, a SAOL to C translator
1665 #    This file: Main loop for runtime
1666 #
1667 # Copyright (c) 1999-2006, Regents of the University of California
1668 # All rights reserved.
1669 #
1670 # Redistribution and use in source and binary forms, with or without
1671 # modification, are permitted provided that the following conditions are
1672 # met:
1673 #
1674 #  Redistributions of source code must retain the above copyright
1675 #  notice, this list of conditions and the following disclaimer.
1676 #
1677 #  Redistributions in binary form must reproduce the above copyright
1678 #  notice, this list of conditions and the following disclaimer in the
1679 #  documentation and/or other materials provided with the distribution.
1680 #
1681 #  Neither the name of the University of California, Berkeley nor the
1682 #  names of its contributors may be used to endorse or promote products
1683 #  derived from this software without specific prior written permission.
1684 #
1685 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1686 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1687 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1688 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1689 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1690 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1691 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1692 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1693 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1694 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1695 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1696 #
1697 #    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
1698 */
1699 
1700 
main(int argc,char * argv[])1701 int main(int argc, char *argv[])
1702 
1703 {
1704   system_init(argc, argv);
1705   effects_init();
1706   main_initpass();
1707   for (kcycleidx=kbase; kcycleidx<=endkcycle; kcycleidx++)
1708     {
1709       pass = IPASS;
1710       scorebeats = scoremult*(kcycleidx - kbase) + scorebase;
1711       absolutetime = (kcycleidx - 1)*KTIME;
1712       main_ipass();
1713       pass = KPASS;
1714       main_control();
1715       if (main_kpass())
1716 	break;
1717       pass = APASS;
1718       for (acycleidx=0; acycleidx<ACYCLE; acycleidx++)
1719 	{
1720 	  for (busidx=0; busidx<ENDBUS;busidx++)
1721 	    bus[busidx]=0.0F;
1722 	  main_apass();
1723 	  for (busidx=BUS_output_bus; busidx<ENDBUS_output_bus;busidx++)
1724 	    {
1725 	      bus[busidx] = (bus[busidx] >  1.0F) ?  1.0F : bus[busidx];
1726 	      asys_obuf[obusidx++] = (bus[busidx] < -1.0F) ? -1.0F:bus[busidx];
1727 	    }
1728 	  if (obusidx >= asys_osize)
1729 	    {
1730 	      obusidx = 0;
1731 	      if (asys_putbuf(&asys_obuf, &asys_osize))
1732 		{
1733 		  fprintf(stderr,"  Sfront: Audio output device problem\n\n");
1734 		  kcycleidx = endkcycle;
1735 		  break;
1736 		}
1737 	    }
1738 	}
1739       acycleidx = 0;
1740       cpuload = ksync();
1741     }
1742   shut_down();
1743   return 0;
1744 }
1745 
1746 
1747 
1748 
1749 
1750