1
2 /*
3 # Sfront, a SAOL to C translator
4 # This file: Reads, processes, and generates code for SASL data.
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
41 #include "tree.h"
42
43 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
44 /* void readscore(int) */
45 /* */
46 /* This top-level function for reading score data is called in */
47 /* postparse.c, for both ASCII and binary score data. Note that */
48 /* some of the second-level score-reading functions located */
49 /* later in this file are also used by readmidi.c. */
50 /* */
51 /*______________________________________________________________*/
52
53 extern tnode * scorelex(int);
54 extern int parseend(sasdata *, tnode *);
55 extern int parsetempo(sasdata *, tnode *, int);
56 extern int parsetable(sasdata *, tnode *, int, int);
57 extern int parsecontrol(sasdata *, tnode *, int);
58 extern int parselcontrol(sasdata *, tnode *, int);
59 extern int parselinstr(sasdata *, tnode *, int, int);
60 extern int parseinstr(sasdata *, tnode *, int, int);
61 extern void showbadline(tnode *);
62 extern void badline(tnode *);
63
64 /*********************************************************/
65 /* read .mp4/ASCII SASL: called in postparse.c */
66 /*********************************************************/
67
readscore(int scotype)68 void readscore(int scotype)
69
70 {
71 sasdata * sdata = NULL;
72 tnode * nsl;
73 tnode * tptr;
74 tnode * tokenptr;
75 int found = 1;
76 int tcount;
77 int hpe;
78
79 switch (scotype) {
80 case BCONFSCORE:
81 found = readprepare(BINSCORE); /* falls through */
82 case FCONFSCORE:
83 sdata = confsasl;
84 break;
85 case BSSTRSCORE:
86 found = readprepare(BINSSTR); /* falls through */
87 bitlinecount = -1;
88 case FSSTRSCORE:
89 sdata = sstrsasl;
90 break;
91 default:
92 internalerror("readscore.c", "readscore() switch");
93 }
94
95 if (!found)
96 return;
97
98 while ((tptr = scorelex(scotype))->ttype != S_EOF)
99 if (tptr->ttype != S_NEWLINE)
100 {
101 tokenptr = nsl = tptr;
102 tcount = 1;
103
104 if ((tptr->ttype == S_BADCHAR) || (tptr->ttype == S_BADNUMBER))
105 {
106 printf("Error: Misformed %s on SASL line.\n",
107 (tptr->ttype == S_BADCHAR) ? "token or string" : "number");
108 showbadline(nsl);
109 }
110
111 while (( (tptr = scorelex(scotype))->ttype != S_NEWLINE ) &&
112 (tptr->ttype != S_EOF))
113 {
114
115 if ((tptr->ttype == S_BADCHAR) || (tptr->ttype == S_BADNUMBER))
116 {
117 printf("Error: Misformed %s on SASL line.\n",
118 (tptr->ttype == S_BADCHAR) ?
119 "token or string" : "number");
120 showbadline(nsl);
121 }
122
123 if (tptr->ttype == S_STAR)
124 {
125 printf("Error: '*' must be first symbol on SASL line.\n");
126 showbadline(nsl);
127 }
128 tokenptr->next = tptr;
129 tokenptr = tptr;
130 tcount++;
131 }
132 if (scotype == BSSTRSCORE)
133 sdata = bitscohastime ? sstrsasl : abssasl;
134 if (nsl->ttype == S_STAR)
135 {
136 nsl = nsl->next;
137 hpe = 1;
138 tcount--;
139 }
140 else
141 hpe = 0;
142 found = 0;
143 if (tcount <= 1)
144 badline(nsl);
145 if (tcount == 2)
146 {
147 if (sdata->endtimeval != NULL)
148 sdata->scorefsize--;
149 found = parseend(sdata, nsl);
150 }
151 if (tcount == 3)
152 {
153 found = parsetempo(sdata, nsl, hpe);
154 if (!found)
155 found = parseinstr(sdata, nsl, tcount, hpe);
156 }
157 if ((!found) &&(tcount > 3) && (nsl->next->ttype == S_TABLE) )
158 found = parsetable(sdata, nsl, tcount, hpe);
159 if ((!found) &&(tcount == 4) && (nsl->next->ttype == S_CONTROL))
160 found = parsecontrol(sdata, nsl, hpe);
161 if ((!found) && (tcount == 5) && (nsl->next->next->ttype == S_CONTROL))
162 found = parselcontrol(sdata, nsl, hpe);
163 if ((!found) && (tcount > 4))
164 found = parselinstr(sdata, nsl, tcount, hpe);
165 if ((!found) &&(tcount > 3))
166 found = parseinstr(sdata, nsl, tcount, hpe);
167 if (!found)
168 badline(nsl);
169 sdata->scorefsize++;
170 if (tptr->ttype == S_EOF)
171 {
172 if (cppsaol == 0)
173 printf("Warning: -sco file does not end in newline.\n");
174 break;
175 }
176 }
177
178 }
179
180
181 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
182 /* */
183 /* Top-level functions for intermediate score processing */
184 /* Called in sfmain.c */
185 /* */
186 /*______________________________________________________________*/
187
188 extern tnode * maketempomap(void);
189 extern int midipointers(tnode **, tnode **);
190 extern void timestampconvert(tnode *, int);
191
192 /*********************************************************/
193 /* renumber abssasl and sstrmidi to absolute time */
194 /*********************************************************/
195
renumberabs(void)196 void renumberabs(void)
197
198 {
199 tnode * tempo, * control, * mstart, * mend;
200 tnode * tmapptr, * tptr, * endptr;
201 float tval, ktime, fval, midiscale;
202 float scorebase, scoremult, scorebeats;
203 int kcycleidx, kbase, hasmidi;
204
205
206 /* logic: mstrfile always needs tempomap, but */
207 /* sstrfile needs it only if writing. */
208 /* will need to change for has_time=0 support */
209
210 if ((boutfile && sstrfile) || mstrfile)
211 tempomap = maketempomap();
212
213 if (!mstrfile)
214 return;
215
216 /* add instr, table, and endval for has_time=0 support */
217
218 tempo = abssasl->temporoot;
219 control = abssasl->controlroot;
220
221 /* do renumbering to absolute time */
222
223 hasmidi = midipointers(&mstart, &mend);
224 tmapptr = tempomap;
225 ktime = 1.0F/krate;
226 kcycleidx = kbase = 1;
227 tval = 120.0F; /* midi file default tempo */
228 scorebase = 0.0F;
229 ktime = scoremult = 1.0F/krate;
230 midiscale = 1.0F/sstrmidi->miditicks;
231 while (tempo || control || hasmidi)
232 {
233 scorebeats = scoremult*(kcycleidx - kbase) + scorebase;
234
235 hasmidi = 0;
236
237 /* convert starttimes for midinotes */
238
239 tptr = mstart;
240 while (tptr)
241 {
242 while (tptr->down &&
243 (tptr->down->rate*midiscale <= scorebeats))
244 {
245 timestampconvert(tptr->down, kcycleidx);
246 tptr->down = tptr->down->next;
247 }
248 if (tptr->down)
249 {
250 hasmidi = 1;
251 }
252 tptr = tptr->next;
253 }
254
255 /* convert endtimes for midinotes */
256
257 tptr = mend;
258 while (tptr)
259 {
260 endptr = tptr->down;
261 while (endptr && endptr->opwidth)
262 {
263 if (endptr->width*midiscale <= scorebeats)
264 {
265 if (!endptr->inwidth)
266 {
267 endptr->inwidth = kcycleidx;
268 endptr->time = (kcycleidx-1.5F)/(float)krate;
269 }
270 if (endptr == tptr->down)
271 tptr->down = tptr->down->next;
272 }
273 endptr = endptr->next;
274 }
275 if (tptr->down)
276 hasmidi = 1;
277 tptr = tptr->next;
278 }
279
280 while (tempo && (tempo->time <= scorebeats))
281 {
282 timestampconvert(tempo, kcycleidx);
283 tempo = tempo->next;
284 }
285 while (control && (control->time <= scorebeats))
286 {
287 timestampconvert(control, kcycleidx);
288 control = control->next;
289 }
290
291 while (tmapptr && (tmapptr->time <= scorebeats))
292 {
293 kbase = kcycleidx;
294 scorebase = scorebeats;
295 if ((fval = (float)atof(tmapptr->val)) < 0.0F)
296 printf("Warning: Encode ignoring negative tempo command.\n\n");
297 else
298 tval = fval;
299 scoremult = 1.666667e-02F*ktime*tval;
300 tmapptr = tmapptr->next;
301 }
302 kcycleidx++;
303 }
304
305 abssasl->compendtime = ((float)kcycleidx/krate);
306
307 if (has.o_settempo)
308 printf("Warning: Settempo() call ignored by streaming encoding\n\n");
309
310 }
311
312
313 extern void mergerootlist(tnode **, tnode **, tnode **, tnode **,
314 tnode **, tnode **);
315 extern void mergelabeltable(sigsym *);
316
317 /*********************************************************/
318 /* merge confsasl and sstrsasl into allsasl */
319 /*********************************************************/
320
mergescores(void)321 void mergescores(void)
322
323 {
324 int i;
325 sigsym * sptr;
326
327 vmcheck(allsasl = calloc(1, sizeof(sasdata)));
328
329 /* after these calls, confsasl and sstrsasl root/tails are NULL */
330
331 mergerootlist(&(confsasl->temporoot), &(confsasl->tempotail),
332 &(sstrsasl->temporoot), &(sstrsasl->tempotail),
333 &(allsasl->temporoot), &(allsasl->tempotail));
334 mergerootlist(&(confsasl->tableroot), &(confsasl->tabletail),
335 &(sstrsasl->tableroot), &(sstrsasl->tabletail),
336 &(allsasl->tableroot), &(allsasl->tabletail));
337 mergerootlist(&(confsasl->controlroot), &(confsasl->controltail),
338 &(sstrsasl->controlroot), &(sstrsasl->controltail),
339 &(allsasl->controlroot), &(allsasl->controltail));
340 mergerootlist(&(confsasl->instrroot), &(confsasl->instrtail),
341 &(sstrsasl->instrroot), &(sstrsasl->instrtail),
342 &(allsasl->instrroot), &(allsasl->instrtail));
343
344 /* confsasl/strsasl num's, scoresize, endtime still valid */
345
346 allsasl->numtempo = confsasl->numtempo + sstrsasl->numtempo;
347 allsasl->numtable = confsasl->numtable + sstrsasl->numtable;
348
349 allsasl->scorefsize = confsasl->scorefsize + sstrsasl->scorefsize;
350
351 allsasl->endtimeval = confsasl->endtimeval ? confsasl->endtimeval :
352 sstrsasl->endtimeval;
353
354 if (confsasl->endtimeval && sstrsasl->endtimeval)
355 {
356 if (atof(confsasl->endtimeval) > atof(sstrsasl->endtimeval))
357 allsasl->endtimeval = confsasl->endtimeval;
358 else
359 allsasl->endtimeval = sstrsasl->endtimeval;
360 }
361
362 /* after this section, conf/sstr labeltables are null */
363
364 allsasl->labeltable = confsasl->labeltable ? confsasl->labeltable :
365 sstrsasl->labeltable;
366
367 if (confsasl->labeltable && sstrsasl->labeltable)
368 mergelabeltable(sstrsasl->labeltable);
369
370 if (abssasl->labeltable)
371 {
372 i = 0;
373 sptr = abssasl->labeltable;
374 while (sptr)
375 {
376 i++;
377 sptr = sptr->next;
378 }
379 abssasl->numlabels = i;
380 mergelabeltable(abssasl->labeltable);
381 }
382
383 abssasl->labeltable = confsasl->labeltable = sstrsasl->labeltable = NULL;
384
385 i = 0;
386 sptr = allsasl->labeltable;
387 while (sptr)
388 {
389 sptr->special = i++;
390 sptr = sptr->next;
391 }
392 allsasl->numlabels = i - abssasl->numlabels;
393
394
395 }
396
397
398 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
399 /* */
400 /* Top-level functions for printing out score data and score */
401 /* functions. Called in writepre.c and sfmain.c. */
402 /* */
403 /*______________________________________________________________*/
404
405 /*********************************************************/
406 /* computes end-time of last SASL note for endtime */
407 /*********************************************************/
408
initendsasl(void)409 void initendsasl(void)
410
411 {
412 float tval;
413 float newtval;
414
415 if (allsasl->instrtail != NULL)
416 {
417 vmcheck(allsasl->endtimeval = (char *) calloc(1024, sizeof(char)));
418 if (allsasl->instrtail->ttype == S_INSTR)
419 {
420 if (atof(allsasl->instrtail->down->next->next->val)>0)
421 sprintf(allsasl->endtimeval,"%1.6e", 2.0F +
422 atof(allsasl->instrtail->val) +
423 atof(allsasl->instrtail->down->next->next->val));
424 else
425 sprintf(allsasl->endtimeval,"%1.6e",
426 atof(allsasl->instrtail->val)+10.0F);
427 }
428 else
429 {
430 if (atof(allsasl->instrtail->down->next->
431 next->next->next->val) > 0 )
432 sprintf(allsasl->endtimeval,"%1.6e", 2.0F +
433 atof(allsasl->instrtail->down->next->next->val) +
434 atof(allsasl->instrtail->
435 down->next->next->next->next->val));
436 else
437 sprintf(allsasl->endtimeval,"%1.6e", 10.0F +
438 atof(allsasl->instrtail->down->next->next->val));
439 }
440 }
441
442
443 if (abssasl->instrtail != NULL)
444 {
445 /* determine worst-case tempo */
446
447 tval = confmidi->miditicks ? 120.0F : 60.0F;
448 vmcheck(abssasl->endtimeval = (char *) calloc(1024, sizeof(char)));
449 if ((abssasl->tempotail != NULL)||(allsasl->tempotail != NULL))
450 {
451 if (abssasl->tempotail)
452 {
453 newtval = (float)atof(abssasl->tempotail->down->next->next->val);
454 if ((newtval > 0.0F) && (newtval < tval))
455 tval = newtval;
456 }
457 if (allsasl->tempotail)
458 {
459 newtval = (float)atof(allsasl->tempotail->down->next->next->val);
460 if ((newtval > 0.0F) && (newtval < tval))
461 tval = newtval;
462 }
463 }
464
465 /* apply tempo to duration */
466
467 if (abssasl->instrtail->ttype == S_INSTR)
468 {
469 if (atof(abssasl->instrtail->down->next->next->val)>0)
470 sprintf(abssasl->endtimeval,"%1.6e", 2.0F +
471 atof(abssasl->instrtail->val) + (60.0F/tval)*
472 atof(abssasl->instrtail->down->next->next->val));
473 else
474 sprintf(abssasl->endtimeval,"%1.6e",
475 atof(abssasl->instrtail->val)+10.0F);
476 }
477 else
478 {
479 if (atof(abssasl->instrtail->down->next->
480 next->next->next->val) > 0 )
481 sprintf(abssasl->endtimeval,"%1.6e", 2.0F +
482 atof(abssasl->instrtail->down->next->next->val) +
483 (60.0F/tval)*atof(abssasl->instrtail->
484 down->next->next->next->next->val));
485 else
486 sprintf(abssasl->endtimeval,"%1.6e", 10.0F +
487 atof(abssasl->instrtail->down->next->next->val));
488 }
489 }
490
491 }
492
493 /*********************************************************/
494 /* declares initialized endtime variable */
495 /*********************************************************/
496
initendtime(void)497 void initendtime(void)
498
499 {
500
501 sigsym * sptr;
502
503 /* if absolute or relative endtimeval set, use it */
504 /* if not, come up with an allsasl value */
505
506 if ((allsasl->endtimeval == NULL) && (abssasl->endtimeval == NULL))
507 {
508 if (cin || session)
509 fprintf(outfile,"#define CSYS_GIVENENDTIME 0\n\n");
510
511 /* first, let MIDI streams set it */
512
513 if (confmidi->miditicks > 0)
514 {
515 vmcheck(allsasl->endtimeval = (char *) calloc(1024, sizeof(char)));
516 sprintf(allsasl->endtimeval,"%1.6e",
517 ((float)confmidi->midimaxtime/confmidi->miditicks)+2.0F);
518 }
519 else
520 {
521
522 /* or else let SASL do it */
523
524 if ((allsasl->instrtail != NULL)||(abssasl->instrtail != NULL))
525 initendsasl();
526 else
527 {
528 /* or else use absolute time or a constant */
529
530 if (abssasl->compendtime)
531 {
532 vmcheck(abssasl->endtimeval = (char *) calloc(1024, 1));
533 sprintf(abssasl->endtimeval,"%f",abssasl->compendtime
534 + 2.0F);
535 }
536 else
537 {
538 vmcheck(allsasl->endtimeval = (char *) calloc(1024, 1));
539 sptr = getvsym(&busnametable,"input_bus");
540 if ((sptr == NULL) && (!cin) && (!session))
541 sprintf(allsasl->endtimeval,"-1.0");
542 else
543 sprintf(allsasl->endtimeval,"60.0");
544 }
545 }
546 }
547 }
548 else
549 if (cin || session)
550 fprintf(outfile,"#define CSYS_GIVENENDTIME 1\n\n");
551
552
553 fprintf(outfile,"#define MAXENDTIME 1E+37\n\n");
554
555 if (abssasl->endtimeval)
556 fprintf(outfile,"int endkinit;\n");
557
558 if (allsasl->endtimeval || abssasl->endtimeval)
559 fprintf(outfile,"float endtime;\n");
560 else
561 internalerror("readscore.c", "initendtime tail");
562 }
563
564 /*************************************************************/
565 /* initialize endkinit and endtime. prints in engine_init() */
566 /*************************************************************/
567
initendtimeassign(void)568 void initendtimeassign(void)
569
570 {
571 if (abssasl->endtimeval)
572 fprintf(outfile," EV(endkinit) = %i;\n", 2 + (int)
573 (krate*atof(abssasl->endtimeval)));
574
575 if (allsasl->endtimeval)
576 fprintf(outfile," EV(endtime) = %sF;\n",allsasl->endtimeval);
577 else
578 {
579 if (abssasl->endtimeval)
580 fprintf(outfile," EV(endtime) = %fF;\n",
581 (1.0F/krate)*((2 + (int)(krate*atof(abssasl->endtimeval)))));
582 else
583 internalerror("readscore.c", "initendtime tail");
584 }
585 fprintf(outfile,"\n");
586 }
587
588
589 /*********************************************************/
590 /* declarations for the score instr variables */
591 /*********************************************************/
592
initscoreinstr(int type,sigsym * sptr)593 void initscoreinstr(int type, sigsym * sptr)
594
595 {
596 int score;
597 char * prefix;
598 char * val;
599
600 if (type == RELTSTAMP)
601 {
602 if (!( allsasl->instrroot))
603 return;
604 prefix = "s";
605 score = sptr->score;
606 }
607 else
608 {
609 if (!(abssasl->instrroot))
610 return;
611 prefix = "sa";
612 score = sptr->ascore;
613 }
614
615 fprintf(outfile,"instr_line %s_%s[%i];\n",prefix,sptr->val, score);
616
617 if ((score > 1) || csasl)
618 {
619 val = dupunderscore(sptr->val);
620 fprintf(outfile,"instr_line * %s_%sfirst;\n", prefix, val);
621 fprintf(outfile,"instr_line * %s_%slast;\n", prefix, val);
622 fprintf(outfile,"instr_line * %s_%send;\n\n", prefix,val);
623 free(val);
624 }
625
626 }
627
628 /*********************************************************/
629 /* engine_init() assignments for instr variables */
630 /*********************************************************/
631
initscoreinstrassign(int type,sigsym * sptr)632 void initscoreinstrassign(int type, sigsym * sptr)
633
634 {
635 int i, score;
636 tnode * tptr;
637 char * prefix;
638 char * val;
639
640 if (type == RELTSTAMP)
641 {
642 if (!(tptr = allsasl->instrroot))
643 return;
644 prefix = "s";
645 score = sptr->score;
646 }
647 else
648 {
649 if (!(tptr = abssasl->instrroot))
650 return;
651 prefix = "sa";
652 score = sptr->ascore;
653 }
654
655 fprintf(outfile," memcpy(EV(%s_%s), %s_%s_init, sizeof EV(%s_%s));\n",
656 prefix, sptr->val, prefix, sptr->val, prefix, sptr->val);
657
658 i = -1;
659 while (tptr != NULL)
660 {
661 if (tptr->sptr == sptr)
662 {
663 i++;
664 }
665 tptr= tptr->next;
666 }
667
668 if ((score > 1) || csasl)
669 {
670 val = dupunderscore(sptr->val);
671 fprintf(outfile," EV(%s_%sfirst) = &EV(%s_%s)[0];\n",
672 prefix,val,prefix,sptr->val);
673 fprintf(outfile," EV(%s_%slast) = &EV(%s_%s)[0];\n",
674 prefix,val,prefix,sptr->val);
675 fprintf(outfile," EV(%s_%send) = &EV(%s_%s)[%i];\n\n",
676 prefix,val,prefix,sptr->val,i);
677 free(val);
678 }
679 }
680
681
682 /*********************************************************/
683 /* declare and init true constant vars for score instrs */
684 /*********************************************************/
685
initscoreinstrconstant(int type,sigsym * sptr)686 void initscoreinstrconstant(int type, sigsym * sptr)
687
688 {
689
690 int i, j, score;
691 tnode * tptr;
692 tnode * pvalptr;
693 char * prefix;
694 sigsym * label;
695
696 if (type == RELTSTAMP)
697 {
698 if (!(tptr = allsasl->instrroot))
699 return;
700 prefix = "s";
701 score = sptr->score;
702 }
703 else
704 {
705 if (!(tptr = abssasl->instrroot))
706 return;
707 prefix = "sa";
708 score = sptr->ascore;
709 }
710
711 fprintf(outfile,"instr_line %s_%s_init[%i] = {\n",prefix,sptr->val,
712 score);
713
714 i = -1;
715 while (tptr != NULL)
716 {
717 if (tptr->sptr == sptr)
718 {
719 i++;
720 if (i != 0)
721 fprintf(outfile,",\n");
722 fprintf(outfile,"{");
723 tptr->arrayidx = i;
724
725 /* float starttime, float endtime, float startabs, float endabs */
726
727 if (type == RELTSTAMP)
728 fprintf(outfile," %sF, MAXENDTIME, MAXENDTIME, MAXENDTIME, ",
729 tptr->val);
730 else
731 fprintf(outfile," MAXENDTIME, MAXENDTIME, %sF, MAXENDTIME, ",
732 tptr->val);
733
734 /* float abstime, float time, float itime */
735
736 fprintf(outfile," 0.0F, 0.0F, 0.0F, ");
737
738 /* float sdur */
739
740 if (tptr->down->next->ttype == S_COL)
741 {
742 fprintf(outfile, "%sF, ",tptr->down->next->next->next->next->val);
743 pvalptr = tptr->down->next->next->next->next->next;
744 label = getsym(&(allsasl->labeltable), tptr->down);
745 }
746 else
747 {
748 fprintf(outfile, " %sF, ",tptr->down->next->next->val);
749 pvalptr = tptr->down->next->next->next;
750 label = NULL;
751 }
752
753 /* int kbirth, int released, int turnoff, int noteon, */
754 /* int notestate, int launch, int numchan, int preset, */
755 /* int notenum */
756
757 fprintf(outfile,"0, 0, 0, 1, 0, 0, 0, 0, 0,");
758
759 /* int label */
760
761 if (label)
762 fprintf(outfile, " %i,", label->special + 1);
763 else
764 fprintf(outfile, " 0,");
765
766 /* float p[] */
767
768 fprintf(outfile," {");
769 j = numpfields;
770 while (j > 0)
771 {
772 if (pvalptr != NULL)
773 {
774 fprintf(outfile," %sF ",pvalptr->val);
775 pvalptr = pvalptr->next;
776 }
777 else
778 fprintf(outfile," 0.0F ");
779 if (!(--j))
780 fprintf(outfile,"},");
781 else
782 fprintf(outfile,",");
783 }
784
785
786 /* struct ninstr_types * nstate */
787
788 fprintf(outfile," NULL "); /* last 3:*pass*/
789 fprintf(outfile,"}");
790 }
791 tptr= tptr->next;
792 }
793 fprintf(outfile,"};\n\n");
794
795 }
796
797
798 /*********************************************************/
799 /* declarations for the score control variables */
800 /*********************************************************/
801
initscorecontrol(int type)802 void initscorecontrol(int type)
803
804 {
805 char * prefix;
806 sasdata * sdata;
807 tnode * tptr;
808 tnode * lptr;
809 sigsym * psptr;
810 sigsym * label;
811
812 if (type == RELTSTAMP)
813 {
814 sdata = allsasl;
815 prefix = "s";
816 }
817 else
818 {
819 sdata = abssasl;
820 prefix = "sa";
821 }
822
823 sdata->numcontrol = 0;
824 tptr = sdata->controlroot;
825 while (tptr != NULL)
826 {
827 if (tptr->ttype == S_LCONTROL)
828 {
829
830 label = getsym(&(allsasl->labeltable), tptr->down->next);
831 if (label == NULL)
832 {
833 printf("Error: Unknown score label %s.\n",tptr->down->next->val);
834 showbadline(tptr->down);
835 }
836 lptr = label->defnode;
837 while (lptr != NULL)
838 {
839 psptr = getsym(&(lptr->down->sptr->defnode->sptr),
840 tptr->down->next->next->next);
841 if ((psptr != NULL) && (psptr->kind == K_IMPORT))
842 sdata->numcontrol++;
843 lptr = lptr->next;
844 }
845 }
846 else
847 {
848 psptr = getsym(&globalsymtable,tptr->down->next->next);
849 if ((psptr != NULL) ||
850 (!strcmp("MIDIctrl",tptr->down->next->next->val)) ||
851 (!strcmp("MIDIbend",tptr->down->next->next->val)) ||
852 (!strcmp("MIDItouch",tptr->down->next->next->val)) )
853 sdata->numcontrol++;
854 }
855 tptr = tptr->next;
856 }
857
858 if (sdata->numcontrol == 0)
859 return;
860
861 fprintf(outfile, "scontrol_lines %scontrol[%i];\n", prefix, sdata->numcontrol);
862 fprintf(outfile, "scontrol_lines * %scontrolidx;\n", prefix);
863 fprintf(outfile, "scontrol_lines * end%scontrol;\n\n", prefix);
864 }
865
866 /*********************************************************/
867 /* content_init() assignments for control variables */
868 /*********************************************************/
869
initscorecontrolassign(int type)870 void initscorecontrolassign(int type)
871
872 {
873 char * prefix;
874 sasdata * sdata;
875 sigsym * sptr;
876 tnode * tptr;
877 tnode * lptr;
878 sigsym * psptr;
879 sigsym * label;
880 int i;
881
882 if (type == RELTSTAMP)
883 {
884 sdata = allsasl;
885 prefix = "s";
886 }
887 else
888 {
889 sdata = abssasl;
890 prefix = "sa";
891 }
892
893 if (sdata->numcontrol == 0)
894 return;
895
896 fprintf(outfile," memcpy(EV(%scontrol), %scontrol_init, sizeof EV(%scontrol));\n",
897 prefix, prefix, prefix);
898
899 i = 0;
900 tptr = sdata->controlroot;
901 while (tptr != NULL)
902 {
903 if (tptr->ttype == S_LCONTROL)
904 {
905
906 label = getsym(&(allsasl->labeltable), tptr->down->next);
907 if (label == NULL)
908 {
909 printf("Error: Unknown score label %s.\n",tptr->down->next->val);
910 showbadline(tptr->down);
911 }
912 lptr = label->defnode;
913 while (lptr != NULL)
914 {
915 sptr = lptr->down->sptr;
916 psptr = getsym(&(lptr->down->sptr->defnode->sptr),
917 tptr->down->next->next->next);
918 if ((psptr != NULL) && (psptr->kind == K_IMPORT))
919 {
920 fprintf(outfile, " EV(%scontrol)[%i].iline = &EV(%s_%s)[%i];\n",
921 prefix, i, prefix, sptr->val,
922 lptr->down->arrayidx);
923 i++;
924 }
925 lptr = lptr->next;
926 }
927 }
928 else
929 {
930 psptr = getsym(&globalsymtable,tptr->down->next->next);
931 if ((psptr != NULL) ||
932 (!strcmp("MIDIctrl",tptr->down->next->next->val)) ||
933 (!strcmp("MIDIbend",tptr->down->next->next->val)) ||
934 (!strcmp("MIDItouch",tptr->down->next->next->val)) )
935 i++;
936 }
937 tptr = tptr->next;
938 }
939
940 fprintf(outfile, " EV(%scontrolidx) = &EV(%scontrol)[0];\n", prefix, prefix);
941 fprintf(outfile, " EV(end%scontrol) = &EV(%scontrol)[%i];\n\n",
942 prefix, prefix, sdata->numcontrol-1);
943 }
944
945 /*********************************************************/
946 /* declare and init true constant vars for score control */
947 /*********************************************************/
948
initscorecontrolconstant(int type)949 void initscorecontrolconstant(int type)
950
951 {
952 char * prefix;
953 sasdata * sdata;
954 int i;
955 tnode * tptr;
956 tnode * lptr;
957 sigsym * psptr;
958 sigsym * label;
959
960 if (type == RELTSTAMP)
961 {
962 sdata = allsasl;
963 prefix = "s";
964 }
965 else
966 {
967 sdata = abssasl;
968 prefix = "sa";
969 }
970
971 sdata->numcontrol = 0;
972 tptr = sdata->controlroot;
973 while (tptr != NULL)
974 {
975 if (tptr->ttype == S_LCONTROL)
976 {
977
978 label = getsym(&(allsasl->labeltable), tptr->down->next);
979 if (label == NULL)
980 {
981 printf("Error: Unknown score label %s.\n",tptr->down->next->val);
982 showbadline(tptr->down);
983 }
984 lptr = label->defnode;
985 while (lptr != NULL)
986 {
987 psptr = getsym(&(lptr->down->sptr->defnode->sptr),
988 tptr->down->next->next->next);
989 if ((psptr != NULL) && (psptr->kind == K_IMPORT))
990 sdata->numcontrol++;
991 lptr = lptr->next;
992 }
993 }
994 else
995 {
996 psptr = getsym(&globalsymtable,tptr->down->next->next);
997 if ((psptr != NULL) ||
998 (!strcmp("MIDIctrl",tptr->down->next->next->val)) ||
999 (!strcmp("MIDIbend",tptr->down->next->next->val)) ||
1000 (!strcmp("MIDItouch",tptr->down->next->next->val)) )
1001 sdata->numcontrol++;
1002 }
1003 tptr = tptr->next;
1004 }
1005
1006 if (sdata->numcontrol == 0)
1007 return;
1008
1009 fprintf(outfile, "scontrol_lines %scontrol_init[%i] = {\n",
1010 prefix, sdata->numcontrol);
1011 i = -1;
1012 tptr = sdata->controlroot;
1013 while (tptr != NULL)
1014 {
1015 if (tptr->ttype == S_LCONTROL)
1016 {
1017
1018 label = getsym(&(allsasl->labeltable),tptr->down->next);
1019 lptr = label->defnode;
1020 while (lptr != NULL)
1021 {
1022 psptr = getsym(&(lptr->down->sptr->defnode->sptr),
1023 tptr->down->next->next->next);
1024 if ((psptr != NULL) && (psptr->kind == K_IMPORT))
1025 {
1026 i++;
1027 if (i != 0)
1028 fprintf(outfile,",\n");
1029 fprintf(outfile,"{");
1030 fprintf(outfile," %sF,", tptr->val); /* t */
1031 fprintf(outfile," %i,", label->special + 1); /* label */
1032 fprintf(outfile," %i, ",lptr->down->arrayidx); /* siptr */
1033 fprintf(outfile," NULL, "); /* iline */
1034 fprintf(outfile,"%s_%s, ", /* imptr */
1035 lptr->down->sptr->val,psptr->val);
1036 fprintf(outfile,"%sF ", /* imval */
1037 tptr->down->next->next->next->next->val);
1038 fprintf(outfile,"}");
1039 }
1040 lptr = lptr->next;
1041 }
1042 }
1043 else
1044 {
1045 psptr = getsym(&globalsymtable,tptr->down->next->next);
1046 if ((psptr != NULL) ||
1047 (!strcmp("MIDIctrl",tptr->down->next->next->val)) ||
1048 (!strcmp("MIDIbend",tptr->down->next->next->val)) ||
1049 (!strcmp("MIDItouch",tptr->down->next->next->val)) )
1050 {
1051 i++;
1052 if (i != 0)
1053 fprintf(outfile,",\n");
1054 fprintf(outfile,"{");
1055 fprintf(outfile," %sF, 0, -1, NULL,",tptr->val);
1056 /* t, label,siptr, iline */
1057 if (psptr != NULL)
1058 fprintf(outfile," GBL_%s, ", psptr->val); /* imptr */
1059 else
1060 {
1061 if (!strcmp("MIDIctrl",tptr->down->next->next->val))
1062 fprintf(outfile," %i, ", MIDIFRAMELEN*
1063 tptr->down->next->next->down->width +
1064 MIDICTRLPOS + tptr->down->next->next->arrayidx);
1065 if (!strcmp("MIDIbend",tptr->down->next->next->val))
1066 fprintf(outfile," %i, ", MIDIFRAMELEN*
1067 tptr->down->next->next->down->width +
1068 MIDIBENDPOS);
1069 if (!strcmp("MIDItouch",tptr->down->next->next->val))
1070 {
1071 if (tptr->down->next->next->arrayidx >= 0)
1072 fprintf(outfile," %i, ", MIDIFRAMELEN*
1073 tptr->down->next->next->down->width +
1074 MIDITOUCHPOS + tptr->down->next->next->arrayidx);
1075 else
1076 fprintf(outfile," %i, ", MIDIFRAMELEN*
1077 tptr->down->next->next->down->width +
1078 MIDICHTOUCHPOS);
1079 }
1080 }
1081 fprintf(outfile," %sF ", /* imval */
1082 tptr->down->next->next->next->val);
1083 fprintf(outfile,"}");
1084 }
1085 }
1086 tptr = tptr->next;
1087 }
1088
1089 fprintf(outfile,"\n};\n\n");
1090 }
1091
1092
1093 /*********************************************************/
1094 /* declarations for the score tempo variables */
1095 /*********************************************************/
1096
initscoretempo(int type)1097 void initscoretempo(int type)
1098
1099 {
1100 char * prefix;
1101
1102 if (type == RELTSTAMP)
1103 {
1104 if (!(allsasl->temporoot))
1105 return;
1106 prefix = "s";
1107 }
1108 else
1109 {
1110 if (!(abssasl->temporoot))
1111 return;
1112 prefix = "sa";
1113 }
1114
1115 fprintf(outfile,"int end%stempo;\n", prefix);
1116 fprintf(outfile,"int %stempoidx;\n\n", prefix);
1117 }
1118
1119 /*********************************************************/
1120 /* content_init() assignments for the tempo variables */
1121 /*********************************************************/
1122
initscoretempoassign(int type)1123 void initscoretempoassign(int type)
1124
1125 {
1126 char * prefix;
1127 tnode * tptr;
1128 int i;
1129
1130 if (type == RELTSTAMP)
1131 {
1132 if (!(tptr = allsasl->temporoot))
1133 return;
1134 prefix = "s";
1135 }
1136 else
1137 {
1138 if (!(tptr = abssasl->temporoot))
1139 return;
1140 prefix = "sa";
1141 }
1142
1143 i = 0;
1144 while (tptr != NULL)
1145 {
1146 i++;
1147 tptr = tptr->next;
1148 }
1149
1150 fprintf(outfile," EV(end%stempo) = %i;\n",prefix,i-1);
1151 }
1152
1153
1154 /*********************************************************/
1155 /* declare and init "true constant" vars for score tempo */
1156 /*********************************************************/
1157
initscoretempoconstant(int type)1158 void initscoretempoconstant(int type)
1159
1160 {
1161 char * prefix;
1162 int i, numtempo;
1163 tnode * tptr;
1164
1165
1166 if (type == RELTSTAMP)
1167 {
1168 if (!(tptr = allsasl->temporoot))
1169 return;
1170 numtempo = allsasl->numtempo;
1171 prefix = "s";
1172 }
1173 else
1174 {
1175 if (!(tptr = abssasl->temporoot))
1176 return;
1177 numtempo = abssasl->numtempo;
1178 prefix = "sa";
1179 }
1180
1181 fprintf(outfile, "stempo_lines %stempo[%i] = {\n", prefix, numtempo + 1);
1182
1183 i = 0;
1184 while (tptr != NULL)
1185 {
1186 if (i++ != 0)
1187 fprintf(outfile,",\n");
1188 fprintf(outfile,"{");
1189 fprintf(outfile,"%sF, %sF",tptr->val,tptr->down->next->next->val);
1190 fprintf(outfile,"}");
1191 tptr = tptr->next;
1192 }
1193 fprintf(outfile,"};\n\n");
1194 }
1195
1196 /*********************************************************/
1197 /* declarations for the score table variables */
1198 /*********************************************************/
1199
initscoretablevars(int type)1200 void initscoretablevars(int type)
1201
1202 {
1203 char * prefix;
1204
1205 if (type == RELTSTAMP)
1206 {
1207 if (!(allsasl->tableroot))
1208 return;
1209 prefix = "s";
1210 }
1211 else
1212 {
1213 if (!(abssasl->tableroot))
1214 return;
1215 prefix = "sa";
1216 }
1217
1218 fprintf(outfile,"int end%stable;\n\n", prefix);
1219 fprintf(outfile,"int %stableidx;\n\n", prefix);
1220 }
1221
1222 /*********************************************************/
1223 /* content_init() assignments for the table variables */
1224 /*********************************************************/
1225
initscoretableassign(int type)1226 void initscoretableassign(int type)
1227
1228 {
1229 int i;
1230 tnode * tptr;
1231 char * prefix;
1232
1233 if (type == RELTSTAMP)
1234 {
1235 if (!(tptr = allsasl->tableroot))
1236 return;
1237 prefix = "s";
1238 }
1239 else
1240 {
1241 if (!(tptr = abssasl->tableroot))
1242 return;
1243 prefix = "sa";
1244 }
1245
1246 i = 0;
1247 while (tptr != NULL)
1248 {
1249 i++;
1250 tptr = tptr->next;
1251 }
1252
1253 fprintf(outfile," EV(end%stable) = %i;\n\n",prefix,i-1);
1254 }
1255
1256
1257 /*********************************************************/
1258 /* declare and init true constant vars for score tables */
1259 /*********************************************************/
1260
initscoretableconstant(int type)1261 void initscoretableconstant(int type)
1262
1263 {
1264 int i, numtable;
1265 tnode * tptr;
1266 tnode * defnode;
1267 char * prefix;
1268
1269 if (type == RELTSTAMP)
1270 {
1271 if (!(tptr = allsasl->tableroot))
1272 return;
1273 numtable = allsasl->numtable;
1274 prefix = "s";
1275 }
1276 else
1277 {
1278 if (!(tptr = abssasl->tableroot))
1279 return;
1280 numtable = abssasl->numtable;
1281 prefix = "sa";
1282 }
1283
1284 fprintf(outfile,"stable_lines %stable[%i] = {\n",
1285 prefix, numtable+1);
1286
1287 i = 0;
1288 while (tptr != NULL)
1289 {
1290 if (i != 0)
1291 fprintf(outfile,",");
1292
1293 fprintf(outfile,"\n{");
1294
1295 defnode = tptr->sptr->defnode;
1296
1297 fprintf(outfile," %sF, TBL_GBL_%s, %i, ",
1298 tptr->val, defnode->down->next->val,
1299 defnode->usesinput ? defnode->arrayidx : -1);
1300
1301 if (defnode->usesinput)
1302 fprintf(outfile,"NULL, &(score_%stdata%i[0])", prefix, i);
1303 else
1304 fprintf(outfile," score_%stable%i, NULL", prefix, i);
1305
1306 fprintf(outfile,"}");
1307 i++;
1308 tptr = tptr->next;
1309 }
1310 fprintf(outfile,"};\n\n");
1311 }
1312
1313
1314 /*********************************************************/
1315 /* initializes score table externs */
1316 /*********************************************************/
1317
initscoretableexterns(int type)1318 void initscoretableexterns(int type)
1319
1320 {
1321 int i, numtable;
1322 tnode * tptr;
1323 char * prefix;
1324
1325 if (type == RELTSTAMP)
1326 {
1327 if (!(tptr = allsasl->tableroot))
1328 return;
1329 numtable = allsasl->numtable;
1330 prefix = "s";
1331 }
1332 else
1333 {
1334 if (!(tptr = abssasl->tableroot))
1335 return;
1336 numtable = abssasl->numtable;
1337 prefix = "sa";
1338 }
1339
1340 i = 0;
1341 while (i < numtable)
1342 {
1343 fprintf(outfile, "extern void score_%stable%i(ENGINE_PTR_TYPE);\n", prefix,i);
1344 fprintf(outfile, "extern %s score_%stdata%i[];\n",
1345 hexstrings ? "char" : "float", prefix, i);
1346 fprintf(outfile, "\n");
1347 i++;
1348 }
1349 fprintf(outfile, "\n");
1350 }
1351
1352
1353 /*********************************************************/
1354 /* prints functions to initialize SASL tables: sfmain.c */
1355 /*********************************************************/
1356
printtablefunctions(void)1357 void printtablefunctions(void)
1358
1359 {
1360 int i;
1361 tnode * tptr;
1362 char name[STRSIZE];
1363
1364 currinputwidth = 1;
1365 currinstrwidth = 1;
1366 currinstancename = "GBL";
1367 curropcodeprefix = "GBL";
1368 currinstrument = NULL;
1369 currinstance = NULL;
1370 curropcodestack = NULL;
1371 redefglobal();
1372
1373 tptr = allsasl->tableroot;
1374 i = -1;
1375 while (tptr != NULL)
1376 {
1377 i++;
1378 if (tptr->sptr->defnode->usesinput)
1379 {
1380 sprintf(name, "score_stdata%i",i);
1381 printtablestring(tptr->sptr, name);
1382 }
1383 else
1384 {
1385 fprintf(outfile,"\n\nvoid score_stable%i(ENGINE_PTR_DECLARE)\n{\n\n",i);
1386 if (wavegeneratorname(tptr->down->next->next->next))
1387 {
1388 wavegeneratorvar(tptr->sptr);
1389 fprintf(outfile," int i,j;\n\n");
1390 createtable(tptr->sptr, "TBL_GBL", S_SASLFILE);
1391 }
1392 fprintf(outfile,"}\n\n");
1393 }
1394 tptr = tptr->next;
1395 }
1396
1397
1398 tptr = abssasl->tableroot;
1399 i = -1;
1400 while (tptr != NULL)
1401 {
1402 i++;
1403 if (tptr->sptr->defnode->usesinput)
1404 {
1405 sprintf(name, "score_satdata%i",i);
1406 printtablestring(tptr->sptr, name);
1407 }
1408 else
1409 {
1410 fprintf(outfile,"\n\nvoid score_satable%i(ENGINE_PTR_DECLARE)\n{\n\n",i);
1411 if (wavegeneratorname(tptr->down->next->next->next))
1412 {
1413 wavegeneratorvar(tptr->sptr);
1414 fprintf(outfile," int i,j;\n\n");
1415 createtable(tptr->sptr, "TBL_GBL", S_SASLFILE);
1416 }
1417 fprintf(outfile,"}\n\n");
1418 }
1419 tptr = tptr->next;
1420 }
1421
1422 redefnormal();
1423 }
1424
1425
1426 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1427 /* */
1428 /* Second-level functions for reading score data. Note that */
1429 /* parsetempo() and parsecontrol() also called by readmidi.c */
1430 /* */
1431 /*______________________________________________________________*/
1432
1433
1434 /*********************************************************/
1435 /* lexical analyzer for score files */
1436 /*********************************************************/
1437
scorelex(int scotype)1438 tnode * scorelex (int scotype)
1439
1440 {
1441 FILE * sfile = NULL;
1442 int c,i,foundit, hashmark;
1443 char buf[LEXBUFSIZE] = {'\0'};
1444 tnode * scorelval;
1445
1446 switch (scotype) {
1447 case BCONFSCORE:
1448 return binconflex();
1449 break;
1450 case FCONFSCORE:
1451 sfile = saslfile;
1452 break;
1453 case BSSTRSCORE:
1454 return binsstrlex();
1455 break;
1456 case FSSTRSCORE:
1457 sfile = sstrfile;
1458 break;
1459 default:
1460 internalerror("readscore.c", "scorelex() switch");
1461 }
1462
1463 scorelval = make_tnode("", S_BADCHAR);
1464
1465 /* delete whitespace, hash-defines, and comments */
1466
1467 foundit = 0;
1468 while (!foundit)
1469 {
1470 while ((isspace(c = getc(sfile)))&&(c != '\n'));
1471 if ((c != '#') && (c != '/'))
1472 foundit = 1;
1473 else
1474 {
1475 hashmark = (c == '#');
1476 c = getc(sfile);
1477 if ((hashmark == 0) && (c != '/'))
1478 {
1479 ungetc(c,sfile);
1480 buf[0]='/'; buf[1]='\0';
1481 scorelval->val = dupval(buf);
1482 scorelval->ttype = S_BADCHAR;
1483 return scorelval;
1484 }
1485 else
1486 {
1487 while ((c != '\n') && (c != EOF))
1488 c = getc(sfile);
1489 if (c == EOF)
1490 foundit = 1;
1491 }
1492 }
1493 }
1494
1495 /* string constant */
1496
1497 if (c == '"')
1498 {
1499 i=0; c = getc(sfile);
1500 while (c != EOF)
1501 if (c != '"')
1502 {
1503 if (i < LEXBUFSIZE)
1504 buf[i++]=(char)c;
1505 c = getc(sfile);
1506 }
1507 else
1508 {
1509 if ((i!=0)&&buf[i-1]=='\\')
1510 {
1511 buf[i-1]= '"';
1512 c = getc(sfile);
1513 }
1514 else
1515 {
1516 if (i < LEXBUFSIZE)
1517 {
1518 buf[i]='\0';
1519 scorelval->ttype = S_STRCONST;
1520 }
1521 else
1522 {
1523 /* string overflows buffer -- keep S_BADCHAR */
1524
1525 buf[LEXBUFSIZE - 1]= '\0';
1526 }
1527
1528 scorelval->val = dupval(buf);
1529 return scorelval;
1530 }
1531 }
1532
1533 /* unterminated string constant fills file -- keep S_BADCHAR */
1534
1535 if (i < LEXBUFSIZE)
1536 buf[i]= '\0';
1537 else
1538 buf[LEXBUFSIZE - 1]= '\0';
1539
1540 scorelval->val = dupval(buf);
1541 return scorelval;
1542 }
1543
1544 /* parse integers and numbers */
1545
1546 i = 0;
1547 if (c == '-')
1548 {
1549 buf[i]= '-'; i++; /* can't overflow */
1550 c = getc(sfile);
1551 if (!(isdigit(c)||(c == '.')))
1552 {
1553 ungetc(c,sfile);
1554 buf[i]='\0'; /* can't overflow */
1555 scorelval->val = dupval(buf);
1556 scorelval->ttype = S_BADNUMBER;
1557 return scorelval;
1558 }
1559 }
1560 if (isdigit(c)||(c == '.'))
1561 {
1562 if (c == '.')
1563 {
1564 buf[i]= '0'; i++; /* can't overflow */
1565 c = getc(sfile);
1566 if (!isdigit(c))
1567 {
1568 ungetc(c,sfile);
1569 buf[i]='\0';
1570 scorelval->val = dupval(buf);
1571 scorelval->ttype = S_BADNUMBER;
1572 return scorelval;
1573 }
1574 else
1575 {
1576 ungetc(c,sfile);
1577 c = '.';
1578 }
1579 }
1580 else
1581 {
1582 while (isdigit(c))
1583 {
1584 if (i < LEXBUFSIZE)
1585 buf[i++]=(char)c;
1586 c = getc(sfile);
1587 }
1588 if ((c != 'e') && (c != '.')) /* an integer, convert to number */
1589 {
1590 ungetc(c,sfile);
1591 if (i + 2 < LEXBUFSIZE)
1592 {
1593 buf[i]='.'; i++;
1594 buf[i]='0'; i++;
1595 buf[i]='\0';
1596 scorelval->ttype = S_NUMBER;
1597 }
1598 else
1599 {
1600 buf[(i < LEXBUFSIZE) ? i : LEXBUFSIZE - 1] = '\0';
1601 scorelval->ttype = S_BADNUMBER;
1602 }
1603 scorelval->val = dupval(buf);
1604 return scorelval;
1605 }
1606 }
1607 if (c == '.')
1608 {
1609 if (i < LEXBUFSIZE)
1610 buf[i++]=(char)c;
1611 c = getc(sfile);
1612 if (!isdigit(c))
1613 {
1614 if (i < LEXBUFSIZE)
1615 buf[i++]= '0';
1616 }
1617 else
1618 {
1619 while (isdigit(c))
1620 {
1621 if (i < LEXBUFSIZE)
1622 buf[i++]=(char)c;
1623 c = getc(sfile);
1624 }
1625 }
1626 }
1627 if (c != 'e')
1628 {
1629 ungetc(c,sfile);
1630 if (i < LEXBUFSIZE)
1631 {
1632 buf[i]='\0';
1633 scorelval->ttype = S_NUMBER;
1634 }
1635 else
1636 {
1637 buf[LEXBUFSIZE - 1]= '\0';
1638 scorelval->ttype = S_BADNUMBER;
1639 }
1640 scorelval->val = dupval(buf);
1641 return scorelval;
1642 }
1643 else
1644 {
1645 if (i < LEXBUFSIZE)
1646 buf[i++]=(char)c;
1647 c = getc(sfile);
1648 if ((c=='+')||(c=='-'))
1649 {
1650 if (i < LEXBUFSIZE)
1651 buf[i++]=(char)c;
1652 c = getc(sfile);
1653 }
1654 if (isdigit(c))
1655 {
1656 while (isdigit(c))
1657 {
1658 if (i < LEXBUFSIZE)
1659 buf[i++]=(char)c;
1660 c = getc(sfile);
1661 }
1662 ungetc(c,sfile);
1663
1664 if (i < LEXBUFSIZE)
1665 {
1666 buf[i]='\0';
1667 scorelval->ttype = S_NUMBER;
1668 }
1669 else
1670 {
1671 buf[LEXBUFSIZE - 1]= '\0';
1672 scorelval->ttype = S_BADNUMBER;
1673 }
1674
1675 scorelval->val = dupval(buf);
1676 return scorelval;
1677 }
1678 else
1679 {
1680 ungetc(c,sfile);
1681 buf[i < LEXBUFSIZE ? i : LEXBUFSIZE - 1]='\0';
1682 scorelval->val = dupval(buf);
1683 scorelval->ttype = S_BADNUMBER;
1684 return scorelval;
1685 }
1686 }
1687 }
1688
1689 if ((isalpha(c))||(c == '_')) /* keywords and identifiers */
1690 {
1691
1692 i = 0;
1693 while (((isalnum(c)) || (c == '_')))
1694 {
1695 if (i < LEXBUFSIZE - 1) /* only first 16 chars matter in spec */
1696 buf[i++] = (char)c;
1697 c = getc(sfile);
1698 }
1699 buf[i] = '\0';
1700 ungetc(c,sfile);
1701 scorelval->val = dupval(buf);
1702
1703 if (!strcmp(buf,"control"))
1704 {
1705 scorelval->ttype = S_CONTROL;
1706 return scorelval;
1707 }
1708
1709 if (!strcmp(buf,"tempo"))
1710 {
1711 scorelval->ttype = S_TEMPO;
1712 return scorelval;
1713 }
1714
1715 if (!strcmp(buf,"table"))
1716 {
1717 scorelval->ttype = S_TABLE;
1718 return scorelval;
1719 }
1720
1721 if (!strcmp(buf,"end"))
1722 {
1723 scorelval->ttype = S_END;
1724 return scorelval;
1725 }
1726
1727 scorelval->ttype = S_IDENT;
1728 return scorelval;
1729 }
1730
1731
1732 buf[0]=(char)c;
1733 buf[1]='\0';
1734 scorelval->val = dupval(buf);
1735 scorelval->ttype = c;
1736
1737 switch (c) {
1738
1739 case '\n':
1740 scorelval->ttype = S_NEWLINE;
1741 return scorelval;
1742 case EOF:
1743 scorelval->ttype = S_EOF;
1744 return scorelval;
1745 case ':':
1746 scorelval->ttype = S_COL;
1747 return scorelval;
1748 case '*':
1749 scorelval->ttype = S_STAR;
1750 return scorelval;
1751 }
1752
1753 scorelval->ttype = S_BADCHAR;
1754 return scorelval;
1755
1756 }
1757
1758 /*********************************************************/
1759 /* parse function for SASL end statement */
1760 /*********************************************************/
1761
parseend(sasdata * sdata,tnode * nsl)1762 int parseend(sasdata * sdata, tnode * nsl)
1763
1764 {
1765
1766 if ( ((nsl->ttype == S_NUMBER) ||
1767 (nsl->ttype == S_INTGR)) &&
1768 (nsl->next->ttype == S_END) )
1769 {
1770 if (sdata->endtimeval == NULL)
1771 sdata->endtimeval = dupval(nsl->val);
1772 else
1773 {
1774 if (atof(nsl->val) < atof(sdata->endtimeval))
1775 sdata->endtimeval = dupval(nsl->val);
1776 }
1777 }
1778 else
1779 badline(nsl);
1780 return 1;
1781 }
1782
1783
1784 extern void mergenodes(tnode **, tnode *);
1785
1786 /*********************************************************/
1787 /* parse function for SASL tempo statement */
1788 /*********************************************************/
1789
parsetempo(sasdata * sdata,tnode * nsl,int hpe)1790 int parsetempo(sasdata * sdata, tnode * nsl, int hpe)
1791
1792 {
1793
1794 tnode * newtempo;
1795 int ret = 0;
1796
1797 if ( ((nsl->ttype == S_NUMBER) ||
1798 (nsl->ttype == S_INTGR)) &&
1799 (nsl->next->ttype == S_TEMPO) &&
1800 ((nsl->next->next->ttype == S_NUMBER) ||
1801 (nsl->next->next->ttype == S_INTGR)) )
1802 {
1803 sdata->numtempo++;
1804 newtempo = make_tnode(nsl->val, S_TEMPO);
1805 newtempo->down = nsl;
1806 newtempo->special = hpe;
1807 newtempo->time = (float) atof(nsl->val);
1808 if (sdata->temporoot == NULL)
1809 {
1810 sdata->temporoot = sdata->tempotail = newtempo;
1811 }
1812 else
1813 {
1814 if (newtempo->time >= sdata->tempotail->time)
1815 {
1816 sdata->tempotail->next = newtempo;
1817 sdata->tempotail = newtempo;
1818 }
1819 else
1820 {
1821 mergenodes(&(sdata->temporoot),newtempo);
1822 }
1823 }
1824 ret = 1;
1825 }
1826 return ret;
1827 }
1828
1829
1830 extern void tablepfieldcheck(tnode *);
1831 extern void scoreaddsymtable(tnode *);
1832
1833 /*********************************************************/
1834 /* parse function for SASL table statement */
1835 /*********************************************************/
1836
parsetable(sasdata * sdata,tnode * nsl,int tcount,int hpe)1837 int parsetable(sasdata * sdata, tnode * nsl, int tcount, int hpe)
1838
1839 {
1840 tnode * newtable;
1841 tnode * tptr;
1842 tnode * pptr;
1843 tnode * wgen;
1844 tnode * sizeptr;
1845 int flag = 1;
1846
1847 if (((nsl->ttype == S_NUMBER) || (nsl->ttype == S_INTGR)) &&
1848 (nsl->next->ttype == S_TABLE) &&
1849 (nsl->next->next->ttype == S_IDENT) &&
1850 (nsl->next->next->next->ttype == S_IDENT) &&
1851 ((flag = (getvsym(&globalsymtable, nsl->next->next->val) != NULL))))
1852 {
1853 sdata->numtable++;
1854 newtable = make_tnode(nsl->val, S_TABLE);
1855 addvsym(&newtable->sptr,nsl->next->next->val, K_NORMAL);
1856 newtable->sptr->defnode = make_tnode("<table>", S_TABLE);
1857 newtable->sptr->defnode->vol = CONSTANT;
1858 tptr = newtable->sptr->defnode->down = make_tnode("TABLE", S_TABLE);
1859 tptr->next = make_tnode(nsl->next->next->val, S_IDENT);
1860 tptr = tptr->next;
1861 tptr->next = make_tnode("(", S_LP);
1862 tptr = tptr->next;
1863 tptr->next = make_tnode(nsl->next->next->next->val, S_IDENT);
1864 wgen = tptr = tptr->next;
1865
1866 if (!wavegeneratorname(wgen))
1867 {
1868 printf("Error: Invalid generator name %s.\n\n",tptr->val);
1869 showbadline(nsl);
1870 }
1871 tablepfieldcheck(nsl);
1872
1873 tptr->next = make_tnode(",", S_COM);
1874 tptr = tptr->next;
1875 tptr->next = make_tnode("<exprstrlist>", S_EXPRSTRLIST);
1876 tptr->next->next = make_tnode(")", S_RP);
1877 pptr = nsl->next->next->next->next;
1878 sizeptr = tptr->next->down = make_tnode("<expr>", S_EXPR);
1879 tptr = tptr->next->down;
1880
1881 while (pptr != NULL)
1882 {
1883 tptr->down = make_tnode(dupval(pptr->val), pptr->ttype);
1884 tptr->rate = tptr->down->rate = IRATETYPE;
1885 tptr->vol = tptr->down->vol = CONSTANT;
1886 tptr->width = tptr->down->width = 1;
1887 if (pptr->ttype == S_IDENT)
1888 {
1889 tptr->vartype = tptr->down->vartype = TABLETYPE;
1890 tptr->down->sptr = pptr->sptr;
1891 }
1892 else
1893 tptr->vartype = tptr->down->vartype = SCALARTYPE;
1894 tptr->res = tptr->down->res;
1895 if (pptr->next)
1896 {
1897 tptr->next = make_tnode(",", S_COM);
1898 tptr = tptr->next;
1899 if (pptr->next->ttype == S_STRCONST)
1900 {
1901 tptr->next = make_tnode(dupval(pptr->next->val), S_STRCONST);
1902 pptr = pptr->next;
1903 tptr = tptr->next;
1904 if (pptr->next)
1905 {
1906 tptr->next = make_tnode(",", S_COM);
1907 tptr = tptr->next;
1908 tptr->next = make_tnode("<expr>", S_EXPR);
1909 }
1910 }
1911 else
1912 tptr->next = make_tnode("<expr>", S_EXPR);
1913 tptr = tptr->next;
1914 }
1915 pptr = pptr->next;
1916 }
1917
1918 newtable->sptr->consval = (char *)
1919 wavereduceconstants(newtable->sptr->defnode, nsl);
1920
1921 if (newtable->sptr->defnode->usesinput == 0)
1922 haswavegenerator(wgen);
1923
1924 newtable->down = nsl;
1925 newtable->special = hpe;
1926 newtable->width = tcount - 4;
1927 newtable->time = (float) atof(nsl->val);
1928 if (sdata->tableroot == NULL)
1929 {
1930 sdata->tableroot = sdata->tabletail = newtable;
1931 }
1932 else
1933 {
1934 if (newtable->time >= sdata->tabletail->time)
1935 {
1936 sdata->tabletail->next = newtable;
1937 sdata->tabletail = newtable;
1938 }
1939 else
1940 {
1941 mergenodes(&(sdata->tableroot),newtable);
1942 }
1943 }
1944 if (boutfile)
1945 {
1946 scoreaddsymtable(nsl->next->next);
1947 scoreaddsymtable(nsl->next->next->next);
1948 }
1949 }
1950 else
1951 {
1952 if (flag)
1953 badline(nsl);
1954 }
1955 return 1;
1956 }
1957
1958 /*********************************************************/
1959 /* parse function for SASL control statement */
1960 /*********************************************************/
1961
parsecontrol(sasdata * sdata,tnode * nsl,int hpe)1962 int parsecontrol(sasdata * sdata, tnode * nsl, int hpe)
1963
1964 {
1965 tnode * newcontrol;
1966
1967 if ( ((nsl->ttype == S_NUMBER) ||
1968 (nsl->ttype == S_INTGR)) &&
1969 (nsl->next->next->ttype == S_IDENT) &&
1970 ((nsl->next->next->next->ttype == S_NUMBER) ||
1971 (nsl->next->next->next->ttype == S_INTGR)) )
1972 {
1973 newcontrol = make_tnode(nsl->val, S_CONTROL);
1974 newcontrol->down = nsl;
1975 newcontrol->special = hpe;
1976 newcontrol->time = (float) atof(nsl->val);
1977 if (sdata->controlroot == NULL)
1978 {
1979 sdata->controlroot = sdata->controltail = newcontrol;
1980 }
1981 else
1982 {
1983 if (newcontrol->time >= sdata->controltail->time)
1984 {
1985 sdata->controltail->next = newcontrol;
1986 sdata->controltail = newcontrol;
1987 }
1988 else
1989 {
1990 mergenodes(&(sdata->controlroot),newcontrol);
1991 }
1992 }
1993 if (boutfile)
1994 scoreaddsymtable(nsl->next->next);
1995 }
1996 else
1997 badline(nsl);
1998 return 1;
1999
2000 }
2001
2002 /*********************************************************/
2003 /* parse function for SASL control statement */
2004 /*********************************************************/
2005
parselcontrol(sasdata * sdata,tnode * nsl,int hpe)2006 int parselcontrol(sasdata * sdata, tnode * nsl, int hpe)
2007
2008 {
2009 tnode * newcontrol;
2010
2011 if ( ((nsl->ttype == S_NUMBER) ||
2012 (nsl->ttype == S_INTGR)) &&
2013 (nsl->next->ttype == S_IDENT) &&
2014 (nsl->next->next->next->ttype == S_IDENT) &&
2015 ((nsl->next->next->next->next->ttype == S_NUMBER) ||
2016 (nsl->next->next->next->next->ttype == S_INTGR)) )
2017 {
2018 newcontrol = make_tnode(nsl->val, S_LCONTROL);
2019 newcontrol->down = nsl;
2020 newcontrol->special = hpe;
2021 newcontrol->time = (float) atof(nsl->val);
2022 if (sdata->controlroot == NULL)
2023 {
2024 sdata->controlroot = sdata->controltail = newcontrol;
2025 }
2026 else
2027 {
2028 if (newcontrol->time >= sdata->controltail->time)
2029 {
2030 sdata->controltail->next = newcontrol;
2031 sdata->controltail = newcontrol;
2032 }
2033 else
2034 {
2035 mergenodes(&(sdata->controlroot),newcontrol);
2036 }
2037 }
2038 if (boutfile)
2039 {
2040 scoreaddsymtable(nsl->next);
2041 scoreaddsymtable(nsl->next->next->next);
2042 }
2043 }
2044 else
2045 badline(nsl);
2046 return 1;
2047 }
2048
2049
2050 extern void instrpfieldcheck(tnode *, tnode *);
2051
2052 /*********************************************************/
2053 /* parse function for SASL instr statement */
2054 /*********************************************************/
2055
parselinstr(sasdata * sdata,tnode * nsl,int tcount,int hpe)2056 int parselinstr(sasdata * sdata, tnode * nsl, int tcount, int hpe)
2057
2058 {
2059
2060 tnode * newinstr;
2061 sigsym * label;
2062 tnode * lptr;
2063
2064 if ( (nsl->ttype == S_IDENT) &&
2065 (nsl->next->ttype == S_COL) &&
2066 ((nsl->next->next->ttype == S_NUMBER) ||
2067 (nsl->next->next->ttype == S_INTGR)) &&
2068 (nsl->next->next->next->ttype == S_IDENT) &&
2069 ((nsl->next->next->next->next->ttype == S_NUMBER) ||
2070 (nsl->next->next->next->next->ttype == S_INTGR)))
2071 {
2072
2073 newinstr = make_tnode(nsl->next->next->val, S_LINSTR);
2074 newinstr->width = tcount - 5; /* num pfields */
2075 newinstr->special = hpe;
2076 newinstr->down = nsl;
2077 newinstr->time = (float) atof(newinstr->val);
2078 addvsym(&(sdata->labeltable), nsl->val, S_LINSTR);
2079 label = getsym(&(sdata->labeltable), nsl);
2080 lptr = make_tnode(nsl->next->next->next->val, S_INSTR);
2081 lptr->down = newinstr;
2082 if (label->defnode == NULL)
2083 label->defnode = lptr;
2084 else
2085 {
2086 lptr->next = label->defnode;
2087 label->defnode = lptr;
2088 }
2089 newinstr->sptr = getsym(&instrnametable,nsl->next->next->next);
2090 if (newinstr->sptr == NULL)
2091 {
2092 printf("Error: Instr %s, used in -sco, not in -orc.\n",
2093 nsl->next->next->next->val);
2094 showbadline(nsl);
2095 }
2096 instrpfieldcheck(nsl, nsl->next->next->next->next->next);
2097 if (nsl->next->next->opwidth)
2098 newinstr->sptr->ascore++;
2099 else
2100 newinstr->sptr->score++;
2101 if (sdata->instrroot == NULL)
2102 {
2103 sdata->instrroot = sdata->instrtail = newinstr;
2104 }
2105 else
2106 {
2107 if (newinstr->time >= sdata->instrtail->time)
2108 {
2109 sdata->instrtail->next = newinstr;
2110 sdata->instrtail = newinstr;
2111 }
2112 else
2113 {
2114 mergenodes(&(sdata->instrroot), newinstr);
2115 }
2116 }
2117 if (boutfile)
2118 {
2119 scoreaddsymtable(nsl);
2120 scoreaddsymtable(nsl->next->next->next);
2121 }
2122 return 1;
2123 }
2124 return 0;
2125 }
2126
2127 /*********************************************************/
2128 /* parse function for SASL instr statement */
2129 /*********************************************************/
2130
parseinstr(sasdata * sdata,tnode * nsl,int tcount,int hpe)2131 int parseinstr(sasdata * sdata, tnode * nsl, int tcount, int hpe)
2132
2133 {
2134
2135 tnode * newinstr;
2136
2137 if ( ((nsl->ttype == S_NUMBER) ||
2138 (nsl->ttype == S_INTGR)) &&
2139 (nsl->next->ttype == S_IDENT) &&
2140 ((nsl->next->next->ttype == S_NUMBER) ||
2141 (nsl->next->next->ttype == S_INTGR)))
2142 {
2143 newinstr = make_tnode(nsl->val, S_INSTR);
2144 newinstr->width = tcount - 3; /* num pfields */
2145 newinstr->special = hpe;
2146 newinstr->down = nsl;
2147 newinstr->time = (float) atof(nsl->val);
2148 newinstr->sptr = getsym(&instrnametable,nsl->next);
2149 if (newinstr->sptr == NULL)
2150 {
2151 printf("Error: Instr %s, used in -sco, not in -orc.\n",
2152 nsl->next->val);
2153 showbadline(nsl);
2154 }
2155 instrpfieldcheck(nsl, nsl->next->next->next);
2156 if (nsl->opwidth)
2157 newinstr->sptr->ascore++;
2158 else
2159 newinstr->sptr->score++;
2160 if (sdata->instrroot == NULL)
2161 {
2162 sdata->instrroot = sdata->instrtail = newinstr;
2163 }
2164 else
2165 {
2166 if (newinstr->time >= sdata->instrtail->time)
2167 {
2168 sdata->instrtail->next = newinstr;
2169 sdata->instrtail = newinstr;
2170 }
2171 else
2172 {
2173 mergenodes(&(sdata->instrroot), newinstr);
2174 }
2175 }
2176 if (boutfile)
2177 scoreaddsymtable(nsl->next);
2178 return 1;
2179 }
2180 return 0;
2181 }
2182
2183 /*********************************************************/
2184 /* shows bad SASL line, closes sfront */
2185 /*********************************************************/
2186
showbadline(tnode * line)2187 void showbadline(tnode * line)
2188
2189
2190 {
2191
2192 printf("Offending line from -sco file:\n\n");
2193 while (line != NULL)
2194 {
2195 printf(" %s ",line->val);
2196 line = line->next;
2197 }
2198 printf("\n");
2199 if (bitfile)
2200 {
2201 printf("Error originates in score_file SA block of -bit file.\n");
2202 printf("Use -scoout and -orcout to generate ASCII files and\n");
2203 printf("run sfront on these files to pinpoint error.\n");
2204 }
2205 else
2206 {
2207 if (cppsaol)
2208 {
2209 printf("If this line not in your main -sco file, look at\n");
2210 printf("files you may have included via pre-processing.\n");
2211 }
2212 }
2213 noerrorplace();
2214
2215 }
2216
2217 /*********************************************************/
2218 /* generic error function for SASL */
2219 /*********************************************************/
2220
badline(tnode * line)2221 void badline(tnode * line)
2222
2223
2224 {
2225 printf("Error: SASL Syntax error: \n\n");
2226 showbadline(line);
2227 }
2228
2229 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2230 /* */
2231 /* Second-level functions for intermediate score processing */
2232 /* */
2233 /*______________________________________________________________*/
2234
2235 extern void addtempomap(tnode **, tnode *);
2236
2237 /*********************************************************/
2238 /* makes a global tempo map for renumbering */
2239 /*********************************************************/
2240
maketempomap(void)2241 tnode * maketempomap(void)
2242
2243 {
2244 tnode * ret, * tptr;
2245 tnode * ctempo, * stempo, * atempo;
2246 int state;
2247
2248 /* tempos from SASL and MIDI in the configuration block */
2249
2250 ctempo = confsasl->temporoot;
2251
2252 /* tempos from has_time = 1 in SASL */
2253
2254 stempo = sstrsasl->temporoot;
2255
2256 /* tempos generated from mstrfile read, in relative form */
2257
2258 atempo = abssasl->temporoot;
2259
2260 /* default tempo */
2261
2262 if (mstrfile)
2263 tptr = ret = make_tnode("120.0", S_TEMPO);
2264 else
2265 tptr = ret = make_tnode("60.0", S_TEMPO);
2266
2267 ret->time = 0.0;
2268
2269 while (ctempo || stempo || atempo)
2270 {
2271 state = (ctempo != NULL) + 2*(stempo != NULL) + 4*(atempo != NULL);
2272 switch(state) {
2273 case 1: /* ctempo only */
2274 addtempomap(&ctempo, tptr);
2275 break;
2276 case 2: /* stempo only */
2277 addtempomap(&stempo, tptr);
2278 break;
2279 case 3: /* stempo and ctempo */
2280 if (stempo->time < ctempo->time)
2281 addtempomap(&stempo, tptr);
2282 else
2283 addtempomap(&ctempo, tptr);
2284 break;
2285 case 4: /* atempo only */
2286 addtempomap(&atempo, tptr);
2287 break;
2288 case 5: /* atempo and ctempo */
2289 if (atempo->time < ctempo->time)
2290 addtempomap(&atempo, tptr);
2291 else
2292 addtempomap(&ctempo, tptr);
2293 break;
2294 case 6: /* atempo and stempo */
2295 if (stempo->time < atempo->time)
2296 addtempomap(&stempo, tptr);
2297 else
2298 addtempomap(&atempo, tptr);
2299 break;
2300 case 7: /* atempo and stempo and ctempo */
2301 if ((stempo->time <= atempo->time) &&
2302 (stempo->time <= ctempo->time))
2303 addtempomap(&stempo, tptr);
2304 else
2305 {
2306 if (atempo->time < ctempo->time)
2307 addtempomap(&atempo, tptr);
2308 else
2309 addtempomap(&ctempo, tptr);
2310 }
2311 break;
2312 }
2313 tptr = tptr->next;
2314 }
2315
2316 /* delete dummy 60.0/120.0 */
2317
2318 ret = ret->next;
2319 return ret;
2320
2321 }
2322
2323 /*********************************************************/
2324 /* set up mstart and mend pointers for renumbering */
2325 /* */
2326 /* fields in each midi note: */
2327 /* */
2328 /* rate: starttime, in miditicks */
2329 /* width: endtime, in miditicks */
2330 /* opwidth: starttime, in kcycleidx (>= 1) */
2331 /* inwidth: endtime, in kcycleidx (>= 1) */
2332 /* res: notenumber */
2333 /* vartype: velocity */
2334 /* usesinput: flag for noteoffwrite */
2335 /*********************************************************/
2336
midipointers(tnode ** mstart,tnode ** mend)2337 int midipointers(tnode ** mstart, tnode ** mend)
2338
2339 {
2340 int hasmidi;
2341 tnode * tptr, *startptr, *endptr;
2342
2343 /* set up lists of current MIDI channel list pointers */
2344
2345 hasmidi = 0;
2346 tptr = sstrmidi->imidiroot;
2347 (*mstart) = (*mend) = startptr = endptr = NULL;
2348 while (tptr)
2349 {
2350 if (!(*mstart))
2351 {
2352 (*mstart) = startptr = make_tnode("tag", S_MIDITAG);
2353 (*mend) = endptr = make_tnode("tag", S_MIDITAG);
2354 }
2355 else
2356 {
2357 startptr->next = make_tnode("tag", S_MIDITAG);
2358 startptr = startptr->next;
2359 endptr->next = make_tnode("tag", S_MIDITAG);
2360 endptr = endptr->next;
2361 }
2362 startptr->down = endptr->down = tptr->down; /* list of notes */
2363 if (tptr->down)
2364 hasmidi = 1;
2365 tptr = tptr->next;
2366 }
2367 return hasmidi;
2368
2369 }
2370
2371 /*********************************************************/
2372 /* converts timestamps from relative to absolute */
2373 /*********************************************************/
2374
timestampconvert(tnode * tptr,int kcycleidx)2375 void timestampconvert(tnode * tptr, int kcycleidx)
2376
2377 {
2378 float ktime;
2379
2380 ktime = 1.0F/krate;
2381 vmcheck(tptr->val = (char *) calloc(64, sizeof(char)));
2382 sprintf(tptr->val, "%f", (kcycleidx-1.5F)*ktime);
2383 tptr->opwidth = kcycleidx;
2384
2385 }
2386
2387 /*********************************************************/
2388 /* merges a sasl rootlist */
2389 /*********************************************************/
2390
mergerootlist(tnode ** oneroot,tnode ** onetail,tnode ** tworoot,tnode ** twotail,tnode ** outroot,tnode ** outtail)2391 void mergerootlist(tnode ** oneroot, tnode ** onetail,
2392 tnode ** tworoot, tnode ** twotail,
2393 tnode ** outroot, tnode ** outtail)
2394
2395 {
2396 tnode * tptr = NULL;
2397
2398 /* first handle simple cases */
2399
2400 if (*tworoot == NULL)
2401 {
2402 *outroot = *oneroot;
2403 *outtail = *onetail;
2404 *onetail = NULL;
2405 return;
2406 }
2407 if (*oneroot == NULL)
2408 {
2409 *outroot = *tworoot;
2410 *outtail = *twotail;
2411 *twotail = NULL;
2412 return;
2413 }
2414
2415 /* set up the merge */
2416
2417 if ((*oneroot)->time < (*tworoot)->time)
2418 {
2419 *outroot = tptr = *oneroot;
2420 *oneroot = (*oneroot)->next;
2421 }
2422 else
2423 {
2424 *outroot = tptr = *tworoot;
2425 *tworoot = (*tworoot)->next;
2426 }
2427
2428 /* do the merge */
2429
2430 while ((*oneroot != NULL) || (*tworoot != NULL))
2431 {
2432 if (*oneroot == NULL)
2433 {
2434 tptr->next = *tworoot;
2435 *outtail = *twotail;
2436 *tworoot = NULL;
2437 break;
2438 }
2439 if (*tworoot == NULL)
2440 {
2441 tptr->next = *oneroot;
2442 *outtail = *onetail;
2443 *oneroot = NULL;
2444 break;
2445 }
2446 if ((*oneroot)->time < (*tworoot)->time)
2447 {
2448 tptr->next = *oneroot;
2449 *oneroot = (*oneroot)->next;
2450 }
2451 else
2452 {
2453 tptr->next = *tworoot;
2454 *tworoot = (*tworoot)->next;
2455 }
2456 tptr = tptr->next;
2457 }
2458
2459 *onetail = *twotail = NULL;
2460 return;
2461 }
2462
2463 /*********************************************************/
2464 /* merges a labeltable list into allsasl */
2465 /*********************************************************/
2466
mergelabeltable(sigsym * sptr)2467 void mergelabeltable(sigsym * sptr)
2468
2469 {
2470 sigsym * label;
2471 tnode * lptr;
2472
2473 while (sptr)
2474 {
2475 if ((label = getvsym(&(allsasl->labeltable),sptr->val)))
2476 {
2477 lptr = sptr->defnode;
2478 while (lptr->next != NULL)
2479 lptr = lptr->next;
2480 lptr->next = label->defnode;
2481 label->defnode = sptr->defnode;
2482 }
2483 else
2484 {
2485 addvsym(&(allsasl->labeltable), sptr->val, S_LINSTR);
2486 label = getvsym(&(allsasl->labeltable),sptr->val);
2487 label->defnode = sptr->defnode;
2488 }
2489 sptr = sptr->next;
2490 }
2491 }
2492
2493
2494 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2495 /* */
2496 /* Utility functions for reading score data. */
2497 /* */
2498 /*______________________________________________________________*/
2499
2500 /*********************************************************/
2501 /* adds score IDENT to symbol table */
2502 /*********************************************************/
2503
scoreaddsymtable(tnode * tptr)2504 void scoreaddsymtable(tnode * tptr)
2505
2506 {
2507 if (!identtoken(tptr))
2508 if ((addvsym(&bitsymtable, tptr->val, K_INTERNAL) == INSTALLED)
2509 && (bitsymtable->next != NULL))
2510 bitsymtable->special = bitsymtable->next->special + 1;
2511 }
2512
2513 /*********************************************************/
2514 /* merge sort for SASL note-ons */
2515 /*********************************************************/
2516
mergenodes(tnode ** rootnode,tnode * newnode)2517 void mergenodes(tnode ** rootnode, tnode * newnode)
2518
2519 {
2520
2521 tnode * tptr;
2522
2523 if ((*rootnode)->time >= newnode->time)
2524 {
2525 newnode->next = *rootnode;
2526 *rootnode = newnode;
2527 return;
2528 }
2529 else
2530 {
2531 tptr = *rootnode;
2532 while (tptr->next != NULL)
2533 {
2534 if (tptr->next->time >= newnode->time)
2535 {
2536 newnode->next = tptr->next;
2537 tptr->next = newnode;
2538 return;
2539 }
2540 tptr = tptr->next;
2541 }
2542 internalerror("readscore.c", "mergenodes()");
2543 }
2544
2545 }
2546
2547
2548 /*********************************************************/
2549 /* checks instr pfields for bad elements */
2550 /*********************************************************/
2551
instrpfieldcheck(tnode * nsl,tnode * ptest)2552 void instrpfieldcheck(tnode * nsl, tnode * ptest)
2553
2554 {
2555
2556 while (ptest != NULL)
2557 {
2558 if ((ptest->ttype != S_NUMBER) && (ptest->ttype != S_INTGR))
2559 {
2560 printf("Error: Element %s not allowed in SASL instr pfields\n",
2561 ptest->val);
2562 showbadline(nsl);
2563 }
2564 ptest = ptest->next;
2565 }
2566
2567 }
2568
2569 /*********************************************************/
2570 /* checks table pfields for bad elements */
2571 /*********************************************************/
2572
tablepfieldcheck(tnode * nsl)2573 void tablepfieldcheck(tnode * nsl)
2574
2575 {
2576
2577 tnode * ptest;
2578 int sample, concat;
2579
2580 sample = !(strcmp(nsl->next->next->next->val,"sample"));
2581 concat = !(strcmp(nsl->next->next->next->val,"concat"));
2582
2583 ptest = nsl->next->next->next->next;
2584
2585 /* check type of size parameter */
2586
2587 if ((ptest->ttype != S_NUMBER) && (ptest->ttype != S_INTGR))
2588 {
2589 printf("Error: Bad size parameter %s in SASL table pfields\n",
2590 ptest->val);
2591 showbadline(nsl);
2592 }
2593 ptest = ptest->next;
2594
2595 /* special cases for concat and sample parameters */
2596
2597 if (sample)
2598 {
2599 if (!ptest || (ptest->ttype != S_STRCONST))
2600 {
2601 if (ptest)
2602 printf("Error: Bad filename parameter %s in SASL table pfields\n",
2603 ptest->val);
2604 else
2605 printf("Error: No filename parameter in SASL table pfields\n");
2606 showbadline(nsl);
2607 }
2608 ptest = ptest->next;
2609 }
2610
2611 if (concat)
2612 {
2613 while (ptest != NULL)
2614 {
2615 if ((ptest->ttype != S_IDENT) ||
2616 (!(ptest->sptr = getvsym(&globalsymtable,ptest->val))) ||
2617 (ptest->sptr->vartype != TABLETYPE))
2618 {
2619 printf("Error: Bad table parameter %s in SASL table pfields\n",
2620 ptest->val);
2621 showbadline(nsl);
2622 }
2623 ptest = ptest->next;
2624 }
2625 }
2626
2627 /* checks all numeric parameters */
2628
2629 while (ptest != NULL)
2630 {
2631 if ((ptest->ttype != S_NUMBER) && (ptest->ttype != S_INTGR))
2632 {
2633 printf("Error: Element %s not allowed in SASL table pfields\n",
2634 ptest->val);
2635 showbadline(nsl);
2636 }
2637 ptest = ptest->next;
2638 }
2639
2640 }
2641
2642 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2643 /* */
2644 /* Utility functions for intermediate score processing. */
2645 /* */
2646 /*______________________________________________________________*/
2647
2648 /*********************************************************/
2649 /* creates a new element for the tempo map */
2650 /*********************************************************/
2651
addtempomap(tnode ** mptr,tnode * tptr)2652 void addtempomap(tnode ** mptr, tnode * tptr)
2653
2654 {
2655 tptr->next = make_tnode((*mptr)->down->next->next->val, S_TEMPO);
2656 tptr->next->time = (*mptr)->time;
2657 *mptr = (*mptr)->next;
2658 }
2659
2660