1 /* a samson box emulator */
2 
3 /* I assume what people really want is a good rendition from their ancient SAM files,
4  *   not an exact replica of the Samson box output.  The latter used 12, 14, 20, 24, 28, and 30-bit
5  *   fractional and integer fields, which are a pain to deal with when we would rather use doubles.
6  *
7  *        gcc sam.c -o sam -lm -O2
8  *        sam TEST.SAM
9  *        -> TEST.wav ("wav" or "riff" header, quad, little-endian float data at box srate)
10  *
11  * to include a read-data file, convert the old SAD file to a raw file of little-endian floats,
12  *   then sam TEST.SAM test.snd
13  *
14  * here's the Snd code I use to turn quad into stereo and scale the result to .9:
15  *
16 
17 (define* (quad->stereo (snd 0))
18   "turn a quad sound into a (new) stereo sound by mixing 4->1 and 3->2"
19   (let ((r0 (make-sampler 0 snd 0))
20 	(r1 (make-sampler 0 snd 1))
21 	(r2 (make-sampler 0 snd 2))
22 	(r3 (make-sampler 0 snd 3)))
23     (let ((new-snd (new-sound :channels 2
24 			      :srate (srate snd)
25 			      :size (frames snd)
26 			      :header-type (header-type snd)
27 			      :sample-type (sample-type snd))))
28       (map-channel (lambda (y)
29                      (+ (next-sample r0) (next-sample r3)))
30                    0 (frames snd) new-snd 0)
31       (map-channel (lambda (y)
32                      (+ (next-sample r1) (next-sample r2)))
33                    0 (frames snd) new-snd 1)
34       (let* ((mx (apply max (maxamp new-snd #t)))
35 	     (scl (/ 0.9 mx)))
36 	(map-channel (lambda (y) (* y scl)) 0 (frames snd) new-snd 0)
37 	(map-channel (lambda (y) (* y scl)) 0 (frames snd) new-snd 1)))))
38  *
39  *
40  * Thanks to Michael McNabb for bug fixes and enhancements!
41  * And thanks to Peter Samson for going back to the schematics to answer our questions!
42  */
43 
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdbool.h>
48 #include <math.h>
49 
50 
51 #define TOTAL_SAMPLES -1
52 /* set TOTAL_SAMPLES to the number of samples you want computed, or -1 to compute all of them */
53 
54 #define DEFAULT_DESCRIBE_COMMANDS false
55 #define REPORT_BAD_COMMANDS true
56 #define FLUSH_BAD_COMMANDS false
57 #define FLUSH_TRAILING_LINGERS false
58 
59 static bool describe_commands = DEFAULT_DESCRIBE_COMMANDS;
60 static int start_describing = -1, stop_describing = -1;
61 static int dump_patch_at = -1;
62 
63 
64 #define LDB(Cmd, Size, Position) ((Cmd >> Position) & ((1 << Size) - 1))
65 #define BIT(Cmd, Position) ((Cmd >> Position) & 1)
66 
67 #define TWOS_12(N) ((N < (1 << 11)) ? N : ((N & 0x7ff) - (1 << 11)))
68 #define TWOS_20(N) ((N < (1 << 19)) ? N : ((N & 0x7ffff) - (1 << 19)))
69 #define TWOS_24(N) ((N < (1 << 23)) ? N : ((N & 0x7fffff) - (1 << 23)))
70 #define TWOS_28(N) ((N < (1 << 27)) ? N : ((N & 0x7ffffff) - (1 << 27)))
71 #define TWOS_30(N) ((N < (1 << 29)) ? N : ((N & 0x1fffffff) - (1 << 29)))
72 
73 #define TWOS_12_TO_DOUBLE(N) ((double)TWOS_12(N) / (double)(1 << 11))
74 #define TWOS_20_TO_DOUBLE(N) ((double)TWOS_20(N) / (double)(1 << 19))
75 
76 #define DOUBLE_12(N) ((double)N / (double)(1 << 11))
77 #define DOUBLE_20(N) ((double)N / (double)(1 << 19))
78 #define DOUBLE_24(N) ((double)N / (double)(1 << 23))
79 #define DOUBLE_28(N) ((double)N / (double)(1 << 27))
80 #define DOUBLE_30(N) ((double)N / (double)(1 << 29))
81 
82 /* mmm -- slightly more accurate to use 1<<12-1, I think */
83 #define UNSIGNED_12_TO_DOUBLE(N) ((double)N / (double)((1 << 12) - 1))
84 #define DOUBLE_TO_TWOS_20(X) ((X >= 0.0) ? (int)(X * (1 << 19)) : (int)((X + 1.0) * (1 << 19)))
85 
86 
87 #if (!defined(M_PI))
88   #define M_PI 3.14159265358979323846264338327
89   #define M_PI_2 (M_PI / 2.0)
90 #endif
91 
92 
93 typedef struct {
94   int GO, GJ, GK, GN, GM, GP, GQ, GL, GSUM, GFM, GS, GMODE;
95   double f_GO, f_GJ, f_GK, f_GM, f_GP, f_GQ, f_GL;
96 } generator;
97 
98 typedef struct {
99   int M0, M1, L0, L1, MIN, MRM, MSUM, MMODE, MMMMM, T, mult_scl_1, mult_scl_0, o_M0, o_M1;
100   double f_M0, f_M1, f_L0, f_L1, o_f_M0, o_f_M1;
101   /* by "2nd multiplication" I think Pete means M0 since it follows M1 so AA -> M0 and BB -> M1 */
102 } modifier;
103 
104 typedef struct {
105   int P, Z, Y, X, I; /* "I" = table lookup index received from modifier */
106   double xd1, xd2; /* mmm - accounts for "extra" hidden delay */
107 } delay;
108 
109 #define SUM_MEMORY_SIZE 64
110 static double gen_outs[SUM_MEMORY_SIZE], gen_ins[SUM_MEMORY_SIZE], mod_outs[SUM_MEMORY_SIZE], mod_ins[SUM_MEMORY_SIZE]; /* "sum memory" */
111 static double prev_gen_ins[SUM_MEMORY_SIZE], prev_mod_ins[SUM_MEMORY_SIZE]; /* some debugging info */
112 static double peak_gen_ins[SUM_MEMORY_SIZE], peak_mod_ins[SUM_MEMORY_SIZE];
113 
114 #define GENERATORS 256
115 #define MODIFIERS 128
116 #define DELAYS 32
117 
118 static generator *gens[GENERATORS];
119 static modifier *mods[MODIFIERS];
120 static delay *dlys[DELAYS];
121 
122 #define DELAY_MEMORY_SIZE 65536
123 static double delay_memory[DELAY_MEMORY_SIZE];
124 static float dac_out[4], dac_out_peak[4];
125 
126 static int tick, pass, DX, processing_ticks, highest_tick_per_pass, samples = 0, srate = 1, total_commands = 0, current_command = 0;
127 
128 FILE *snd_file = NULL;                /* for now just riff/wave quad, but srate depends on tick setting */
129 FILE *read_data_file = NULL;
130 static char *filename = NULL;         /* mmm - Keep SAM filename around */
131 static char *output_filename = NULL;  /* mmm - And generate matching output file name == <sam name>.wav */
132 
start_clean(void)133 static void start_clean(void)
134 {
135   int i;
136   for (i = 0; i < SUM_MEMORY_SIZE; i++)
137     {
138       gen_outs[i] = 0.0; /* "outs" are this pass */
139       gen_ins[i] = 0.0;  /* "ins" are last pass */
140       mod_outs[i] = 0.0;
141       mod_ins[i] = 0.0;
142 
143       prev_mod_ins[i] = 0.0;
144       prev_gen_ins[i] = 0.0;
145       peak_mod_ins[i] = 0.0;
146       peak_gen_ins[i] = 0.0;
147     }
148 
149   for (i = 0; i < GENERATORS; i++)
150     gens[i] = (generator *)calloc(1, sizeof(generator));
151 
152   for (i = 0; i < MODIFIERS; i++)
153     {
154       mods[i] = (modifier *)calloc(1, sizeof(modifier));
155       mods[i]->mult_scl_1 = 1;
156       mods[i]->mult_scl_0 = 1;
157     }
158 
159   for (i = 0; i < DELAYS; i++)
160     dlys[i] = (delay *)calloc(1, sizeof(delay));
161 
162   for (i = 0; i < DELAY_MEMORY_SIZE; i++)
163     delay_memory[i] = 0.0;
164 
165   for (i = 0; i < 4; i++)
166     {
167       dac_out[i] = 0.0;
168       dac_out_peak[i] = 0.0;
169     }
170 
171   tick = 0;
172   pass = 0;
173 }
174 
175 
all_done(void)176 static void all_done(void)
177 {
178   if (snd_file)
179     {
180       int header_info[1];
181       fclose(snd_file);
182       snd_file = fopen(output_filename, "r+"); /* mmm */
183       fseek(snd_file, 4L, SEEK_SET);
184       header_info[0] = 88 + samples * 4 * 4;  /* total data bytes  4 chans, 4 bytes/float */
185       fwrite((void *)header_info, 4, 1, snd_file);
186       fseek(snd_file, 76L, SEEK_SET);
187       header_info[0] = samples * 4 * 4;
188       fwrite((void *)header_info, 4, 1, snd_file);
189       fclose(snd_file);
190 
191       fprintf(stderr, "%s: %dHz, %d samples, %.4f secs", output_filename, srate, samples, (double)samples / (double)srate); /* mmm */
192       fprintf(stderr, ", maxamps: %.3f %.3f %.3f %.3f\n", dac_out_peak[0], dac_out_peak[1], dac_out_peak[2], dac_out_peak[3]);
193     }
194   exit(0);
195 }
196 
197 
dac_write(double data,int chan)198 static void dac_write(double data, int chan)
199 {
200   /* during a given pass we accumulate output to the dac */
201   dac_out[chan] += (float)(data / 2.0);
202   /* mmm - /2 seems best now that other scalings have been adjusted */
203 }
204 
205 
206 /* ---------------------------------------- generator processing ---------------------------------------- */
207 
208 /*
209  * DAJ - Here is JOS's translation into english of the generator processing.
210  *
211  * Associated with each generator are the following quantities:
212  * FrqSwp20  (20 bits) alpha -- oscillator frequency sweep rate
213  * OscFrq28  (28 bits) omega -- oscillator frequency
214  * OscAng20  (20 bits) theta -- oscillator angle
215  * NumCos11  (11 bits) number of cosines to be summed
216  * CosScl4   (4 bits) binary scale of cosine or sum of cosines
217  * AmpSwp20  (20 bits) delta -- decay rate
218  * CurAmp24  (24 bits) phi -- decay exponent
219  * AmpOff12  (12 bits) asymptote
220  * OutSum6   (6 bits) sum memory address into which output is added
221  * FmSum7    (7 bits) sum memory address from which frequency modulation data is taken
222  *	    FmSum7 = QAAAAAA
223  *	    Q: 0  generator-last-pass quadrant
224  *	       1  modifier-last-pass quadrant
225  *	     AAAAAA:  sum address within quadrant
226  * Gmode10   (10 bits) generator mode
227  *	     Gmode10 = RRRREESSSS
228  *
229  * Processing
230  * ----------
231  *
232  *	Calculations performed for a generator, governed by its
233  * mode, proceed as detailed below.
234  *
235  * 1)  The word in sum memory addressed by FmSum7 is read (20 bits);
236  * 	the sum is formed of it and the high-order 20 bits of
237  * 	OscFrq28 (call the result FmPhase20).
238  *
239  * 2)  If the oscillator side is running, FrqSwp20, right-adjusted with
240  * 	sign extended, is added into OscFrq28.
241  *
242  * 3)  If the oscillator mode is SIN(J+Fm), FmPhase20 is taken; otherwise OscAng20.
243  * 	Call the 20-bit result Phase20, and its high-order 13 bits
244  * 	Phase13.
245  *
246  * 4)  If the oscillator side is running, FmPhase20 is added into OscAng20.
247  *
248  * 5)  If the run mode is WRITEDATA, the word in sum memory addressed by FmSum7
249  * 	is sent to the CPU as the next write-data item; if the run
250  * 	mode is DACOUT it is sent to the DAC addressed by the low-order
251  * 	4 bits of FrqSwp20.
252  *
253  * 6)  In oscillator modes other than SIN(K) and SIN(J+Fm), Phase13 is multiplied
254  * 	by NumCos11.  Call the low-order 12 bits of the product, with two bits
255  * 	equal to 01 appended to the right, the 14-bit result SinAdr.
256  * 	In oscillator modes SIN(K) and SIN(J+Fm), SinAdr is the high-order 13
257  * 	bits of Phase20, with a bit equal to 1 appended to the right.
258  *
259  * 7)  If the oscillator mode is SIN(K) or SIN(J+Fm), pi/2 is taken (the binary
260  * 	number 010...0); otherwise Phase13.  Call the result CscAdr.
261  *
262  * 8)  In floating point, the product csc (CscAdr) * sin (SinAdr) is
263  * 	formed; then converted to fixed point with a scale factor
264  * 	of 2**(-CosScl4).  Call the result (13 bits) TblOut13.
265  *
266  *
267  * 9)  The result of the oscillator side (13 bits, call it OscOut13) is
268  * 	then determined according to the oscillator mode.
269  * 	SSSS: SUMCOS 	TblOut13
270  * 	      SAWTOOTH 	Phase13 (but 0 when Phase13 is 1000000000000)
271  * 	      SQUARE 	-1/2 (on a scale from -1 to +1) if Phase13 is negative,
272  * 		   	  else +1/2
273  * 	      PULSE 	+1/2 if overflow occurred in step 1) or 4) above;
274  * 		     	  else 0.
275  * 	      SIN(K) 	TblOut13
276  * 	      SIN(J+Fm) TblOut13
277  *
278  * 10)  The high-order 12 bits of CurAmp24 are taken (call the result CurAmp12).
279  *
280  * 11)  If the envelope side is running, AmpSwp20 right-adjusted, sign
281  * 	extended, is added into CurAmp24 (overflow dealt with according
282  * 	to the run mode).  (The overflow condition is CurAmp24 changing
283  * 	sign such that the high-order bit of the resultant CurAmp24 equals
284  * 	the sign bit of AmpSwp20.)
285  *
286  * 12)  If the envelope mode is 10 or 11, 2**(-CurAmp12) is looked up;
287  * 	otherwise CurAmp12 is taken.  Call the resulting 12 bits NewAmp12.
288  * 	Scaling is such that if CurAmp12 is 0 then 2**(-CurAmp12) is
289  * 	111 111 111 101 binary; if CurAmp12 is 000 100 000 000 binary,
290  * 	then 2**(-CurAmp12) is 011 111 111 110.
291  *
292  * 13)  If the envelope mode is 01 or 11, NewAmp12 is added to AmpOff12; else
293  * 	it is subtracted from AmpOff12.  This creates Env12, the result
294  * 	of the envelope side.
295  *
296  * 14)  OscOut13 is multiplied by Env12.  If the run mode specifies adding
297  * 	into sum memory, the high-order 19 bits of the rounded product,
298  * 	right-adjusted with sign extended, are added into the sum
299  * 	memory location designated by OutSum6; except that in run mode
300  * 	READDATA, the product is added to the next read-data item from the
301  * 	CPU and the sum replaces the contents of the sum memory
302  * 	location addressed.
303  */
304 
305 #define osc_mode(gmode) (gmode & 0xf)
306 
307 /*
308 SSSS: 0100  sum of cosines
309       0001  sawtooth
310       0010  square
311       0011  pulse train
312       0000  sin (K)
313       1000  sin (J + fm)
314 */
315 
316 #define SUMCOS 4
317 #define SAWTOOTH 1
318 #define SQUARE 2
319 #define PULSE 3
320 #define SIN_K 0
321 #define SIN_FM 8
322 
323 
324 #define osc_env(gmode) ((gmode >> 4) & 0x3)
325 
326 /*
327 EE: 00  L - Q
328     01  L + Q
329     10  L - 2**(-Q)
330     11  L + 2**(-Q)
331 */
332 
333 #define L_PLUS_Q 1
334 #define L_MINUS_Q 0
335 #define L_MINUS_2_TO_MINUS_Q 2
336 #define L_PLUS_2_TO_MINUS_Q 3
337 
338 
339 #define osc_run(gmode) ((gmode >> 6) & 0xf)
340 
set_osc_run(int gen,int RRRR)341 static void set_osc_run(int gen, int RRRR)
342 {
343   generator *g;
344   if (gen >= GENERATORS) {fprintf(stderr, "gen mode set overflow\n"); gen = 0;}
345   g = gens[gen];
346   /* RRRREESSSS */
347   g->GMODE = (g->GMODE & 0x3f) | (RRRR << 6);
348 
349   if (g->GMODE == 3) g->GMODE = 2; /* if write data, send it to the DAC outputs instead */
350 }
351 
352 /*				 osc. run?  env. run?  add to sum?
353   RRRR:0000 inactive		    no	       no	   no
354      0001 pause			    no	       no	   no
355      1111 running A		    yes	    yes, sticky	   yes
356      1110 running B		    yes	    yes, free;	   yes
357 					  triggers subseq.
358 					    on overflow
359      1001 wait			    yes	       no	   no
360      1101 running C		    yes	    yes, free;	   yes
361 					    stops and
362 					  triggers subseq.
363 					    on overflow
364      0111 read data from computer   no	       yes	   yes
365      0011 write data to computer    no	       no	   no
366      0010 write data to DAC	    no	       no	   no
367 	   (address in GO)
368 */
369 
370 
osc_is_running(int mode)371 static bool osc_is_running(int mode)
372 {
373   int RRRR;
374   RRRR = osc_run(mode);
375   return((RRRR == 15) || (RRRR == 14) || (RRRR == 9) || (RRRR == 13));
376 }
377 
378 
env_is_running(int mode)379 static bool env_is_running(int mode)
380 {
381   int RRRR;
382   RRRR = osc_run(mode);
383   return((RRRR == 15) || (RRRR == 14) || (RRRR == 7) || (RRRR == 13));
384 }
385 
386 
adding_to_sum(int mode)387 static bool adding_to_sum(int mode)
388 {
389   int RRRR;
390   RRRR = osc_run(mode);
391   return((RRRR == 15) || (RRRR == 14) || (RRRR == 7) || (RRRR == 13));
392 }
393 
394 
gen_is_active(generator * g)395 static bool gen_is_active(generator *g)
396 {
397   return((osc_is_running(g->GMODE)) && (g->GQ != 0) && (g->GJ != 0));
398 }
399 
400 
gen_amp(generator * g)401 static double gen_amp(generator *g)
402 {
403   int emode;
404   double Q;
405 
406   if (osc_run(g->GMODE) == 0) return(0.0);
407 
408   emode = osc_env(g->GMODE);
409   if ((emode == L_PLUS_2_TO_MINUS_Q) ||
410       (emode == L_MINUS_2_TO_MINUS_Q))
411     Q = pow(2.0, -16.0 * g->f_GQ);
412   else Q = g->f_GQ;
413 
414   if ((emode == L_PLUS_Q) ||
415       (emode == L_PLUS_2_TO_MINUS_Q))
416     return(g->f_GL + Q);
417   return(g->f_GL - Q);
418 }
419 
420 
421 static bool read_data_warned = false;
422 
process_gen(int gen)423 static void process_gen(int gen)
424 {
425   #define FmSum7    g->GFM
426   #define OutSum6   g->GSUM
427   #define FrqSwp20  g->f_GO
428   #define OscFreq28 g->f_GJ
429   #define OscAng20  g->f_GK
430   #define NumCos11  g->GN
431   #define AmpSwp20  g->f_GP
432   #define AmpOff12  g->f_GL
433   #define Gmode10   g->GMODE
434   #define CurAmp24  g->f_GQ
435   #define CosScl4   g->GM
436   #define ShiftOut  g->GS
437 
438   generator *g;
439   double fm, FmPhase20, Phase20, SinAdr, CscAdr, TblOut13, OscOut13, CurAmp12, NewAmp12, Env12, temp;
440 
441   g = gens[gen];
442   if (osc_run(g->GMODE) == 0) /* inactive */
443     return;
444 
445   if (osc_run(Gmode10) == 3)
446     {
447       /* mmm - just ignore write-data generators since everything is being written out anyway */
448       return;
449     }
450 
451   if ((FmSum7 >> 6) == 0)
452     fm = gen_ins[FmSum7 & 0x3f];
453   else fm = mod_ins[FmSum7 & 0x3f];
454   /* fm *= 0.5; */
455 
456   FmPhase20 = fm + OscFreq28;
457 
458   if (osc_is_running(Gmode10))
459     OscFreq28 += (FrqSwp20 / 256.0);     /* right adjusted 20 bit */
460 
461   if (osc_mode(Gmode10) == SIN_FM) /* sin(J+fm) */
462     Phase20 = FmPhase20;
463   else Phase20 = OscAng20;
464 
465   if (osc_is_running(Gmode10))
466     OscAng20 += FmPhase20;
467 
468   /* mmm - dac write goes here and does not stop the processing (probably makes no diff) */
469   if (osc_run(Gmode10) == 2)
470     {
471       dac_write(fm, g->GO & 0xf); /* in this case, we need the integer value of GO */
472       return;
473     }
474 
475   /* probably should be osc_mode(Gmode10) == SUMCOS */
476   if ((osc_mode(Gmode10) != SIN_K) &&
477       (osc_mode(Gmode10) != SIN_FM))
478     {
479       SinAdr = (Phase20 * NumCos11);           /* was & 0xfff) << 2) + 1 */
480       CscAdr = Phase20;
481       if (fmod(CscAdr, 1.0) != 0.0)
482 	temp = sin(M_PI * SinAdr) / sin(M_PI * CscAdr);       /* was (1 << 13)) */
483       else temp = (double)NumCos11;
484     }
485   else
486     {
487       SinAdr = Phase20;                        /* was >> 6) | 1 */
488       temp = sin(M_PI * SinAdr);
489     }
490 
491   TblOut13 = temp / (double)(1 << CosScl4);
492 
493   switch (osc_mode(Gmode10))
494     {
495     case SUMCOS: case SIN_K: case SIN_FM:
496       OscOut13 = TblOut13;
497       break;
498 
499     case SAWTOOTH:
500       OscOut13 = fmod(Phase20, 2.0) - 1.0;
501       break;
502 
503     case SQUARE:
504       if (fmod(Phase20, 2.0) < 1.0)
505 	OscOut13 = -0.5;
506       else OscOut13 = 0.5;
507       break;
508 
509     case PULSE:
510       /* pulse mode was primarily used for triggered noise */
511       if ((OscAng20 >= 2.0) || (OscAng20 < -2.0))
512 	{
513 	  OscAng20 = fmod(OscAng20, 2.0);
514 	  OscOut13 = 0.5;
515 	}
516       else OscOut13 = 0.0;
517       break;
518     }
519 
520   CurAmp12 = CurAmp24;
521 
522   if (env_is_running(Gmode10))
523     {
524       double old_amp;
525       old_amp = CurAmp24;
526       CurAmp24 += (AmpSwp20 / 32.0); /* was 16.0 */  /* mmm - don't know why 32 but it seems to be more accurate than 16 */
527       /*
528 	The envelope side of the generator can be sticky, which means
529 	that rather than overflow it will stay at the last value it attained
530 	before it would have overflowed; or it can be free, in which case it
531 	wraps around.
532 
533 	Transitions between run modes can be accomplished in various ways.
534 	1)  A command can output a new GMODE.
535 	2)  A MISC command can specify "clear all pause bits", which
536 		will cause any generator in run mode 0001 to change to
537 		mode 1111.
538 	3)  A MISC command can specify "clear all wait bits", which
539 		will cause any generator in run mode 1001 to change to
540 		mode 1111.
541 	4)  If the envelope side of a generator in run mode 1101
542 		overflows, that generator goes to run mode 1001.
543 	5)  A generator in run mode 1001 will go to run mode 1101 if
544 		on the same pass the preceding generator (the one
545 		whose generator number is one less) caused a
546 		trigger (was in run mode 1110 or 1101 and envelope
547 		overflowed).
548       */
549       if ((CurAmp24 > 1.0) || (CurAmp24 < 0.0))  /*  if ((BIT(CurAmp24, 23) != BIT(old_amp, 23)) && (BIT(CurAmp24, 22) == BIT(AmpSwp20, 19))) */
550 	{
551 	  /* overflow */
552 	  if (osc_run(Gmode10) == 15)              /* "running A" */
553 	    CurAmp24 = old_amp;
554 	  else
555 	    {
556 	      if (osc_run(Gmode10) == 13)          /* "running C" */
557 		{
558 		  set_osc_run(gen, 9);
559 		  if (osc_run(gens[gen + 1]->GMODE) == 9)
560 		    set_osc_run(gen + 1, 13);
561 		}
562 	      else
563 		{
564 		  if ((osc_run(Gmode10) == 14) &&  /* "running B" */
565 		      (osc_run(gens[gen + 1]->GMODE) == 9))
566 		    set_osc_run(gen + 1, 13);
567 		}
568 	    }
569 	}
570     }
571 
572   if ((osc_env(Gmode10) == L_PLUS_2_TO_MINUS_Q) ||
573       (osc_env(Gmode10) == L_MINUS_2_TO_MINUS_Q))
574     NewAmp12 = pow(2.0, -16.0 * CurAmp12);
575   else NewAmp12 = CurAmp12; /* was / 4 */  /* mmm - no scaling called for here */
576 
577   /* I think this matches the spec:
578    *    if temp6 is 0, then 2^(-temp6) is 1, the specs say #b111111111101,
579    *       which assuming 12 bit unsigned fractions is 4093/4096,
580    *   if temp6 is #b000100000000 (256), 2^(-temp6) is #b011111111110,
581    *       which is .5 (fractional) so we really want 2^(-16*temp6) = 2^-1
582    */
583 
584   /* in the notes: "The scaling involved is a left shift of temp6 by 4 bits".
585    *    This scaling matters in FM since it is a multiplier on the index, and in pluck.
586    */
587 
588   if ((osc_env(Gmode10) == L_PLUS_Q) ||
589       (osc_env(Gmode10) == L_PLUS_2_TO_MINUS_Q))
590     Env12 = AmpOff12 + NewAmp12;
591   else Env12 = AmpOff12 - NewAmp12;
592 
593   OscOut13 *= Env12;
594   if (adding_to_sum(Gmode10))
595     {
596       if (osc_run(Gmode10) != 7)
597 	{
598 	  /* "If GS is 0, the high-order 19 bits
599 	     of the rounded product are taken, right-adjusted with sign
600 	     extended; if GS is 1, the high-order 20 bits of the rounded
601 	     product are taken."
602 	  */
603 	  if (g->GS == 0)
604 	    gen_outs[OutSum6] += OscOut13 / 2.0;   /* mmm - right-shifted high order 19 bits so divide by 2 */
605 	  else gen_outs[OutSum6] += OscOut13;      /* mmm - no shift, so leave value alone */
606 	}
607       else
608 	{
609 	  /* read-data: assume we're reading floats from a raw file */
610 	  if (read_data_file)
611 	    {
612 	      float read_data_value;
613 	      fread((void *)(&read_data_value), 4, 1, read_data_file);
614 	      gen_outs[OutSum6] = OscOut13 + read_data_value;  /* was * 2 */
615 	      /*
616 		 "If the run mode
617 		 specifies adding into sum memory, Temp9 is added into the sum
618 		 memory location designated by GSUM; except that in run mode
619 		 0111, the product is added to the next read-data item from the
620 		 CPU and the sum replaces the contents of the sum memory
621 		 location addressed."
622 	      */
623 	    }
624 	  else
625 	    {
626 	      if (!read_data_warned)
627 		{
628 		  fprintf(stderr, "read data?!?\n");
629 		  read_data_warned = true;
630 		}
631 	    }
632 	}
633     }
634 }
635 
636 
637 /* ---------------------------------------- modifier processing ---------------------------------------- */
638 
639 /*
640  * 	Each modifier has the following numeric parameters.
641  * M0  (30 bits) coefficient
642  * M1  (30 bits) other coefficient
643  * L0  (20 bits) running term
644  * L1  (20 bits) other running term
645  * MIN  (8 bits) address in sum memory where modifier reads "A" data
646  * MRM  (8 bits) address in sum memory where modifier reads "B" data
647  * 	MIN, MRM = QQAAAAAA
648  *     QQ:
649  *      00  generator-last-pass quadrant
650  * 	01  modifier-last-pass quadrant
651  * 	10  modifier-this-pass quadrant
652  * 	11  (reserved)
653  *     AAAAAA: sum address within quadrant
654  * MSUM  (7 bits) result address in sum memory
655  * 	MSUM = RAAAAAA
656  *     R: 0  add to sum
657  *        1  replace sum
658  *     AAAAAA: sum address in modifier-this-pass quadrant
659  */
660 
print_mod_read_name(int m)661 static void print_mod_read_name(int m)
662 {
663   char *mem_names[4] = {"gen-ins", "mod-ins", "mod-outs", "oops"};
664   fprintf(stderr, "%s[", mem_names[(m >> 6) & 0x3]);
665   if (((m & 0x3f) == 0) && (((m >> 6) & 0x3) != 0))
666     fprintf(stderr, "zero");
667   else fprintf(stderr, "%d", m & 0x3f);
668   fprintf(stderr, "]");
669 }
670 
671 
mod_read(int addr)672 static double mod_read(int addr)
673 {
674   int QQ, A;
675   A = addr & 0x3f;
676   QQ = LDB(addr, 2, 6);
677   switch (QQ)
678     {
679     case 0: return(gen_ins[A]);
680     case 1: return(mod_ins[A]);
681     case 2: return(mod_outs[A]);
682 
683     case 3:
684       /* "reserved", but it seems to happen in MARS.SAM, and Pete says:
685        *
686        * "Thanks to Al Kossow of the Computer History Museum for putting scans
687        *  of the (preliminary) synthesizer schematics and the theory-of-
688        *  operation manual up on bitsavers.org.
689        *
690        *  It appears that QQ=3 will work the same as QQ=1, i.e. modifier last
691        *  pass quadrant."
692        */
693       return(mod_ins[A]);
694     }
695 
696   return(0);
697 }
698 
699 
mod_write(int addr,double val)700 static void mod_write(int addr, double val)
701 {
702   int R, AAAAAA;
703 
704   if (isnan(val))
705     {
706       fprintf(stderr, "write %d %d NaN!\n", addr >> 6, addr & 0x3f);
707     }
708   AAAAAA = addr & 0x3f;
709   R = BIT(addr, 6);
710   if (R == 0)
711     mod_outs[AAAAAA] += val;
712   else mod_outs[AAAAAA] = val;
713 }
714 
715 /*
716  * MMODE  (9 bits) modifier mode
717  * 	MMODE = MMMMMAABB
718  * AA:  scale of second multiplication
719  * BB:  scale of first multiplication
720  * For fraction multiplications:
721  *   00:  x 1
722  *   01:  x 2
723  *   10:  x 4
724  *   11:  x 8
725  * For integer multiplications:
726  *   00:  x 1/4
727  *   01:  x 1/2
728  *   10:  x 1
729  *   11:  x 2
730  *  A multiplication involving parameter M1 will be the first
731  *   multiplication; one involving M0 will be the second.
732  *
733  * MMMMM: function
734  *   00000:  inactive
735  *   00010:  uniform noise
736  *   00011:  triggered uniform noise
737  *   00100:  latch
738  *   00110:  threshold
739  *   00111:  invoke delay unit
740  *
741  *   01000:  two poles
742  *   01001:  two poles, M0 variable
743  *   01011:  two poles, M1 variable
744  *   01100:  two zeros
745  *   01101:  two zeros, M0 variable
746  *   01111:  two zeros, M1 variable
747  *
748  *   10000:  integer mixing
749  *   10001:  one pole
750  *   10100:  mixing
751  *   10110:  one zero
752  *
753  *   11000:  four-quadrant multiplication
754  *   11001:  amplitude modulation
755  *   11010:  maximum
756  *   11011:  minimum
757  *   11100:  signum
758  *   11101:  zero-crossing pulser
759  *
760  *   others:  (reserved)
761  */
762 
763 #define mod_mode(M) ((M >> 4) & 0x1f)
764 #define M_INACTIVE 0
765 #define M_NOISE 2
766 #define M_TRIGGERED_NOISE 3
767 #define M_LATCH 4
768 #define M_THRESHOLD 6
769 #define M_DELAY 7
770 #define M_TWO_POLE 8
771 #define M_TWO_POLE_M0 9
772 #define M_TWO_POLE_M1 11
773 #define M_TWO_ZERO 12
774 #define M_TWO_ZERO_M0 13
775 #define M_TWO_ZERO_M1 15
776 #define M_INTEGER_MIXING 16
777 #define M_ONE_POLE 17
778 #define M_MIXING 20
779 #define M_ONE_ZERO 22
780 #define M_MULTIPLY 24
781 #define M_AMP_MOD 25
782 #define M_MAX 26
783 #define M_MIN 27
784 #define M_SIGNUM 28
785 #define M_ZERO_CROSS 29
786 
787 static double delay_read(int dly);
788 static void delay_write(int dly, double val);
789 
process_mod(int mod)790 static void process_mod(int mod)
791 {
792   modifier *m;
793   int mode, IS;
794   double S, A, B, tmp0, tmp1;
795 
796   m = mods[mod];
797   mode = mod_mode(m->MMODE);
798   if (mode == M_INACTIVE)
799     {
800       /* technically, mod_write(m->MSUM, 0.0) which might be in "replace" mode if BIT(m->MSUM, 6) is not 0 */
801       return;
802     }
803 
804   A = mod_read(m->MIN);
805   B = mod_read(m->MRM);
806 
807   switch (mode)
808     {
809     case M_INACTIVE:
810       /* 00000:	inactive.  S := 0
811        */
812       break;
813 
814     case M_NOISE:
815       /* 00010:	uniform noise.  S := L0 + L1*M0 (integer multiply, low-order
816        *                        20 bits of product used; overflow ignored); L1 := S
817        *
818        * see below -- I don't think this is correct.
819        */
820       /* IS = (m->L0 + (m->L1 * m->M0)) & 0xfffff; */
821 
822       IS = (m->L0 + ((m->L1 * m->M0) >> 10)) & 0xfffff;
823       mod_write(m->MSUM, TWOS_20_TO_DOUBLE(IS));
824       m->L1 = IS;
825       break;
826 
827     case M_TRIGGERED_NOISE:
828       /* 00011:	triggered uniform noise.  S := L0 + L1*M0 (integer multiply,
829        *          low-order 20 bits of product used; overflow ignored);
830        *          if B*M1 (integer multiply, low-order 20 bits of product
831        *          used; overflow ignored) is not 0, L1 := S
832        */
833 
834       /* IS = (m->L0 + (m->L1 * m->M0)) & 0xfffff; */
835       /* I'm getting an immediate fixed-point from the SAM files that used triggered noise! */
836       /* they used the M0 seed of 359035904, (L1: 204282), which immediately cycles. */
837       /* perhaps the spec is wrong... -- I'll try taking the middle bits */
838 
839       IS = (m->L0 + ((m->L1 * m->M0) >> 10)) & 0xfffff;
840       mod_write(m->MSUM, TWOS_20_TO_DOUBLE(IS));
841       if ((B != 0.0) &&
842 	  (m->M1 != 0))
843 	m->L1 = IS;
844       break;
845 
846     case M_LATCH:
847       /* 00100:	latch (sample and hold).  S := L1;  If B*M1 is not 0, L1 := A
848        *   but in the errata:
849        *   "BIL has discovered empirically that the modifier latch mode operation should actually read
850        * 00100:	latch (sample and hold).  S := L1;  If B*M1 is not 0, L1 := A*M0"
851        */
852       mod_write(m->MSUM, m->f_L1);
853       if ((B * m->f_M1) != 0.0) m->f_L1 = A * m->f_M0;
854       break;
855 
856     case M_THRESHOLD:
857       /* 00110:	threshold.  If A*M0 + L0 is less than 0, then S := 0;
858        *                    if A*M0 + L0 is equal to or greater than 0, then S := B*M1
859        */
860       tmp0 = A * m->f_M0 + m->f_L0;
861       if (tmp0 < 0.0)
862 	mod_write(m->MSUM, 0.0);
863       else mod_write(m->MSUM, B * m->f_M1);
864       break;
865 
866     case M_DELAY:
867       /* 00111:	invoke delay unit.
868        *     Unit # := MRM (low-order 5 bits);
869        *     S := L0 + L1*M0;  L0 := DM;  Temp0 := A + DM*M1;
870        *     L1 := Temp0;  DM := Temp0
871        */
872       /* to handle table lookups, we need the integer side here */
873       /* fprintf(stderr, "d%d, m%d: %.4f = %.4f + %.4f * %.4f\n", m->MRM & 0x1f, mod, m->f_L0 + m->f_L1 * m->f_M0, m->f_L0, m->f_L1, m->f_M0); */
874 
875       mod_write(m->MSUM, m->f_L0 + m->f_L1 * m->f_M0);
876       m->f_L0 = delay_read(m->MRM & 0x1f);
877       m->f_L1 = A + m->f_L0 * m->f_M1;
878       delay_write(m->MRM & 0x1f, m->f_L1);
879       break;
880 
881     case M_TWO_POLE:
882     case M_TWO_POLE_M0:
883     case M_TWO_POLE_M1:
884       /* 01000:	two poles.               S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S
885        *
886        * 01001:	two poles, M0 variable.  S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S; M0 := M0 + B
887        *
888        * 01011:	two poles, M1 variable.  S := L1*M1 + L0*M0 + A; L0 := L1; L1 := S; M1 := M1 + B
889        */
890       tmp0 = m->f_L1 * m->f_M1;
891       tmp1 = m->f_L0 * m->f_M0;
892       S = tmp0 + tmp1 + A;  /* divide A by 1024.0 here probably */
893       mod_write(m->MSUM, S);
894       m->f_L0 = m->f_L1;
895       m->f_L1 = S;
896       if (mode == M_TWO_POLE_M0)
897 	m->f_M0 += (B / 1024.0);
898       /* "when a quantity is added to M0 or M1 it is added right-justified, with sign extended"
899        *    does that include "A" above? I think it does... (see one and two_zero below).
900        */
901       if (mode == M_TWO_POLE_M1)
902 	m->f_M1 += (B / 1024.0);
903       break;
904 
905     case M_TWO_ZERO:
906     case M_TWO_ZERO_M0:
907     case M_TWO_ZERO_M1:
908       /* 01100:	two zeros.               S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A
909        *
910        * 01101: two zeros, M0 variable.  S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A; M0 := M0 + B
911        *
912        * 01101:	two zeros, M0 variable.  S := L1*M1 + L0*M0 + A; L0 := L1; L1 := A; M1 := M1 + B
913        */
914       tmp0 = m->f_L1 * m->f_M1;
915       tmp1 = m->f_L0 * m->f_M0;
916       mod_write(m->MSUM, tmp0 + tmp1 + A); /* divide A by 1024.0 here probably */
917       m->f_L0 = m->f_L1;
918       m->f_L1 = A / 1024.0;
919       if (mode == M_TWO_ZERO_M0)
920 	m->f_M0 += (B / 1024.0);
921       if (mode == M_TWO_ZERO_M1)
922 	m->f_M1 += (B / 1024.0);
923       break;
924 
925     case M_INTEGER_MIXING:
926       /* 10000:	integer mixing.  S := A*M0 + B*M1 (integer multiply, low-order
927        * 20 bits of product used; overflow ignored)
928        */
929       /* I don't remember how we used this -- I'll assume the M's are the ints */
930       mod_write(m->MSUM, A * m->M0 + B * m->M1);
931       break;
932 
933     case M_MIXING:
934       /* 10100:	mixing.  S := A*M0 + B*M1
935        */
936       mod_write(m->MSUM, A * m->f_M0 + B * m->f_M1);
937       break;
938 
939     case M_ONE_POLE:
940       /* 10001:	one pole.  S := L1*M1 + B*M0; L1 := S
941        *
942        *    but in the errata:
943        *    "DAJ - It seems that the modifier mode one pole is really
944        * 10001:	one pole.  S := L1*M1 + B*L0; L1 := S"
945        *
946        * but I think that is incorrect; old reverbs are definitely using the spec form of the 1-pole filter
947        */
948       tmp0 = m->f_L1 * m->f_M1;
949       /* tmp1 = B * m->f_L0; */
950       tmp1 = B * m->f_M0;
951 
952       m->f_L1 = tmp0 + tmp1;
953       mod_write(m->MSUM, m->f_L1);
954       break;
955 
956     case M_ONE_ZERO:
957       /* 10110:	one zero.  S := L1*M1 + L0*M0; L0 := L1; L1 := A
958        */
959       tmp0 = m->f_L1 * m->f_M1;
960       tmp1 = m->f_L0 * m->f_M0;
961       m->f_L0 = m->f_L1;
962       m->f_L1 = A / 1024.0;
963       mod_write(m->MSUM, tmp0 + tmp1);
964       break;
965 
966     case M_MULTIPLY:
967       /* 11000:	four-quadrant multiplication.  S := L1*M1; L1 := A*B
968        */
969       mod_write(m->MSUM, m->f_L1 * m->f_M1);
970       m->f_L1 = A * B;
971       break;
972 
973     case M_AMP_MOD:
974       /* 11001:	amplitude modulation.  S := L1*M1;  L1 := A * ((B+1)/2)
975        *        (The term ((B+1)/2) interprets B as a signed two's-complement
976        *        fraction ranging in value from -1 to +1-epsilon.)
977        */
978       mod_write(m->MSUM, m->f_L1 * m->f_M1);
979       m->f_L1 = A * (B + 1.0) * 0.5;
980       break;
981 
982     case M_MAX:
983       /* 11010:	maximum.  S := max (A*M0, B*M1)
984        */
985       tmp0 = A * m->f_M0;
986       tmp1 = B * m->f_M1;
987       mod_write(m->MSUM, (tmp0 > tmp1) ? tmp0 : tmp1);
988       break;
989 
990     case M_MIN:
991       /* 11011:	minimum.  S := min (A*M0, B*M1)
992        */
993       tmp0 = A * m->f_M0;
994       tmp1 = B * m->f_M1;
995       mod_write(m->MSUM, (tmp0 < tmp1) ? tmp0 : tmp1);
996       break;
997 
998     case M_SIGNUM:
999       /* 11100:	signum.  If A*M0 is less than B*M1, then S := -1 (integer)
1000        *                 if A*M0 equals B*M1, then S := 0;
1001        *                 if A*M0 is greater than B*M1, the S := 1 (integer)
1002        */
1003       tmp0 = A * m->f_M0;
1004       tmp1 = B * m->f_M1;
1005       if (tmp0 < tmp1) mod_write(m->MSUM, TWOS_20_TO_DOUBLE(-1));
1006       else if (tmp0 == tmp1) mod_write(m->MSUM, 0.0);
1007       else mod_write(m->MSUM, TWOS_20_TO_DOUBLE(1));
1008       break;
1009 
1010     case M_ZERO_CROSS:
1011       /* 11101:	zero-crossing pulser.  Temp0 := B*M0; Temp1 := L1*M1;
1012        *        if Temp1 is not 0 and either Temp0 is 0 or Temp0*Temp1 is
1013        *        negative then S := -epsilon, else S := 0; L1 := Temp0
1014        *        (The term -epsilon is a binary number with all bits set.)
1015        */
1016       tmp0 = B * m->f_M0;
1017       tmp1 = m->f_L1 * m->f_M0;
1018       if ((tmp1 != 0) &&
1019 	  ((tmp0 == 0) || (tmp0 * tmp1 < 0)))
1020 	mod_write(m->MSUM, TWOS_20_TO_DOUBLE(-1));
1021       m->f_L1 = tmp0;
1022       break;
1023 
1024     default:
1025       fprintf(stderr, "reserved modifier mode?\n");
1026       break;
1027     }
1028 }
1029 
1030 
1031 
1032 /* ---------------------------------------- delay processing ---------------------------------------- */
1033 
1034 /*	Each delay unit has the following numeric parameters.
1035  *
1036  * P  mode (4 bits).  The mode is interpreted as follows:
1037  * 		mode: 0000  inactive
1038  * 		      1000  delay line
1039  * 		      1010  table look-up
1040  * 		      1011  table look-up, argument rounded
1041  * 		      1100  delay tap
1042  * 		      others: (reserved)
1043  */
1044 
1045 #define D_INACTIVE 0
1046 #define D_LINE 8
1047 #define D_TABLE_LOOKUP 10
1048 #define D_TABLE_LOOKUP_ROUNDED 11
1049 #define D_TAP 12
1050 
1051 /*
1052  * Z  unit length (16 bits) or binary scale factor (4 bits).
1053  * 	In delay line and delay tap modes, Z gives 1 less than the
1054  * 	total number of locations in delay memory used by the delay
1055  * 	unit, i.e. the index of the last delay memory address for
1056  * 	this unit.  In table look-up modes, the low-order four bits
1057  * 	of Z specify the number of binary places that the argument
1058  * 	is shifted to the right before it is used to address the
1059  * 	memory; if rounding is specified, the address after shifting
1060  * 	is incremented by 1 if the most-significant bit shifted out
1061  * 	was a 1.
1062  *
1063  * Y  index (16 bits).  In delay line and delay tap modes, this is the
1064  * 	running index on the memory area for the unit.
1065  *
1066  * X  base address (16 bits).  The base address is the lowest-numbered
1067  * 	delay memory location used by this unit.
1068  *
1069  * 	In inactive mode, delay memory is not modified and the unit
1070  * returns indeterminate results.  Delay units not accommodated due
1071  * to the number of ticks in a pass act as if in the inactive mode.
1072  * If the number of processing ticks is 4*n + m where m is 1, 2, or 3,
1073  * delay unit number n should be put in the inactive mode.
1074  *
1075  * 	In delay line mode, a 20-bit data word is received from
1076  * the modifier that calls for the delay unit, and another 20-bit
1077  * word is sent to it.  The word received is put into the next slot
1078  * in the delay line.  It will be retrieved and sent back to the
1079  * modifier Z+3 passes later.  In delay tap mode, a word is sent to
1080  * the modifier but delay memory is not written into.
1081  *
1082  * 	In table look-up mode, the 20-bit data word received
1083  * from the modifier is shifted to the right Z bits, bringing in zeros,
1084  * and the right 16 bits of the result are used to address the memory
1085  * area assigned to the unit.  The 20-bit word in the addressed memory
1086  * location is returned to the modifier three passes later.
1087  */
1088 
1089 static bool table_read_warned = false, table_write_warned = false;
1090 
delay_read(int dly)1091 static double delay_read(int dly)
1092 {
1093   delay *d;
1094   d = dlys[dly];
1095   switch (d->P)
1096     {
1097     case D_INACTIVE:
1098       return(0.0);
1099 
1100     case D_LINE:
1101     case D_TAP:
1102       /* return the value with a hidden 2 sample delay (Z+3 == total delay length + 2) */
1103 #if 0
1104       return(delay_memory[d->X + d->Y]);
1105 #else
1106       {
1107 	/* I originally thought this was making a raspy or crackling sound in the reverbs, but now I don't hear it (bil) */
1108 	double val;
1109 	val = d->xd2;
1110 	d->xd2 = d->xd1;
1111 	d->xd1 = delay_memory[d->X + d->Y];
1112 	return val;
1113       }
1114 #endif
1115 
1116     case D_TABLE_LOOKUP:
1117     case D_TABLE_LOOKUP_ROUNDED:
1118       {
1119 	int Z_shift, dY;
1120 	if (!table_read_warned)
1121 	  {
1122 	    fprintf(stderr, "table lookup read is unlikely to work.\n");
1123 	    table_read_warned = true;
1124 	  }
1125 	Z_shift = d->Z & 0xf;
1126 	dY = (d->I >> Z_shift) & 0xffff;
1127 	return(delay_memory[d->X + dY]);
1128       }
1129     }
1130   return(0);
1131 }
1132 
1133 
delay_write(int dly,double val)1134 static void delay_write(int dly, double val)
1135 {
1136   delay *d;
1137   d = dlys[dly];
1138   switch (d->P)
1139     {
1140     case D_INACTIVE:
1141     case D_TAP:
1142       break;
1143 
1144     case D_LINE:
1145       delay_memory[d->X + d->Y] = val;
1146       break;
1147 
1148     case D_TABLE_LOOKUP:
1149     case D_TABLE_LOOKUP_ROUNDED:
1150 	if (!table_write_warned)
1151 	  {
1152 	    fprintf(stderr, "table lookup write is unlikely to work.\n");
1153 	    table_write_warned = true;
1154 	  }
1155       d->I = DOUBLE_TO_TWOS_20(val); /* can this work? */
1156       break;
1157     }
1158 }
1159 
1160 
process_dly(int dly)1161 static void process_dly(int dly)
1162 {
1163   delay *d;
1164   d = dlys[dly];
1165   d->Y += 1;
1166   if (d->Y > d->Z) /* unit size - 1 so not >= ? */
1167     d->Y = 0;
1168 }
1169 
1170 
1171 /* ---------------------------------------- run! ---------------------------------------- */
1172 
1173 static void dump_patch(void);
1174 
linger(int time)1175 static void linger(int time)
1176 {
1177   /* process each sample ("pass") until pass == time */
1178   /*   but linger was a 20-bit number, so it wrapped around I believe, so pass should be mod 2^20? */
1179 
1180   if (!snd_file)
1181     {
1182       fprintf(stderr, "no ticks setting found!\n");
1183       exit(0);
1184     }
1185 
1186   if (time < pass)
1187     pass = pass - (1 << 20);
1188 
1189   /* old SAM files had endless strings of lingers at the end generating enormous empty sound files, but
1190    *
1191    * mmm - this was causing the long trailing reverb of some of my files to be cut off.
1192    */
1193 
1194   if ((FLUSH_TRAILING_LINGERS) &&
1195       ((total_commands - current_command) < 100) &&
1196       (total_commands > 1000) &&
1197       ((time - pass) > (6 * srate)))
1198     {
1199       fprintf(stderr, "ignore trailing %d sample (%.3f second) linger (%d)\n",
1200 	      time - pass, (double)(time - pass) / (double)srate, total_commands - current_command);
1201       pass = time;
1202       return;
1203     }
1204 
1205   while (pass < time)
1206     {
1207       /* run through all available ticks, processing gen+mod+dly,
1208        *   then write accumulated dac_outs, clear, update memories (this-pass -> last-pass),
1209        *   and increment pass
1210        */
1211       int i, tick, gen = 0, mod = 0, dly = 0;
1212 
1213       for (tick = 0; tick < processing_ticks; tick++)
1214 	{
1215 	  /* given the timing info I'll simplify a bit and run 1 gen per tick, 1 mod every 2 ticks, and 1 delay every 4 ticks */
1216 	  if (gen < GENERATORS)
1217 	    process_gen(gen++);
1218 
1219 	  /* I'm guessing... */
1220 	  if (((tick & 1) == 0) &&
1221 	      (mod < MODIFIERS))
1222 	    process_mod(mod++);
1223 
1224 	  if (((tick & 3) == 0) &&
1225 	      (dly < DELAYS))
1226 	    process_dly(dly++);
1227 	}
1228 
1229       if (dump_patch_at == samples)
1230 	dump_patch();
1231 
1232       for (i = 0; i < SUM_MEMORY_SIZE; i++)
1233 	{
1234 	  if (fabs(gen_ins[i]) > peak_gen_ins[i])
1235 	    peak_gen_ins[i] = fabs(gen_ins[i]);
1236 	  prev_gen_ins[i] = gen_ins[i];
1237 	  gen_ins[i] = gen_outs[i];
1238 	  gen_outs[i] = 0.0;
1239 
1240 	  if (fabs(mod_ins[i]) > peak_mod_ins[i])
1241 	    peak_mod_ins[i] = fabs(mod_ins[i]);
1242 	  prev_mod_ins[i] = mod_ins[i];
1243 	  mod_ins[i] = mod_outs[i];
1244 	  mod_outs[i] = 0.0;
1245 	}
1246 
1247       fwrite(dac_out, 4, 4, snd_file);
1248       samples++;
1249       for (i = 0; i < 4; i++)
1250 	{
1251 	  if (fabs(dac_out[i]) > dac_out_peak[i])
1252 	    dac_out_peak[i] = fabs(dac_out[i]);
1253 	  dac_out[i] = 0.0;
1254 	}
1255       pass++;
1256 
1257       if (samples == TOTAL_SAMPLES)
1258 	all_done();
1259     }
1260 }
1261 
1262 
1263 /* ---------------------------------------- commands ---------------------------------------- */
1264 
1265 /*
1266  *    -----------------------------------------------------------------
1267  *    :	      (20) data		: 0  0  0  0  0:  RR : x  x: W: P: S:
1268  *    -----------------------------------------------------------------
1269  * MISC
1270  *      RR: 00  no effect
1271  *          01  load DX from data
1272  *	    10  load TTL buffer A from left 16 bits of data
1273  *	    11  load TTL buffer B from left 16 bits of data
1274  *		  set analog output filters from right 4 bits of data:
1275  *		    01xx  Mode 0
1276  *		    00nn  Mode 1, frequency f0, f1, f2, or f3 according
1277  *			to nn
1278  *	W:  if 1, clear all wait bits
1279  *	P:  if 1, clear all pause bits
1280  *	S:  if 1, stop clock
1281  */
1282 
misc_command(int cmd)1283 static void misc_command(int cmd)
1284 {
1285   int data, RR, W, P, S;
1286   char *RR_name[4] = {"noop", "load DX", "TTL-A", "TTL-B"};
1287 
1288   data = LDB(cmd, 20, 12);
1289   RR = LDB(cmd, 2, 5);
1290   W = BIT(cmd, 2);
1291   P = BIT(cmd, 1);
1292   S = BIT(cmd, 0);
1293 
1294   if (describe_commands)
1295     fprintf(stderr, "sam: %d, %s%s%s%s\n",
1296 	    data,
1297 	    RR_name[RR],
1298 	    (W == 1) ? "" : ", clear waits",
1299 	    (P == 1) ? "" : ", clear pauses",
1300 	    (S == 1) ? "" : ", stop clock");
1301 
1302   if (RR == 1) DX = data;
1303 
1304   if (W == 1)
1305     {
1306       /* cause any generator in run mode 1001 to change to mode 1111 */
1307       int i;
1308       for (i = 0; i < GENERATORS; i++)
1309 	if ((gens[i]) && (osc_run(gens[i]->GMODE) == 9))
1310 	  set_osc_run(i, 15);
1311     }
1312 
1313   if (P == 1)
1314     {
1315       /* cause any generator in run mode 0001 to change to mode 1111 */
1316       int i;
1317       for (i = 0; i < GENERATORS; i++)
1318 	if ((gens[i]) && (osc_run(gens[i]->GMODE) == 1))
1319 	  set_osc_run(i, 15);
1320     }
1321 
1322   if (REPORT_BAD_COMMANDS)
1323     {
1324       if ((S == 1) &&
1325 	  ((total_commands - current_command) > 1000))
1326 	fprintf(stderr, "sam: %x: stop clock?\n", cmd);
1327     }
1328 }
1329 
1330 
1331 /*
1332  *    -----------------------------------------------------------------
1333  *    :	  (16) data	:(4)data: 0  0  0  0  1: U  U:  (5) unit #  :
1334  *    -----------------------------------------------------------------
1335  * DLY X, Y, Z
1336  *	UU:  00  X    16 bits base address; clear Y
1337  *	     01  Y    16 bits one's complement of index
1338  *	     10  Z,P  16 bits delay unit size minus 1, or scale (low
1339  *			  4 bits of 16); 4 bits mode
1340  *	     11  (unused)
1341  */
1342 
P_name(int P)1343 static const char *P_name(int P)
1344 {
1345   switch (P)
1346     {
1347     case D_INACTIVE:             return("inactive");
1348     case D_LINE:                 return("line");
1349     case D_TAP:                  return("tap");
1350     case D_TABLE_LOOKUP:         return("table");
1351     case D_TABLE_LOOKUP_ROUNDED: return("rtable");
1352     default:                     return("unknown");
1353     }
1354 }
1355 
1356 
dly_command(int cmd)1357 static void dly_command(int cmd)
1358 {
1359   int unit, UU, data_4, data_16;
1360   delay *d;
1361   char *UU_name[4] = {"set base, clear index", "set index", "set size", "un-used!"};
1362 
1363   unit = (cmd & 0x1f);
1364   UU = LDB(cmd, 2, 5);
1365 
1366   if (UU == 3)
1367     {
1368       fprintf(stderr, "unknown delay command!\n");
1369       return;
1370     }
1371 
1372   data_4 = LDB(cmd, 4, 12);
1373   data_16 = LDB(cmd, 16, 16);
1374 
1375   d = dlys[unit];
1376   switch (UU)
1377     {
1378     case 0:
1379       d->X = data_16;
1380       d->Y = 0;
1381       break;
1382 
1383     case 1:
1384       d->Y = data_16;
1385       break;
1386 
1387     case 2:
1388       d->Z = data_16;
1389       d->P = data_4;
1390       break;
1391     }
1392 
1393   if (describe_commands)
1394     {
1395       fprintf(stderr, "d%d %s", unit, UU_name[UU]);
1396       if (UU == 0)
1397 	fprintf(stderr, ": X: %d", d->X);
1398       else
1399 	{
1400 	  if (UU == 1)
1401 	    fprintf(stderr, ": Y: %d", d->Y);
1402 	  else fprintf(stderr, ": Z: %d, P: %s", d->Z, P_name(d->P));
1403 	}
1404       fprintf(stderr, "\n");
1405     }
1406 }
1407 
1408 
1409 /*
1410  *    -----------------------------------------------------------------
1411  *    :	      (20) data		: 0  0  0  1  0: x  x: T  T: x  x  x:
1412  *    -----------------------------------------------------------------
1413  * TIMER
1414  *	TT: 00  no effect
1415  *	    10  Linger: process no further commands until pass counter
1416  *		    equals data
1417  *	    11  clear pass counter, then Linger as for 10
1418  *	    01  set pass counter from data
1419  */
1420 
timer_command(int cmd)1421 static void timer_command(int cmd)
1422 {
1423   int data, TT;
1424   char *TT_name[4] = {"noop", "set pass", "linger", "clear pass and linger"};
1425 
1426   TT = LDB(cmd, 2, 3);
1427   data = LDB(cmd, 20, 12);
1428 
1429   if (describe_commands)
1430     fprintf(stderr, "sam %s: %d at sample %d %.4f\n", TT_name[TT], data, samples, (double)samples / (double)srate);
1431 
1432   switch (TT)
1433     {
1434     case 0:
1435       break;
1436     case 1:
1437       pass = data;
1438       break;
1439     case 2:
1440       linger(data);
1441       break;
1442     case 3:
1443       pass = 0;
1444       linger(data);
1445       break;
1446     }
1447 }
1448 
1449 
1450 /*
1451  *   -----------------------------------------------------------------
1452  *   : xxx xxx xxx x : (10) data  : 0  0  0  1  1: x  x: 0: Q: x  x  x:
1453  *   -----------------------------------------------------------------
1454  * TICKS
1455  *	Q: 0  designate highest-numbered processing tick per pass
1456  *		    (should not exceed 255 [See appendix - DAJ])
1457  *	   1  designate next-to-highest-numbered tick (processing
1458  *	      plus overhead plus update) per pass
1459  */
1460 static bool bit_31_warned = false;
1461 
ticks_command(int cmd)1462 static void ticks_command(int cmd)
1463 {
1464   int Q, data, bit_31;
1465   char *Q_name[2] = {"set highest processing tick", "set highest tick"};
1466 
1467   bit_31 = BIT(cmd, 4);
1468   Q = BIT(cmd, 3);
1469   data = LDB(cmd, 10, 12);
1470 
1471   if (REPORT_BAD_COMMANDS)
1472     {
1473       if (bit_31 != 0)
1474 	{
1475 	  if (!bit_31_warned)
1476 	    {
1477 	      fprintf(stderr, "ticks bit 31 is on?\n");
1478 	      bit_31_warned = true;
1479 	    }
1480 	  return; /* what is going on here? */
1481 	}
1482     }
1483 
1484   if (data != 0) /* used at end of some box sequences, but that confuses srate */
1485     {
1486       if (Q == 0)
1487 	processing_ticks = data + 1; /* mmm - data is highest numbered processing tick per pass, so processing_ticks is 1 greater. */
1488       else
1489 	{
1490 	  if (srate <= 1)
1491 	    {
1492 	      /* mmm - srate can now be set from the command line in certain cases. I had some weird tick settings for some reason.
1493 	       * mmm - highest_tick_per_pass is actually being set here to the max *number* of ticks per pass, including overhead
1494 	       */
1495 	      highest_tick_per_pass = data + 2; /* why isn't this 9? */
1496 
1497 	      /* "It's not clear from the documentation, so to clarify:  On the # TICKS
1498 	       *  command, the number to be supplied for Q=1 is the total number of ticks
1499 	       * per pass minus 2. (TVR - 7 August 1984)"
1500 	       */
1501 
1502 	      /* it's a 10 bit field, and higher bits are ignored, so the slowest we
1503 	       *   can run is 5010Hz or thereabouts
1504 	       */
1505 
1506 	      if (highest_tick_per_pass > GENERATORS)
1507 		highest_tick_per_pass = GENERATORS;  /* mmm - could it not be higher in some cases? */
1508 
1509 	      srate = (int)(1000000000.0 / (double)(highest_tick_per_pass * 195));
1510 	    }
1511 	  else
1512 	    {
1513 	      highest_tick_per_pass = (1000000000.0 / (double)srate / 195.0);
1514 	    }
1515 	}
1516     }
1517 
1518   if (describe_commands)
1519     {
1520       fprintf(stderr, "sam %s: %d", Q_name[Q], data);
1521       if (Q == 1)
1522 	fprintf(stderr, " (%d Hz)", srate);
1523       fprintf(stderr, "\n");
1524     }
1525 
1526   if ((data != 0) && (srate != 0))
1527     {
1528       if ((snd_file) && (samples == 0) && (Q == 1)) /* 2 tick commands at the start? */
1529 	{
1530 	  fclose(snd_file);                         /* start over... */
1531 	  snd_file = NULL;
1532 	}
1533 
1534       if (snd_file == NULL)
1535 	{
1536 	  /* now that we know the sampling rate, open the output file */
1537 	  int header_info[24] = {1179011410, 88, 1163280727, 1263424842,
1538 				 28, 0, 0, 0,
1539 				 0, 0, 0, 0,
1540 				 544501094, 16, 262147, 44100,
1541 				 705600, 2097168, 1635017060, 16,
1542 				 0, 0, 0, 0};
1543 	  header_info[15] = srate;
1544 
1545 	  /* mmm - generate output filename based on input filename */
1546 	  {
1547 	    char *dot;
1548 	    int i, len;
1549 	    len = strlen(filename);
1550 	    output_filename = (char *)malloc(len + 1);
1551 	    strcpy(output_filename, filename);
1552 	    /* dot = strchr(output_filename, '.');
1553 	     *     can be confused by ../test/TEST.SAM
1554 	     */
1555 	    for (i = len - 1; i > 0; i--)
1556 	      if (filename[i] == '.')
1557 		{
1558 		  dot = (char *)(output_filename + i);
1559 		  break;
1560 		}
1561 	    strcpy(dot + 1, "wav");
1562 	    snd_file = fopen(output_filename, "w");
1563 	  }
1564 
1565 	  if (!snd_file)
1566 	    {
1567 	      fprintf(stderr, "can't open test.snd!\n");
1568 	      exit(0);
1569 	    }
1570 	  fwrite((void *)header_info, 4, 24, snd_file);
1571 	}
1572     }
1573 }
1574 
1575 
1576 static int last_GMODE_command = 0;
1577 
1578 /* GQ  (24 bits) phi -- decay exponent
1579  *    -----------------------------------------------------------------
1580  * GQ  :      (20) data         : 0  0  1: E:      (8)   gen #      :
1581  *    -----------------------------------------------------------------
1582  *
1583  *	E: 0  Q right-adjusted, sign extended
1584  *	   1  Q left-adjusted, low bits from left of DX; clear DX
1585  */
1586 
gq_command(int cmd)1587 static void gq_command(int cmd)
1588 {
1589   /* GQ is 24 bits */
1590   int data, E, gen, old_DX = 0, old_GQ;
1591   double old_f_GQ;
1592   generator *g;
1593   char *E_name[2] = {"right adjusted", "left adjusted + DX"};
1594 
1595   gen = LDB(cmd, 8, 0);
1596   E = BIT(cmd, 8);
1597   data = LDB(cmd, 20, 12);
1598 
1599   g = gens[gen];
1600   old_GQ = g->GQ;
1601   old_f_GQ = g->f_GQ;
1602 
1603   /* spec says "sign extended" which makes me think this number is signed, but I think it is unsigned in exp modes */
1604   /* mmm - I also believe it is unsigned. */
1605   /* pete:
1606    *       Hmm, it looks like it makes more sense to call it unsigned. Certainly
1607    *       the multiplication of envelope times waveform treats the envelope as
1608    *       unsigned (i.e. non-negative).
1609    */
1610 
1611   if (E == 0)
1612     g->GQ = data; /* mmm */
1613   else
1614     {
1615       g->GQ = (data << 4) | ((DX >> 16) & 0xf); /* mmm */
1616       old_DX = DX;
1617       DX = 0;
1618     }
1619 
1620   g->f_GQ = (double)(g->GQ) / (double)(1 << 24); /* mmm - proper scaling of unsigned value */
1621 
1622   if (describe_commands)
1623     {
1624       if (E == 0)
1625 	fprintf(stderr, "g%d amp: %s, %d %.4f\n", gen, E_name[E], g->GQ, g->f_GQ);
1626       else fprintf(stderr, "g%d amp: %s, %d = %d %.4f (DX: %d)\n", gen, E_name[E], data, g->GQ, g->f_GQ, old_DX);
1627     }
1628 
1629 #if 0
1630   if ((gen_is_active(g)) &&
1631       (samples > last_GMODE_command))
1632     {
1633       if (REPORT_BAD_COMMANDS)
1634 	fprintf(stderr, "sample %d (%.3f), command %d, stray amp: g%d %.4f from %.4f (last mode sample: %d)\n",
1635 		samples, (double)samples / (double)srate, current_command,
1636 		gen, g->f_GQ, old_f_GQ,
1637 		last_GMODE_command);
1638       if (FLUSH_BAD_COMMANDS)
1639 	{
1640 	  g->GQ = old_GQ;
1641 	  g->f_GQ = old_f_GQ;
1642 	}
1643     }
1644 #endif
1645 }
1646 
1647 
1648 /* GJ  (28 bits) omega -- oscillator frequency
1649  *    -----------------------------------------------------------------
1650  * GJ  :      (20) data         : 0  1  0: E:      (8)   gen #      :
1651  *    -----------------------------------------------------------------
1652  *
1653  *	E: 0  J right-adjusted, sign extended
1654  *	   1  J left-adjusted, low bits from left of DX; clear DX
1655  */
1656 
gj_command(int cmd)1657 static void gj_command(int cmd)
1658 {
1659   /* GJ is 28 bits */
1660   int data, E, gen, old_DX = 0, old_GJ;
1661   double old_f_GJ;
1662   generator *g;
1663   char *E_name[2] = {"right adjusted", "left adjusted + DX"};
1664 
1665   gen = LDB(cmd, 8, 0);
1666   E = BIT(cmd, 8);
1667   data = LDB(cmd, 20, 12);
1668 
1669   g = gens[gen];
1670   old_GJ = g->GJ;
1671   old_f_GJ = g->GJ;
1672 
1673   if (E == 0)
1674     g->GJ = TWOS_20(data);
1675   else
1676     {
1677       g->GJ = TWOS_28(((data << 8) + (DX >> 12))); /* need 28 - 20 = 8 bits? */
1678       old_DX = DX;
1679       DX = 0;
1680     }
1681 
1682   g->f_GJ = DOUBLE_28(g->GJ);
1683 
1684   if (describe_commands)
1685     {
1686       if (E == 0)
1687 	fprintf(stderr, "g%d freq: %s, %d %.4f (%.4f Hz)\n", gen, E_name[E], g->GJ, g->f_GJ, g->f_GJ * 0.5 * srate);
1688       else fprintf(stderr, "g%d freq: %s (DX: %d), %d = %d %.4f (%.4f Hz)\n", gen, E_name[E], old_DX, data, g->GJ, g->f_GJ, g->f_GJ * 0.5 * srate);
1689     }
1690 
1691   if ((gen_is_active(g)) &&
1692       (g->GJ != old_GJ) &&
1693       (samples > last_GMODE_command))
1694     {
1695       if (REPORT_BAD_COMMANDS)
1696 	fprintf(stderr, "sample %d (%.3f), command %d, stray freq: g%d %.4f from %.4f (last mode sample: %d), data: %d\n",
1697 		samples, (double)samples / (double)srate, current_command,
1698 		gen, g->f_GJ * 0.5 * srate, DOUBLE_28(old_GJ) * 0.5 *srate,
1699 		last_GMODE_command, data);
1700 
1701       if (FLUSH_BAD_COMMANDS)
1702 	{
1703 	  g->GJ = old_GJ;
1704 	  g->f_GJ = old_f_GJ;
1705 	}
1706     }
1707 }
1708 
1709 
1710 /* GP  (20 bits) delta -- decay rate
1711  *    -----------------------------------------------------------------
1712  * GP  :      (20) data         : 0  1  1  0:      (8)   gen #      :
1713  *    -----------------------------------------------------------------
1714  */
1715 
gp_command(int cmd)1716 static void gp_command(int cmd)
1717 {
1718   /* GP is 20 bits */
1719   int data, gen;
1720   generator *g;
1721 
1722   gen = LDB(cmd, 8, 0);
1723   data = LDB(cmd, 20, 12);
1724 
1725   g = gens[gen];
1726   g->GP = TWOS_20(data);
1727   g->f_GP = DOUBLE_20(g->GP);
1728 
1729   if (describe_commands)
1730     fprintf(stderr, "g%d amp change: %d (%.4f/sec), amp: %.4f\n", gen, g->GP, g->f_GP * srate, g->f_GQ);
1731 }
1732 
1733 
1734 /* GN  (11 bits) number of cosines to be summed
1735  * GM  (4 bits) binary scale of cosine or sum of cosines
1736  * GS  (1 bit) whether to shift output when adding to sum memory
1737  * GN, -----------------------------------------------------------------
1738  * GM, :N:M:S S:x: (11) GN :(4) GM : 0  1  1  1:      (8)   gen #      :
1739  * GS  -----------------------------------------------------------------
1740  *
1741  *	N:  if 1, disable loading GN
1742  *	M:  if 1, disable loading GM
1743  *	SS: 00  clear GS to 0
1744  *	    01  set GS to 1
1745  *	    10  no effect
1746  *	    11  (reserved)
1747  */
1748 
gn_command(int cmd)1749 static void gn_command(int cmd)
1750 {
1751   int N, M, SS, GN, GM, gen;
1752   generator *g;
1753   char *SS_name[4] = {", clear GS", ", set GS to 1", "", ", GS reserved?"};
1754 
1755   gen = LDB(cmd, 8, 0);
1756   GM = LDB(cmd, 4, 12);
1757   GN = LDB(cmd, 11, 16);
1758   SS = LDB(cmd, 2, 28);
1759   M = BIT(cmd, 30);
1760   N = BIT(cmd, 31);
1761 
1762   if (describe_commands)
1763     {
1764       if (N == 1)
1765 	{
1766 	  if (M == 1)
1767 	    fprintf(stderr, "g%d sum-memory shift:%s\n", gen, SS_name[SS]);
1768 	  else fprintf(stderr, "g%d ncos scale: %d%s\n", gen, GM, SS_name[SS]);
1769 	}
1770       else
1771 	{
1772 	  if (M == 1)
1773 	    fprintf(stderr, "g%d ncos: %d%s\n", gen, GN, SS_name[SS]);
1774 	  else fprintf(stderr, "g%d ncos: %d%s, scale: %d\n", gen, GN, SS_name[SS], GM);
1775 	}
1776     }
1777 
1778   g = gens[gen];
1779   if (N == 0)
1780     g->GN = GN;
1781   if (M == 0)
1782     g->GM = GM;
1783 
1784   switch(SS)
1785     {
1786     case 0:
1787       g->GS = 0;
1788       break;
1789 
1790     case 1:
1791       g->GS = 1;
1792       break;
1793     }
1794 }
1795 
1796 
1797 /* GL  (12 bits) asymptote
1798  * GSUM  (6 bits) sum memory address into which output is added
1799  *      -----------------------------------------------------------------
1800  * GL,  :L:S:  (12) GL   : (6) GSUM : 1  0  0  0:      (8)   gen #      :
1801  * GSUM -----------------------------------------------------------------
1802  *
1803  *	L:  if 1, disable loading GL
1804  *	S:  if 1, disable loading GSUM
1805  */
1806 
gl_command(int cmd)1807 static void gl_command(int cmd)
1808 {
1809   int GL, GSUM, L, S, gen, old_GSUM;
1810   generator *g;
1811 
1812   gen = LDB(cmd, 8, 0);
1813   GSUM = LDB(cmd, 6, 12);
1814   GL = LDB(cmd, 12, 18);
1815   L = BIT(cmd, 31);
1816   S = BIT(cmd, 30);
1817 
1818   g = gens[gen];
1819   old_GSUM = g->GSUM;
1820 
1821   if (L == 0)
1822     {
1823       /* is this signed? -- posies treats it as unsigned, I believe */
1824 #if 1
1825       g->GL = GL;
1826       g->f_GL = UNSIGNED_12_TO_DOUBLE(GL);
1827 #else
1828       g->GL = TWOS_12(GL);
1829       g->f_GL = DOUBLE_12(g->GL);
1830 #endif
1831     }
1832 
1833   if (S == 0)
1834     g->GSUM = GSUM;
1835 
1836   if (describe_commands)
1837     {
1838       if (L == 1)
1839 	{
1840 	  if (S == 1)
1841 	    fprintf(stderr, "g%d: noop\n", gen);
1842 	  else fprintf(stderr, "g%d outloc: gen-outs[%d]\n", gen, g->GSUM);
1843 	}
1844       else
1845 	{
1846 	  if (S == 0)
1847 	    fprintf(stderr, "g%d amp offset: %d = %.4f\n", gen, g->GL, g->f_GL);
1848 	  else fprintf(stderr, "g%d outloc: gen-outs[%d] + amp offset: %d = %.4f\n", gen, g->GSUM, g->GL, g->f_GL);
1849 	}
1850     }
1851 
1852   if (REPORT_BAD_COMMANDS)
1853     {
1854       if ((GL == 1) && (L == 1) && (S == 0))
1855 	fprintf(stderr, "sample %d (%.3f), command %d, possible gen output loc overflow: g%d %d\n",
1856 		samples, (double)samples / (double)srate, current_command,
1857 		gen, GSUM);
1858 
1859       if ((gen_is_active(g)) &&
1860 	  (g->GSUM != old_GSUM) &&
1861 	  (samples > last_GMODE_command) &&
1862 	  (S == 0))
1863 	fprintf(stderr, "sample %d (%.3f), command %d, stray output loc: g%d %d from %d (last mode sample: %d)\n",
1864 		samples, (double)samples / (double)srate, current_command,
1865 		gen, g->GSUM, old_GSUM,
1866 		last_GMODE_command);
1867     }
1868 }
1869 
1870 
1871 /* (20 bits) theta -- oscillator angle
1872  *    -----------------------------------------------------------------
1873  * GK  :      (20) data         : 1  0  0  1:      (8)   gen #      :
1874  *    -----------------------------------------------------------------
1875 */
1876 
gk_command(int cmd)1877 static void gk_command(int cmd)
1878 {
1879   /* GK is 20 bits */
1880   int data, gen, old_GK;
1881   double old_f_GK;
1882   generator *g;
1883 
1884   gen = LDB(cmd, 8, 0);
1885   data = LDB(cmd, 20, 12);
1886 
1887   g = gens[gen];
1888   old_GK = g->GK;
1889   old_f_GK = g->f_GK;
1890 
1891   g->GK = TWOS_20(data);
1892   g->f_GK = DOUBLE_20(g->GK);
1893 
1894   if (describe_commands)
1895     fprintf(stderr, "g%d phase: %d %.4f\n", gen, g->GK, g->f_GK);
1896 
1897   if ((gen_is_active(g)) &&
1898       (samples > last_GMODE_command))
1899     {
1900       if (REPORT_BAD_COMMANDS)
1901 	fprintf(stderr, "sample %d (%.3f), command %d, stray phase: g%d %.4f (last mode sample: %d)\n",
1902 		samples, (double)samples / (double)srate, current_command,
1903 		gen, g->f_GK,
1904 		last_GMODE_command);
1905       if (FLUSH_BAD_COMMANDS)
1906 	{
1907 	  g->GK = old_GK;
1908 	  g->f_GK = old_f_GK;
1909 	}
1910     }
1911 }
1912 
1913 
1914 /* GFM  (7 bits) sum memory address from which frequency modulation
1915  * GMODE  (10 bits) generator mode
1916  *    -----------------------------------------------------------------
1917  *    :M:F:C:  (10) GMODE :(7) GFM: 1  0  1  0:      (8)   gen #      :
1918  *    -----------------------------------------------------------------
1919  * GMODE,
1920  * GFM	M:  if 1, disable loading GMODE
1921  *	F:  if 1, disable loading GFM
1922  *	C:  if 1, clear GK
1923  */
1924 
bad_mode(int mode)1925 static bool bad_mode(int mode)
1926 {
1927   int R, E, S;
1928   R = osc_run(mode);
1929   E = osc_env(mode);
1930   S = osc_mode(mode);
1931 
1932   if ((R != 2) && (R != 7) && (R != 3) && (R != 0))
1933     switch (S)
1934       {
1935       case SUMCOS: case SAWTOOTH: case SQUARE: case PULSE: case SIN_K: case SIN_FM:
1936 	break;
1937       default:
1938 	return(true);
1939       }
1940 
1941   switch (R)
1942     {
1943     case 0: case 1: case 15: case 14: case 9: case 13: case 7: case 3: case 2:
1944       break;
1945     default:
1946       return(true);
1947     }
1948 
1949   return(false);
1950 }
1951 
1952 
print_gmode_name(int mode)1953 static void print_gmode_name(int mode)
1954 {
1955   /* RRRREESSSS */
1956   int R, E, S;
1957   char *E_name[4] = {"L-Q", "L+Q", "L-2^Q", "L+2^Q"};
1958 
1959   R = osc_run(mode);
1960   E = osc_env(mode);
1961   S = osc_mode(mode);
1962 
1963   if (R == 0)
1964     {
1965       fprintf(stderr, "inactive");
1966       return;
1967     }
1968 
1969   if ((R != 2) && (R != 7) && (R != 3))
1970     {
1971       switch (S)
1972 	{
1973 	case SUMCOS:   fprintf(stderr, "ncos");    break;
1974 	case SAWTOOTH: fprintf(stderr, "saw");     break;
1975 	case SQUARE:   fprintf(stderr, "square");  break;
1976 	case PULSE:    fprintf(stderr, "pulse");   break;
1977 	case SIN_K:    fprintf(stderr, "sin");     break;
1978 	case SIN_FM:   fprintf(stderr, "sin+fm");  break;
1979 	default:       fprintf(stderr, "unknown"); break;
1980 	}
1981 
1982       fprintf(stderr, "-%s-", E_name[E]);
1983     }
1984 
1985   switch (R)
1986     {
1987     case 1:  fprintf(stderr, "pause");  break;
1988     case 15: fprintf(stderr, "A");      break;
1989     case 14: fprintf(stderr, "B");      break;
1990     case 9:  fprintf(stderr, "wait");   break;
1991     case 13: fprintf(stderr, "C");      break;
1992     case 7:  fprintf(stderr, "rd");     break;
1993     case 3:  fprintf(stderr, "wrt");    break;
1994     case 2:  fprintf(stderr, "DAC");    break;
1995     default: fprintf(stderr, "unknown"); break;
1996     }
1997 }
1998 
1999 
gmode_command(int cmd)2000 static void gmode_command(int cmd)
2001 {
2002   int gen, M, F, C, GMODE, GFM, old_GMODE, old_GFM;
2003   bool gen_was_active;
2004   generator *g;
2005 
2006   last_GMODE_command = samples;
2007 
2008   gen = LDB(cmd, 8, 0);
2009   GFM = LDB(cmd, 7, 12);
2010   GMODE = LDB(cmd, 10, 19);
2011   M = BIT(cmd, 31);
2012   F = BIT(cmd, 30);
2013   C = BIT(cmd, 29);
2014 
2015   g = gens[gen];
2016   old_GFM = g->GFM;
2017   old_GMODE = g->GMODE;
2018   gen_was_active = gen_is_active(g);
2019 
2020   if (M == 0)
2021     g->GMODE = GMODE;
2022   if (F == 0)
2023     g->GFM = GFM;
2024   if (C == 1)
2025     g->GK = 0;
2026 
2027   /*
2028   if (osc_env(GMODE) > 1) fprintf(stderr, "expt %d ", samples);
2029   */
2030 
2031   if (describe_commands)
2032     {
2033       fprintf(stderr, "g%d ", gen);
2034       if (M == 0)
2035 	{
2036 	  fprintf(stderr, "mode: ");
2037 	  print_gmode_name(g->GMODE);
2038 	}
2039       if (F == 0)
2040 	{
2041 	  if (M == 0) fprintf(stderr, ", ");
2042 	  fprintf(stderr, "inloc: %s[%d]", ((g->GFM >> 6) == 0) ? "gen-ins" : "mod-ins", g->GFM & 0x3f);
2043 	}
2044       if (C == 1)
2045 	{
2046 	  if ((M == 0) || (F == 0))
2047 	    fprintf(stderr, ", ");
2048 	  fprintf(stderr, "clear phase");
2049 	}
2050       fprintf(stderr, "\n");
2051     }
2052 
2053   if (REPORT_BAD_COMMANDS)
2054     {
2055       if (bad_mode(GMODE))
2056 	fprintf(stderr, "sample %d (%.3f), command %d, bad mode: g%d %x\n",
2057 		samples, (double)samples / (double)srate, current_command,
2058 		gen, GMODE);
2059 
2060       if ((gen_is_active(g)) &&
2061 	  (gen >= processing_ticks))
2062 	fprintf(stderr, "sample %d (%.3f), command %d, g%d cannot actually run (procticks: %d)\n",
2063 		samples, (double)samples / (double)srate, current_command,
2064 		gen, processing_ticks);
2065 
2066 #if 0
2067       if ((gen_was_active) &&
2068 	  (!gen_is_active(g)) &&
2069 	  (g->f_GQ != 0.0))
2070 	fprintf(stderr, "sample %d (%.3f), command %d, g%d turned off with amp %.4f\n",
2071 		samples, (double)samples / (double)srate, current_command,
2072 		gen, g->f_GQ);
2073 #endif
2074 
2075       if ((gen_was_active) &&
2076 	  ((g->GFM != old_GFM) || (g->GMODE != old_GMODE)) &&
2077 	  (samples > last_GMODE_command))
2078 	{
2079 	  if (g->GFM != old_GFM)
2080 	    fprintf(stderr, "sample %d (%.3f), command %d, stray input loc: g%d %d from %d (last mode sample: %d)\n",
2081 		    samples, (double)samples / (double)srate, current_command,
2082 		    gen, g->GFM, old_GFM,
2083 		    last_GMODE_command);
2084 	  else
2085 	    {
2086 	      fprintf(stderr, "sample %d (%.3f), command %d, stray mode: g%d ",
2087 		      samples, (double)samples / (double)srate, current_command, gen);
2088 	      print_gmode_name(g->GMODE);
2089 	      fprintf(stderr, " from ");
2090 	      print_gmode_name(old_GMODE);
2091 	      fprintf(stderr, " (last mode sample: %d)\n", last_GMODE_command);
2092 	    }
2093 	}
2094     }
2095 }
2096 
2097 
2098 /* GO  (20 bits) alpha -- oscillator frequency sweep rate
2099  *     -----------------------------------------------------------------
2100  * GO  :      (20) data         : 1  0  1  1:      (8)   gen #      :
2101  *     -----------------------------------------------------------------
2102 */
2103 
go_command(int cmd)2104 static void go_command(int cmd)
2105 {
2106   /* GO is 20  bits */
2107   int data, gen;
2108   generator *g;
2109 
2110   gen = LDB(cmd, 8, 0);
2111   data = LDB(cmd, 20, 12);
2112 
2113   g = gens[gen];
2114   g->GO = TWOS_20(data);
2115   g->f_GO = DOUBLE_20(g->GO);
2116 
2117   if (describe_commands)
2118     {
2119       if (osc_run(g->GMODE) == 2)
2120 	fprintf(stderr, "g%d DAC out: %d\n", gen, data);
2121       else fprintf(stderr, "g%d freq change: %d %.4f (%.4f Hz/sec), freq: %.4f\n",
2122 		   gen, g->GO, g->f_GO, g->f_GO * 0.5 * srate * srate / 256.0, g->f_GJ * srate * 0.5);
2123     }
2124 }
2125 
2126 
2127 /* M0  (30 bits) coefficient
2128  * M1  (30 bits) other coefficient
2129  *    -----------------------------------------------------------------
2130  * MM  :      (20) data         : 1  1  0: V  V:     (7)   mod #    :
2131  *    -----------------------------------------------------------------
2132  *
2133  *	VV: 00  M0 right-adjusted, sign extended
2134  *	    01  M1 right-adjusted, sign extended
2135  *	    10  M0 left-adjusted, low bits from left of DX; clear DX
2136  *	    11  M1 left-adjusted, low bits from left of DX; clear DX
2137  */
2138 
2139 /* To avoid endless repetition in the modifier processing, I'll incorporate the scalers
2140  *   into M0 and M1 when they are set, or when the scalers are changed, but this means
2141  *   (for simplicity) keeping track of the original M0 and M1 values: ("o_M0" and friends)
2142  */
2143 
mm_command(int cmd)2144 static void mm_command(int cmd)
2145 {
2146   /* M0 and M1 are 30 bits */
2147   int mod, VV, data, old_DX = 0;
2148   modifier *m;
2149 
2150   mod = LDB(cmd, 7, 0);
2151   VV = LDB(cmd, 2, 7);
2152   data = LDB(cmd, 20, 12);
2153 
2154   m = mods[mod];
2155 
2156   switch (VV)
2157     {
2158     case 0:
2159       m->M0 = TWOS_20(data);
2160       m->f_M0 = DOUBLE_30(m->M0);
2161       m->o_M0 = m->M0;
2162       m->o_f_M0 = m->f_M0;
2163       m->M0 = m->M0 * m->mult_scl_0 / 4;
2164       m->f_M0 *= m->mult_scl_0;
2165       break;
2166 
2167     case 1:
2168       m->M1 = TWOS_20(data);
2169       m->f_M1 = DOUBLE_30(m->M1);
2170       m->o_M1 = m->M1;
2171       m->o_f_M1 = m->f_M1;
2172       m->M1 = m->M1 * m->mult_scl_1 / 4;
2173       m->f_M1 *= m->mult_scl_1;
2174       break;
2175 
2176     case 2:
2177       m->M0 = TWOS_30(((data << 10) + ((DX >> 10) & 0x3ff)));
2178       m->f_M0 = DOUBLE_30(m->M0);
2179       m->o_M0 = m->M0;
2180       m->o_f_M0 = m->f_M0;
2181       old_DX = DX;
2182       DX = 0;
2183       m->M0 = (m->M0 / 4) * m->mult_scl_0; /* try not to set the sign bit */
2184       m->f_M0 *= m->mult_scl_0;
2185       break;
2186 
2187     case 3:
2188       m->M1 = TWOS_30(((data << 10) + ((DX >> 10) & 0x3ff)));
2189       m->f_M1 = DOUBLE_30(m->M1);
2190       m->o_M1 = m->M1;
2191       m->o_f_M1 = m->f_M1;
2192       old_DX = DX;
2193       DX = 0;
2194       m->M1 = (m->M1 / 4) * m->mult_scl_1;
2195       m->f_M1 *= m->mult_scl_1;
2196       break;
2197     }
2198 
2199   if (describe_commands)
2200     {
2201       switch (VV)
2202 	{
2203 	case 0:
2204 	  fprintf(stderr, "m%d M0: %d: %d %.6f\n", mod, data, m->M0, m->f_M0);
2205 	  break;
2206 	case 1:
2207 	  fprintf(stderr, "m%d M1: %d: %d %.6f\n", mod, data, m->M1, m->f_M1);
2208 	  break;
2209 	case 2:
2210 	  fprintf(stderr, "m%d M0+DX: data: %d + DX: %d (scl: %d), %d -> %d, %.6f -> %.6f\n",
2211 		  mod, data, old_DX, m->mult_scl_0, m->o_M0, m->M0, m->o_f_M0, m->f_M0);
2212 	  break;
2213 	case 3:
2214 	  fprintf(stderr, "m%d M1+DX: data: %d + DX: %d (scl: %d), %d -> %d, %.6f -> %.6f\n",
2215 		  mod, data, old_DX, m->mult_scl_1, m->o_M1, m->M1, m->o_f_M1, m->f_M1);
2216 	  break;
2217 	}
2218     }
2219 }
2220 
2221 
2222 /* L0  (20 bits) running term
2223  * L1  (20 bits) other running term
2224  *    -----------------------------------------------------------------
2225  * ML :      (20) data         : 1  1  1  0: N:     (7)   mod #    :
2226  *    -----------------------------------------------------------------
2227  *
2228  *	N: 0  L0
2229  *	   1  L1
2230  */
2231 
ml_command(int cmd)2232 static void ml_command(int cmd)
2233 {
2234   int mod, N, data;
2235   modifier *m;
2236 
2237   mod = LDB(cmd, 7, 0);
2238   data = LDB(cmd, 20, 12);
2239   N = BIT(cmd, 7);
2240 
2241   m = mods[mod];
2242   if (N == 0)
2243     {
2244       m->L0 = TWOS_20(data);
2245       m->f_L0 = DOUBLE_20(m->L0);
2246     }
2247   else
2248     {
2249       m->L1 = TWOS_20(data);
2250       m->f_L1 = DOUBLE_20(m->L1);
2251     }
2252 
2253   if (describe_commands)
2254     {
2255       if (N == 0)
2256 	fprintf(stderr, "m%d L0: %d: %d %.6f\n", mod, data, m->L0, m->f_L0);
2257       else fprintf(stderr, "m%d L1: %d: %d %.6f\n", mod, data, m->L1, m->f_L1);
2258     }
2259 }
2260 
2261 
2262 /* MSUM  (7 bits) result address in sum memory
2263  * MMODE  (9 bits) modifier mode
2264  *    -----------------------------------------------------------------
2265  *    :M:S:C:H: (9) MMODE :(7)MSUM: 1  1  1  1  0:      (7)  mod #    :
2266  *    -----------------------------------------------------------------
2267  *
2268  * MMODE,
2269  * MSUM	M:  if 1, disable loading MMMMM bits of MMODE
2270  *	S:  if 1, disable loading MSUM
2271  *	C:  if 1, clear L0
2272  *	H:  if 1, disable loading AABB bits of MMODE
2273  */
2274 
mode_name(int m)2275 static const char *mode_name(int m)
2276 {
2277   switch (m)
2278     {
2279     case M_INACTIVE:        return("inactive");
2280     case M_NOISE:           return("noise");
2281     case M_TRIGGERED_NOISE: return("triggered-noise");
2282     case M_LATCH:           return("latch");
2283     case M_THRESHOLD:       return("thresh");
2284     case M_DELAY:           return("delay");
2285     case M_TWO_POLE:        return("2pole");
2286     case M_TWO_POLE_M0:     return("2pole-M0");
2287     case M_TWO_POLE_M1:     return("2pole-M1");
2288     case M_TWO_ZERO:        return("2zero");
2289     case M_TWO_ZERO_M0:     return("2zero-M0");
2290     case M_TWO_ZERO_M1:     return("2zero-M1");
2291     case M_INTEGER_MIXING:  return("int-mix");
2292     case M_ONE_POLE:        return("1pole");
2293     case M_MIXING:          return("mix");
2294     case M_ONE_ZERO:        return("1zero");
2295     case M_MULTIPLY:        return("multiply");
2296     case M_AMP_MOD:         return("am");
2297     case M_MAX:             return("max");
2298     case M_MIN:             return("min");
2299     case M_SIGNUM:          return("signum");
2300     case M_ZERO_CROSS:      return("0cross");
2301     }
2302   return("unknown");
2303 }
2304 
2305 
mmode_command(int cmd)2306 static void mmode_command(int cmd)
2307 {
2308   int mod, MSUM, MMODE, M, S, C, H;
2309   modifier *m;
2310 
2311   mod = LDB(cmd, 7, 0);
2312   MSUM = LDB(cmd, 7, 12);
2313   MMODE = LDB(cmd, 9, 19);
2314   M = BIT(cmd, 31);
2315   S = BIT(cmd, 30);
2316   C = BIT(cmd, 29);
2317   H = BIT(cmd, 28);
2318 
2319   m = mods[mod];
2320   if (S == 0)
2321     m->MSUM = MSUM;
2322   if (C == 1)
2323     {
2324       m->L0 = 0;
2325       m->f_L0 = 0.0;
2326     }
2327 
2328   /* MMODE is MMMMMAABB */
2329   if (H == 0)
2330     {
2331       /* set up the scale factors now, so we don't have to futz around later */
2332       /* BB = first (!) */
2333       m->mult_scl_1 = (1 << (MMODE & 0x3));
2334       m->mult_scl_0 = (1 << ((MMODE >> 2) & 0x3));
2335       /* whenever M0/M1 are set, we will include these factors */
2336 
2337       m->M0 = (m->o_M0 / 4) * m->mult_scl_0; /* order matters -- don't want to set sign bit by accident */
2338       m->M1 = (m->o_M1 / 4) * m->mult_scl_1;
2339       m->f_M0 = m->o_f_M0 * m->mult_scl_0;
2340       m->f_M1 = m->o_f_M1 * m->mult_scl_1;
2341 
2342       if (M == 0)
2343 	m->MMODE = MMODE;                                  /* set both */
2344       else m->MMODE = (MMODE & 0xf) + (m->MMODE & 0x1f0); /* H is 0, so set AABB */
2345     }
2346   else
2347     {
2348       if (M == 0)
2349 	m->MMODE = (MMODE & 0x1f0) + (m->MMODE & 0xf);    /* M is 0, so set MMMMM */
2350     }
2351 
2352   if (describe_commands)
2353     {
2354       fprintf(stderr, "m%d ", mod);
2355       if (M == 0)
2356 	fprintf(stderr, "mode: %s", mode_name(MMODE >> 4));
2357       if (H == 0)
2358 	{
2359 	  if (M == 0)
2360 	    fprintf(stderr, ", ");
2361 	  fprintf(stderr, "AA: %d, BB: %d (M0: %d, %.3f, M1: %d, %.3f)", (MMODE >> 2) & 0x3, MMODE & 0x3, m->M0, m->f_M0, m->M1, m->f_M1);
2362 	}
2363       if (S == 0)
2364 	{
2365 	  if ((H == 0) || (M == 0))
2366 	    fprintf(stderr, ", ");
2367 	  fprintf(stderr, "outloc(%s): mod-outs[%d]", ((MSUM >> 6) == 0) ? "+" : "=", MSUM & 0x3f);
2368 	}
2369       if (C == 1)
2370 	{
2371 	  if ((S == 0) || (H == 0) || (M == 0))
2372 	    fprintf(stderr, ", ");
2373 	  fprintf(stderr, "L0=0");
2374 	}
2375       fprintf(stderr, "\n");
2376     }
2377 
2378   if (REPORT_BAD_COMMANDS)
2379     {
2380       if (((MMODE >> 4) != M_INACTIVE) &&
2381 	  ((mod * 2) >= processing_ticks))
2382 	fprintf(stderr, "sample %d (%.3f), command %d, m%d cannot actually run (procticks: %d)\n",
2383 		samples, (double)samples / (double)srate, current_command,
2384 		mod, processing_ticks);
2385     }
2386 }
2387 
2388 
2389 /* MIN  (8 bits) address in sum memory where modifier reads "A" data
2390  * MRM  (8 bits) address in sum memory where modifier reads "B" data
2391  *    -----------------------------------------------------------------
2392  *    :R:I:C C: (8) MRM : (8) MIN : 1  1  1  1  1:      (7)  mod #    :
2393  *    -----------------------------------------------------------------
2394  *
2395  * MRM,
2396  * MIN,	R:  if 1, disable loading MRM
2397  * MT	I:  if 1, disable loading MIN
2398  *	CC: 00  turn off truncation
2399  *	    01  turn on truncation
2400  *	    10  clear L1
2401  *	    11  no effect
2402  */
2403 
mrm_command(int cmd)2404 static void mrm_command(int cmd)
2405 {
2406   int mod, MRM, MIN, R, I, CC;
2407   modifier *m;
2408 
2409   mod = LDB(cmd, 7, 0);
2410   MIN = LDB(cmd, 8, 12);
2411   MRM = LDB(cmd, 8, 20);
2412   R = BIT(cmd, 31);
2413   I = BIT(cmd, 30);
2414   CC = LDB(cmd, 2, 28);
2415 
2416   m = mods[mod];
2417   if (R == 0)
2418     m->MRM = MRM;
2419   if (I == 0)
2420     m->MIN = MIN;
2421 
2422   switch (CC)
2423     {
2424     case 0:
2425       m->T = 0;
2426       break;
2427 
2428     case 1:
2429       m->T = 1;
2430       break;
2431 
2432     case 2:
2433       m->L1 = 0;
2434       m->f_L1 = 0.0;
2435       break;
2436     }
2437 
2438   if (describe_commands)
2439     {
2440       fprintf(stderr, "m%d inlocs:", mod);
2441       if (R == 0)
2442 	{
2443 	  if (mod_mode(m->MMODE) == M_DELAY)
2444 	    fprintf(stderr, ", delay: %d", MRM & 0x1f);
2445 	  else
2446 	    {
2447 	      fprintf(stderr, ", MRM: ");
2448 	      print_mod_read_name(MRM);
2449 	    }
2450 	}
2451       if (I == 0)
2452 	{
2453 	  fprintf(stderr, ", MIN: ");
2454 	  print_mod_read_name(MIN);
2455 	}
2456       if (CC == 0) fprintf(stderr, ", trunc off");
2457       if (CC == 1) fprintf(stderr, ", trunc on");
2458       if (CC == 2) fprintf(stderr, ", L1=0");
2459       fprintf(stderr, "\n");
2460     }
2461 }
2462 
2463 
handle_command(int cmd)2464 static void handle_command(int cmd)
2465 {
2466   /* actually we should take highest_tick - processing_ticks - 8 commands at a time, then run a sample */
2467 
2468   int op;
2469   if ((start_describing <= samples) &&
2470       (stop_describing >= samples))
2471     describe_commands = true;
2472   else describe_commands = DEFAULT_DESCRIBE_COMMANDS;
2473 
2474   op = LDB(cmd, 4, 8);
2475 
2476   switch (op)
2477     {
2478     case 0:
2479       if (BIT(cmd, 7) == 1)
2480 	dly_command(cmd);
2481       else misc_command(cmd);
2482       break;
2483 
2484     case 1:
2485       if (BIT(cmd, 7) == 1)
2486 	ticks_command(cmd);
2487       else timer_command(cmd);
2488       break;
2489 
2490     case 2: case 3:
2491       gq_command(cmd);
2492       break;
2493 
2494     case 4: case 5:
2495       gj_command(cmd);
2496       break;
2497 
2498     case 6:
2499       gp_command(cmd);
2500       break;
2501 
2502     case 7:
2503       gn_command(cmd);
2504       break;
2505 
2506     case 8:
2507       gl_command(cmd);
2508       break;
2509 
2510     case 9:
2511       gk_command(cmd);
2512       break;
2513 
2514     case 10:
2515       gmode_command(cmd);
2516       break;
2517 
2518     case 11:
2519       go_command(cmd);
2520       break;
2521 
2522     case 12: case 13:
2523       mm_command(cmd);
2524       break;
2525 
2526     case 14:
2527       ml_command(cmd);
2528       break;
2529 
2530     case 15:
2531       if (BIT(cmd, 7) == 0)
2532 	mmode_command(cmd);
2533       else mrm_command(cmd);
2534       break;
2535 
2536     default:
2537       fprintf(stderr, "impossible command\n");
2538       break;
2539     }
2540 
2541   current_command++;
2542 }
2543 
2544 
2545 /* ---------------------------------------- debugging ---------------------------------------- */
2546 
2547 #if 0
2548 static void dump_gens(void)
2549 {
2550   int i;
2551   for (i = 0; i < GENERATORS; i++)
2552     if (gens[i]->GMODE != 0)
2553       fprintf(stderr, "g%d GMODE: %d, %d [%.3f] -> %d [%.3f], GQ: %.3f, GP: %.3f, GL: %.3f, GJ: %.3f, GO: %.3f, GN: %d, GS: %d\n",
2554 	      i,
2555 	      gens[i]->GMODE,
2556 	      gens[i]->GFM, ((gens[i]->GFM >> 6) == 0) ? gen_ins[gens[i]->GFM & 0x3f] : mod_ins[gens[i]->GFM & 0x3f],
2557 	      gens[i]->GSUM, gen_outs[gens[i]->GSUM],
2558 	      gens[i]->f_GQ, gens[i]->f_GP, gens[i]->f_GL, gens[i]->f_GJ, gens[i]->f_GO,
2559 	      gens[i]->GN, gens[i]->GS);
2560 }
2561 
2562 
2563 static void dump_mods(void)
2564 {
2565   int i;
2566   for (i = 0; i < MODIFIERS; i++)
2567     if (mods[i]->MMODE != 0)
2568       fprintf(stderr, "m%d MMODE: %d, (%d [%.3f] %d [%.3f]) -> %d [%.3f], M0: %.3f, M1: %.3f, L0: %.3f, L1: %.3f\n",
2569 	      i,
2570 	      mods[i]->MMODE,
2571 	      mods[i]->MIN, mod_read(mods[i]->MIN),
2572 	      mods[i]->MRM, mod_read(mods[i]->MRM),
2573 	      mods[i]->MSUM, mod_outs[mods[i]->MSUM],
2574 	      mods[i]->f_M0, mods[i]->f_M1, mods[i]->f_L0, mods[i]->f_L1);
2575 }
2576 #endif
2577 
dump_gen_sum(int addr)2578 static void dump_gen_sum(int addr)
2579 {
2580   int i;
2581   /* show prev-ins : ins : out, g%d for all writers */
2582   fprintf(stderr, "g-sum%d: %.3f %.3f %.3f [max: %.3f]", addr, prev_gen_ins[addr], gen_ins[addr], gen_outs[addr], peak_gen_ins[addr]);
2583 
2584   for (i = 0; i < GENERATORS; i++)
2585     if ((gens[i]->GMODE != 0) &&
2586 	(gens[i]->GSUM == addr))
2587       fprintf(stderr, " g%d", i);
2588 }
2589 
2590 
dump_mod_sum(int addr)2591 static void dump_mod_sum(int addr)
2592 {
2593   int i;
2594   /* show prev-ins : ins : out, m%d for all writers */
2595   fprintf(stderr, "m-sum%d: %.3f %.3f %.3f [max: %.3f]", addr, prev_mod_ins[addr], mod_ins[addr], mod_outs[addr], peak_mod_ins[addr]);
2596 
2597   for (i = 0; i < MODIFIERS; i++)
2598     if ((mod_mode(mods[i]->MMODE) != M_INACTIVE) &&
2599 	((mods[i]->MSUM &0x3f) == addr))
2600       fprintf(stderr, " m%d", i);
2601 }
2602 
2603 
print_mod_sum(int addr)2604 static void print_mod_sum(int addr)
2605 {
2606   int loc;
2607   loc = addr & 0x3f;
2608   switch ((addr >> 6) & 0x3)
2609     {
2610     case 0:
2611       fprintf(stderr, "[");
2612       dump_gen_sum(loc);
2613       break;
2614     case 1:
2615       fprintf(stderr, "[");
2616       if (loc == 0)
2617 	{
2618 	  if ((prev_mod_ins[0] != 0.0) || (mod_ins[0] != 0.0) || (mod_outs[0] != 0.0) || (peak_mod_ins[0] != 0))
2619 	    dump_mod_sum(0);
2620 	  else fprintf(stderr, "zero");
2621 	}
2622       else dump_mod_sum(loc);
2623       break;
2624     case 2:
2625       fprintf(stderr, "-out[");
2626       if (loc == 0)
2627 	{
2628 	  if ((prev_mod_ins[0] != 0.0) || (mod_ins[0] != 0.0) || (mod_outs[0] != 0.0) || (peak_mod_ins[0] != 0))
2629 	    dump_mod_sum(0);
2630 	  else fprintf(stderr, "zero");
2631 	}
2632       else dump_mod_sum(loc);
2633       break;
2634     case 3:
2635       fprintf(stderr, "[illegal: %d", addr);
2636       break;
2637     }
2638 }
2639 
2640 
gen_mem_readers(int addr)2641 static int gen_mem_readers(int addr)
2642 {
2643   int i, rds = 0;
2644   for (i = 0; i < GENERATORS; i++)
2645     if ((gens[i]->GMODE != 0) &&
2646 	(gens[i]->GFM == addr)) /* Q bit 0 = gen */
2647       rds++;
2648   for (i = 0; i < MODIFIERS; i++)
2649     if (mod_mode(mods[i]->MMODE) != M_INACTIVE)
2650     {
2651       if (mods[i]->MIN == addr) /* QQ bits = 0 = gen */
2652 	rds++;
2653       if ((mod_mode(mods[i]->MMODE) != M_DELAY) &&
2654 	  (mods[i]->MRM == addr))
2655 	rds++;
2656     }
2657   return(rds);
2658 }
2659 
2660 
mod_mem_readers(int addr)2661 static int mod_mem_readers(int addr)
2662 {
2663   int i, rds = 0;
2664   for (i = 0; i < GENERATORS; i++)
2665     if ((gens[i]->GMODE != 0) &&
2666 	(gens[i]->GFM == 64 + addr)) /* Q bit 1 = mod */
2667       rds++;
2668   for (i = 0; i < MODIFIERS; i++)
2669     if (mod_mode(mods[i]->MMODE) != M_INACTIVE)
2670     {
2671       if ((mods[i]->MIN == 64 + addr) ||
2672 	  (mods[i]->MIN == 128 + addr))
2673 	rds++;
2674       if ((mod_mode(mods[i]->MMODE) != M_DELAY) &&
2675 	  ((mods[i]->MRM == 64 + addr) ||
2676 	   (mods[i]->MRM == 128 + addr)))
2677 	rds++;
2678     }
2679   return(rds);
2680 }
2681 
2682 
dump_patch(void)2683 static void dump_patch(void)
2684 {
2685   /* try to show all currently active elements and memory with some history */
2686   int i, p;
2687 
2688   fprintf(stderr, "sample: %d, command: %d, ", samples, current_command);
2689 
2690   for (i = 0, p = 0; i < GENERATORS; i++)
2691     if (gens[i]->GMODE != 0)
2692       p++;
2693   fprintf(stderr, "active gens: %d, ", p);
2694 
2695   for (i = 0, p = 0; i < MODIFIERS; i++)
2696     if (mod_mode(mods[i]->MMODE) != M_INACTIVE)
2697       p++;
2698   fprintf(stderr, "active mods: %d, ", p);
2699 
2700   for (i = 0, p = 0; i < DELAYS; i++)
2701     if (dlys[i]->P != 0)
2702       p++;
2703   fprintf(stderr, "active delays: %d\n\n", p);
2704 
2705   for (i = 0; i < GENERATORS; i++)
2706     if (gens[i]->GMODE != 0)
2707       {
2708 	generator *g;
2709 	g = gens[i];
2710 	fprintf(stderr, "g%d ", i);
2711 	print_gmode_name(g->GMODE);
2712 
2713 	fprintf(stderr, " [");
2714 	if ((g->GFM >> 6) == 0)
2715 	  dump_gen_sum(g->GFM & 0x3f);
2716 	else print_mod_sum(g->GFM);
2717 
2718 	fprintf(stderr, "]->[");
2719 	if (osc_run(g->GMODE) == 2)
2720 	  fprintf(stderr, "OUT%d", g->GO & 0xf);
2721 	else dump_gen_sum(g->GSUM);
2722 
2723 	fprintf(stderr, " (%d)], (amp: %.3f, freq: %.3f",
2724 		gen_mem_readers(g->GSUM),
2725 		gen_amp(g),
2726 		g->f_GJ * 0.5 * srate);
2727 	if (g->f_GJ == 0.0)
2728 	  fprintf(stderr, ", phase: %.3f", g->f_GK);
2729 
2730 	fprintf(stderr, ")\n");
2731       }
2732   fprintf(stderr, "\n");
2733 
2734   for (i = 0; i < MODIFIERS; i++)
2735     if (mod_mode(mods[i]->MMODE) != M_INACTIVE)
2736       {
2737 	modifier *m;
2738 	m = mods[i];
2739 	fprintf(stderr, "m%d %s ", i, mode_name(mod_mode(m->MMODE)));
2740 
2741 	if (mod_mode(m->MMODE) == M_MIXING)
2742 	  fprintf(stderr, "%.4f * ", m->f_M0);
2743 	fprintf(stderr, "A");
2744 	print_mod_sum(m->MIN);
2745 	fprintf(stderr, "], ");
2746 
2747 	if (mod_mode(m->MMODE) == M_MIXING)
2748 	  fprintf(stderr, "%.4f * ", m->f_M1);
2749 	fprintf(stderr, "B");
2750 	if (mod_mode(m->MMODE) == M_DELAY)
2751 	  {
2752 	    delay *d;
2753 	    d = dlys[m->MRM & 0x1f];
2754 	    fprintf(stderr, "[delay: %d (%.4f)", m->MRM & 0x1f, delay_memory[d->X + d->Y]);
2755 	    fprintf(stderr, ", M0: %.4f, M1: %.4f, L0: %.4f, L1: %.4f", m->f_M0, m->f_M1, m->f_L0, m->f_L1);
2756 	  }
2757 	else print_mod_sum(m->MRM);
2758 
2759 	fprintf(stderr, "]->[");
2760 	if ((m->MSUM >> 6) != 0)
2761 	  fprintf(stderr, "-replace");
2762 	dump_mod_sum(m->MSUM & 0x3f);
2763 
2764 	fprintf(stderr, " (%d)]\n", mod_mem_readers(m->MSUM));
2765       }
2766   fprintf(stderr, "\n");
2767 
2768   for (i = 0; i < DELAYS; i++)
2769     if (dlys[i]->P != D_INACTIVE)
2770       {
2771 	delay *d;
2772 	d = dlys[i];
2773 	fprintf(stderr, "d%d %s %.3f (%d + %d of %d)\n",
2774 		i, P_name(d->P),
2775 		delay_memory[d->X + d->Y],
2776 		d->X, d->Y, d->Z);
2777       }
2778   {
2779     double dmax;
2780     dmax = fabs(delay_memory[0]);
2781     for (i = 1; i < DELAY_MEMORY_SIZE; i++)
2782       if (fabs(delay_memory[i]) > dmax)
2783 	dmax = fabs(delay_memory[i]);
2784     fprintf(stderr, "delay memory peak: %.4f\n\n", dmax);
2785   }
2786 }
2787 
2788 
2789 
2790 /* ---------------------------------------- main program ---------------------------------------- */
2791 
main(int argc,char ** argv)2792 int main(int argc, char **argv)
2793 {
2794   if (argc < 2)
2795     fprintf(stderr, "sam filename [read_data file] [srate]\n"); /* mmm */
2796   else
2797     {
2798       FILE *sam_file;
2799       filename = argv[1];
2800 
2801       sam_file = fopen(filename, "r");
2802       if (!sam_file)
2803 	fprintf(stderr, "can't find %s\n", filename);
2804       else
2805 	{
2806 	  long size;
2807 	  fseek(sam_file, 0, SEEK_END);
2808 	  size = ftell(sam_file);
2809 	  rewind(sam_file);
2810 
2811 	  if (size <= 0)
2812 	    {
2813 	      fprintf(stderr, "%s is empty\n", filename);
2814 	      fclose(sam_file);
2815 	    }
2816 	  else
2817 	    {
2818 	      size_t bytes;
2819 	      unsigned char *command;
2820 	      int i;
2821 
2822 	      if (argc > 2)
2823 		{
2824 		  read_data_file = fopen(argv[2], "r");
2825 		  if (argc > 3)
2826 		    {
2827 		      /* mmm - set srate explicitly.  I had an inexplicably high max tick setting in one sam file with read data input. */
2828 		      sscanf(argv[3], "%d", &srate);
2829 		    }
2830 		}
2831 
2832 	      start_clean();
2833 
2834 	      command = (unsigned char *)calloc(size + 1, sizeof(unsigned char));
2835 	      bytes = fread(command, sizeof(unsigned char), size, sam_file);
2836 	      fclose(sam_file);
2837 
2838 	      /* these were stored in at least 2 different formats
2839 	       *
2840 	       * FASTF.SAM:  "Type: 32BITR BADSAM ;Looks like a SAM command file but has questionable data"
2841 	       * MACDON.SAM: "Type: SAM SIMPLE    ;Simple SAM command file (corresponding sound file possible)"
2842 	       *
2843 	       * FASTF was written as 32 bits (using the 1st case below), and MACDON as 36 (using the 2nd case).
2844 	       * it looks like someone got a flag backwards, and wrote the known-good 32-bit files as 36,
2845 	       *    and the possibly not-32 bit files as 32. I can't find the corresponding code in the writers
2846 	       *    that Nando found on the exabyte tapes.
2847 	       *
2848 	       * The *.SAM.snd files are raw big-endian 24-bit int data (stereo?)
2849 	       *    with many (6?) renditions?
2850 	       */
2851 
2852 #if 1
2853 	      if ((command[0] != 0) || /* just a first guess */
2854 		  (command[1] != 0))
2855 		{
2856 		  fprintf(stderr, "32\n");
2857 		  total_commands = bytes / 4;
2858 		  current_command = 0;
2859 		  for (i = 0; i < bytes; i += 4)
2860 		    {
2861 		      int cmd;
2862 		      int b1, b2, b3, b4;
2863 		      b1 = command[i + 0];
2864 		      b2 = command[i + 1];
2865 		      b3 = command[i + 2];
2866 		      b4 = command[i + 3];
2867 		      cmd = b4 + (b3 << 8) + (b2 << 16) + (b1 << 24);
2868 		      handle_command(cmd);
2869 		    }
2870 		}
2871 	      else
2872 		{
2873 		  fprintf(stderr, "36\n");
2874 		  total_commands = bytes / 5;
2875 		  current_command = 0;
2876 		  for (i = 0; i < bytes; i += 5)
2877 		    {
2878 		      int cmd;
2879 		      int b1, b2, b3, b4, b5;
2880 		      b1 = command[i + 0];
2881 		      b2 = command[i + 1];
2882 		      b3 = command[i + 2];
2883 		      b4 = command[i + 3];
2884 		      b5 = command[i + 4];
2885 		      cmd = ((b5 >> 4) & 0xff) + (b4 << 4) + (b3 << 12) + (b2 << 20) + ((b1 & 0xff) << 28);
2886 		      handle_command(cmd);
2887 		    }
2888 		}
2889 #else
2890 	      /* another format that Mike used:
2891 	       *   cmd = (b1 << 28) | (b2 << 24) | (b3 << 16) | (b4 << 8) | b5;
2892 	       */
2893 	      total_commands = bytes / 5;
2894 	      current_command = 0;
2895 	      for (i = 0; i < bytes; i += 5)
2896 		{
2897 		  int cmd;
2898 		  int b1, b2, b3, b4, b5;
2899 		  b1 = command[i + 0];
2900 		  b2 = command[i + 1];
2901 		  b3 = command[i + 2];
2902 		  b4 = command[i + 3];
2903 		  b5 = command[i + 4];
2904 		  cmd = (b1 << 28) | (b2 << 24) | (b3 << 16) | (b4 << 8) | b5;
2905 		  handle_command(cmd);
2906 		}
2907 #endif
2908 	    }
2909 
2910 	  all_done();
2911 	}
2912     }
2913   return(0);
2914 }
2915 
2916 /* on the cover of an old copy of the specs:
2917 
2918    NOT TO LEAVE THE MUSIC ROOM                 [red ink and underlined]
2919 
2920    Would be an awful fate,                     [pencilled in below]
2921    Said Cleopatra to her groom,
2922    and struck him on the pate!
2923 */
2924