1 
2 /*
3 #    Sfront, a SAOL to C translator
4 #    This file: Code generaton: core wavetables
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 "tree.h"
41 
42 
43 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
44 /*                                                              */
45 /* Top-level functions for wavetable logging and identification */
46 /*                                                              */
47 /*______________________________________________________________*/
48 
49 
50 /*********************************************************/
51 /* returns 1 if S_IDENT is a wavetable generator, else 0 */
52 /*********************************************************/
53 
wavegeneratorname(tnode * ident)54 int wavegeneratorname(tnode * ident)
55 
56 {
57 
58  switch (ident->val[0]) {
59   case 'b':
60     if (!(strcmp(ident->val,"buzz")))
61       return 1;
62     return 0;
63   case 'c':
64     if (!(strcmp(ident->val,"concat")))
65       return 1;
66     if (!(strcmp(ident->val,"cubicseg")))
67       return 1;
68     return 0;
69   case 'd':
70     if (!(strcmp(ident->val,"data")))
71       return 1;
72     return 0;
73   case 'e':
74     if (!(strcmp(ident->val,"empty")))
75       return 1;
76     if (!(strcmp(ident->val,"expseg")))
77       return 1;
78     return 0;
79   case 'h':
80     if (!(strcmp(ident->val,"harm")))
81       return 1;
82     if (!(strcmp(ident->val,"harm_phase")))
83       return 1;
84     return 0;
85   case 'l':
86     if (!(strcmp(ident->val,"lineseg")))
87       return 1;
88     return 0;
89   case 'p':
90     if (!(strcmp(ident->val,"periodic")))
91       return 1;
92     if (!(strcmp(ident->val,"polynomial")))
93       return 1;
94     return 0;
95   case 'r':
96     if (!(strcmp(ident->val,"random")))
97       return 1;
98     return 0;
99   case 's':
100     if (!(strcmp(ident->val,"sample")))
101       return 1;
102     if (!(strcmp(ident->val,"spline")))
103       return 1;
104     if (!(strcmp(ident->val,"step")))
105       return 1;
106     return 0;
107   case 'w':
108     if (!(strcmp(ident->val,"window")))
109       return 1;
110     return 0;
111   }
112  return 0; /* will never happen */
113 }
114 
115 /*********************************************************/
116 /*        incremenets counter in has structure           */
117 /*********************************************************/
118 
haswavegenerator(tnode * ident)119 void haswavegenerator(tnode * ident)
120 
121 {
122 
123   switch (ident->val[0]) {
124   case 'b':
125     if (!(strcmp(ident->val,"buzz")))
126       {
127 	has.w_buzz++;
128 	return;
129       }
130     return;
131   case 'c':
132     if (!(strcmp(ident->val,"concat")))
133       {
134 	has.w_concat++;
135 	return;
136       }
137     if (!(strcmp(ident->val,"cubicseg")))
138       {
139 	has.w_cubicseg++;
140 	return;
141       }
142     return;
143   case 'd':
144     if (!(strcmp(ident->val,"data")))
145       {
146 	has.w_data++;
147 	return;
148       }
149     return;
150   case 'e':
151     if (!(strcmp(ident->val,"empty")))
152       {
153 	has.w_empty++;
154 	return;
155       }
156     if (!(strcmp(ident->val,"expseg")))
157       {
158 	has.w_expseg++;
159 	return;
160       }
161     return;
162   case 'h':
163     if (!(strcmp(ident->val,"harm")))
164       {
165 	has.w_harm++;
166 	return;
167       }
168     if (!(strcmp(ident->val,"harm_phase")))
169       {
170 	has.w_harm_phase++;
171 	return;
172       }
173     return;
174   case 'l':
175     if (!(strcmp(ident->val,"lineseg")))
176       {
177 	has.w_lineseg++;
178 	return;
179       }
180     return;
181   case 'p':
182     if (!(strcmp(ident->val,"periodic")))
183       {
184 	has.w_periodic++;
185 	return;
186       }
187     if (!(strcmp(ident->val,"polynomial")))
188       {
189 	has.w_polynomial++;
190 	return;
191       }
192     return;
193   case 'r':
194     if (!(strcmp(ident->val,"random")))
195       {
196 	has.w_random++;
197 	return;
198       }
199     return;
200   case 's':
201     if (!(strcmp(ident->val,"sample")))
202       {
203 	has.w_sample++;
204 	return;
205       }
206     if (!(strcmp(ident->val,"spline")))
207       {
208 	has.w_spline++;
209 	return;
210       }
211     if (!(strcmp(ident->val,"step")))
212       {
213 	has.w_step++;
214 	return;
215       }
216     return;
217   case 'w':
218     if (!(strcmp(ident->val,"window")))
219       {
220 	has.w_window++;
221 	return;
222       }
223     return;
224   default:
225     return;
226   }
227 }
228 
229 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
230 /*                                                              */
231 /*      Top-level functions for wavetable code generation.      */
232 /*                                                              */
233 /*______________________________________________________________*/
234 
235 extern char * makewstring(char *);
236 
237 /*********************************************************/
238 /*  declares local variables for table generators        */
239 /*                                                       */
240 /* modes values:                                         */
241 /*                                                       */
242 /*        S_SASLFILE: SASL table commands (readscore.c)  */
243 /*        S_OPCODE  : opcode tables       (writeop.c)    */
244 /*        S_INSTR   : instr tables        (writeorc.c)   */
245 /*        S_GLOBAL  : global tables       (writeorc.c)   */
246 /*                                                       */
247 /*********************************************************/
248 
wavegeneratorvar(sigsym * sptr)249 void wavegeneratorvar(sigsym * sptr)
250 
251 {
252   tnode * wname = sptr->defnode->down->next;
253   tnode * ident = sptr->defnode->down->next->next->next;
254   tnode * tptr =  sptr->defnode->down->next->next->next->next->next->down;
255   sampleinfo * sinfo;
256   int i,j;
257   int lc = 0;
258   char * lname = makewstring(wname->val);
259 
260   /* no variables declarations needed for constant tables */
261 
262   if ((sptr->defnode->vol == CONSTANT) && (sptr->defnode->usesinput))
263     return;
264 
265   if (tptr == NULL)
266     {
267       printf("Error: Generator needs size parameter.\n");
268       showerrorplace(sptr->defnode->down->linenum,
269 		     sptr->defnode->down->filename);
270     }
271 
272   z[lc++] = "int %2$s_size;";
273   z[lc++] = "float %2$s_rounding;";
274   tptr = tptr->next;
275   if (tptr != NULL)
276     tptr = tptr->next;
277 
278   switch (ident->val[0]) {
279   case 'b':
280     if (!(strcmp(ident->val,"buzz")))
281       {
282 	z[lc++]="float %2$s_scale;";
283 	z[lc++]="float %2$s_base;";
284 	z[lc++]="float %2$s_index;";
285 	z[lc++]="float %2$s_acc;";
286 	i = 1;
287 	while (tptr != NULL)
288 	  {
289 	    if (tptr->ttype == S_EXPR)
290 	      {
291 		switch (i) {
292 		case 1:
293 		  z[lc++]="int %2$s_nharm;";
294 		  break;
295 		case 2:
296 		  z[lc++]="int %2$s_lowharm;";
297 		  break;
298 		case 3:
299 		  z[lc++]="float %2$s_rolloff;";
300 		  break;
301 		default:
302 		  printf("Error: Too many parameters for buzz generator.\n");
303 		  showerrorplace(sptr->defnode->down->linenum,
304 				 sptr->defnode->down->filename);
305 		}
306 		i++;
307 	      }
308 	    tptr = tptr->next;
309 	  }
310 	if (i<4)
311 	  {
312 	    printf("Error: Too few parameters for buzz generator.\n");
313 	    showerrorplace(sptr->defnode->down->linenum,
314 			   sptr->defnode->down->filename);
315 	  }
316 	printwavesymblock2(lc, wname);
317 	break;
318       }
319     break;
320   case 'c':
321     if (!(strcmp(ident->val,"concat")))
322       {
323 	i = 1;
324 	while (tptr != NULL)
325 	  {
326 	    if (tptr->ttype == S_EXPR)
327 	      {
328 		mz(lc); sprintf(z[lc++],"int %s_ft%i;",lname,i);
329 		i++;
330 	      }
331 	    tptr = tptr->next;
332 	  }
333 	printwavesymblock2(lc, wname);
334 	break;
335       }
336     if (!(strcmp(ident->val,"cubicseg")))
337       {
338 	i = 1; j = 0;
339 	z[lc++]="float %2$s_xf;";
340 	z[lc++]="float %2$s_Q;";
341 	z[lc++]="float %2$s_R;";
342 	z[lc++]="float %2$s_S;";
343 	z[lc++]="float %2$s_T;";
344 	while (tptr != NULL)
345 	  {
346 	    if (tptr->ttype == S_EXPR)
347 	      {
348 		switch (j) {
349 		case 0:
350 		  mz(lc); sprintf(z[lc++],"float %s_infl%i;",lname,i);
351 		  mz(lc); sprintf(z[lc++],"float %s_a%i;",lname,i);
352 		  mz(lc); sprintf(z[lc++],"float %s_b%i;",lname,i);
353 		  mz(lc); sprintf(z[lc++],"float %s_c%i;",lname,i);
354 		  mz(lc); sprintf(z[lc++],"float %s_d%i;",lname,i);
355 		  break;
356 		case 1:
357 		  mz(lc); sprintf(z[lc++],"float %s_y%i;",lname, 2*i-1);
358 		  break;
359 		case 2:
360 		  mz(lc); sprintf(z[lc++],"float %s_x%i;",lname,i);
361 		  break;
362 		case 3:
363 		  mz(lc); sprintf(z[lc++],"float %s_y%i;",lname, 2*i);
364 		  break;
365 		}
366 		j++;
367 		if (j == 4)
368 		  {
369 		    j = 0; i++;
370 		  }
371 	      }
372 	    tptr = tptr->next;
373 	  }
374 
375 	/* for correct compilation for 'not enough x' error condition */
376 
377 	mz(lc);
378 	if (j != 0)
379 	  i++;
380 	sprintf(z[lc++],"float %s_infl%i;",lname,i);
381 
382 	printwavesymblock2(lc, wname);
383 	break;
384       }
385     break;
386   case 'd':
387     if (!(strcmp(ident->val,"data")))
388       {
389 	i = 1;
390 	while (tptr != NULL)
391 	  {
392 	    if (tptr->ttype == S_EXPR)
393 	      {
394 		mz(lc); sprintf(z[lc++],"float %s_p%i;",lname,i);
395 		i++;
396 	      }
397 	    tptr = tptr->next;
398 	  }
399 	printwavesymblock2(lc, wname);
400 	break;
401       }
402     break;
403   case 'e':
404     if (!(strcmp(ident->val,"empty")))
405       {
406 	if (tptr != NULL)
407 	  {
408 	    printf("Error: Too many parameters for empty generator.\n");
409 	    showerrorplace(sptr->defnode->down->linenum,
410 			   sptr->defnode->down->filename);
411 	  }
412 	printwavesymblock2(lc, wname);
413 	break;
414       }
415     if (!(strcmp(ident->val,"expseg")))
416       {
417 	i = 1;
418 	while (tptr != NULL)
419 	  {
420 	    if (tptr->ttype == S_EXPR)
421 	      {
422 		if ((i % 2) == 1)
423 		  {
424 		    mz(lc); sprintf(z[lc++],"float %s_x%i;",lname,(i/2)+1);
425 		    mz(lc); sprintf(z[lc++],"float %s_d%i;",lname,(i/2)+1);
426 		    mz(lc); sprintf(z[lc++],"float %s_e%i;",lname,(i/2)+1);
427 		  }
428 		else
429 		  {
430 		    mz(lc); sprintf(z[lc++],"float %s_y%i;",lname,(i/2));
431 		  }
432 		i++;
433 	      }
434 	    tptr = tptr->next;
435 	  }
436 	if ((i % 2) == 0)
437 	  {
438 	    mz(lc); sprintf(z[lc++],"float %s_y%i;",lname,(i/2));
439 	  }
440 	printwavesymblock2(lc, wname);
441 	break;
442       }
443     break;
444   case 'h':
445     if (!(strcmp(ident->val,"harm")))
446       {
447 	z[lc++]="float %2$s_base;";
448 	z[lc++]="float %2$s_index;";
449 	i = 1;
450 	while (tptr != NULL)
451 	  {
452 	    if (tptr->ttype == S_EXPR)
453 	      {
454 		mz(lc); sprintf(z[lc++],"float %s_f%i;",lname,i);
455 		i++;
456 	      }
457 	    tptr = tptr->next;
458 	  }
459 	printwavesymblock2(lc, wname);
460 	break;
461       }
462     if (!(strcmp(ident->val,"harm_phase")))
463       {
464 	z[lc++]="float %2$s_base;";
465 	z[lc++]="float %2$s_index;";
466 	i = 1;
467 	while (tptr != NULL)
468 	  {
469 	    if (tptr->ttype == S_EXPR)
470 	      {
471 		if ((i % 2) == 1)
472 		  {
473 		    mz(lc); sprintf(z[lc++],"float %s_f%i;",lname,(i/2)+1);
474 		  }
475 		else
476 		  {
477 		    mz(lc); sprintf(z[lc++],"float %s_ph%i;",lname,(i/2));
478 		  }
479 		i++;
480 	      }
481 	    tptr = tptr->next;
482 	  }
483 	if ((i % 2) == 0)
484 	  {
485 	    printf("Error: F parameter w/o a ph in harm_phase generator.\n");
486 	    showerrorplace(sptr->defnode->down->linenum,
487 			   sptr->defnode->down->filename);
488 	  }
489 	printwavesymblock2(lc, wname);
490 	break;
491       }
492     break;
493   case 'l':
494     if (!(strcmp(ident->val,"lineseg")))
495       {
496 	i = 1;
497 	while (tptr != NULL)
498 	  {
499 	    if (tptr->ttype == S_EXPR)
500 	      {
501 		if ((i % 2) == 1)
502 		  {
503 		    mz(lc); sprintf(z[lc++],"float %s_x%i;",lname,(i/2)+1);
504 		    mz(lc); sprintf(z[lc++],"float %s_d%i;",lname,(i/2)+1);
505 		  }
506 		else
507 		  {
508 		    mz(lc); sprintf(z[lc++],"float %s_y%i;",lname,(i/2));
509 		  }
510 		i++;
511 	      }
512 	    tptr = tptr->next;
513 	  }
514 	if ((i % 2) == 0)
515 	  {
516 	    mz(lc); sprintf(z[lc++],"float %s_y%i;",lname,(i/2));
517 	  }
518 	printwavesymblock2(lc, wname);
519 	break;
520       }
521     break;
522   case 'p':
523     if (!(strcmp(ident->val,"periodic")))
524       {
525 	z[lc++]="float %2$s_base;";
526 	z[lc++]="float %2$s_index;";
527 	i = 1;
528 	while (tptr != NULL)
529 	  {
530 	    if (tptr->ttype == S_EXPR)
531 	      {
532 		switch(i % 3) {
533 		case 1:
534 		  mz(lc); sprintf(z[lc++],"float %s_p%i;",lname,(i/3)+1);
535 		  break;
536 		case 2:
537 		  mz(lc); sprintf(z[lc++],"float %s_f%i;",lname,(i/3)+1);
538 		  break;
539 		case 0:
540 		  mz(lc); sprintf(z[lc++],"float %s_ph%i;",lname,(i/3));
541 		  break;
542 		}
543 		i++;
544 	      }
545 	    tptr = tptr->next;
546 	  }
547 	if ((i % 3) != 1)
548 	  {
549 	    printf("Error: Incomplete data triplet in periodic generator.\n");
550 	    showerrorplace(sptr->defnode->down->linenum,
551 			   sptr->defnode->down->filename);
552 	  }
553 	printwavesymblock2(lc, wname);
554 	break;
555       }
556     if (!(strcmp(ident->val,"polynomial")))
557       {
558 	i = 1;
559 	z[lc++]="float %2$s_scale;";
560 	z[lc++]="float %2$s_index;";
561 	z[lc++]="float %2$s_acc;";
562 	while (tptr != NULL)
563 	  {
564 	    if (tptr->ttype == S_EXPR)
565 	      {
566 		switch (i) {
567 		case 1:
568 		  z[lc++]="float %2$s_xmin;";
569 		  break;
570 		case 2:
571 		  z[lc++]="float %2$s_xmax;";
572 		  break;
573 		default:
574 		  mz(lc); sprintf(z[lc++],"float %s_a%i;",lname,i-3);
575 		  break;
576 		}
577 		i++;
578 	      }
579 	    tptr = tptr->next;
580 	  }
581 	printwavesymblock2(lc, wname);
582 	break;
583       }
584     break;
585   case 'r':
586     if (!(strcmp(ident->val,"random")))
587       {
588 	i = 1;
589 	z[lc++]="float %2$s_c1;";
590 	z[lc++]="float %2$s_x;";
591 	z[lc++]="float %2$s_y;";
592 	while (tptr != NULL)
593 	  {
594 	    if (tptr->ttype == S_EXPR)
595 	      {
596 		switch (i) {
597 		case 1:
598 		  z[lc++]="int %2$s_dist;";
599 		  break;
600 		case 2:
601 		  z[lc++]="float %2$s_p1;";
602 		  break;
603 		case 3:
604 		  z[lc++]="float %2$s_p2;";
605 		  break;
606 		default:
607 		  printf("Error: Too many parameters for random generator.\n");
608 		  showerrorplace(sptr->defnode->down->linenum,
609 				 sptr->defnode->down->filename);
610 		}
611 		i++;
612 	      }
613 	    tptr = tptr->next;
614 	  }
615 	if (i<3)
616 	  {
617 	    printf("Error: Insufficient parameters for random generator.\n");
618 	    showerrorplace(sptr->defnode->down->linenum,
619 			   sptr->defnode->down->filename);
620 	  }
621 	printwavesymblock2(lc, wname);
622 	break;
623       }
624     break;
625   case 's':
626     if (!(strcmp(ident->val,"sample")))
627       {
628 	z[lc++]="int %2$s_skip;";
629 
630 	sinfo = (sampleinfo *)
631 	  sptr->defnode->down->next->next->next->next->next->down->next->next->ibus;
632 
633 	mz(lc);
634 	sprintf(z[lc++],"unsigned char %s_c[%i];",lname, sinfo->framebytes);
635 
636 	printwavesymblock2(lc, wname);
637 	break;
638       }
639     if (!(strcmp(ident->val,"spline")))
640       {
641 	z[lc++]="float %2$s_xf;";
642 	z[lc++]="float %2$s_Q;";
643 	z[lc++]="float %2$s_R;";
644 	z[lc++]="float %2$s_S;";
645 	z[lc++]="float %2$s_x1;";
646 	z[lc++]="float %2$s_y1;";
647 	z[lc++]="float %2$s_k1;";
648 	i = 1;
649 	while (tptr != NULL)
650 	  {
651 	    if (tptr->ttype == S_EXPR)
652 	      {
653 		if (!(i % 3))
654 		  {
655 		    mz(lc);
656 		    sprintf(z[lc++],"float %s_y%i;",lname,(i/3)+1);
657 		    mz(lc);
658 		    sprintf(z[lc++],"float %s_x%i;",lname,(i/3)+1);
659 		    mz(lc);
660 		    sprintf(z[lc++],"float %s_k%i;",lname,(i/3)+1);
661 		    mz(lc);
662 		    sprintf(z[lc++],"float %s_a%i;",lname,(i/3));
663 		    mz(lc);
664 		    sprintf(z[lc++],"float %s_b%i;",lname,(i/3));
665 		    mz(lc);
666 		    sprintf(z[lc++],"float %s_c%i;",lname,(i/3));
667 		    mz(lc);
668 		    sprintf(z[lc++],"float %s_d%i;",lname,(i/3));
669 		  }
670 		i++;
671 	      }
672 	    tptr = tptr->next;
673 	  }
674 	printwavesymblock2(lc, wname);
675 	break;
676       }
677     if (!(strcmp(ident->val,"step")))
678       {
679 	i = 1;
680 	z[lc++]="float %2$s_x1;";
681 	while (tptr != NULL)
682 	  {
683 	    if (tptr->ttype == S_EXPR)
684 	      {
685 		if (!(i % 2))
686 		  {
687 		    mz(lc); sprintf(z[lc++],"float %s_y%i;",lname,(i/2));
688 		    mz(lc); sprintf(z[lc++],"float %s_x%i;",lname,(i/2)+1);
689 		  }
690 		i++;
691 	      }
692 	    tptr = tptr->next;
693 	  }
694 	printwavesymblock2(lc, wname);
695 	break;
696       }
697     break;
698   case 'w':
699     if (!(strcmp(ident->val,"window")))
700       {
701 	z[lc++]="float %2$s_c1;";
702 	z[lc++]="float %2$s_c2;";
703 	z[lc++]="double %2$s_d1;";
704 	z[lc++]="double %2$s_d2;";
705 	z[lc++]="double %2$s_d3;";
706 	i = 1;
707 	while (tptr != NULL)
708 	  {
709 	    if (tptr->ttype == S_EXPR)
710 	      {
711 		switch (i) {
712 		case 1:
713 		  z[lc++]="int %2$s_type;";
714 		  break;
715 		case 2:
716 		  z[lc++]="float %2$s_p;";
717 		  break;
718 		default:
719 		  printf("Error: Too many parameters for window generator.\n");
720 		  showerrorplace(sptr->defnode->down->linenum,
721 				 sptr->defnode->down->filename);
722 		}
723 		i++;
724 	      }
725 	    tptr = tptr->next;
726 	  }
727 	if (i == 1)
728 	  {
729 	    printf("Error: Type parameter needed for window generator.\n");
730 	    showerrorplace(sptr->defnode->down->linenum,
731 			   sptr->defnode->down->filename);
732 	  }
733 	printwavesymblock2(lc, wname);
734 	break;
735       }
736     break;
737   default:
738     break;
739   }
740   free(lname);
741 }
742 
743 extern void createwavetable(sigsym *, char *, int);
744 
745 
746 /*********************************************************/
747 /*       high-level routine that creates table code      */
748 /*                                                       */
749 /* modes values:                                         */
750 /*                                                       */
751 /*        S_SASLFILE: SASL table commands (readscore.c)  */
752 /*        S_OPCODE  : opcode tables       (writeop.c)    */
753 /*        S_INSTR   : instr tables        (writeorc.c)   */
754 /*        S_GLOBAL  : global tables       (writeorc.c)   */
755 /*        S_FUTURE  : tstamp check        (writeorc.c)   */
756 /*                                                       */
757 /*********************************************************/
758 
createtable(sigsym * ident,char * prefix,int mode)759 void createtable(sigsym * ident, char * prefix, int mode)
760 
761 
762 {
763   int lc = 0;
764   sigsym * gptr;
765 
766   switch(ident->kind) {
767   case K_NORMAL:
768     if ((ident->defnode->vol == CONSTANT) && (ident->defnode->usesinput))
769       createconstanttable(ident, prefix, mode);
770     else
771       createwavetable(ident, prefix, mode);
772     break;
773   case K_IMPORT:
774     if ((gptr = getvsym(&globalsymtable, ident->val)) == NULL)
775       internalerror("wtparse.c","createtable");
776     if ((ident->tref->assigntot == 0) && (gptr->tref->assigntot == 0))
777       {
778 	/* hash-define statements alias it to global wavetable */
779 
780 	if (startupinstr && (currinstrument == startupinstr))
781 	  tablestartupcheck(ident, mode, K_IMPORTEXPORT);
782 	break;
783       }
784     if (startupinstr && (currinstrument == startupinstr))
785       tablestartupcheck(ident, mode, K_IMPORT);
786     z[lc++]= "i = NT(%1$s).len = EV(gtables)[TBL_GBL_%2$s].len;";
787     z[lc++]= "NT(%1$s).lenf = EV(gtables)[TBL_GBL_%2$s].lenf;";
788     z[lc++]= "NT(%1$s).start = EV(gtables)[TBL_GBL_%2$s].start;";
789     z[lc++]= "NT(%1$s).end = EV(gtables)[TBL_GBL_%2$s].end;";
790     z[lc++]= "NT(%1$s).base = EV(gtables)[TBL_GBL_%2$s].base;";
791     z[lc++]= "NT(%1$s).stamp = EV(gtables)[TBL_GBL_%2$s].stamp;";
792     z[lc++]= "NT(%1$s).sr = EV(gtables)[TBL_GBL_%2$s].sr;";
793     z[lc++]= "NT(%1$s).tend = EV(gtables)[TBL_GBL_%2$s].tend;";
794     z[lc++]= "NT(%1$s).oconst = EV(gtables)[TBL_GBL_%2$s].oconst;";
795     z[lc++]= "NT(%1$s).dint = EV(gtables)[TBL_GBL_%2$s].dint;";
796     z[lc++]= "NT(%1$s).dfrac = EV(gtables)[TBL_GBL_%2$s].dfrac;";
797     z[lc++]= "NT(%1$s).sffl = EV(gtables)[TBL_GBL_%2$s].sffl;";
798     z[lc++]= "NT(%1$s).sfui = EV(gtables)[TBL_GBL_%2$s].sfui;";
799     z[lc++]= "NT(%1$s).dsincr = EV(gtables)[TBL_GBL_%2$s].dsincr;";
800     if ((ident->tref->assigntval == 0) &&
801 	(gptr->tref->assigntval == 0))
802       {
803 	z[lc++]= "NT(%1$s).t = EV(gtables)[TBL_GBL_%2$s].t;";
804       }
805     else
806       {
807 	z[lc++]= "NT(%1$s).t = (float *) malloc((i+1)*sizeof(float));";
808 	z[lc++]= "for(;i >= 0;i--)";
809 	z[lc++]= "  NT(%1$s).t[i] = EV(gtables)[TBL_GBL_%2$s].t[i];";
810 	z[lc++]= "NT(%1$s).llmem = 1;";
811       }
812     printwaveblock(lc,ident,prefix);
813     break;
814   case K_IMPORTEXPORT:
815     /* hash-define statements alias it to global wavetable */
816 
817     if (startupinstr && (currinstrument == startupinstr))
818       tablestartupcheck(ident, mode, K_IMPORTEXPORT);
819     break;
820   default:
821     break;
822   }
823 }
824 
825 /*********************************************************/
826 /*     prints warnings and errors for startup tables     */
827 /*     called in createtable() above, and in writeop.c   */
828 /*********************************************************/
829 
tablestartupcheck(sigsym * ident,int mode,int kind)830 void tablestartupcheck(sigsym * ident, int mode, int kind)
831 
832 {
833   switch(kind) {
834   case K_IMPORT:
835     switch (mode) {
836     case S_INSTR:
837       printf("Error: Importing table \"%s\" in startup instrument\n"
838 	     "       would cause run-time error, as tables do\n"
839 	     "       not exist until after startup's i-cycle.\n\n",
840 	     ident->val);
841       showerrorplace(ident->defnode->linenum,
842 		     ident->defnode->filename);
843       break;
844     case S_OPCODE:
845       printf("Warning: Importing table \"%s\" in an opcode called\n"
846 	     "         by the startup instrument may cause a run-time\n"
847 	     "         error, as tables do not exist during startup's i-cycle.\n\n",
848 	     ident->val);
849       break;
850     }
851     break;
852   case K_IMPORTEXPORT:
853     switch (mode) {
854     case S_INSTR:
855       printf("Warning: %s table \"%s\" in startup instrument\n"
856 	     "         may cause run-time error, as tables do\n"
857 	     "         not exist until after startup's i-cycle.\n\n",
858 	     ident->kind == K_IMPORT ? "Importing" : "Import/export of",
859 	     ident->val);
860       break;
861     case S_OPCODE:
862       printf("Warning: %s table \"%s\" in an opcode called\n"
863 	     "         by the startup instrument may cause a run-time\n"
864 	     "         error, as tables do not exist during startup's i-cycle.\n\n",
865 	     ident->kind == K_IMPORT ? "Importing" : "Import/export of",
866 	     ident->val);
867       break;
868     }
869     break;
870   }
871   return;
872 }
873 
874 
875 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
876 /*                                                              */
877 /* Second-level functions to generate table initialization code */
878 /*                                                              */
879 /*______________________________________________________________*/
880 
881 extern void wavevarinit(sigsym *, char *);
882 extern void tablepreamble(sigsym *, char *, int, int);
883 extern int tablelistlength(tnode *);
884 extern void samplefilecode(sigsym *, char *, int *);
885 extern void randomconstcode(sigsym *, char *, tnode *, int *);
886 
887 /*********************************************************/
888 /*        adds code that creates a table                 */
889 /*                                                       */
890 /*     TABLE IDENT LP IDENT COM exprstrlist RP           */
891 /*********************************************************/
892 
createwavetable(sigsym * ident,char * prefix,int mode)893 void createwavetable(sigsym * ident, char * prefix, int mode)
894 
895 {
896 
897  tnode * genptr = ident->defnode->down->next->next->next;
898  tnode * aptr = ident->defnode->down->next->next->next->next->next->down;
899  int i,j,k;
900  int lc=0;
901  char * lname = makewstring(ident->val);
902 
903  wavevarinit(ident,prefix);
904 
905  switch (genptr->val[0]) {
906   case 'b':
907     if (!(strcmp(genptr->val,"buzz")))
908       {
909 	tablepreamble(ident,prefix,mode,GENBUZZ);
910 
911 	z[lc++] = "if ((%2$s_rolloff == 1.0F)||(%2$s_rolloff == 0.0F)||";
912 	z[lc++] = "    (%2$s_rolloff == -1.0F))";
913 	z[lc++] = " {";
914 	z[lc++] = "   %2$s_scale = 1.0F;";
915 	z[lc++] = "   if ((%2$s_rolloff == 1.0F)||(%2$s_rolloff == -1.0F))";
916 	z[lc++] = "    %2$s_scale = 1.0F/(1 + %2$s_nharm);";
917 	z[lc++] = " }";
918 	z[lc++] = "else";
919 	z[lc++] = "  %2$s_scale = (1.0F-(float)fabs(%2$s_rolloff))/";
920 	z[lc++] ="        (1-(float)fabs((float)pow(%2$s_rolloff,%2$s_nharm+1)));";
921 	z[lc++] = "%2$s_base = 6.283185F/%2$s_size;";
922 
923 	z[lc++] = "while (i >= 0)";
924 	z[lc++] = " {";
925 	z[lc++] = "  NT(%1$s).t[i] = 0.0F;";
926 
927 	z[lc++] = "  %2$s_index = i*%2$s_base;";
928 	z[lc++] = "  %2$s_acc = 1.0F;";
929 	z[lc++] = "  j = %2$s_lowharm + 1;";
930 	z[lc++] = "  while (j <= (%2$s_lowharm + %2$s_nharm))";
931 	z[lc++] = "   {";
932 	z[lc++] = "     NT(%1$s).t[i] += %2$s_acc*(float)cos(%2$s_index*j);";
933 	z[lc++] = "     %2$s_acc *= %2$s_rolloff;";
934 	z[lc++] = "     j++;";
935 	z[lc++] = "   }";
936 	z[lc++] = "  NT(%1$s).t[i] *= %2$s_scale;";
937 	z[lc++] = "  i--;";
938 	z[lc++] = " }";
939 
940 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
941 	break;
942       }
943     break;
944   case 'c':
945     if (!(strcmp(genptr->val,"concat")))
946       {
947 	tablepreamble(ident, prefix, mode, GENCONCAT);
948 
949 	z[lc++] = "while (i >= 0)";
950 	z[lc++] = " NT(%1$s).t[i--] = 0.0F;";
951 	z[lc++] = "i = 0;";
952 	j = 1;
953 	i = tablelistlength(aptr);
954 	while (j <= i)
955 	  {
956 	    z[lc++] = "j = 0;";
957 	    mz(lc); sprintf(z[lc++],
958 	    "while ((j < AP%i.len) && (i+j < %s_size))",
959 			    j,lname);
960 	    z[lc++] = " {";
961 	    mz(lc); sprintf(z[lc++],
962 			    "   NT(%s_%s).t[i+j] = AP%i.t[j];",
963 			    prefix,ident->val,j);
964 	    z[lc++] = "   j++;";
965 	    z[lc++] = " }";
966 	    mz(lc); sprintf(z[lc++],"i += AP%i.len;", j);
967 	    j++;
968 	  }
969 
970 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
971 	break;
972       }
973     if (!(strcmp(genptr->val,"cubicseg")))
974       {
975 	tablepreamble(ident,prefix,mode,GENCUBIC);
976 	k = j = tablelistlength(aptr)/4;
977 
978 	z[lc++]= "while (i >= 0)";
979 	z[lc++]= "{";
980 	z[lc++]= "  NT(%1$s).t[i] = 0.0F;";
981 
982 	mz(lc); sprintf(z[lc++], "  %s_xf = i;", lname);
983 
984 	while (j >= 1)
985 	  {
986 	    mz(lc);
987 	    if (j == k)
988 	      sprintf(z[lc++],
989 	    "  if ((i >= %s_infl%i) && (i <= %s_infl%i) )",
990 		   lname,j,lname,j+1);
991 	    else
992 	      sprintf(z[lc++],
993 	    "  if ((i >= %s_infl%i) && (i < %s_infl%i) )",
994 		   lname,j,lname,j+1);
995 	    mz(lc); sprintf(z[lc++],
996 			    "    NT(%s_%s).t[i] =  %s_xf*%s_xf*%s_xf*%s_a%i + "
997 			    "%s_xf*%s_xf*%s_b%i + %s_xf*%s_c%i + %s_d%i;",
998 			    prefix,ident->val,
999 			    lname, lname, lname, lname,j,
1000 			    lname, lname, lname, j,
1001 			    lname, lname, j,
1002 			    lname, j);
1003 
1004 	    j--;
1005 	  }
1006 	z[lc++]= "  i--;";
1007 	z[lc++]= "}";
1008 
1009 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1010 	break;
1011       }
1012     break;
1013   case 'd':
1014     if (!(strcmp(genptr->val,"data")))
1015       {
1016 	j = tablelistlength(aptr) - 1;
1017 	tablepreamble(ident,prefix,mode,GENNUMDATA);
1018 
1019 	z[lc++]= "   while (i >= 0)";
1020 	z[lc++]= "   switch(i) {";
1021 	while (j>=0)
1022 	  {
1023 	    mz(lc); sprintf(z[lc++],"    case %i:",j);
1024 	    mz(lc); sprintf(z[lc++],"    NT(%s_%s).t[i--] = %s_p%i;",
1025 		     prefix,ident->val,lname,j+1);
1026 	    z[lc++]="     break;";
1027 	    j--;
1028 	  }
1029 	z[lc++]= "     default :";
1030 	z[lc++]= "     NT(%1$s).t[i--] = 0.0F;";
1031 	z[lc++]= "}";
1032 
1033 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1034       }
1035     break;
1036   case 'e':
1037     if (!(strcmp(genptr->val,"empty")))
1038       {
1039 	if ((aptr->next != NULL))
1040 	  {
1041 	    printf("Error: Incorrect number of args.\n");
1042 	    showerrorplace(ident->defnode->down->linenum,
1043 			   ident->defnode->down->filename);
1044 	  }
1045 	tablepreamble(ident,prefix,mode,GENILLEGAL);
1046 
1047 	z[lc++]= "while (i >= 0)";
1048 	z[lc++]= "  NT(%1$s).t[i--] = 0.0F;";
1049 
1050 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1051 
1052 	break;
1053       }
1054     if (!(strcmp(genptr->val,"expseg")))
1055       {
1056 	tablepreamble(ident,prefix,mode,GENPAIRS);
1057 	j = tablelistlength(aptr)/2;
1058 
1059 	z[lc++]= "while (i >= 0)";
1060 	z[lc++]= "{";
1061 	z[lc++]= "  NT(%1$s).t[i] = 0.0F;";
1062 	while (j >= 2)
1063 	  {
1064 	    mz(lc); sprintf(z[lc++],
1065 	    "  if ((i >= %s_x%i) && (i < %s_x%i) && (%s_x%i != %s_x%i))",
1066 		   lname,j-1,lname,j,lname,j-1,lname,j);
1067 	    mz(lc); sprintf(z[lc++],
1068            "    NT(%s_%s).t[i] =  %s_y%i*(float)pow((double)%s_d%i,",
1069                 prefix,ident->val,lname,j-1,lname,j-1);
1070 
1071 	    mz(lc); sprintf(z[lc++],
1072            "                      (double) %s_e%i*(i -  %s_x%i));",
1073                 lname,j-1,lname,j-1);
1074 
1075 	    j--;
1076 	  }
1077 	z[lc++]= "  i--;";
1078 	z[lc++]= "}";
1079 
1080 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1081 	break;
1082       }
1083     break;
1084   case 'h':
1085     if (!(strcmp(genptr->val,"harm")))
1086       {
1087 	tablepreamble(ident,prefix,mode,GENILLEGAL);
1088 
1089 	z[lc++] = "%2$s_base = 6.283185F/%2$s_size;";
1090 	j = tablelistlength(aptr);
1091 
1092 	z[lc++] = "while (i >= 0)";
1093 	z[lc++] = " {";
1094 	z[lc++] = "  NT(%1$s).t[i] = 0.0F;";
1095 	z[lc++] = "  %2$s_index = i*%2$s_base;";
1096 	while (j>=1)
1097 	  {
1098 	    z[lc++] = "  NT(%1$s).t[i] += ";
1099 	    mz(lc); sprintf(z[lc++],"   %s_f%i*(float)sin(%i.0F*%s_index);",
1100 			    lname,j,j,lname);
1101 	    j--;
1102 	  }
1103 	z[lc++] = "  i--;";
1104 	z[lc++] = " }";
1105 
1106 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1107 	break;
1108       }
1109     if (!(strcmp(genptr->val,"harm_phase")))
1110       {
1111 	j = tablelistlength(aptr);
1112 	if ( (j % 2) == 1)
1113 	  genex(&lc, ident->defnode->down,
1114 		"Odd number of parameters (not including size)");
1115 	else
1116 	  {
1117 	    tablepreamble(ident,prefix,mode,GENILLEGAL);
1118 
1119 	    z[lc++] = "%2$s_base = 6.283185F/%2$s_size;";
1120 	    z[lc++] = "while (i >= 0)";
1121 	    z[lc++] = " {";
1122 	    z[lc++] = "  NT(%1$s).t[i] = 0.0F;";
1123 	    z[lc++] = "  %2$s_index = i*%2$s_base;";
1124 	    while (j>=2)
1125 	      {
1126 		z[lc++] = "  NT(%1$s).t[i] += ";
1127 
1128 		mz(lc); sprintf(z[lc++],
1129 		"   %s_f%i*(float)sin((%i.0F*%s_index+ %s_ph%i));",
1130 		       lname,j/2,j/2,lname,lname,j/2);
1131 
1132 		j= j - 2;
1133 	      }
1134 	    z[lc++] = "  i--;";
1135 	    z[lc++] = " }";
1136 	  }
1137 
1138 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1139 	break;
1140       }
1141     break;
1142   case 'l':
1143     if (!(strcmp(genptr->val,"lineseg")))
1144       {
1145 
1146 	tablepreamble(ident,prefix,mode,GENPAIRS);
1147 	j = tablelistlength(aptr)/2;
1148 
1149 	z[lc++]= "while (i >= 0)";
1150 	z[lc++]= "{";
1151 	z[lc++]= "  NT(%1$s).t[i] = 0.0F;";
1152 	while (j >= 2)
1153 	  {
1154 	    mz(lc); sprintf(z[lc++],
1155 	    "  if ((i >= %s_x%i) && (i < %s_x%i) && (%s_x%i != %s_x%i))",
1156 		   lname,j-1,lname,j,lname,j-1,lname,j);
1157 	    mz(lc); sprintf(z[lc++],
1158 	    "    NT(%s_%s).t[i] =  %s_y%i + %s_d%i*(i -  %s_x%i);",
1159                 prefix,ident->val,lname,j-1,lname,j-1,lname,j-1);
1160 
1161 	    j--;
1162 	  }
1163 	z[lc++]= "  i--;";
1164 	z[lc++]= "}";
1165 
1166 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1167 	break;
1168       }
1169     break;
1170   case 'p':
1171     if (!(strcmp(genptr->val,"periodic")))
1172       {
1173 	j = tablelistlength(aptr);
1174 	if ( (j % 3) != 0)
1175 	  genex(&lc, ident->defnode->down,
1176 		"Number of parameters not divisible by 3");
1177 	else
1178 	  {
1179 	    tablepreamble(ident,prefix,mode,GENILLEGAL);
1180 
1181 	    z[lc++] = "%2$s_base = 6.283185F/%2$s_size;";
1182 	    z[lc++] = "while (i >= 0)";
1183 	    z[lc++] = " {";
1184 	    z[lc++] = "  NT(%1$s).t[i] = 0.0F;";
1185 	    z[lc++] = "  %2$s_index = i*%2$s_base;";
1186 
1187 	    while (j>=3)
1188 	      {
1189 		z[lc++] = "  NT(%1$s).t[i] += ";
1190 
1191 		mz(lc); sprintf(z[lc++],
1192 		"   %s_f%i*(float)sin(%s_p%i*%s_index+ %s_ph%i);",
1193 		lname,j/3,lname,j/3, lname,lname,j/3);
1194 
1195 		j= j - 3;
1196 	      }
1197 	    z[lc++] = "  i--;";
1198 	    z[lc++] = " }";
1199 	  }
1200 
1201 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1202 	break;
1203       }
1204     if (!(strcmp(genptr->val,"polynomial")))
1205       {
1206 	tablepreamble(ident,prefix,mode,GENILLEGAL);
1207 
1208 	i = tablelistlength(aptr) -3;
1209 	j = 0;
1210 	z[lc++] = "%2$s_scale = (1.0F/%2$s_size)*(%2$s_xmax-%2$s_xmin);";
1211 	z[lc++] = "while (i >= 0)";
1212 	z[lc++] = " {";
1213 	z[lc++] = "  NT(%1$s).t[i] = 0.0F;";
1214 	z[lc++] = "  %2$s_index = %2$s_xmin + %2$s_scale*(%2$s_size - i);";
1215 	z[lc++] = "  %2$s_acc = 1.0F;";
1216 	z[lc++] = "  NT(%1$s).t[i] = %2$s_a0;";
1217 	while (j < i)
1218 	  {
1219 	    z[lc++] = "  %2$s_acc *= %2$s_index;";
1220 	    mz(lc); sprintf(z[lc++],"   NT(%s_%s).t[i] += %s_a%i*%s_acc;",
1221 			prefix,ident->val,lname,j+1,lname);
1222 	    j++;
1223 	  }
1224 	z[lc++] = "  i--;";
1225 	z[lc++] = " }";
1226 
1227 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1228 	break;
1229       }
1230     break;
1231   case 'r':
1232     if (!(strcmp(genptr->val,"random")))
1233       {
1234 	j = tablelistlength(aptr);
1235 	tablepreamble(ident,prefix,mode,GENILLEGAL);
1236 
1237 	if (aptr->next->next->vol == CONSTANT)
1238 	  {
1239 	    randomconstcode(ident, prefix, aptr, &lc);
1240 	    break;
1241 	  }
1242 
1243 	/* general-purpose code: only used if dist is a variable */
1244 
1245 	z[lc++] = "switch(%2$s_dist) {";
1246 	z[lc++] = " case 1:";
1247 	if (j==3)
1248 	  z[lc++] = "  %2$s_c1 = %2$s_p2 - %2$s_p1;";
1249 	else
1250 	  genex(&lc, ident->defnode->down, "Wrong number of parameters (dist 1)");
1251 
1252 	z[lc++] = "  break;";
1253 	z[lc++] = " case 2:";
1254 	if (j==3)
1255 	  {
1256 	    z[lc++] = "  %2$s_c1 = %2$s_p2 - %2$s_p1;";
1257 	    z[lc++] = "if (%2$s_p2 == %2$s_p1)";
1258 	    genex(&lc, ident->defnode->down, "p1 == p2 (dist 2)");
1259 	  }
1260 	else
1261 	  genex(&lc, ident->defnode->down, "Wrong number of parameters (dist 2)");
1262 
1263 	z[lc++] = "  break;";
1264 	z[lc++] = " case 3:";
1265 	z[lc++] = "  break;";
1266 	z[lc++] = " case 4:";
1267 	if (j==3)
1268 	  {
1269 	    z[lc++] = "  if (%2$s_p2 <= 0.0F)";
1270 	    genex(&lc, ident->defnode->down, "p2 <= 0 (dist 4)");
1271 	    z[lc++] = "  %2$s_c1 = (float)sqrt(2*%2$s_p2);";
1272 	  }
1273 	else
1274 	  genex(&lc, ident->defnode->down, "Wrong number of parameters (dist 4)");
1275 
1276 	z[lc++] = "  break;";
1277 	z[lc++] = " case 5:";
1278 	z[lc++] = "  break;";
1279 	z[lc++] = " default:";
1280 	genex(&lc, ident->defnode->down, "Illegal distribution (not 1,2,3,4,5)");
1281 	z[lc++] = "}";
1282 
1283 	z[lc++] = "j = 0; i = 0;";
1284 	z[lc++] = "while (i < %2$s_size)";
1285 	z[lc++] = " {";
1286 	z[lc++] = "   switch(%2$s_dist) {";
1287 	z[lc++] = "    case 1:";
1288 	z[lc++] = "     NT(%1$s).t[i] = %2$s_c1*RMULT*((float)rand()) + %2$s_p1;";
1289 	z[lc++] = "     break;";
1290 	z[lc++] = "    case 2:";
1291 	z[lc++] = "     %2$s_x = RMULT*((float)rand());";
1292 	z[lc++] = "     %2$s_y = RMULT*((float)rand());";
1293 	z[lc++] = "     if (%2$s_x > %2$s_y)";
1294 	z[lc++] = "       NT(%1$s).t[i] =  %2$s_c1*%2$s_x + %2$s_p1;";
1295 	z[lc++] = "     else";
1296 	z[lc++] = "       NT(%1$s).t[i] =  %2$s_c1*%2$s_y + %2$s_p1;";
1297 	z[lc++] = "     break;";
1298 	z[lc++] = "    case 3:";
1299 	z[lc++] = "     NT(%1$s).t[i] = -%2$s_p1*(float)log(RMULT*((float)rand())+1e-45F);";
1300 	z[lc++] = "     break;";
1301 	z[lc++] = "    case 4:";
1302 	z[lc++] = "     NT(%1$s).t[i] = %2$s_p1+%2$s_c1*";
1303         z[lc++] = "             (float)sqrt(-2.0F*(float)log(RMULT*((float)rand())+1e-45F))";
1304         z[lc++] = "                   *(float)cos(6.283185F*RMULT*((float)rand()));";
1305 	z[lc++] = "     break;";
1306 	z[lc++] = "    case 5:";
1307 	z[lc++] = "     NT(%1$s).t[i] = 0;";
1308 	z[lc++] = "     if (j == 0)";
1309 	z[lc++] = "      {";
1310 	z[lc++] = "        j = ROUND(-%2$s_p1*(float)log(RMULT*((float)rand())+1e-45F))+1;";
1311 	z[lc++] = "        if (i != 0)";
1312 	z[lc++] = "         NT(%1$s).t[i] = 1.0F;";
1313 	z[lc++] = "      }";
1314 	z[lc++] = "      j--;";
1315 	z[lc++] = "     break;";
1316 	z[lc++] = "   }";
1317 	z[lc++] = "  i++;";
1318 	z[lc++] = " }";
1319 	z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1320       }
1321     break;
1322   case 's':
1323     if (!(strcmp(genptr->val,"sample")))
1324       {
1325 	samplefilecode(ident, prefix, &lc);
1326 	break;
1327       }
1328     if (!(strcmp(genptr->val,"spline")))
1329       {
1330 	tablepreamble(ident,prefix,mode,GENSPLINE);
1331 	k = j = ((tablelistlength(aptr)+1)/3)-1;
1332 
1333 	z[lc++]= "while (i >= 0)";
1334 	z[lc++]= "{";
1335 	z[lc++]= "  NT(%1$s).t[i] = 0.0F;";
1336 
1337 	mz(lc); sprintf(z[lc++], "  %s_xf = i;", lname);
1338 
1339 	while (j >= 1)
1340 	  {
1341 	    mz(lc);
1342 	    if (j == k)
1343 	      sprintf(z[lc++],
1344 		 "  if ((i >= %s_x%i) && (i <= %s_x%i) && (%s_x%i != %s_x%i))",
1345 		      lname,j,lname,j+1,lname,j,lname,j+1);
1346 	    else
1347 	      sprintf(z[lc++],
1348 		 "  if ((i >= %s_x%i) && (i < %s_x%i) && (%s_x%i != %s_x%i))",
1349 		      lname,j,lname,j+1,lname,j,lname,j+1);
1350 	    mz(lc); sprintf(z[lc++],
1351 			    "    NT(%s_%s).t[i] =  %s_xf*%s_xf*%s_xf*%s_a%i + "
1352 			    "%s_xf*%s_xf*%s_b%i + %s_xf*%s_c%i + %s_d%i;",
1353 
1354 			    prefix,ident->val, lname, lname, lname, lname, j,
1355 			    lname, lname, lname,j,
1356 			    lname, lname,j,
1357 			    lname,j);
1358 
1359 	    j--;
1360 	  }
1361 	z[lc++]= "  i--;";
1362 	z[lc++]= "}";
1363 	z[lc++]= "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1364 	break;
1365       }
1366     if (!(strcmp(genptr->val,"step")))
1367       {
1368 
1369 	tablepreamble(ident,prefix,mode,GENSTEP);
1370 	j = (tablelistlength(aptr)/2)+1;
1371 
1372 	z[lc++]= "while (i >= 0)";
1373 	z[lc++]= "{";
1374 	z[lc++]= "  NT(%1$s).t[i] = 0.0F;";
1375 	while (j >= 2)
1376 	  {
1377 	    mz(lc); sprintf(z[lc++],
1378 	    "  if ((i >= %s_x%i) && (i < %s_x%i))",
1379 			    lname,j-1,lname,j);
1380 	    mz(lc); sprintf(z[lc++],
1381 	    "    NT(%s_%s).t[i] =  %s_y%i;", prefix,ident->val,lname,j-1);
1382 
1383 	    j--;
1384 	  }
1385 	z[lc++]= "  i--;";
1386 	z[lc++]= "}";
1387 
1388 	z[lc++]= "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1389 	break;
1390       }
1391     break;
1392   case 'w':
1393     if (!(strcmp(genptr->val,"window")))
1394       {
1395 	j = tablelistlength(aptr);
1396 	tablepreamble(ident,prefix,mode,GENILLEGAL);
1397 
1398 
1399 	z[lc++] = "switch(%2$s_type) {";
1400 	z[lc++] = " case 1:";
1401 	z[lc++] = " case 2:";
1402 	z[lc++] = "  %2$s_c1 = 6.283185F/(%2$s_size-1.0F);";
1403 	z[lc++] = "  break;";
1404 	z[lc++] = " case 3:";
1405 	z[lc++] = "  %2$s_c1 = 2.0F/(%2$s_size-1.0F);";
1406 	z[lc++] = "  %2$s_c2 = 1.0F/%2$s_c1;";
1407 	z[lc++] = "  break;";
1408 	z[lc++] = " case 4:";
1409 	z[lc++] = "  %2$s_c1 = - 18.0F/(%2$s_size*%2$s_size);";
1410 	z[lc++] = "  %2$s_c2 = - 0.5F*%2$s_size;";
1411 	z[lc++] = "  break;";
1412 	z[lc++] = " case 5:";
1413 	if (j==2)
1414 	  {
1415 	    z[lc++] = "  %2$s_d1 = (%2$s_size-1.0)/2.0;";
1416 	    z[lc++] = "  %2$s_d2 = %2$s_d1*%2$s_d1;";
1417 	    z[lc++] = "  %2$s_d3 = 1.0/modbessel(%2$s_p*%2$s_d1);";
1418 	  }
1419 	else
1420 	  genex(&lc, ident->defnode->down, "Parameter p needed (type 5)");
1421 	z[lc++] = "  break;";
1422 	z[lc++] = " case 6:";
1423 	z[lc++] = "  break;";
1424 	z[lc++] = " default:";
1425 	genex(&lc, ident->defnode->down, "Illegal window type (not 1,2,3,4,5,6)");
1426 
1427 	z[lc++] = "}";
1428 
1429 
1430 	z[lc++] = "while (i >= 0)";
1431 	z[lc++] = " {";
1432 	z[lc++] = "   switch(%2$s_type) {";
1433 	z[lc++] = "    case 1:";
1434 	z[lc++] = "     NT(%1$s).t[i] = 0.54F - 0.46F*(float)cos(%2$s_c1*i);";
1435 	z[lc++] = "     break;";
1436 	z[lc++] = "    case 2:";
1437 	z[lc++] = "     NT(%1$s).t[i] = 0.5F*(1.0F - (float)cos(%2$s_c1*i));";
1438 	z[lc++] = "     break;";
1439 	z[lc++] = "    case 3:";
1440 	z[lc++] = "     NT(%1$s).t[i] = 1.0F - %2$s_c1*(float)fabs(i - %2$s_c2);";
1441 	z[lc++] = "     break;";
1442 	z[lc++] = "    case 4:";
1443 	z[lc++] = "     NT(%1$s).t[i] = ";
1444 	z[lc++] = "         (float)exp(%2$s_c1*(%2$s_c2+i)*(%2$s_c2+i));";
1445 	z[lc++] = "     break;";
1446 	z[lc++] = "    case 5:";
1447 	if (j==2)
1448 	  {
1449 	    z[lc++] = "     NT(%1$s).t[i] = (float)(%2$s_d3*modbessel(%2$s_p*";
1450 	    z[lc++] = "      sqrt(%2$s_d2 - (i-%2$s_d1)*(i-%2$s_d1))));";
1451 	  }
1452 	z[lc++] = "     break;";
1453 	z[lc++] = "    case 6:";
1454 	z[lc++] = "     NT(%1$s).t[i] = 1.0F;";
1455 	z[lc++] = "     break;";
1456 	z[lc++] = "   }";
1457 	z[lc++] = "  i--;";
1458 	z[lc++] = " }";
1459 
1460 	z[lc++]= "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
1461       }
1462     break;
1463   default:
1464     break;
1465   }
1466  printwavesymblock(lc,ident,prefix);
1467  free(lname);
1468 }
1469 
1470 
1471 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1472 /*                                                              */
1473 /* Lower-level functions wavevarinit() and tablepreamble()      */
1474 /* do large code-generation subtasks for createwavetable().     */
1475 /*                                                              */
1476 /*______________________________________________________________*/
1477 
1478 extern void wavevarinitcheck(tnode *);
1479 
1480 /*********************************************************/
1481 /*  initializes variables for generator execution        */
1482 /*********************************************************/
1483 
wavevarinit(sigsym * sptr,char * prefix)1484 void wavevarinit(sigsym * sptr, char * prefix)
1485 
1486 
1487 {
1488   tnode * wname = sptr->defnode->down->next;
1489   tnode * ident = sptr->defnode->down->next->next->next;
1490   tnode * tptr =  sptr->defnode->down->next->next->next->next->next->down;
1491   int i, j, depth, currblocksafe;
1492   int lc = 0;
1493   int tabletype;   /* for concat */
1494   char tablename[STRSIZE];
1495   char * idxstr;
1496   char * lname = makewstring(wname->val);
1497 
1498   currblocksafe = currblockrate;
1499   currblockrate = IRATETYPE;
1500 
1501   if (tptr == NULL)
1502     {
1503       printf("Error: Generator needs size parameter.\n");
1504       showerrorplace(wname->linenum, wname->filename);
1505     }
1506   wavevarinitcheck(tptr);
1507 
1508   fprintf(outfile,"   %s_rounding = ", lname);
1509   blocktree(tptr->down, PRINTTOKENS);
1510   fprintf(outfile,";\n");
1511 
1512   fprintf(outfile,"   %s_size = ROUND(%s_rounding);\n",
1513 	  lname, lname);
1514 
1515   tptr = tptr->next;
1516   if (tptr != NULL)
1517     tptr = tptr->next;
1518 
1519   switch (ident->val[0]) {
1520   case 'b':
1521     if (!(strcmp(ident->val,"buzz")))
1522       {
1523 	i = 1;
1524 	while (tptr != NULL)
1525 	  {
1526 	    if (tptr->ttype == S_EXPR)
1527 	      {
1528 		wavevarinitcheck(tptr);
1529 		switch (i) {
1530 		case 1:
1531 		  fprintf(outfile,"   %s_rounding = ", lname);
1532 		  blocktree(tptr->down, PRINTTOKENS);
1533 		  fprintf(outfile,";\n");
1534 		  fprintf(outfile,"   %s_nharm = ROUND(%s_rounding);\n",
1535 			  lname, lname);
1536 		  break;
1537 		case 2:
1538 		  fprintf(outfile,"   %s_rounding = ", lname);
1539 		  blocktree(tptr->down, PRINTTOKENS);
1540 		  fprintf(outfile,";\n");
1541 		  fprintf(outfile,"   %s_lowharm = ROUND(%s_rounding);\n",
1542 			  lname, lname);
1543 		  break;
1544 		case 3:
1545 		  fprintf(outfile,"   %s_rolloff = ",lname);
1546 		  blocktree(tptr->down, PRINTTOKENS);
1547 		  fprintf(outfile,";\n");
1548 		  break;
1549 		}
1550 		i++;
1551 	      }
1552 	    tptr = tptr->next;
1553 	  }
1554 	break;
1555       }
1556     break;
1557   case 'c':
1558     if (!(strcmp(ident->val,"concat")))
1559       {
1560 	i = 1;
1561 	while (tptr != NULL)
1562 	  {
1563 	    if (tptr->ttype == S_EXPR)
1564 	      {
1565 		if (!(tptr->vartype == TABLETYPE))
1566 		  {
1567 		    printf("Error: Concat ft args must be tables.\n");
1568 		    showerrorplace(wname->linenum, wname->filename);
1569 		  }
1570 		currarrayindex = 0;
1571 		currscalarflag = 1;
1572 		sprintf(tablename,"%s_ft%i",lname,i);
1573 		if (tptr->down->next == NULL)
1574 		  {
1575 		    /* a table */
1576 
1577 		    fprintf(outfile,"   %s = ", tablename);
1578 		    tabletype = maketableindex(tptr->down, curropcodestack,
1579 					       &idxstr, &depth);
1580 		    fprintf(outfile,"%s;\n",idxstr);
1581 		    printtabledefine(i++, tablename, tabletype, depth);
1582 		  }
1583 		else
1584 		  {
1585 
1586 		    /* a tablemap */
1587 
1588 		    printtmapcase(tptr->down,
1589 				  tptr->down->next->next, tablename);
1590 		    printtabledefine(i++, tablename, S_TABLEMAP, -1);
1591 		  }
1592 	      }
1593 	    tptr = tptr->next;
1594 	  }
1595 	break;
1596       }
1597     if (!(strcmp(ident->val,"cubicseg")))
1598       {
1599 	i = 1; j = 0;
1600 	while (tptr != NULL)
1601 	  {
1602 	    if (tptr->ttype == S_EXPR)
1603 	      {
1604 		wavevarinitcheck(tptr);
1605 		switch (j) {
1606 		case 0:
1607 		  fprintf(outfile,"   %s_rounding = ", lname);
1608 		  blocktree(tptr->down, PRINTTOKENS);
1609 		  fprintf(outfile,";\n");
1610 		  fprintf(outfile,"   %s_infl%i = ROUND(%s_rounding);\n",
1611 			  lname,i,lname);
1612 		  break;
1613 		case 1:
1614 		  fprintf(outfile,"   %s_y%i = ",lname, 2*i-1);
1615 		  blocktree(tptr->down, PRINTTOKENS);
1616 		  fprintf(outfile,";\n");
1617 		  break;
1618 		case 2:
1619 		  fprintf(outfile,"   %s_rounding = ", lname);
1620 		  blocktree(tptr->down, PRINTTOKENS);
1621 		  fprintf(outfile,";\n");
1622 		  fprintf(outfile,"   %s_x%i = ROUND(%s_rounding);\n",
1623 			  lname,i,lname);
1624 		  break;
1625 		case 3:
1626 		  fprintf(outfile,"   %s_y%i = ",lname, 2*i);
1627 		  blocktree(tptr->down, PRINTTOKENS);
1628 		  fprintf(outfile,";\n");
1629 		  break;
1630 		}
1631 		j++;
1632 		if (j == 4)
1633 		  {
1634 		    j = 0; i++;
1635 		  }
1636 	      }
1637 	    tptr = tptr->next;
1638 	  }
1639 	z[lc++] = "if (%2$s_infl1 != 0.0F)";
1640 	genex(&lc, wname, "First inflection point != 0");
1641 	i--;
1642 	if ((j != 2)|| (i<2))
1643 	  genex(&lc, wname, "Not enough x values");
1644 	else
1645 	  {
1646 	    j = 1;
1647 	    while (j <= i)
1648 	      {
1649 		z[lc++] = "";
1650 		mz(lc); sprintf(z[lc++],
1651 		"if (%s_x%i <= %s_infl%i)",
1652 				lname,j,lname,j);
1653 		genex(&lc, wname, "Infl not strictly between surrounding xvals");
1654 		mz(lc); sprintf(z[lc++],
1655 		"if (%s_infl%i <= %s_x%i)",
1656 				lname,j+1,lname,j);
1657 		genex(&lc, wname, "Infl not strictly between surrounding xvals");
1658 
1659 		mz(lc); sprintf(z[lc++],
1660                 "%s_Q = %s_infl%i*%s_infl%i*%s_infl%i;",
1661 				lname,lname,j,lname,j,lname,j);
1662 		mz(lc); sprintf(z[lc++],
1663 		"%s_Q += - %s_x%i*%s_x%i*%s_x%i;",
1664 				lname,lname,j,lname,j,lname,j);
1665 		mz(lc); sprintf(z[lc++],
1666 		"%s_Q += - 3.0F*%s_x%i*%s_x%i*(%s_infl%i-%s_x%i);",
1667 				lname,lname,j,lname,
1668 				j,lname,j,lname,j);
1669 		mz(lc); sprintf(z[lc++],
1670 		"if (%s_Q == 0.0F)",
1671 				lname);
1672 		genex(&lc, wname, "No cubic solution for these parameters");
1673 
1674 		mz(lc); sprintf(z[lc++],
1675 	        "%s_R = %s_infl%i*%s_infl%i;",
1676 				lname,lname,j,lname,j);
1677 		mz(lc); sprintf(z[lc++],
1678 	        "%s_R += - %s_x%i*%s_x%i;",
1679 				lname,lname,j,lname,j);
1680 		mz(lc); sprintf(z[lc++],
1681                 "%s_R += - 2.0F*%s_x%i*(%s_infl%i-%s_x%i);",
1682 				lname,lname,j,lname,j
1683 				,lname,j);
1684 		mz(lc); sprintf(z[lc++],
1685                 "if (%s_R == 0.0F)",
1686 				lname);
1687 		genex(&lc, wname, "No cubic solution for these parameters");
1688 
1689 		mz(lc); sprintf(z[lc++],
1690 	        "%s_S = %s_x%i*%s_x%i*%s_x%i;",
1691 				lname,lname,j,lname,j
1692 				,lname,j);
1693 		mz(lc); sprintf(z[lc++],
1694 	        "%s_S += - %s_infl%i*%s_infl%i*%s_infl%i;",
1695 				lname,lname,j+1,lname,j+1
1696 				,lname,j+1);
1697 		mz(lc); sprintf(z[lc++],
1698                 "%s_S += - 3.0F*%s_x%i*%s_x%i*(%s_x%i-%s_infl%i);"
1699 				,lname,lname,j,lname,j
1700 				,lname,j,lname,j+1);
1701 		mz(lc); sprintf(z[lc++],
1702                 "if (%s_S == 0.0F)",
1703 				lname);
1704 		genex(&lc, wname, "No cubic solution for these parameters");
1705 
1706 		mz(lc); sprintf(z[lc++],
1707 	        "%s_T = %s_x%i*%s_x%i;",
1708 				lname,lname,j,lname,j);
1709 		mz(lc); sprintf(z[lc++],
1710 	        "%s_T += - %s_infl%i*%s_infl%i;",
1711 				lname,lname,j+1,lname,j+1);
1712 		mz(lc); sprintf(z[lc++],
1713                 "%s_T += - 2.0F*%s_x%i*(%s_x%i-%s_infl%i);"
1714 				,lname,lname,j,lname,j
1715 				,lname,j+1);
1716 		mz(lc); sprintf(z[lc++],
1717                 "if (%s_T == 0.0F)",
1718 				lname);
1719 		genex(&lc, wname, "No cubic solution for these parameters");
1720 
1721 		mz(lc); sprintf(z[lc++],
1722 	        "if ((%s_Q/%s_R) == (%s_S/%s_T))",
1723 				lname,lname,lname,lname);
1724 		genex(&lc, wname, "No cubic solution for these parameters");
1725 
1726 		mz(lc); sprintf(z[lc++],
1727                 "%s_a%i = 1.0F/((%s_Q/%s_R) - (%s_S/%s_T));",
1728 				lname,j,lname,lname,
1729 				lname,lname);
1730 		mz(lc); sprintf(z[lc++],
1731   "%s_a%i *= (%s_y%i-%s_y%i)/%s_R - (%s_y%i-%s_y%i)/%s_T;",
1732 				lname,j,
1733 				lname,2*j-1,
1734 				lname,2*j,
1735 				lname,
1736 				lname,2*j,
1737 				lname,2*j+1,
1738 				lname);
1739 
1740 		mz(lc); sprintf(z[lc++],
1741                 "%s_b%i = 1.0F/((%s_R/%s_Q) - (%s_T/%s_S));",
1742 				lname,j,lname,lname,
1743 				lname,lname);
1744 		mz(lc); sprintf(z[lc++],
1745   "%s_b%i *= (%s_y%i-%s_y%i)/%s_Q - (%s_y%i-%s_y%i)/%s_S;",
1746 				lname,j,
1747 				lname,2*j-1,
1748 				lname,2*j,
1749 				lname,
1750 				lname,2*j,
1751 				lname,2*j+1,
1752 				lname);
1753 
1754 		mz(lc); sprintf(z[lc++],
1755   "%s_c%i = - 3.0F*%s_a%i*%s_x%i*%s_x%i - 2.0F*%s_b%i*%s_x%i;",
1756 				lname,j, lname,j,
1757 				lname,j, lname,j,
1758 				lname,j, lname,j);
1759 		mz(lc); sprintf(z[lc++],
1760   "%s_d%i = %s_y%i - %s_a%i*%s_x%i*%s_x%i*%s_x%i;",
1761 				lname,j, lname,2*j,
1762 				lname,j, lname,j,
1763 				lname,j, lname,j);
1764 
1765 		mz(lc); sprintf(z[lc++],
1766 "%s_d%i += - %s_b%i*%s_x%i*%s_x%i - %s_c%i*%s_x%i;"
1767 				,lname,j,lname,j
1768 				,lname,j,lname,j
1769 				,lname,j,lname,j);
1770 
1771 		j++;
1772 	      }
1773 	   z[lc++]="";
1774 
1775 	  }
1776 	printwavesymblock2(lc,wname);
1777 	break;
1778       }
1779     break;
1780   case 'd':
1781     if (!(strcmp(ident->val,"data")))
1782       {
1783 	i = 1;
1784 	while (tptr != NULL)
1785 	  {
1786 	    if (tptr->ttype == S_EXPR)
1787 	      {
1788 		wavevarinitcheck(tptr);
1789 		fprintf(outfile,"   %s_p%i = ",lname,i);
1790 		blocktree(tptr->down, PRINTTOKENS);
1791 		fprintf(outfile,";\n");
1792 		i++;
1793 	      }
1794 	    tptr = tptr->next;
1795 	  }
1796 	break;
1797       }
1798     break;
1799   case 'e':
1800     if (!(strcmp(ident->val,"empty")))
1801       {
1802 	break;
1803       }
1804     if (!(strcmp(ident->val,"expseg")))
1805       {
1806 	i = 1;
1807 	while (tptr != NULL)
1808 	  {
1809 	    if (tptr->ttype == S_EXPR)
1810 	      {
1811 		wavevarinitcheck(tptr);
1812 		if ((i % 2) == 1)
1813 		  {
1814 		    fprintf(outfile,"   %s_rounding = ", lname);
1815 		    blocktree(tptr->down, PRINTTOKENS);
1816 		    fprintf(outfile,";\n");
1817 		    fprintf(outfile,"   %s_x%i = ROUND(%s_rounding);\n",
1818 			    lname, (i/2)+1, lname);
1819 		  }
1820 		else
1821 		  {
1822 		    fprintf(outfile,"   %s_y%i = ",lname,(i/2));
1823 		    blocktree(tptr->down, PRINTTOKENS);
1824 		    fprintf(outfile,";\n");
1825 		  }
1826 		i++;
1827 	      }
1828 	    tptr = tptr->next;
1829 	  }
1830 	i--;
1831 	if (i % 2 == 1)
1832 	  genex(&lc, wname, "Odd number of parameters (not including size)");
1833 	else
1834 	  {
1835 	    i = i/2;
1836 	    while (i >= 2)
1837 	      {
1838 		mz(lc); sprintf(z[lc++],"if (%s_x%i > %s_x%i)",
1839 				lname,i-1,lname,i);
1840 		genex(&lc, wname, "xvals not a non-decreasing sequence");
1841 		mz(lc); sprintf(z[lc++],"if (%s_y%i == 0.0F)",
1842 				lname,i);
1843 		genex(&lc, wname, "yval == 0.0F");
1844 		mz(lc); sprintf(z[lc++],"if ((%s_y%i>0.0F) != (%s_y%i>0.0F))",
1845 				lname,i-1,lname,i);
1846 		genex(&lc, wname, "yvals not all the same sign");
1847 		mz(lc); sprintf(z[lc++],"%s_d%i = %s_y%i/%s_y%i;",
1848 				lname,i-1,lname,i,lname,i-1);
1849 		mz(lc); sprintf(z[lc++],"if (%s_x%i != %s_x%i)",
1850 				lname,i-1,lname,i);
1851 		mz(lc); sprintf(z[lc++],"%s_e%i= 1.0F/(%s_x%i-%s_x%i);",
1852 				lname,i-1,
1853 				lname,i,
1854 				lname,i-1);
1855 		i--;
1856 	      }
1857 	    z[lc++]="if (%2$s_x1 != 0.0F)";
1858 	    genex(&lc, wname, "x1 is not equal to zero");
1859 	    z[lc++]="if (%2$s_y1 == 0.0F)";
1860 	    genex(&lc, wname, "y1 is equal to zero");
1861 	  }
1862 	printwavesymblock2(lc,wname);
1863 	break;
1864       }
1865     break;
1866   case 'h':
1867     if (!(strcmp(ident->val,"harm")))
1868       {
1869 	i = 1;
1870 	while (tptr != NULL)
1871 	  {
1872 	    if (tptr->ttype == S_EXPR)
1873 	      {
1874 		wavevarinitcheck(tptr);
1875 		fprintf(outfile,"   %s_f%i = ",lname,i);
1876 		i++;
1877 		blocktree(tptr->down, PRINTTOKENS);
1878 		fprintf(outfile,";\n");
1879 	      }
1880 	    tptr = tptr->next;
1881 	  }
1882 	break;
1883       }
1884     if (!(strcmp(ident->val,"harm_phase")))
1885       {
1886 	i = 1;
1887 	while (tptr != NULL)
1888 	  {
1889 	    if (tptr->ttype == S_EXPR)
1890 	      {
1891 		wavevarinitcheck(tptr);
1892 		if ((i % 2) == 1)
1893 		  fprintf(outfile,"   %s_f%i = ",lname,(i/2)+1);
1894 		else
1895 		  fprintf(outfile,"   %s_ph%i = ",lname,(i/2));
1896 		blocktree(tptr->down, PRINTTOKENS);
1897 		fprintf(outfile,";\n");
1898 		i++;
1899 	      }
1900 	    tptr = tptr->next;
1901 	  }
1902 	break;
1903       }
1904     break;
1905   case 'l':
1906     if (!(strcmp(ident->val,"lineseg")))
1907       {
1908 	i = 1;
1909 	while (tptr != NULL)
1910 	  {
1911 	    if (tptr->ttype == S_EXPR)
1912 	      {
1913 		wavevarinitcheck(tptr);
1914 		if ((i % 2) == 1)
1915 		  {
1916 		    fprintf(outfile,"   %s_rounding = ", lname);
1917 		    blocktree(tptr->down, PRINTTOKENS);
1918 		    fprintf(outfile,";\n");
1919 		    fprintf(outfile,"   %s_x%i = ROUND(%s_rounding);\n",
1920 			    lname, (i/2)+1, lname);
1921 		  }
1922 		else
1923 		  {
1924 		    fprintf(outfile,"   %s_y%i = (",lname,(i/2));
1925 		    blocktree(tptr->down, PRINTTOKENS);
1926 		    fprintf(outfile,");\n");
1927 		  }
1928 		i++;
1929 	      }
1930 	    tptr = tptr->next;
1931 	  }
1932 	i--;
1933 	if (i % 2 == 1)
1934 	  genex(&lc, wname, "Odd number of parameters (not including size)");
1935 	else
1936 	  {
1937 	    i = i/2;
1938 	    while (i >= 2)
1939 	      {
1940 		mz(lc); sprintf(z[lc++],
1941                 "if (%s_x%i > %s_x%i)",
1942 				lname,i-1,lname,i);
1943 		genex(&lc, wname, "xvals not a non-decreasing sequence");
1944 		mz(lc); sprintf(z[lc++],
1945                 "if (%s_x%i != %s_x%i)",
1946 				lname,i-1,lname,i);
1947 		mz(lc); sprintf(z[lc++],
1948 	        "%s_d%i=(%s_y%i-%s_y%i)/(%s_x%i-%s_x%i);",
1949 			lname,i-1, lname,i,
1950 			lname,i-1, lname,i,lname,i-1);
1951 		i--;
1952 	      }
1953 	    z[lc++]="if (%2$s_x1 != 0.0F)";
1954 	    genex(&lc, wname, "x1 != 0");
1955 	  }
1956 	printwavesymblock2(lc,wname);
1957 	break;
1958       }
1959     break;
1960   case 'p':
1961     if (!(strcmp(ident->val,"periodic")))
1962       {
1963 	i = 1;
1964 	while (tptr != NULL)
1965 	  {
1966 	    if (tptr->ttype == S_EXPR)
1967 	      {
1968 		wavevarinitcheck(tptr);
1969 		switch(i % 3) {
1970 		case 1:
1971 		  fprintf(outfile,"   %s_p%i = ",lname,(i/3)+1);
1972 		  break;
1973 		case 2:
1974 		  fprintf(outfile,"   %s_f%i = ",lname,(i/3)+1);
1975 		  break;
1976 		case 0:
1977 		  fprintf(outfile,"   %s_ph%i = ",lname,(i/3));
1978 		  break;
1979 		}
1980 		blocktree(tptr->down, PRINTTOKENS);
1981 		fprintf(outfile,";\n");
1982 		i++;
1983 	      }
1984 	    tptr = tptr->next;
1985 	  }
1986 	break;
1987       }
1988     if (!(strcmp(ident->val,"polynomial")))
1989       {
1990 	i = 1;
1991 	while (tptr != NULL)
1992 	  {
1993 	    if (tptr->ttype == S_EXPR)
1994 	      {
1995 		switch (i) {
1996 		case 1:
1997 		  fprintf(outfile,"   %s_xmin = ",lname);
1998 		  break;
1999 		case 2:
2000 		  fprintf(outfile,"   %s_xmax = ",lname);
2001 		  break;
2002 		default:
2003 		  fprintf(outfile,"   %s_a%i = ",lname,i-3);
2004 		  break;
2005 		}
2006 		blocktree(tptr->down, PRINTTOKENS);
2007 		fprintf(outfile,";\n");
2008 		i++;
2009 	      }
2010 	    tptr = tptr->next;
2011 	  }
2012 	if (i<4)
2013 	  genex(&lc, wname, "Not enough parameters");
2014 	z[lc++]="if (%2$s_xmax == %2$s_xmin)";
2015 	genex(&lc, wname, "xmin = xmax");
2016 	printwavesymblock2(lc,wname);
2017 	break;
2018       }
2019     break;
2020   case 'r':
2021     if (!(strcmp(ident->val,"random")))
2022       {
2023 	i = 1;
2024 	while (tptr != NULL)
2025 	  {
2026 	    if (tptr->ttype == S_EXPR)
2027 	      {
2028 		wavevarinitcheck(tptr);
2029 		switch (i) {
2030 		case 1:
2031 		  fprintf(outfile,"   %s_rounding = ", lname);
2032 		  blocktree(tptr->down, PRINTTOKENS);
2033 		  fprintf(outfile,";\n");
2034 		  fprintf(outfile,"   %s_dist = ROUND(%s_rounding);\n",
2035 			  lname, lname);
2036 		  break;
2037 		case 2:
2038 		  fprintf(outfile,"   %s_p1 = ",lname);
2039 		  blocktree(tptr->down, PRINTTOKENS);
2040 		  fprintf(outfile,";\n");
2041 		  break;
2042 		case 3:
2043 		  fprintf(outfile,"   %s_p2 = ",lname);
2044 		  blocktree(tptr->down, PRINTTOKENS);
2045 		  fprintf(outfile,";\n");
2046 		  break;
2047 		default:
2048 		  printf("Error: Too many parameters.\n");
2049 		  showerrorplace(wname->linenum, wname->filename);
2050 		}
2051 		i++;
2052 	      }
2053 	    tptr = tptr->next;
2054 	  }
2055 	break;
2056       }
2057     break;
2058   case 's':
2059     if (!(strcmp(ident->val,"sample")))
2060       {
2061 	/* check skip if present, codegen in samplefilecode */
2062 
2063 	tptr = (tptr->next) ? tptr->next->next : NULL;
2064 
2065 	if (tptr)
2066 	  wavevarinitcheck(tptr);
2067 
2068 	break;
2069       }
2070     if (!(strcmp(ident->val,"spline")))
2071       {
2072 	i = 1; j = 1;
2073 	while (tptr != NULL)
2074 	  {
2075 	    if (tptr->ttype == S_EXPR)
2076 	      {
2077 		wavevarinitcheck(tptr);
2078 		switch(i % 3) {
2079 		case 0:
2080 		  fprintf(outfile,"   %s_k%i = ",lname,(i/3)+1);
2081 		  blocktree(tptr->down, PRINTTOKENS);
2082 		  fprintf(outfile,";\n");
2083 		  break;
2084 		case 1:
2085 		  fprintf(outfile,"   %s_rounding = ", lname);
2086 		  blocktree(tptr->down, PRINTTOKENS);
2087 		  fprintf(outfile,";\n");
2088 		  fprintf(outfile,"   %s_x%i = ROUND(%s_rounding);\n",
2089 			  lname,(i/3)+1,lname);
2090 		  break;
2091 		case 2:
2092 		  fprintf(outfile,"   %s_y%i = ",lname,(i/3)+1);
2093 		  blocktree(tptr->down, PRINTTOKENS);
2094 		  fprintf(outfile,";\n");
2095 		  j++;
2096 		  break;
2097 		}
2098 		i++;
2099 	      }
2100 	    tptr = tptr->next;
2101 	  }
2102 	j--;i--;
2103 
2104 	z[lc++]="%2$s_k1 = 0.0F;";
2105 	mz(lc); sprintf(z[lc++],"%s_k%i = 0.0F;", lname,j);
2106 
2107 	if (j<2)
2108 	  genex(&lc, wname, "Less than 2 parameters");
2109 	if ((i % 3) != 2)
2110 	  genex(&lc, wname, "Sequence must end with yn.");
2111 
2112 	else
2113 	  {
2114 	    i = 1;
2115 	    while (i < j)
2116 	      {
2117 		mz(lc); sprintf(z[lc++],"if (%s_x%i > %s_x%i)",
2118 			lname,i,lname,i+1);
2119 		genex(&lc, wname, "xvals not a non-decreasing sequence");
2120 
2121 		mz(lc); sprintf(z[lc++],"if (%s_x%i != %s_x%i)",
2122 			lname,i,lname,i+1);
2123 		z[lc++]="{";
2124 
2125 		mz(lc); sprintf(z[lc++],"%s_Q = 1.0F/(%s_x%i - %s_x%i);",
2126 			lname,lname,i,lname,i+1);
2127 
2128 		mz(lc); sprintf(z[lc++],
2129 	       "%s_R = %s_Q*(%s_x%i*%s_x%i - %s_x%i*%s_x%i) - 2.0F*%s_x%i;",
2130 				lname,lname,lname,i,lname,i,
2131 				lname,i+1,lname,i+1,lname,i);
2132 
2133 		z[lc++]="if (%2$s_R == 0.0F)";
2134 		genex(&lc, wname, "No spline solution for these parameters");
2135 
2136 		z[lc++]="%2$s_R =1.0F/%2$s_R;";
2137 
2138 		mz(lc); sprintf(z[lc++],
2139 	       "%s_S = %s_Q*(%s_x%i*%s_x%i - %s_x%i*%s_x%i) - 2.0F*%s_x%i;",
2140 				lname,lname,lname,i,lname,i,
2141 				lname,i+1,lname,i+1,lname,i+1);
2142 
2143 		z[lc++]="if (%2$s_S == 0.0F)";
2144 		genex(&lc, wname, "No spline solution for these parameters");
2145 
2146 		z[lc++]="%2$s_S =1.0F/%2$s_S;";
2147 
2148 		mz(lc); sprintf(z[lc++],
2149 		"%s_a%i = %s_Q*(%s_x%i*%s_x%i*%s_x%i-%s_x%i*%s_x%i*%s_x%i)*(%s_R-%s_S);",
2150 				lname,i,lname,
2151 				lname,i,lname,i,lname,i,
2152 				lname,i+1,lname,i+1,lname,i+1,
2153 				lname,lname);
2154 
2155 		mz(lc); sprintf(z[lc++],
2156 		"%s_a%i += -3.0F*(%s_R*%s_x%i*%s_x%i - %s_S*%s_x%i*%s_x%i);",
2157 				lname,i,
2158 				lname, lname,i,lname,i,
2159 				lname, lname,i+1,lname,i+1);
2160 
2161 		mz(lc); sprintf(z[lc++],"if (%s_a%i==0.0F)",lname,i);
2162 		genex(&lc, wname, "No spline solution for these parameters");
2163 
2164 		mz(lc); sprintf(z[lc++],
2165 		"%s_a%i =1.0F/%s_a%i;",
2166 				lname,i,lname,i);
2167 
2168 		mz(lc); sprintf(z[lc++],
2169 		"%s_a%i *= %s_Q*(%s_y%i-%s_y%i)*(%s_R-%s_S) - %s_R*%s_k%i + %s_S*%s_k%i;",
2170 				lname,i,lname,lname,i,lname,i+1,
2171 				lname,lname,lname,lname,i,
2172 				lname,lname,i+1);
2173 
2174 		mz(lc); sprintf(z[lc++],
2175 		"%s_b%i = %s_Q*(%s_k%i-%s_k%i)*0.5F;",
2176 				lname,i,
2177 				lname, lname,i,lname,i+1);
2178 		mz(lc); sprintf(z[lc++],
2179 		"%s_b%i += - 1.5F*%s_a%i*%s_Q*(%s_x%i*%s_x%i - %s_x%i*%s_x%i);",
2180 				lname,i,lname,i,lname,
2181 				lname,i,lname,i,lname,i+1,lname,i+1);
2182 
2183 		mz(lc); sprintf(z[lc++],
2184 		"%s_c%i = %s_k%i - 3.0F*%s_a%i*%s_x%i*%s_x%i -2.0F*%s_b%i*%s_x%i;",
2185 				lname,i,lname,i,lname,i,lname,i,
2186 				lname,i,lname,i,lname,i);
2187 
2188 		mz(lc); sprintf(z[lc++],
2189 	    "%s_d%i=%s_y%i-%s_a%i*%s_x%i*%s_x%i*%s_x%i-%s_b%i*%s_x%i*%s_x%i-%s_c%i*%s_x%i;"
2190 				,lname,i,lname,i,lname,i,lname,i
2191 				,lname,i,lname,i,lname,i,lname,i
2192 				,lname,i,lname,i,lname,i);
2193 
2194 		z[lc++]="}";
2195 		i++;
2196 	      }
2197 
2198 	  }
2199 	printwavesymblock2(lc,wname);
2200 	break;
2201 
2202       }
2203     if (!(strcmp(ident->val,"step")))
2204       {
2205 	i = 1;
2206 	while (tptr != NULL)
2207 	  {
2208 	    if (tptr->ttype == S_EXPR)
2209 	      {
2210 		wavevarinitcheck(tptr);
2211 		if ((i % 2) == 1)
2212 		  {
2213 		    fprintf(outfile,"   %s_rounding = ", lname);
2214 		    blocktree(tptr->down, PRINTTOKENS);
2215 		    fprintf(outfile,";\n");
2216 		    fprintf(outfile,"   %s_x%i = ROUND(%s_rounding);\n",
2217 			    lname, (i/2)+1, lname);
2218 		  }
2219 		else
2220 		  {
2221 		    fprintf(outfile,"   %s_y%i = ",lname,(i/2));
2222 		    blocktree(tptr->down, PRINTTOKENS);
2223 		    fprintf(outfile,";\n");
2224 		  }
2225 		i++;
2226 	      }
2227 	    tptr = tptr->next;
2228 	  }
2229 	i--;
2230 	if (i % 2 == 0)
2231 	  genex(&lc, wname, "Not enough parameters");
2232 	else
2233 	  {
2234 	    i = (i/2) + 1;
2235 	    while (i >= 2)
2236 	      {
2237 		mz(lc); sprintf(z[lc++],"if (%s_x%i > %s_x%i)",
2238 				lname,i-1,lname,i);
2239 		genex(&lc, wname, "xvals not a non-decreasing sequence");
2240 
2241 		i--;
2242 	      }
2243 	    z[lc++]="if (%2$s_x1 != 0.0F)";
2244 	    genex(&lc, wname, "x1 != 0");
2245 	  }
2246 	printwavesymblock2(lc,wname);
2247 	break;
2248       }
2249     break;
2250   case 'w':
2251     if (!(strcmp(ident->val,"window")))
2252       {
2253 	i = 1;
2254 	while (tptr != NULL)
2255 	  {
2256 	    if (tptr->ttype == S_EXPR)
2257 	      {
2258 		wavevarinitcheck(tptr);
2259 		switch (i) {
2260 		case 1:
2261 		  fprintf(outfile,"   %s_rounding = ", lname);
2262 		  blocktree(tptr->down, PRINTTOKENS);
2263 		  fprintf(outfile,";\n");
2264 
2265 		  fprintf(outfile,"   %s_type = ROUND(%s_rounding);\n",
2266 			  lname, lname);
2267 		  break;
2268 		case 2:
2269 		  fprintf(outfile,"   %s_p = ",lname);
2270 		  blocktree(tptr->down, PRINTTOKENS);
2271 		  fprintf(outfile,";\n");
2272 		  break;
2273 		default:
2274 		  printf("Error: Too many parameters.\n");
2275 		  showerrorplace(wname->linenum, wname->filename);
2276 		}
2277 		i++;
2278 	      }
2279 	    tptr = tptr->next;
2280 	  }
2281 	break;
2282       }
2283     break;
2284   default:
2285     break;
2286   }
2287   free(lname);
2288   currblockrate = currblocksafe;
2289 }
2290 
2291 extern void samplefilepreamble(sigsym *, int *);
2292 
2293 /*********************************************************/
2294 /* adds code common to all tables to wavegenerator       */
2295 /*********************************************************/
2296 
tablepreamble(sigsym * ident,char * prefix,int mode,int action)2297 void tablepreamble(sigsym * ident, char * prefix, int mode, int action)
2298 
2299 {
2300 
2301   int lc = 0;
2302   int j;
2303   char * lname = makewstring(ident->val);
2304 
2305   tnode * aptr = ident->defnode->down->next->next->next->next->next->down;
2306 
2307   z[lc++]= " ";
2308 
2309   if (0)
2310     {
2311       z[lc++]= "NT(%1$s).start = 0;";
2312       z[lc++]= "NT(%1$s).end = 0;";
2313       z[lc++]= "NT(%1$s).sr = 0;";
2314       z[lc++]= "NT(%1$s).dint = 0;";
2315       z[lc++]= "NT(%1$s).dfrac = 0;";
2316       z[lc++]= "NT(%1$s).sffl = 0;";
2317       z[lc++]= "NT(%1$s).sfui = 0;";
2318       z[lc++]= "NT(%1$s).dsincr = 0;";
2319       z[lc++]= "NT(%1$s).base = 0;";
2320       z[lc++]= "NT(%1$s).oconst = 0;";
2321       z[lc++]= "NT(%1$s).tend = 0;";
2322     }
2323 
2324   z[lc++]= "i = NT(%1$s).len = %2$s_size;";
2325 
2326   switch (action) {
2327   case GENILLEGAL:
2328     z[lc++]= "if (i < 1)";
2329     genex(&lc, ident->defnode->down, "Table length < 1");
2330     break;
2331   case GENNUMDATA:
2332     z[lc++]= "if (i == -1) ";
2333     mz(lc); sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %i;",
2334 		    lname, prefix,ident->val, tablelistlength(aptr));
2335     z[lc++]= "if (i < 1)";
2336     genex(&lc, ident->defnode->down, "Table length < 1");
2337     break;
2338   case GENSTEP:
2339     z[lc++]= "if (i == -1) ";
2340     mz(lc);sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %s_x%i;",
2341 		   lname,prefix,ident->val,lname,
2342 		   (tablelistlength(aptr)/2)+1);
2343     z[lc++]= "if (i < 1)";
2344     genex(&lc, ident->defnode->down, "Table length < 1");
2345     break;
2346   case GENPAIRS:
2347     z[lc++]= "if (i == -1) ";
2348     mz(lc);sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %s_x%i;",
2349 		   lname,prefix,ident->val,lname,
2350 		   tablelistlength(aptr)/2);
2351     z[lc++]= "if (i < 1)";
2352     genex(&lc, ident->defnode->down, "Table length < 1");
2353     break;
2354   case GENCUBIC:
2355     z[lc++]= "if (i == -1) ";
2356     j = tablelistlength(aptr);
2357     mz(lc);
2358     if (4*(j/4) == j)
2359       sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %s_x%i;",
2360 		     lname,prefix,ident->val,
2361 		     lname,tablelistlength(aptr)/4);
2362     else
2363       sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %s_infl%i;",
2364 		     lname,prefix,ident->val,
2365 		     lname,(tablelistlength(aptr)/4)+1);
2366     z[lc++]= "if (i < 1)";
2367     genex(&lc, ident->defnode->down, "Table length < 1");
2368     break;
2369   case GENSPLINE:
2370     z[lc++]= "if (i == -1) ";
2371     mz(lc);sprintf(z[lc++],"  %s_size = i = NT(%s_%s).len = %s_x%i;",
2372 		   lname, prefix,ident->val,
2373 		   lname,((tablelistlength(aptr)+1)/3));
2374     z[lc++]= "if (i < 1)";
2375     genex(&lc, ident->defnode->down, "Table length < 1");
2376     break;
2377   case GENBUZZ:
2378     z[lc++]="if ((%2$s_lowharm<0))";
2379     genex(&lc, ident->defnode->down, "Low harm must be >= 0");
2380     z[lc++]="if ((i < 1) && (%2$s_nharm<1))";
2381     genex(&lc, ident->defnode->down, "Buzz size and nharm both < 1");
2382     z[lc++]="if ((i < 1) || (%2$s_nharm<1))";
2383     z[lc++]="{";
2384     z[lc++]="  if (i < 1)";
2385     z[lc++]="    NT(%1$s).len = %2$s_size = i = 2*(%2$s_lowharm + %2$s_nharm);";
2386     z[lc++]="  else";
2387     z[lc++]="   %2$s_nharm = (int)floor(i/2.0 - %2$s_lowharm);";
2388     z[lc++]="}";
2389     z[lc++]="if (((%2$s_acc=fabs(%2$s_rolloff))<1.0F)&&(%2$s_rolloff!=0.0F))";
2390     z[lc++]="{";
2391     z[lc++]=  "j = -(int)(17.0F/log(%2$s_acc)) + %2$s_lowharm + 1;";
2392     z[lc++]=  "%2$s_nharm = (%2$s_nharm > j) ? j : %2$s_nharm;";
2393     z[lc++]="}";
2394 
2395     break;
2396   case GENCONCAT:
2397     z[lc++]= "if (i < 1)";
2398     z[lc++]= "{";
2399     z[lc++]= "  i = 0;";
2400     j = tablelistlength(aptr);
2401     while (j >=1)
2402       {
2403 	mz(lc); sprintf(z[lc++],"  if (AP%i.t == NULL)", j);
2404 	genex(&lc, ident->defnode->down, "Can't concat an uninitialized table");
2405 	mz(lc); sprintf(z[lc++],"  i += AP%i.len;", j);
2406 	j--;
2407       }
2408     z[lc++]= "   if (i < 1)";
2409     genex(&lc, ident->defnode->down, "Table length < 1");
2410     z[lc++]= "   NT(%1$s).len = %2$s_size = i;";
2411     z[lc++]= "}";
2412     break;
2413   default:
2414     internalerror("wtparse.c", "case statement");
2415   }
2416 
2417   if (interp == INTERP_SINC)
2418     {
2419       z[lc++]= "NT(%1$s).sffl = 1.0F;";
2420       z[lc++]= "NT(%1$s).sfui = 0x00010000;";
2421       z[lc++]= "NT(%1$s).dsincr = SINC_PILEN;";
2422     }
2423 
2424   z[lc++]= "NT(%1$s).stamp = EV(scorebeats);";
2425   z[lc++]= "NT(%1$s).lenf = (float)(i);";
2426   z[lc++]= "NT(%1$s).oconst = EV(ATIME)*((float)i);";
2427   z[lc++]= "if (i>0)";
2428   z[lc++]= "{";
2429   z[lc++]= "  NT(%1$s).tend = i - 1;";
2430   z[lc++]= "}";
2431   z[lc++]= "NT(%1$s).t = (float *) malloc((i+1)*sizeof(float));";
2432   z[lc++]= "NT(%1$s).llmem = 1;";
2433   z[lc++]= "i--;";
2434   z[lc++]= " ";
2435   printwavesymblock(lc,ident,prefix);
2436   free(lname);
2437   return;
2438 
2439 }
2440 
2441 
2442 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2443 /*                                                              */
2444 /* Simpler utility functions used by code generation routines.  */
2445 /*                                                              */
2446 /*______________________________________________________________*/
2447 
2448 /*********************************************************/
2449 /*     do variable checks for generator execution        */
2450 /*********************************************************/
2451 
wavevarinitcheck(tnode * tptr)2452 void wavevarinitcheck(tnode * tptr)
2453 
2454 {
2455   widthupdate(tptr);
2456   if (truewidth(tptr->width) != 1)
2457     {
2458       while (tptr->down != NULL)
2459 	tptr = tptr->down;
2460       printf("Error: Generator arguments must be width 1.\n");
2461       showerrorplace(tptr->linenum, tptr->filename);
2462     }
2463   curropcoderate = ARATETYPE;
2464   currtreerate = UNKNOWN;
2465   rateupdate(tptr);
2466   if (tptr->rate != IRATETYPE)
2467     {
2468       while (tptr->down != NULL)
2469 	tptr = tptr->down;
2470       printf("Error: Generators arguments must run at i-rate.\n");
2471       showerrorplace(tptr->linenum, tptr->filename);
2472     }
2473   if ((tptr->vartype == TMAPTYPE)||(tptr->vartype == TABLETYPE))
2474     {
2475       while (tptr->down != NULL)
2476 	tptr = tptr->down;
2477       printf("Error: Table(map) an inappropriate argument.\n");
2478       showerrorplace(tptr->linenum, tptr->filename);
2479     }
2480 }
2481 
2482 /*********************************************************/
2483 /* computes length of argument list for table (w/o size) */
2484 /*********************************************************/
2485 
tablelistlength(tnode * tptr)2486 int tablelistlength(tnode * tptr)
2487 
2488 {
2489   int j=0;
2490 
2491   tptr = tptr->next;
2492   if (tptr != NULL)
2493     tptr = tptr->next;
2494   while (tptr != NULL)
2495     {
2496       j++;
2497       tptr = tptr->next;
2498       if (tptr != NULL)
2499 	tptr = tptr->next;
2500     }
2501   return j;
2502 }
2503 
2504 /*********************************************************/
2505 /*       creates alias-free local variable name          */
2506 /*********************************************************/
2507 
makewstring(char * val)2508 char * makewstring(char * val)
2509 
2510 {
2511   char * lname;
2512 
2513   vmcheck(lname = calloc(strlen(val)+strlen("_sym_") + 1,
2514                          sizeof(char)));
2515   strcpy(lname, val);
2516   strcat(lname, "__sym");
2517   return(lname);
2518 
2519 }
2520 
2521 
2522 /*********************************************************/
2523 /*          adds aiff/wav sample reading code            */
2524 /*********************************************************/
2525 
samplefilecode(sigsym * ident,char * prefix,int * lcptr)2526 void samplefilecode(sigsym * ident, char * prefix, int * lcptr)
2527 
2528 {
2529   char newval[STRSIZE];
2530   int lc = *lcptr;
2531   sampleinfo * sinfo;
2532   double intdummy;
2533   tnode * sizeptr;
2534   tnode * fileptr;
2535   tnode * skipptr = NULL;
2536   unsigned int size = 0;
2537   int tsize = 0;
2538   unsigned int skip = 0;
2539   int known, currblocksafe;
2540   char * lname = makewstring(ident->val);
2541   char * suffix;
2542   char bytecount;
2543 
2544   /* see wtconst.c for regularization of constant size and skip */
2545 
2546   sizeptr = ident->defnode->down->next->next->next->next->next->down;
2547   fileptr = sizeptr->next->next;
2548   skipptr = (fileptr->next) ? fileptr->next->next : NULL;
2549 
2550   sinfo = (sampleinfo *) fileptr->ibus;
2551 
2552   /***********************************************/
2553   /* set variables independent of size and skip  */
2554   /***********************************************/
2555 
2556   z[lc++]= "NT(%1$s).stamp = EV(scorebeats);";
2557 
2558   mz(lc); sprintf(z[lc++], "NT(%s_%s).sr = %i;", prefix, ident->val,
2559 		  sinfo->srate);
2560 
2561   if (reentrant)
2562     {
2563       mz(lc); sprintf(z[lc++], "if (EV(ARATE) == %u.0F)", sinfo->srate);
2564       mz(lc); sprintf(z[lc++], "  {");
2565       mz(lc); sprintf(z[lc++], "    NT(%s_%s).dint = 1;", prefix, ident->val);
2566       mz(lc); sprintf(z[lc++], "    NT(%s_%s).dfrac = 0;", prefix, ident->val);
2567       mz(lc); sprintf(z[lc++], "  }");
2568       mz(lc); sprintf(z[lc++], "else");
2569       mz(lc); sprintf(z[lc++], "  {");
2570       mz(lc); sprintf(z[lc++], "     NT(%s_%s).dfrac = (unsigned int)"
2571 		      "(4294967296.0*((%u.0/EV(ARATE)) - ((int)(%u.0/EV(ARATE)))));",
2572 		      prefix, ident->val, sinfo->srate, sinfo->srate);
2573       mz(lc); sprintf(z[lc++], "     NT(%s_%s).dint = (unsigned int)(%u.0/EV(ARATE));",
2574 		      prefix, ident->val, sinfo->srate);
2575       mz(lc); sprintf(z[lc++], "  }");
2576     }
2577   else
2578     {
2579       if (srate == sinfo->srate)
2580 	{
2581 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).dint = 1;", prefix, ident->val);
2582 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).dfrac = 0;", prefix, ident->val);
2583 	}
2584       else
2585 	{
2586 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).dfrac = %uU;", prefix, ident->val,
2587 			  (unsigned int) (4294967296.0*
2588 					   modf(((double)sinfo->srate)/((double)srate),
2589 						&intdummy)));
2590 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).dint = %uU;", prefix, ident->val,
2591 			  (unsigned int) intdummy);
2592 	}
2593     }
2594 
2595   if (interp == INTERP_SINC)
2596     {
2597       if (reentrant)
2598 	{
2599 	  mz(lc); sprintf(z[lc++], "if (EV(ARATE) >= %u.0F)", sinfo->srate);
2600 	  mz(lc); sprintf(z[lc++], "  {");
2601 	  mz(lc); sprintf(z[lc++],    "NT(%s_%s).sffl = 1.0F;", prefix, ident->val);
2602 	  mz(lc); sprintf(z[lc++],    "NT(%s_%s).sfui = 0x00010000;", prefix, ident->val);
2603 	  mz(lc); sprintf(z[lc++],    "NT(%s_%s).dsincr = SINC_PILEN;", prefix, ident->val);
2604 	  mz(lc); sprintf(z[lc++], "  }");
2605 	  mz(lc); sprintf(z[lc++], "else");
2606 	  mz(lc); sprintf(z[lc++], "  {");
2607 	  mz(lc); sprintf(z[lc++], "   if (SINC_UPMAX*EV(ARATE) > %u.0F)",
2608 			  sinfo->srate);
2609 	  mz(lc); sprintf(z[lc++], "     NT(%s_%s).sffl = (EV(ARATE)/NT(%s_%s).sr);",
2610 			  prefix, ident->val, prefix, ident->val);
2611 	  mz(lc); sprintf(z[lc++], "   else");
2612 	  mz(lc); sprintf(z[lc++], "     NT(%s_%s).sffl = (1.0F/SINC_UPMAX);",
2613 			  prefix, ident->val);
2614 	  mz(lc); sprintf(z[lc++], "   NT(%s_%s).sfui = ((float)(pow(2,16)))*NT(%s_%s).sffl + 0.5F;",
2615 			  prefix, ident->val, prefix, ident->val);
2616 	  mz(lc); sprintf(z[lc++], "   NT(%s_%s).dsincr = (SINC_PILEN*NT(%s_%s).sfui) >> 16;",
2617 			  prefix, ident->val, prefix, ident->val);
2618 	  mz(lc); sprintf(z[lc++], "  }");
2619 	}
2620       else
2621 	{
2622 	  if (srate >= sinfo->srate)
2623 	    {
2624 	      mz(lc); sprintf(z[lc++], "NT(%s_%s).sffl = 1.0F;", prefix, ident->val);
2625 	      mz(lc); sprintf(z[lc++], "NT(%s_%s).sfui = 0x00010000;", prefix, ident->val);
2626 	      mz(lc); sprintf(z[lc++], "NT(%s_%s).dsincr = SINC_PILEN;", prefix, ident->val);
2627 	    }
2628 	  else
2629 	    {
2630 	      if (srate*sinc_upmax > sinfo->srate)
2631 		{
2632 		  mz(lc); sprintf(z[lc++], "NT(%s_%s).sffl = (EV(ARATE)/NT(%s_%s).sr);",
2633 				  prefix, ident->val, prefix, ident->val);
2634 		}
2635 	      else
2636 		{
2637 		  mz(lc); sprintf(z[lc++], "NT(%s_%s).sffl = (1.0F/SINC_UPMAX);",
2638 				  prefix, ident->val);
2639 		}
2640 
2641 	      mz(lc); sprintf(z[lc++],
2642 			      "NT(%s_%s).sfui = ((float)(pow(2,16)))*NT(%s_%s).sffl + 0.5F;",
2643 			      prefix, ident->val, prefix, ident->val);
2644 	      mz(lc); sprintf(z[lc++],
2645 			      "NT(%s_%s).dsincr = (SINC_PILEN*NT(%s_%s).sfui) >> 16;",
2646 			      prefix, ident->val, prefix, ident->val);
2647 	    }
2648 	}
2649     }
2650 
2651   if (sinfo->hasbase)
2652     {
2653       mz(lc); sprintf(z[lc++], "NT(%s_%s).base = %s;", prefix, ident->val,
2654 		      compactfloat(newval, sinfo->base));
2655     }
2656 
2657   if (sinfo->hasloop)
2658     {
2659       mz(lc); sprintf(z[lc++], "NT(%s_%s).start = %i;",
2660 		      prefix, ident->val, sinfo->start);
2661       if (sinfo->end)
2662 	{
2663 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).tend = NT(%s_%s).end = %i;",
2664 			  prefix, ident->val, prefix, ident->val, sinfo->end);
2665 	}
2666     }
2667 
2668   /***********************************************/
2669   /* table parameters that depend on size/skip   */
2670   /***********************************************/
2671 
2672   if ((known = (sizeptr->vol == CONSTANT) &&
2673       ((skipptr == NULL) || (skipptr->vol == CONSTANT))))
2674     {
2675       /******************************/
2676       /* for constant size and skip */
2677       /******************************/
2678 
2679       if (skipptr)
2680 	skip = atoi(skipptr->down->val);
2681 
2682       if (atoi(sizeptr->down->val) <= 0)
2683 	{
2684 	  tsize = 1;
2685 	  size = sinfo->len - skip;
2686 	}
2687       else
2688 	size = atoi(sizeptr->down->val);
2689 
2690       mz(lc); sprintf(z[lc++],
2691 		      "NT(%s_%s).lenf = (float)(NT(%s_%s).len = %i);",
2692 		      prefix,ident->val, prefix, ident->val, size);
2693 
2694       mz(lc); sprintf(z[lc++], "NT(%s_%s).oconst = NT(%s_%s).lenf*EV(ATIME);",
2695 		      prefix,ident->val, prefix, ident->val);
2696 
2697       mz(lc); sprintf(z[lc++], "NT(%s_%s).t = (float *)(calloc(%i, %i));",
2698 		      prefix, ident->val, size + 1, (int)sizeof(float));
2699 
2700       if (sinfo->hasloop)
2701 	{
2702 	  if (!(sinfo->end))
2703 	    {
2704 	      mz(lc); sprintf(z[lc++], "NT(%s_%s).tend = %i;",
2705 			      prefix,ident->val, size - 1);
2706 	    }
2707 	}
2708       else
2709 	{
2710 	  mz(lc); sprintf(z[lc++], "NT(%s_%s).tend = %i;",
2711 			  prefix,ident->val, size - 1);
2712 	}
2713     }
2714   else
2715     {
2716 
2717       /**********************************/
2718       /* for variable size and/or skip */
2719       /*********************************/
2720 
2721       if ((skipptr == NULL) || (skipptr->vol == CONSTANT))
2722 	{
2723 	  if (skipptr)
2724 	    skip = atoi(skipptr->down->val);
2725 
2726 	  mz(lc); sprintf(z[lc++], "%s_skip = %i;", lname, skip);
2727 	}
2728       else
2729 	{
2730 	  currblocksafe = currblockrate;
2731 	  currblockrate = IRATETYPE;
2732 	  fprintf(outfile,"   %s_rounding = ", lname);
2733 	  blocktree(skipptr->down, PRINTTOKENS);
2734 	  fprintf(outfile,";\n");
2735 	  fprintf(outfile,"   %s_skip = ROUND(%s_rounding);\n",
2736 		  lname, lname);
2737 	  fprintf(outfile,"   if (%s_skip < 0)\n",lname);
2738 	  fprintf(outfile,"     %s_skip = 0;\n",lname);
2739 	  currblockrate = currblocksafe;
2740 	}
2741 
2742       mz(lc); sprintf(z[lc++],
2743 		      "NT(%s_%s).lenf = (float)(NT(%s_%s).len = "
2744 		      "((%s_size <= 0) ? (%i - %s_skip) : %s_size));",
2745 		      prefix, ident->val, prefix, ident->val, lname,
2746 		      sinfo->len, lname, lname);
2747 
2748       mz(lc); sprintf(z[lc++], "NT(%s_%s).oconst = NT(%s_%s).lenf*EV(ATIME);",
2749 		      prefix,ident->val, prefix, ident->val);
2750 
2751       z[lc++]= "NT(%1$s).t = (float *)(calloc(NT(%1$s).len +1,";
2752       z[lc++]= "                       sizeof(float)));";
2753 
2754       if (sinfo->hasloop)
2755 	{
2756 	  if (!(sinfo->end))
2757 	    {
2758 	      z[lc++]="NT(%1$s).tend = NT(%1$s).len - 1;";
2759 	    }
2760 	}
2761       else
2762 	{
2763 	  z[lc++]="NT(%1$s).tend = NT(%1$s).len - 1;";
2764 	}
2765     }
2766 
2767   /***********************************/
2768   /* code for reading data from file */
2769   /***********************************/
2770 
2771   if ((suffix = strrchr(fileptr->val, '.')) && (suffix = strrchr(suffix, '@')))
2772     suffix[0] = '\0';
2773 
2774   mz(lc); sprintf(z[lc++], "EV(sfile) = fopen(\"%s\", \"rb\");", fileptr->val);
2775 
2776   if (suffix)
2777     suffix[0] = '@';
2778 
2779   z[lc++]= "if (EV(sfile) == NULL)";
2780   genex(&lc, ident->defnode->down, "Samplefile not found");
2781 
2782   if (known)
2783     {
2784       /* we don't fseek() to simplify signal handling for real-time */
2785 
2786       mz(lc); sprintf(z[lc++], "for (i = 0; i < %i; i++)",
2787 		      sinfo->point + skip*sinfo->framebytes);
2788       z[lc++]= "if (!rread(%2$s_c,1,1,EV(sfile)))";
2789       genex(&lc, ident->defnode->down, "Corrupt samplefile");
2790 
2791       mz(lc); sprintf(z[lc++], "for (i=0; i < %i; i++)",
2792 		      tsize ? size : ((size < (sinfo->len - skip)) ?
2793 				      size : (sinfo->len - skip)));
2794       z[lc++]= "{";
2795 
2796     }
2797   else
2798     {
2799 
2800       mz(lc); sprintf(z[lc++], "for (i = 0; i < %i + %i*%s_skip; i++)",
2801 		      sinfo->point, sinfo->framebytes, lname);
2802       z[lc++]= "if (!rread(%2$s_c,1,1,EV(sfile)))";
2803       genex(&lc, ident->defnode->down, "Corrupt samplefile");
2804 
2805       z[lc++]="for (i=0; i < NT(%1$s).len; i++)";
2806       z[lc++]= "{";
2807       mz(lc); sprintf(z[lc++], "if (i >= (%i - %s_skip))",
2808 		      sinfo->len, lname);
2809       z[lc++]="  break;";
2810     }
2811 
2812   mz(lc); sprintf(z[lc++], "if (!rread(%s_c,1,%i,EV(sfile)))",
2813 		  lname, sinfo->framebytes);
2814   genex(&lc, ident->defnode->down, "Corrupt samplefile");
2815 
2816   if (sinfo->wav)
2817     {
2818       if (sinfo->chanpoint > -1)
2819 	{
2820 	  switch (sinfo->numbytes) {
2821 	  case 3:
2822 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -23))*(";
2823 	    mz(lc);  sprintf(z[lc++], "    ((int)(%s_c[%hhi])) + ",
2824 			     lname, sinfo->chanpoint);
2825 	    mz(lc);  sprintf(z[lc++], "    (((int)(%s_c[%hhi])) << 8) +",
2826 			     lname, sinfo->chanpoint + 1);
2827 	    mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 16));",
2828 			     lname, sinfo->chanpoint + 2);
2829 	    break;
2830 	  case 2:
2831 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -15))*(";
2832 	    mz(lc);  sprintf(z[lc++], "    ((int)(%s_c[%hhi])) + ",
2833 			     lname, sinfo->chanpoint);
2834 	    mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 8));",
2835 			     lname, sinfo->chanpoint + 1);
2836 	    break;
2837 	  case 1:
2838 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -7))*(";
2839 	    mz(lc);  sprintf(z[lc++], "    ((short)(%s_c[%hhi])) - 128); ",
2840 			     lname, sinfo->chanpoint);
2841 	    break;
2842 	  }
2843 	}
2844       else
2845 	{
2846 	  switch (sinfo->numbytes) {
2847 	  case 3:
2848 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -23))*(";
2849 
2850 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2851 			     (int)(sinfo->framebytes/sinfo->numbytes));
2852 	    break;
2853 	  case 2:
2854 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -15))*(";
2855 
2856 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2857 			     (int)(sinfo->framebytes/sinfo->numbytes));
2858 	    break;
2859 	  case 1:
2860 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -7))*(";
2861 
2862 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2863 			     (int)(sinfo->framebytes/sinfo->numbytes));
2864 	    break;
2865 	  }
2866 
2867 	  bytecount = 0;
2868 	  while (bytecount < sinfo->framebytes)
2869 	    {
2870 	      switch (sinfo->numbytes) {
2871 	      case 3:
2872 		mz(lc);  sprintf(z[lc++], "    %c ((int)(%s_c[%hhi])) + ",
2873 				 bytecount ? '+' : ' ', lname, bytecount);
2874 		mz(lc);  sprintf(z[lc++], "    (((int)(%s_c[%hhi])) << 8) +",
2875 				 lname, bytecount + 1);
2876 		mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 16)",
2877 				 lname, bytecount + 2);
2878 		break;
2879 	      case 2:
2880 		mz(lc);  sprintf(z[lc++], "    %c ((int)(%s_c[%hhi])) + ",
2881 				 bytecount ? '+' : ' ', lname, bytecount);
2882 		mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 8)",
2883 				 lname, bytecount + 1);
2884 		break;
2885 	      case 1:
2886 		mz(lc);  sprintf(z[lc++], "    %c ((short)(%s_c[%hhi])) - 128 ",
2887 				 bytecount ? '+' : ' ', lname, bytecount);
2888 		break;
2889 	      }
2890 	      bytecount += sinfo->numbytes;
2891 	    }
2892 	  z[lc++]= "     );";
2893 	}
2894     }
2895   else
2896     {
2897       if (sinfo->chanpoint > -1)
2898 	{
2899 	  switch (sinfo->numbytes) {
2900 	  case 3:
2901 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -23))*(";
2902 	    mz(lc);  sprintf(z[lc++], "    ((int)(%s_c[%hhi])) + ",
2903 			     lname, sinfo->chanpoint + 2);
2904 	    mz(lc);  sprintf(z[lc++], "    (((int)(%s_c[%hhi])) << 8) +",
2905 			     lname, sinfo->chanpoint + 1);
2906 	    mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 16));",
2907 			     lname, sinfo->chanpoint);
2908 	    break;
2909 	  case 2:
2910 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -15))*(";
2911 	    mz(lc);  sprintf(z[lc++], "    ((int)(%s_c[%hhi])) + ",
2912 			     lname, sinfo->chanpoint + 1);
2913 	    mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 8));",
2914 			     lname, sinfo->chanpoint);
2915 	    break;
2916 	  case 1:
2917 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -7))*(";
2918 	    mz(lc);  sprintf(z[lc++], "    ((short)(%s_c[%hhi]))); ",
2919 			     lname, sinfo->chanpoint);
2920 	    break;
2921 	  }
2922 	}
2923       else
2924 	{
2925 	  switch (sinfo->numbytes) {
2926 	  case 3:
2927 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -23))*(";
2928 
2929 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2930 			     (int)(sinfo->framebytes/sinfo->numbytes));
2931 	    break;
2932 	  case 2:
2933 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -15))*(";
2934 
2935 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2936 			     (int)(sinfo->framebytes/sinfo->numbytes));
2937 	    break;
2938 	  case 1:
2939 	    z[lc++]= "     NT(%1$s).t[i] = ((float)pow(2, -7))*(";
2940 
2941 	    mz(lc);  sprintf(z[lc++], "     1.0F/%i.0F)*(",
2942 			     (int)(sinfo->framebytes/sinfo->numbytes));
2943 	    break;
2944 	  }
2945 
2946 	  bytecount = 0;
2947 	  while (bytecount < sinfo->framebytes)
2948 	    {
2949 	      switch (sinfo->numbytes) {
2950 	      case 3:
2951 		mz(lc);  sprintf(z[lc++], "    %c ((int)(%s_c[%hhi])) + ",
2952 				 bytecount ? '+': ' ', lname, bytecount + 2);
2953 		mz(lc);  sprintf(z[lc++], "    (((int)(%s_c[%hhi])) << 8) +",
2954 				 lname, bytecount + 1);
2955 		mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 16)",
2956 				 lname, bytecount);
2957 		break;
2958 	      case 2:
2959 		mz(lc);  sprintf(z[lc++], "    %c ((int)(%s_c[%hhi])) + ",
2960 				 bytecount ? '+': ' ', lname, bytecount + 1);
2961 		mz(lc);  sprintf(z[lc++], "    (((int)((char)(%s_c[%hhi]))) << 8)",
2962 				 lname, bytecount);
2963 		break;
2964 	      case 1:
2965 		mz(lc);  sprintf(z[lc++], "    %c ((short)(%s_c[%hhi])) ",
2966 				 bytecount ? '+': ' ', lname, bytecount);
2967 		break;
2968 	      }
2969 	      bytecount += sinfo->numbytes;
2970 	    }
2971 	  z[lc++]= "     );";
2972 	}
2973     }
2974 
2975   z[lc++]= "}";
2976 
2977   z[lc++]= " fclose(EV(sfile));";
2978   if (known)
2979     {
2980       mz(lc); sprintf(z[lc++], "NT(%s_%s).t[%i] = NT(%s_%s).t[0];",
2981 		      prefix, ident->val, size, prefix, ident->val);
2982     }
2983   else
2984     {
2985       z[lc++]= "NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
2986     }
2987 
2988   *lcptr = lc;
2989   free(lname);
2990 
2991 }
2992 
2993 /*********************************************************/
2994 /*          simplifies random if dist is a constant      */
2995 /*********************************************************/
2996 
randomconstcode(sigsym * ident,char * prefix,tnode * aptr,int * lcptr)2997 void randomconstcode(sigsym * ident, char * prefix,
2998 		     tnode * aptr, int * lcptr)
2999 
3000 {
3001   int lc = *lcptr;
3002   tnode * distptr = aptr->next->next;
3003   tnode * p1ptr;
3004   tnode * p2ptr;
3005   int dist;
3006 
3007   dist = make_int(distptr->down);
3008 
3009   if ((dist < 1) || (dist > 5))
3010     {
3011       printf("Error: Illegal random wavetable distribution %i.\n", dist);
3012       showerrorplace(aptr->down->linenum, aptr->down->filename);
3013     }
3014 
3015   p1ptr = distptr->next->next;
3016   p2ptr = p1ptr->next ? p1ptr->next->next : NULL;
3017 
3018   if ((p2ptr == NULL) && ((dist == 1) || (dist == 2)|| (dist == 4)))
3019     {
3020       printf("Error: Random wavetable distribution %i needs p2.\n", dist);
3021       showerrorplace(aptr->down->linenum, aptr->down->filename);
3022     }
3023 
3024   switch (dist) {
3025   case 1:
3026     z[lc++] = "  %2$s_c1 = %2$s_p2 - %2$s_p1;";
3027     break;
3028   case 2:
3029     z[lc++] = "  %2$s_c1 = %2$s_p2 - %2$s_p1;";
3030     z[lc++] = "if (%2$s_p2 == %2$s_p1)";
3031     genex(&lc, ident->defnode->down, "p1 == p2 (dist 2)");
3032     break;
3033   case 3:
3034     break;
3035   case 4:
3036     z[lc++] = "  if (%2$s_p2 <= 0.0F)";
3037     genex(&lc, ident->defnode->down, "p2 <= 0 (dist 4)");
3038     z[lc++] = "  %2$s_c1 = (float)sqrt(2*%2$s_p2);";
3039     break;
3040   case 5:
3041     z[lc++] = "j = 0;";
3042     break;
3043   }
3044 
3045   z[lc++] = "i = 0;";
3046   z[lc++] = "while (i < %2$s_size)";
3047   z[lc++] = " {";
3048 
3049   switch (dist) {
3050   case 1:
3051     z[lc++] = "     NT(%1$s).t[i] = %2$s_c1*RMULT*((float)rand()) + %2$s_p1;";
3052     break;
3053   case 2:
3054     z[lc++] = "     %2$s_x = RMULT*((float)rand());";
3055     z[lc++] = "     %2$s_y = RMULT*((float)rand());";
3056     z[lc++] = "     if (%2$s_x > %2$s_y)";
3057     z[lc++] = "       NT(%1$s).t[i] =  %2$s_c1*%2$s_x + %2$s_p1;";
3058     z[lc++] = "     else";
3059     z[lc++] = "       NT(%1$s).t[i] =  %2$s_c1*%2$s_y + %2$s_p1;";
3060     break;
3061   case 3:
3062     z[lc++] = "     NT(%1$s).t[i] = -%2$s_p1*(float)log(RMULT*((float)rand())+1e-45F);";
3063     break;
3064   case 4:
3065     z[lc++] = "     NT(%1$s).t[i] = %2$s_p1+%2$s_c1*";
3066     z[lc++] = "             (float)sqrt(-2.0F*(float)log(RMULT*((float)rand())+1e-45F))";
3067     z[lc++] = "               *(float)cos(6.283185F*RMULT*((float)rand()));";
3068     break;
3069   case 5:
3070     z[lc++] = "     NT(%1$s).t[i] = 0;";
3071     z[lc++] = "     if (j == 0)";
3072     z[lc++] = "      {";
3073     z[lc++] = "        j = ROUND(-%2$s_p1*(float)log(RMULT*((float)rand())+1e-45F))+1;";
3074     z[lc++] = "        if (i != 0)";
3075     z[lc++] = "         NT(%1$s).t[i] = 1.0F;";
3076     z[lc++] = "      }";
3077     z[lc++] = "      j--;";
3078     break;
3079   }
3080   z[lc++] = "  i++;";
3081   z[lc++] = " }";
3082   z[lc++] = "  NT(%1$s).t[NT(%1$s).len] = NT(%1$s).t[0];";
3083 
3084   *lcptr = lc;
3085 
3086 }
3087