1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 /*
23 * We are going to use this file, sonic-6, as the first review of have SMP
24 * support. Prior to this there was a lot of local storage that would prevent
25 * having multiple threads running this code and it needs to be made multi-
26 * entrant. This means amongst other things burying parameters in the baudio
27 * structure passed on the stack however the different operators also need to
28 * have this before we can have it generally deployable. There are issues here
29 * though. We only have a single set of buffers for the whole baudio, not per
30 * voice and if multiple cores start using them the result is non-determinate.
31 *
32 * This probably means the best we can target is that each baudio can be a
33 * separate thread, but not voices within one baudio.
34 *
35 * This should only affect the audio engine code, the init operation will only
36 * have a single thread.
37 */
38 /*#define DEBUG */
39
40 #include "bristol.h"
41 #include "bristolsonic6.h"
42
43 extern int buildCurrentTable(Baudio *, float);
44
45 static int
sonic6GlobalController(Baudio * baudio,u_char controller,u_char operator,float value)46 sonic6GlobalController(Baudio *baudio, u_char controller,
47 u_char operator, float value)
48 {
49 int ivalue = value * CONTROLLER_RANGE;
50
51 #ifdef DEBUG
52 printf("sonic6GlobalControl(%i, %i, %f)\n", controller, operator, value);
53 #endif
54
55 /*
56 * Reverb
57 */
58 if (controller == 101)
59 {
60 if (baudio->effect[0] == NULL)
61 return(0);
62
63 if (operator == 0)
64 {
65 baudio->effect[0]->param->param[operator].float_val = value;
66 baudio->effect[0]->param->param[operator].int_val = 1;
67 } else
68 baudio->effect[0]->param->param[operator].float_val = value;
69 /*
70 printf("%f F %f, C %f, W %f, G %f ? %f\n",
71 baudio->effect[0]->param->param[0].float_val,
72 baudio->effect[0]->param->param[1].float_val,
73 baudio->effect[0]->param->param[2].float_val,
74 baudio->effect[0]->param->param[3].float_val,
75 baudio->effect[0]->param->param[4].float_val,
76 baudio->effect[0]->param->param[5].float_val);
77 */
78
79 return(0);
80 }
81
82 if (controller != 126)
83 return(0);
84
85 switch (operator) {
86 case 0:
87 baudio->glide = value * value * baudio->glidemax;
88 break;
89 case 1:
90 SONICLOCAL->mastervolume = value;
91 break;
92 case 2:
93 baudio->gtune = 1.0
94 + (baudio->note_diff - 1)
95 * (value * 2 - 1);
96
97 buildCurrentTable(baudio, baudio->gtune);
98 alterAllNotes(baudio);
99 break;
100 case 10:
101 SONICLOCAL->directA = value * 128;
102 break;
103 case 11:
104 SONICLOCAL->directB = value * 128;
105 break;
106 case 12:
107 SONICLOCAL->directRM = value * 64;
108 break;
109 case 13:
110 SONICLOCAL->genAB = value;
111 break;
112 case 14:
113 SONICLOCAL->genXY = value;
114 break;
115 case 15:
116 /* Waveform */
117 baudio->mixflags &= ~X_WAVE_MASK;
118 baudio->mixflags |= (X_TRI << ivalue);
119 break;
120 case 16:
121 /* Mod */
122 baudio->mixflags &= ~X_MOD_MASK;
123 baudio->mixflags |= (X_MOD_ADSR << ivalue);
124 break;
125 case 17:
126 /* Waveform */
127 baudio->mixflags &= ~Y_WAVE_MASK;
128 baudio->mixflags |= (Y_TRI << ivalue);
129 break;
130 case 18:
131 /* Mod */
132 baudio->mixflags &= ~Y_MOD_MASK;
133 baudio->mixflags |= (Y_MOD_ADSR << ivalue);
134 break;
135 case 19:
136 /* Mod */
137 if (value == 0)
138 baudio->mixflags &= ~X_MULTI;
139 else
140 baudio->mixflags |= X_MULTI;
141 break;
142 case 20:
143 /* Mod */
144 if (value == 0)
145 baudio->mixflags &= ~Y_MULTI;
146 else
147 baudio->mixflags |= Y_MULTI;
148 break;
149 case 21:
150 SONICLOCAL->moda_xy = value * value * 50;
151 break;
152 case 22:
153 SONICLOCAL->moda_adsr = value * 4;
154 break;
155 case 23:
156 SONICLOCAL->modb_a = value * value * value;
157 break;
158 case 24:
159 SONICLOCAL->modb_xy = value * value * 50;
160 break;
161 case 25:
162 SONICLOCAL->modb_pwm = value * 512;
163 break;
164 case 26:
165 /* Mod */
166 if (value == 0)
167 baudio->mixflags |= RM_A;
168 else
169 baudio->mixflags &= ~RM_A;
170 break;
171 case 27:
172 /* Mod */
173 if (value == 0)
174 baudio->mixflags |= RM_XY;
175 else
176 baudio->mixflags &= ~RM_XY;
177 break;
178 case 28:
179 SONICLOCAL->mix_ab = value * 4;
180 break;
181 case 29:
182 SONICLOCAL->mix_rm = value * 0.5;
183 break;
184 case 30:
185 SONICLOCAL->mix_ext = value;
186 break;
187 case 31:
188 SONICLOCAL->mix_noise = value;
189 break;
190 case 32:
191 baudio->mixflags &= ~(A_LFO|A_KBD);
192 if (ivalue == 2)
193 baudio->mixflags |= A_LFO;
194 else if (ivalue == 1)
195 baudio->mixflags |= A_KBD;
196 break;
197 case 33:
198 SONICLOCAL->fmodadsr = value * 2;
199 break;
200 case 34:
201 SONICLOCAL->fmodxy = value * value * 24;
202 break;
203 case 35:
204 /* Mod */
205 if (value == 0)
206 baudio->mixflags &= ~BYPASS;
207 else
208 baudio->mixflags |= BYPASS;
209 break;
210 case 36:
211 /* Mod */
212 if (value == 0)
213 baudio->mixflags &= ~X_TRIGGER;
214 else
215 baudio->mixflags |= X_TRIGGER;
216 break;
217 case 37:
218 /* Mod */
219 if (value == 0)
220 baudio->mixflags &= ~Y_TRIGGER;
221 else
222 baudio->mixflags |= Y_TRIGGER;
223 break;
224 }
225
226 return(0);
227 }
228
229 int
operateSonic6Preops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)230 operateSonic6Preops(audioMain *audiomain, Baudio *baudio,
231 bristolVoice *voice, register float *startbuf)
232 {
233 bristolbzero(SONICLOCAL->outbuf, audiomain->segmentsize);
234
235 /*
236 * Noise - we do this early for the same reason as oscillator 3
237 */
238 if ((baudio->mixflags & MULTI_NOISE) == 0)
239 {
240 bristolbzero(SONICLOCAL->noisebuf, audiomain->segmentsize);
241
242 audiomain->palette[(*baudio->sound[6]).index]->specs->io[0].buf
243 = SONICLOCAL->noisebuf;
244 (*baudio->sound[6]).operate(
245 (audiomain->palette)[4],
246 voice,
247 (*baudio->sound[6]).param,
248 voice->locals[voice->index][6]);
249 }
250
251 if ((baudio->mixflags & X_MULTI) == 0)
252 {
253 /*
254 * Operate LFO if we have a single LFO per synth.
255 */
256 audiomain->palette[16]->specs->io[1].buf
257 = audiomain->palette[16]->specs->io[2].buf
258 = audiomain->palette[16]->specs->io[3].buf
259 = audiomain->palette[16]->specs->io[4].buf
260 = audiomain->palette[16]->specs->io[5].buf
261 = audiomain->palette[16]->specs->io[6].buf
262 = NULL;
263
264 audiomain->palette[16]->specs->io[0].buf = SONICLOCAL->noisebuf;
265
266 switch (baudio->mixflags & X_WAVE_MASK) {
267 default:
268 case X_TRI:
269 audiomain->palette[16]->specs->io[1].buf = SONICLOCAL->lfoxbuf;
270 break;
271 case X_SAW:
272 audiomain->palette[16]->specs->io[6].buf = SONICLOCAL->lfoxbuf;
273 break;
274 case X_RAMP:
275 audiomain->palette[16]->specs->io[5].buf = SONICLOCAL->lfoxbuf;
276 break;
277 case X_SQUARE:
278 audiomain->palette[16]->specs->io[2].buf = SONICLOCAL->lfoxbuf;
279 break;
280 }
281
282 (*baudio->sound[7]).operate(
283 (audiomain->palette)[16],
284 voice,
285 (*baudio->sound[7]).param,
286 baudio->locals[voice->index][7]);
287
288 bufadd(SONICLOCAL->lfoxbuf, 1.0, audiomain->samplecount);
289 }
290
291 if ((baudio->mixflags & Y_MULTI) == 0)
292 {
293 audiomain->palette[16]->specs->io[1].buf
294 = audiomain->palette[16]->specs->io[2].buf
295 = audiomain->palette[16]->specs->io[3].buf
296 = audiomain->palette[16]->specs->io[4].buf
297 = audiomain->palette[16]->specs->io[5].buf
298 = audiomain->palette[16]->specs->io[6].buf
299 = NULL;
300
301 audiomain->palette[16]->specs->io[0].buf = SONICLOCAL->noisebuf;
302
303 switch (baudio->mixflags & Y_WAVE_MASK) {
304 default:
305 case Y_TRI:
306 audiomain->palette[16]->specs->io[1].buf = SONICLOCAL->lfoybuf;
307 break;
308 case Y_SAW:
309 audiomain->palette[16]->specs->io[6].buf = SONICLOCAL->lfoybuf;
310 break;
311 case Y_RAMP:
312 audiomain->palette[16]->specs->io[5].buf = SONICLOCAL->lfoybuf;
313 break;
314 case Y_RAND:
315 audiomain->palette[16]->specs->io[3].buf = SONICLOCAL->lfoybuf;
316 break;
317 }
318
319 (*baudio->sound[8]).operate(
320 (audiomain->palette)[16],
321 voice,
322 (*baudio->sound[8]).param,
323 baudio->locals[voice->index][8]);
324
325 bufadd(SONICLOCAL->lfoybuf, 1.0, audiomain->samplecount);
326 }
327
328 return(0);
329 }
330
331 int
operateOneSonic6Voice(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)332 operateOneSonic6Voice(audioMain *audiomain, Baudio *baudio,
333 bristolVoice *voice, register float *startbuf)
334 {
335 #ifdef DEBUG
336 audiomain->debuglevel = -1;
337 #endif
338
339 bristolbzero(SONICLOCAL->freqbuf, audiomain->segmentsize);
340 bristolbzero(SONICLOCAL->oscabuf, audiomain->segmentsize);
341 bristolbzero(SONICLOCAL->oscbbuf, audiomain->segmentsize);
342 bristolbzero(SONICLOCAL->filtbuf, audiomain->segmentsize);
343
344 /* Multi Mods */
345 if (baudio->mixflags & MULTI_NOISE)
346 {
347 bristolbzero(SONICLOCAL->noisebuf, audiomain->segmentsize);
348
349 audiomain->palette[(*baudio->sound[6]).index]->specs->io[0].buf
350 = SONICLOCAL->noisebuf;
351 (*baudio->sound[6]).operate(
352 (audiomain->palette)[4],
353 voice,
354 (*baudio->sound[6]).param,
355 voice->locals[voice->index][6]);
356 }
357
358 if (baudio->mixflags & X_MULTI)
359 {
360 /*
361 * Operate LFO if we have a single LFO per synth.
362 */
363 audiomain->palette[16]->specs->io[1].buf
364 = audiomain->palette[16]->specs->io[2].buf
365 = audiomain->palette[16]->specs->io[3].buf
366 = audiomain->palette[16]->specs->io[4].buf
367 = audiomain->palette[16]->specs->io[5].buf
368 = audiomain->palette[16]->specs->io[6].buf
369 = NULL;
370
371 audiomain->palette[16]->specs->io[0].buf = SONICLOCAL->noisebuf;
372
373 switch (baudio->mixflags & X_WAVE_MASK) {
374 default:
375 case X_TRI:
376 audiomain->palette[16]->specs->io[1].buf = SONICLOCAL->lfoxbuf;
377 break;
378 case X_SAW:
379 audiomain->palette[16]->specs->io[6].buf = SONICLOCAL->lfoxbuf;
380 break;
381 case X_RAMP:
382 audiomain->palette[16]->specs->io[5].buf = SONICLOCAL->lfoxbuf;
383 break;
384 case X_SQUARE:
385 audiomain->palette[16]->specs->io[2].buf = SONICLOCAL->lfoxbuf;
386 break;
387 }
388
389 (*baudio->sound[7]).operate(
390 (audiomain->palette)[16],
391 voice,
392 (*baudio->sound[7]).param,
393 baudio->locals[voice->index][7]);
394
395 bufadd(SONICLOCAL->lfoxbuf, 1.0, audiomain->samplecount);
396 }
397
398 if (baudio->mixflags & Y_MULTI)
399 {
400 audiomain->palette[16]->specs->io[1].buf
401 = audiomain->palette[16]->specs->io[2].buf
402 = audiomain->palette[16]->specs->io[3].buf
403 = audiomain->palette[16]->specs->io[4].buf
404 = audiomain->palette[16]->specs->io[5].buf
405 = audiomain->palette[16]->specs->io[6].buf
406 = NULL;
407
408 audiomain->palette[16]->specs->io[0].buf = SONICLOCAL->noisebuf;
409
410 switch (baudio->mixflags & Y_WAVE_MASK) {
411 default:
412 case Y_TRI:
413 audiomain->palette[16]->specs->io[1].buf = SONICLOCAL->lfoybuf;
414 break;
415 case Y_SAW:
416 audiomain->palette[16]->specs->io[6].buf = SONICLOCAL->lfoybuf;
417 break;
418 case Y_RAMP:
419 audiomain->palette[16]->specs->io[5].buf = SONICLOCAL->lfoybuf;
420 break;
421 case Y_RAND:
422 audiomain->palette[16]->specs->io[3].buf = SONICLOCAL->lfoybuf;
423 break;
424 }
425
426 (*baudio->sound[8]).operate(
427 (audiomain->palette)[16],
428 voice,
429 (*baudio->sound[8]).param,
430 baudio->locals[voice->index][8]);
431
432 bufadd(SONICLOCAL->lfoybuf, 1.0, audiomain->samplecount);
433 }
434
435 /*
436 * Run the ADSR. We need to review all the various trigger options here
437 * for keyboard or the two LFO retriggers.
438 */
439 audiomain->palette[1]->specs->io[0].buf
440 = SONICLOCAL->adsrbuf;
441
442 if (voice->flags & (BRISTOL_KEYON|BRISTOL_KEYREON))
443 SONICLOCAL->xtrigstate = SONICLOCAL->ytrigstate = 0;
444
445 if (baudio->mixflags & X_TRIGGER)
446 {
447 if ((SONICLOCAL->xtrigstate < 0.5) &&
448 (*(SONICLOCAL->lfoxbuf) > 0.5))
449 voice->flags |= BRISTOL_KEYREON;
450 SONICLOCAL->xtrigstate = *(SONICLOCAL->lfoxbuf);
451 }
452
453 if (baudio->mixflags & Y_TRIGGER)
454 {
455 if ((SONICLOCAL->ytrigstate < 0.5) &&
456 (*(SONICLOCAL->lfoybuf) > 0.5))
457 voice->flags |= BRISTOL_KEYREON;
458 SONICLOCAL->ytrigstate = *(SONICLOCAL->lfoybuf);
459 }
460
461 (*baudio->sound[3]).operate(
462 (audiomain->palette)[1],
463 voice,
464 (*baudio->sound[3]).param,
465 voice->locals[voice->index][3]);
466
467 /*
468 * See if the LFO have to be tempered
469 */
470 switch (baudio->mixflags & X_MOD_MASK) {
471 case X_MOD_ADSR:
472 bufmerge(SONICLOCAL->lfoxbuf, 0.1,
473 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
474 bristolbzero(SONICLOCAL->lfoxbuf, audiomain->segmentsize);
475 audiomain->palette[2]->specs->io[0].buf = SONICLOCAL->scratch;
476 audiomain->palette[2]->specs->io[1].buf = SONICLOCAL->adsrbuf;
477 audiomain->palette[2]->specs->io[2].buf = SONICLOCAL->lfoxbuf;
478
479 (*baudio->sound[5]).operate(
480 (audiomain->palette)[2],
481 voice,
482 (*baudio->sound[5]).param,
483 voice->locals[voice->index][5]);
484 break;
485 case X_MOD_WHEEL:
486 bufmerge(SONICLOCAL->zerobuf, 0.0,
487 SONICLOCAL->lfoxbuf, voice->baudio->contcontroller[1],
488 audiomain->samplecount);
489 break;
490 }
491
492 /*
493 * See if the LFO have to be tempered
494 */
495 switch (baudio->mixflags & Y_MOD_MASK) {
496 case Y_MOD_ADSR:
497 bufmerge(SONICLOCAL->lfoybuf, 0.1,
498 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
499 audiomain->palette[2]->specs->io[0].buf = SONICLOCAL->scratch;
500 audiomain->palette[2]->specs->io[1].buf = SONICLOCAL->adsrbuf;
501 audiomain->palette[2]->specs->io[2].buf = SONICLOCAL->lfoybuf;
502
503 (*baudio->sound[5]).operate(
504 (audiomain->palette)[2],
505 voice,
506 (*baudio->sound[5]).param,
507 voice->locals[voice->index][5]);
508 break;
509 case Y_MOD_WHEEL:
510 bufmerge(SONICLOCAL->zerobuf, 0.0,
511 SONICLOCAL->lfoybuf, voice->baudio->contcontroller[1],
512 audiomain->samplecount);
513 break;
514 }
515
516 bufmerge(SONICLOCAL->lfoxbuf, 1.0 - SONICLOCAL->genXY,
517 SONICLOCAL->lfoxybuf, 0.0,
518 audiomain->samplecount);
519 bufmerge(SONICLOCAL->lfoybuf, SONICLOCAL->genXY,
520 SONICLOCAL->lfoxybuf, 1.0,
521 audiomain->samplecount);
522 /* Multi Mods done */
523
524 /* OSC A */
525 /*
526 * We need to do a couple of things here for the different OSC since one
527 * will track glide and the other will not. The first call does not use
528 * glide for Osc-A but does for Osc-B later. This dual use of the call is
529 * supported since only calling once with glide does not damage the glide
530 * parameters in the voice structure.
531 *
532 * We need to check for keyboard tracking, high (drone) or LFO settings.
533 */
534 if (baudio->mixflags & A_KBD)
535 fillFreqTable(baudio, voice, SONICLOCAL->freqbuf,
536 audiomain->samplecount, 0);
537 else {
538 float freq = 10.0, *bufptr = SONICLOCAL->freqbuf;
539 int i = audiomain->samplecount;
540
541 if (baudio->mixflags & A_LFO)
542 freq = 1.0;
543
544 for (; i > 0; i-=8)
545 {
546 *bufptr++ = freq;
547 *bufptr++ = freq;
548 *bufptr++ = freq;
549 *bufptr++ = freq;
550 *bufptr++ = freq;
551 *bufptr++ = freq;
552 *bufptr++ = freq;
553 *bufptr++ = freq;
554 }
555 }
556
557 /*
558 * Oscillator A
559 */
560 audiomain->palette[8]->specs->io[0].buf = SONICLOCAL->freqbuf;
561 audiomain->palette[8]->specs->io[1].buf = SONICLOCAL->zerobuf;
562 audiomain->palette[8]->specs->io[2].buf = SONICLOCAL->oscabuf;
563
564 /*
565 * Put in the mods. We will eventually use the switch to select between
566 * LFO, KBD, and KEY_LFO. Note: if genXY == 1.0 then we should route
567 * X->A and Y->B directly.
568 bufmerge(SONICLOCAL->freqbuf, 1.0,
569 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
570 */
571 if (SONICLOCAL->genXY == 1.0)
572 bufmerge(SONICLOCAL->lfoxbuf, SONICLOCAL->moda_xy,
573 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
574 else
575 bufmerge(SONICLOCAL->lfoxybuf, SONICLOCAL->moda_xy,
576 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
577 bufmerge(SONICLOCAL->adsrbuf, SONICLOCAL->moda_adsr,
578 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
579
580 /*
581 * Operate this oscillator
582 */
583 (*baudio->sound[0]).operate(
584 (audiomain->palette)[8],
585 voice,
586 (*baudio->sound[0]).param,
587 voice->locals[voice->index][0]);
588
589 /*
590 * See if we need to put this into the direct output.
591 */
592 if (SONICLOCAL->directA != 0)
593 bufmerge(SONICLOCAL->oscabuf, SONICLOCAL->directA,
594 baudio->leftbuf, 1.0, audiomain->samplecount);
595 /* OSC A done */
596
597 /* OSC B */
598 /* Get a frequence table with glide added in */
599 fillFreqTable(baudio, voice, SONICLOCAL->freqbuf,
600 audiomain->samplecount, 1);
601
602 /*
603 * Oscillator B
604 */
605 audiomain->palette[8]->specs->io[0].buf
606 = SONICLOCAL->freqbuf;
607 audiomain->palette[8]->specs->io[1].buf
608 = SONICLOCAL->scratch;
609 audiomain->palette[8]->specs->io[2].buf
610 = SONICLOCAL->oscbbuf;
611
612 /*
613 * Put in the mods. Note: if genXY == 1.0 then we should route
614 * X->A and Y->B directly.
615 */
616 if (SONICLOCAL->genXY == 1.0)
617 bufmerge(SONICLOCAL->lfoybuf, SONICLOCAL->modb_xy,
618 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
619 else
620 bufmerge(SONICLOCAL->lfoxybuf, SONICLOCAL->modb_xy,
621 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
622 bufmerge(SONICLOCAL->oscabuf, SONICLOCAL->modb_a,
623 SONICLOCAL->freqbuf, 1.0, audiomain->samplecount);
624 bufmerge(SONICLOCAL->lfoxybuf, SONICLOCAL->modb_pwm,
625 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
626
627 /*
628 * Operate this oscillator
629 */
630 (*baudio->sound[1]).operate(
631 (audiomain->palette)[8],
632 voice,
633 (*baudio->sound[1]).param,
634 voice->locals[voice->index][1]);
635
636 /*
637 * See if we need to put this into the direct output.
638 */
639 if (SONICLOCAL->directB != 0)
640 bufmerge(SONICLOCAL->oscbbuf, SONICLOCAL->directB,
641 baudio->leftbuf, 1.0, audiomain->samplecount);
642 /* OSC B done */
643
644 /* RING MOD */
645 if (baudio->mixflags & RM_A)
646 audiomain->palette[20]->specs->io[0].buf = SONICLOCAL->oscabuf;
647 else
648 audiomain->palette[20]->specs->io[0].buf = startbuf;
649 if (baudio->mixflags & RM_XY) {
650 audiomain->palette[20]->specs->io[1].buf = SONICLOCAL->scratch;
651 bufmerge(SONICLOCAL->lfoxybuf, 12.0,
652 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
653 } else
654 audiomain->palette[20]->specs->io[1].buf = SONICLOCAL->oscbbuf;
655
656 audiomain->palette[20]->specs->io[2].buf = SONICLOCAL->rmbuf;
657
658 (*baudio->sound[2]).operate(
659 (audiomain->palette)[20],
660 voice,
661 (*baudio->sound[2]).param,
662 voice->locals[voice->index][2]);
663
664 /*
665 * See if we need to put this into the direct output.
666 */
667 if (SONICLOCAL->directRM != 0)
668 bufmerge(SONICLOCAL->rmbuf, SONICLOCAL->directRM,
669 baudio->leftbuf, 1.0, audiomain->samplecount);
670 /* RING MOD done */
671
672 /* MIXER */
673 bufmerge(SONICLOCAL->oscbbuf, SONICLOCAL->genAB,
674 SONICLOCAL->oscabuf, 1.0 - SONICLOCAL->genAB, audiomain->samplecount);
675
676 bufmerge(SONICLOCAL->noisebuf, SONICLOCAL->mix_noise,
677 SONICLOCAL->rmbuf, SONICLOCAL->mix_rm, audiomain->samplecount);
678 bufmerge(SONICLOCAL->oscabuf, SONICLOCAL->mix_ab,
679 SONICLOCAL->rmbuf, 1.0, audiomain->samplecount);
680 bufmerge(startbuf, SONICLOCAL->mix_ext,
681 SONICLOCAL->rmbuf, 1.0, audiomain->samplecount);
682 /* MIXER done */
683
684 /* FILTER */
685 /*
686 * If we have mods on the filter, apply them here.
687 */
688 bufmerge(SONICLOCAL->adsrbuf, SONICLOCAL->fmodadsr,
689 SONICLOCAL->scratch, 0.0, audiomain->samplecount);
690 bufmerge(SONICLOCAL->lfoxybuf, SONICLOCAL->fmodxy,
691 SONICLOCAL->scratch, 1.0, audiomain->samplecount);
692
693 /*
694 * Run the mixed oscillators into the filter. Input and output buffers
695 * are the same.
696 */
697 audiomain->palette[3]->specs->io[0].buf = SONICLOCAL->rmbuf;
698 audiomain->palette[3]->specs->io[1].buf = SONICLOCAL->scratch;
699 audiomain->palette[3]->specs->io[2].buf = SONICLOCAL->filtbuf;
700
701 /* Filter input stage EQ. Brings signal in line with max filter output */
702 bufmerge(SONICLOCAL->zerobuf, 0.0,
703 SONICLOCAL->rmbuf, 96.0, audiomain->samplecount);
704
705 (*baudio->sound[4]).operate(
706 (audiomain->palette)[3],
707 voice,
708 (*baudio->sound[4]).param,
709 voice->locals[voice->index][4]);
710 /* FILTER done */
711
712 /* AMP */
713 if (baudio->mixflags & BYPASS)
714 bufmerge(SONICLOCAL->filtbuf, 12.0,
715 baudio->leftbuf, 1.0, audiomain->samplecount);
716 else {
717 audiomain->palette[2]->specs->io[0].buf = SONICLOCAL->filtbuf;
718 audiomain->palette[2]->specs->io[1].buf = SONICLOCAL->adsrbuf;
719 audiomain->palette[2]->specs->io[2].buf = baudio->leftbuf;
720
721 (*baudio->sound[5]).operate(
722 (audiomain->palette)[2],
723 voice,
724 (*baudio->sound[5]).param,
725 voice->locals[voice->index][5]);
726 }
727 /* AMP done */
728
729 return(0);
730 }
731
732 int
operateSonic6Postops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)733 operateSonic6Postops(audioMain *audiomain, Baudio *baudio,
734 bristolVoice *voice, register float *startbuf)
735 {
736 bufmerge(baudio->leftbuf, SONICLOCAL->mastervolume,
737 baudio->leftbuf, 0.0, audiomain->samplecount);
738
739 return(0);
740 }
741
742 static int
destroyOneSonic6Voice(audioMain * audiomain,Baudio * baudio)743 destroyOneSonic6Voice(audioMain *audiomain, Baudio *baudio)
744 {
745 printf("destroying Sonic-6\n");
746
747 bristolfree(SONICLOCAL->oscabuf);
748 bristolfree(SONICLOCAL->oscbbuf);
749 bristolfree(SONICLOCAL->noisebuf);
750 bristolfree(SONICLOCAL->freqbuf);
751 bristolfree(SONICLOCAL->filtbuf);
752 bristolfree(SONICLOCAL->rmbuf);
753 bristolfree(SONICLOCAL->lfoxbuf);
754 bristolfree(SONICLOCAL->lfoybuf);
755 bristolfree(SONICLOCAL->lfoxybuf);
756 bristolfree(SONICLOCAL->adsrbuf);
757 bristolfree(SONICLOCAL->outbuf);
758 bristolfree(SONICLOCAL->zerobuf);
759 bristolfree(SONICLOCAL->scratch);
760
761 return(0);
762 }
763
764 int
bristolSonic6Init(audioMain * audiomain,Baudio * baudio)765 bristolSonic6Init(audioMain *audiomain, Baudio *baudio)
766 {
767 printf("initialising Sonic-6\n");
768
769 baudio->soundCount = 9; /* Number of operators in this voice (Sonic6) */
770
771 /*
772 * Assign an array of sound pointers.
773 */
774 baudio->sound = (bristolSound **)
775 bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
776 baudio->effect = (bristolSound **)
777 bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
778
779 /*
780 * Two VCO
781 * RingMod
782 * Noise
783 * Env
784 * AMP
785 * Filter
786 * Two LFO, may run to three if we put in a global LFO
787 *
788 * Possibly add a reverb?
789 */
790 /* VCO */
791 initSoundAlgo( 8, 0, baudio, audiomain, baudio->sound);
792 initSoundAlgo( 8, 1, baudio, audiomain, baudio->sound);
793 /* Ring Mod */
794 initSoundAlgo( 20, 2, baudio, audiomain, baudio->sound);
795 /* An ADSR */
796 initSoundAlgo( 1, 3, baudio, audiomain, baudio->sound);
797 /* A filter */
798 initSoundAlgo( 3, 4, baudio, audiomain, baudio->sound);
799 /* An amplifier */
800 initSoundAlgo( 2, 5, baudio, audiomain, baudio->sound);
801 /* An noise source */
802 initSoundAlgo( 4, 6, baudio, audiomain, baudio->sound);
803 /* LFO */
804 initSoundAlgo( 16, 7, baudio, audiomain, baudio->sound);
805 initSoundAlgo( 16, 8, baudio, audiomain, baudio->sound);
806
807 baudio->param = sonic6GlobalController;
808 baudio->destroy = destroyOneSonic6Voice;
809 baudio->operate = operateOneSonic6Voice;
810 baudio->preops = operateSonic6Preops;
811 baudio->postops = operateSonic6Postops;
812
813 /* We need to flag this for the parallel filters */
814 baudio->mixlocals = bristolmalloc0(sizeof(bSonic6));
815
816 /*
817 * Put in a reverb on our effects list.
818 */
819 initSoundAlgo(22, 0, baudio, audiomain, baudio->effect);
820
821 if (SONICLOCAL->oscabuf == (float *) NULL)
822 SONICLOCAL->oscabuf = (float *) bristolmalloc0(audiomain->segmentsize);
823 if (SONICLOCAL->oscbbuf == (float *) NULL)
824 SONICLOCAL->oscbbuf = (float *) bristolmalloc0(audiomain->segmentsize);
825 if (SONICLOCAL->noisebuf == (float *) NULL)
826 SONICLOCAL->noisebuf = (float *) bristolmalloc0(audiomain->segmentsize);
827 if (SONICLOCAL->freqbuf == (float *) NULL)
828 SONICLOCAL->freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
829 if (SONICLOCAL->filtbuf == (float *) NULL)
830 SONICLOCAL->filtbuf = (float *) bristolmalloc0(audiomain->segmentsize);
831 if (SONICLOCAL->rmbuf == (float *) NULL)
832 SONICLOCAL->rmbuf = (float *) bristolmalloc0(audiomain->segmentsize);
833 if (SONICLOCAL->lfoxbuf == (float *) NULL)
834 SONICLOCAL->lfoxbuf = (float *) bristolmalloc0(audiomain->segmentsize);
835 if (SONICLOCAL->lfoybuf == (float *) NULL)
836 SONICLOCAL->lfoybuf = (float *) bristolmalloc0(audiomain->segmentsize);
837 if (SONICLOCAL->lfoxybuf == (float *) NULL)
838 SONICLOCAL->lfoxybuf = (float *) bristolmalloc0(audiomain->segmentsize);
839 if (SONICLOCAL->adsrbuf == (float *) NULL)
840 SONICLOCAL->adsrbuf = (float *) bristolmalloc0(audiomain->segmentsize);
841 if (SONICLOCAL->outbuf == (float *) NULL)
842 SONICLOCAL->outbuf = (float *) bristolmalloc0(audiomain->segmentsize);
843 if (SONICLOCAL->zerobuf == (float *) NULL)
844 SONICLOCAL->zerobuf = (float *) bristolmalloc0(audiomain->segmentsize);
845 if (SONICLOCAL->scratch == (float *) NULL)
846 SONICLOCAL->scratch = (float *) bristolmalloc0(audiomain->segmentsize);
847
848 return(0);
849 }
850
851