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