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 /*#define DEBUG */
22 
23 #include "bristol.h"
24 #include "bristolmm.h"
25 #include "bristolobx.h"
26 
27 /*
28  * Use of these obx global buffers will be an issue with use of multiple
29  * audio threads, unless we ensure a single thread deals with any given algo
30  * type, since then they are only used sequentially.
31  *
32  * (This file was copied from the prophet, hence shares much of the code)
33  */
34 static float *freq = (float *) NULL;
35 static float *freqbuf = (float *) NULL;
36 static float *adsrbuf = (float *) NULL;
37 static float *filtbuf = (float *) NULL;
38 static float *noisebuf = (float *) NULL;
39 static float *oscbbuf = (float *) NULL;
40 static float *oscabuf = (float *) NULL;
41 static float *scratchbuf = (float *) NULL;
42 
43 static float *lfosqr = (float *) NULL;
44 static float *lfo = (float *) NULL;
45 static float *lfosine = (float *) NULL;
46 static float *modsine = (float *) NULL;
47 static float *lfosh = (float *) NULL;
48 
49 int
obxController(Baudio * baudio,u_char operator,u_char controller,float value)50 obxController(Baudio *baudio, u_char operator, u_char controller, float value)
51 {
52 	int ivalue = value * CONTROLLER_RANGE;
53 
54 #ifdef DEBUG
55 	printf("bristolOBXControl(%i, %i, %f)\n", operator, controller, value);
56 #endif
57 
58 	if (operator != 126)
59 		return(0);
60 
61 	switch (controller) {
62 		case 0:
63 			baudio->glide = value * value * baudio->glidemax;
64 			break;
65 		case 1:
66 			if (ivalue == 0)
67 				baudio->mixflags &= ~BRISTOL_V_UNISON;
68 			else
69 				baudio->mixflags |= BRISTOL_V_UNISON;
70 			break;
71 		case 2: /* Global tune */
72 			baudio->gtune = 1.0
73 				+ (baudio->note_diff - 1)
74 				* (value * 2 - 1);
75 
76 			buildCurrentTable(baudio, baudio->gtune);
77 			alterAllNotes(baudio);
78 			break;
79 		case 3: /* S/H */
80 			if (ivalue == 0)
81 				baudio->mixflags &= ~O_S_H;
82 			else
83 				baudio->mixflags |= O_S_H;
84 			break;
85 		case 4: /* Depth Mod 1 - float */
86 			((pmods *) baudio->mixlocals)->d_mod1 = value;
87 			break;
88 		case 5: /* Osc1 freq */
89 			if (ivalue == 0)
90 				baudio->mixflags &= ~O_FREQ_1;
91 			else
92 				baudio->mixflags |= O_FREQ_1;
93 			break;
94 		case 6: /* Osc2 freq */
95 			if (ivalue == 0)
96 				baudio->mixflags &= ~O_FREQ_2;
97 			else
98 				baudio->mixflags |= O_FREQ_2;
99 			break;
100 		case 7: /* Filt mod */
101 			if (ivalue == 0)
102 				baudio->mixflags &= ~O_FILT;
103 			else
104 				baudio->mixflags |= O_FILT;
105 			break;
106 		case 8: /* Depth Mod 2 - float */
107 			((pmods *) baudio->mixlocals)->d_mod2 = value;
108 			break;
109 		case 9: /* PWM Osc1 */
110 			if (ivalue == 0)
111 				baudio->mixflags &= ~O_PWM_1;
112 			else
113 				baudio->mixflags |= O_PWM_1;
114 			break;
115 		case 10: /* PWM Osc2 */
116 			if (ivalue == 0)
117 				baudio->mixflags &= ~O_PWM_2;
118 			else
119 				baudio->mixflags |= O_PWM_2;
120 			break;
121 		case 11: /* Crossmod A->B */
122 			if (ivalue == 0)
123 				baudio->mixflags &= ~O_XMOD;
124 			else
125 				baudio->mixflags |= O_XMOD;
126 			break;
127 		case 12: /* Osc1->Filt */
128 			if (ivalue == 0)
129 				baudio->mixflags &= ~O_F_OSC1;
130 			else
131 				baudio->mixflags |= O_F_OSC1;
132 			break;
133 		case 13: /* KBD->Filt */
134 			if (ivalue == 0)
135 				baudio->mixflags &= ~O_F_KBD;
136 			else
137 				baudio->mixflags |= O_F_KBD;
138 			break;
139 		case 14: /* Osc2->Filt */
140 			if (ivalue == 0)
141 				baudio->mixflags &= ~O_F_OSC2_1;
142 			else
143 				baudio->mixflags |= O_F_OSC2_1;
144 			break;
145 		case 15: /* Osc2->Filt */
146 			if (ivalue == 0)
147 				baudio->mixflags &= ~O_F_OSC2_2;
148 			else
149 				baudio->mixflags |= O_F_OSC2_2;
150 			break;
151 		case 16: /* Noise->Filt */
152 			if (ivalue == 0)
153 				baudio->mixflags &= ~O_F_NOISE1;
154 			else
155 				baudio->mixflags |= O_F_NOISE1;
156 			break;
157 		case 17: /* Noise->Filt */
158 			if (ivalue == 0)
159 				baudio->mixflags &= ~O_F_NOISE2;
160 			else
161 				baudio->mixflags |= O_F_NOISE2;
162 			break;
163 		case 18: /* Trem */
164 			if (ivalue == 0)
165 				baudio->mixflags &= ~O_TREM;
166 			else
167 				baudio->mixflags |= O_TREM;
168 			break;
169 		case 19: /* LFO Sine */
170 			if (ivalue == 0)
171 				baudio->mixflags &= ~O_LFO_SINE;
172 			else
173 				baudio->mixflags |= O_LFO_SINE;
174 			break;
175 		case 20: /* LFO Square */
176 			if (ivalue == 0)
177 				baudio->mixflags &= ~O_LFO_SQUARE;
178 			else
179 				baudio->mixflags |= O_LFO_SQUARE;
180 			break;
181 		case 21: /* S/H */
182 			if (ivalue == 0)
183 				baudio->mixflags &= ~O_LFO_SH;
184 			else
185 				baudio->mixflags |= O_LFO_SH;
186 			break;
187 		case 22: /* Multi LFO */
188 			if (ivalue == 0)
189 				baudio->mixflags &= ~O_MULTI_LFO;
190 			else
191 				baudio->mixflags |= O_MULTI_LFO;
192 			break;
193 		case 23: /* Envmods */
194 			if (ivalue == 0)
195 				baudio->mixflags &= ~O_ENV_MOD;
196 			else
197 				baudio->mixflags |= O_ENV_MOD;
198 			break;
199 		case 24: /* 4Pole */
200 			if (ivalue == 0)
201 				baudio->mixflags &= ~O_F_4POLE;
202 			else
203 				baudio->mixflags |= O_F_4POLE;
204 			break;
205 		case 25: /* Layer modes */
206 			if (ivalue == 0)
207 				baudio->mixflags &= ~O_MOD1_ENABLE;
208 			else
209 				baudio->mixflags |= O_MOD1_ENABLE;
210 			break;
211 		case 26: /* Mod LFO Depth */
212 			((pmods *) baudio->mixlocals)->wheelmod = value;
213 			break;
214 		case 27: /* Multi Mod LFO */
215 			if (ivalue == 0)
216 				baudio->mixflags &= ~O_MOD2_ENABLE;
217 			else
218 				baudio->mixflags |= O_MOD2_ENABLE;
219 			break;
220 		case 28: /* Pan */
221 			((pmods *) baudio->mixlocals)->pan = value;
222 			break;
223 		case 29: /* Modulate PWM */
224 			if (ivalue == 0)
225 				baudio->mixflags &= ~O_MOD_PWM;
226 			else
227 				baudio->mixflags |= O_MOD_PWM;
228 			break;
229 		case 30: /* Voice selections */
230 			if (value > 0.0)
231 				baudio->voicecount = ((pmods *) baudio->mixlocals)->voicecount;
232 			else
233 				baudio->voicecount =
234 						((pmods *) baudio->mixlocals)->voicecount >> 1;
235 			printf("voicecount now %i\n", baudio->voicecount);
236 			break;
237 	}
238 	return(0);
239 }
240 
241 /*
242  * Preops will do noise, and one oscillator - the LFO.
243  */
244 int
operateOBXPreops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)245 operateOBXPreops(audioMain *audiomain, Baudio *baudio,
246 bristolVoice *voice, register float *startbuf)
247 {
248 	register int samplecount = audiomain->samplecount;
249 
250 #ifdef DEBUG
251 	if ((audiomain->debuglevel & BRISTOL_DEBUG_MASK) > BRISTOL_DEBUG5)
252 		printf("operateOBXPreops(%x, %x, %x) %i\n",
253 			baudio, voice, startbuf, baudio->cvoices);
254 #endif
255 
256 	if (freqbuf == (float *) NULL)
257 		freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
258 
259 	if (noisebuf == (float *) NULL)
260 		noisebuf = (float *) bristolmalloc0(audiomain->segmentsize);
261 
262 	bristolbzero(noisebuf, audiomain->segmentsize);
263 
264 /* NOISE - This should go in a preops call.... */
265 	/*
266 	 * Noise - we do this early for the same reason as oscillator 3
267 	 */
268 	audiomain->palette[(*baudio->sound[7]).index]->specs->io[0].buf = noisebuf;
269 	(*baudio->sound[7]).operate(
270 		(audiomain->palette)[4],
271 		voice,
272 		(*baudio->sound[7]).param,
273 		voice->locals[voice->index][7]);
274 /* NOISE OVER */
275 
276 /* LFO */
277 	/*
278 	 * Third oscillator. We do this first, since it may be used to modulate
279 	 * the first two oscillators.
280 	 */
281 	if ((baudio->mixflags & O_MULTI_LFO) == 0)
282 	{
283 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[0].buf
284 			= noisebuf;
285 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[1].buf
286 			= lfo;
287 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[2].buf
288 			= lfosqr;
289 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[3].buf
290 			= lfosh;
291 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[4].buf
292 			= lfosine;
293 
294 		(*baudio->sound[2]).operate(
295 			(audiomain->palette)[16],
296 			voice,
297 			(*baudio->sound[2]).param,
298 			baudio->locals[voice->index][2]);
299 
300 		/*
301 		 * See what LFO options to mix
302 		 */
303 		if (baudio->mixflags & (O_LFO_SINE|O_LFO_SQUARE|O_LFO_SH))
304 		{
305 			bristolbzero(lfo, audiomain->segmentsize);
306 			if (baudio->mixflags & O_LFO_SINE)
307 				bufmerge(lfosine, 1.0, lfo, 1.0, samplecount);
308 			if (baudio->mixflags & O_LFO_SQUARE)
309 				bufmerge(lfosqr, 1.0, lfo, 1.0, samplecount);
310 			if (baudio->mixflags & O_LFO_SH)
311 				bufmerge(lfosh, 0.1, lfo, 1.0, samplecount);
312 		}
313 	}
314 /* LFO OVER */
315 
316 /* MOD LFO */
317 	audiomain->palette[(*baudio->sound[8]).index]->specs->io[0].buf = NULL;
318 	audiomain->palette[(*baudio->sound[8]).index]->specs->io[1].buf = NULL;
319 	audiomain->palette[(*baudio->sound[8]).index]->specs->io[2].buf = NULL;
320 	audiomain->palette[(*baudio->sound[8]).index]->specs->io[3].buf = NULL;
321 	audiomain->palette[(*baudio->sound[8]).index]->specs->io[4].buf = modsine;
322 
323 	(*baudio->sound[8]).operate(
324 		(audiomain->palette)[16],
325 		voice,
326 		(*baudio->sound[8]).param,
327 		baudio->locals[voice->index][8]);
328 /* MODLFO OVER */
329 
330 	/*
331 	 * We cannot do the mod routing yet as much of it is poly.
332 	 *
333 	 */
334 	return(0);
335 }
336 
337 int
operateOneOBX(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)338 operateOneOBX(audioMain *audiomain, Baudio *baudio,
339 bristolVoice *voice, register float *startbuf)
340 {
341 	register int samplecount = audiomain->samplecount;
342 
343 	/*
344 	 * We need to run through every bristolSound on the baudio sound chain.
345 	 * We need to pass the correct set of parameters to each operator, and
346 	 * ensure they get the correct local variable set.
347 	 */
348 	if (freqbuf == NULL)
349 		return(0);
350 	if (adsrbuf == NULL)
351 		return(0);
352 
353 	bristolbzero(freqbuf, audiomain->segmentsize);
354 	bristolbzero(adsrbuf, audiomain->segmentsize);
355 	bristolbzero(filtbuf, audiomain->segmentsize);
356 	bristolbzero(oscbbuf, audiomain->segmentsize);
357 	bristolbzero(oscabuf, audiomain->segmentsize);
358 
359 /* ADSR - POLY MOD */
360 	/*
361 	 * Run the ADSR for the filter.
362 	 */
363 	audiomain->palette[(*baudio->sound[3]).index]->specs->io[0].buf = adsrbuf;
364 	(*baudio->sound[3]).operate(
365 		(audiomain->palette)[1],
366 		voice,
367 		(*baudio->sound[3]).param,
368 		voice->locals[voice->index][3]);
369 /* ADSR - POLY MOD - OVER */
370 
371 /* LFO */
372 	/*
373 	 * Third oscillator. We do this first, since it may be used to modulate
374 	 * the first two oscillators.
375 	 */
376 
377 	if (baudio->mixflags & O_MULTI_LFO)
378 	{
379 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[0].buf
380 			= noisebuf;
381 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[1].buf
382 			= lfo;
383 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[2].buf
384 			= lfosqr;
385 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[3].buf
386 			= lfosh;
387 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[4].buf
388 			= lfosine;
389 
390 		(*baudio->sound[2]).operate(
391 			(audiomain->palette)[16],
392 			voice,
393 			(*baudio->sound[2]).param,
394 			baudio->locals[voice->index][2]);
395 
396 		/*
397 		 * See what LFO options to mix
398 		 */
399 		if (baudio->mixflags & (O_LFO_SINE|O_LFO_SQUARE|O_LFO_SH))
400 		{
401 			bristolbzero(lfo, audiomain->segmentsize);
402 			if (baudio->mixflags & O_LFO_SINE)
403 				bufmerge(lfosine, 1.0, lfo, 1.0, samplecount);
404 			if (baudio->mixflags & O_LFO_SQUARE)
405 				bufmerge(lfosqr, 1.0, lfo, 1.0, samplecount);
406 			if (baudio->mixflags & O_LFO_SH)
407 				bufmerge(lfosh, 0.1, lfo, 1.0, samplecount);
408 		}
409 	}
410 /* LFO OVER */
411 
412 /* OSC A */
413 	/*
414 	 * First insert our buffer pointers, we do this by inserting the buffers
415 	 * into the existing opspec structures.
416 	 */
417 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[0].buf
418 		= freqbuf;
419 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[1].buf
420 		= scratchbuf;
421 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[2].buf
422 		= oscabuf;
423 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[3].buf = 0;
424 
425 	/*
426 	 * Fill tmpbuf1 with our frequency information
427 	 */
428 	fillFreqTable(baudio, voice, freq, samplecount, 1);
429 
430 	/*
431 	 * If we have any mods on the oscillators, we need to put them in here.
432 	 * This should be under the control of polypressure and/or channelpressure?
433 	 */
434 	bzero(scratchbuf, audiomain->segmentsize);
435 	/*
436 	 * PUT IN MOD ROUTING. We have d_mod1 adjusting freq and d_mod2 adjusting
437 	 * PW
438 	 */
439 	bufmerge(freq, 1.0, freqbuf, 0.0, samplecount);
440 	if (baudio->mixflags & O_FREQ_1)
441 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod1 * 0.4,
442 			freqbuf, 1.0, samplecount);
443 	if (baudio->mixflags & O_PWM_1)
444 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod2 * 128,
445 			scratchbuf, 0.0, samplecount);
446 
447 	if (baudio->mixflags & O_MOD_PWM)
448 		bufmerge(modsine,
449 			((pmods *) baudio->mixlocals)->wheelmod
450 				* baudio->contcontroller[1] * 512,
451 			scratchbuf, 1.0, samplecount);
452 
453 	if (baudio->mixflags & O_MOD1_ENABLE)
454 	{
455 		/*
456 		 * Wheel mod....
457 		 */
458 		bufmerge(modsine,
459 			((pmods *) baudio->mixlocals)->wheelmod * baudio->contcontroller[1]
460 				* 0.6, freqbuf, 1.0, samplecount);
461 	}
462 
463 	(*baudio->sound[0]).operate(
464 		(audiomain->palette)[8],
465 		voice,
466 		(*baudio->sound[0]).param,
467 		voice->locals[voice->index][0]);
468 /* OSC A - DONE */
469 
470 /* OSC B */
471 	/*
472 	 * Second oscillator
473 	 */
474 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[0].buf
475 		= freq;
476 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[1].buf
477 		= scratchbuf;
478 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[2].buf
479 		= oscbbuf;
480 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[3].buf
481 		= oscabuf;
482 	/*
483 	 * Fill tmpbuf1 with our frequency information - should already have it
484 	 * done, including mods? The Second oscillator may not be doing glide,
485 	 * controlled by the UNISON flag. If we do not have unison, then force
486 	 * dfreq and cfreq together (temporarily?).
487 	fillFreqTable(baudio, voice, freqbuf, samplecount, 0);
488 	 */
489 
490 	/* This should perhaps go into PWM and/or freq buf? */
491 	if (baudio->mixflags & O_ENV_MOD)
492 		bufmerge(adsrbuf, ((pmods *) baudio->mixlocals)->d_mod1,
493 			freq, 1.0, samplecount);
494 
495 	/*
496 	 * Put in any mods we want.
497 	 */
498 	bzero(scratchbuf, audiomain->segmentsize);
499 	if (baudio->mixflags & O_FREQ_2)
500 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod1 * 0.4,
501 			freq, 1.0, samplecount);
502 	if (baudio->mixflags & O_PWM_2)
503 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod2 * 128,
504 			scratchbuf, 0.0, samplecount);
505 	if (baudio->mixflags & O_XMOD)
506 		bufmerge(oscabuf, 0.4, freq, 1.0, samplecount);
507 
508 	if (baudio->mixflags & O_MOD_PWM)
509 		bufmerge(modsine,
510 			((pmods *) baudio->mixlocals)->wheelmod
511 				* baudio->contcontroller[1] * 512,
512 			scratchbuf, 1.0, samplecount);
513 
514 	if (baudio->mixflags & O_MOD2_ENABLE)
515 	{
516 		/*
517 		 * Wheel mod....
518 		 */
519 		bufmerge(modsine,
520 			((pmods *) baudio->mixlocals)->wheelmod * baudio->contcontroller[1]
521 				* 0.6, freq, 1.0, samplecount);
522 	}
523 
524 	/*
525 	 * And finally operate this oscillator
526 	 */
527 	(*baudio->sound[1]).operate(
528 		(audiomain->palette)[8],
529 		voice,
530 		(*baudio->sound[1]).param,
531 		voice->locals[voice->index][1]);
532 /* OSC B -DONE */
533 
534 /* FILTER */
535 	/*
536 	 * If we have mods on the filter, apply them here.
537 	 */
538 	bufmerge(adsrbuf, 1.5, scratchbuf, 0.0, samplecount);
539 	if (baudio->mixflags & O_FILT)
540 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod1 * 1.5,
541 			scratchbuf, 1.0, samplecount);
542 
543 	/*
544 	 * These should be radio buttons that can be deselected. Rather than that,
545 	 * as it is easier and more flexible, take different levels depending on
546 	 * what is selected
547 	 */
548 	if ((baudio->mixflags & O_F_OSC2_1) ||
549 		(baudio->mixflags & O_F_OSC2_2))
550 	{
551 		if (baudio->mixflags & O_F_OSC2_1)
552 		{
553 			if (baudio->mixflags & O_F_OSC2_2)
554 				bufmerge(oscabuf, 0.0, oscbbuf, 1.0, samplecount);
555 			else
556 				bufmerge(oscabuf, 0.0, oscbbuf, 0.25, samplecount);
557 		} else
558 			bufmerge(oscabuf, 0.0, oscbbuf, 0.5, samplecount);
559 	} else
560 		bufmerge(oscabuf, 0.0, oscbbuf, 0.0, samplecount);
561 
562 	if (baudio->mixflags & O_F_OSC1)
563 		bufmerge(oscabuf, 0.0, oscabuf, 1.0, samplecount);
564 	else
565 		bufmerge(oscabuf, 0.0, oscabuf, 0.0, samplecount);
566 
567 	if ((baudio->mixflags & O_F_NOISE1) ||
568 		(baudio->mixflags & O_F_NOISE2))
569 	{
570 		if (baudio->mixflags & O_F_NOISE1)
571 		{
572 			if (baudio->mixflags & O_F_NOISE2)
573 				bufmerge(noisebuf, 0.8, oscbbuf, 1.0, samplecount);
574 			else
575 				bufmerge(noisebuf, 0.2, oscbbuf, 1.0, samplecount);
576 		} else
577 			bufmerge(noisebuf, 0.4, oscbbuf, 1.0, samplecount);
578 	}
579 
580 	/*
581 	 * Mix the oscillators together. Had to do the filter mods first though.
582 	 *
583 	 * This is mostly wrong. Most of the buttons taken as filter mods were
584 	 * actually mixing options into the filter.
585 	 */
586 	bufmerge(oscabuf, 64.0, oscbbuf, 64.0, samplecount);
587 
588 	/*
589 	 * Run the mixed oscillators into the filter. Input and output buffers
590 	 * are the same.
591 	 */
592 	audiomain->palette[(*baudio->sound[4]).index]->specs->io[0].buf = oscbbuf;
593 	audiomain->palette[(*baudio->sound[4]).index]->specs->io[1].buf =scratchbuf;
594 	audiomain->palette[(*baudio->sound[4]).index]->specs->io[2].buf = filtbuf;
595 
596 	(*baudio->sound[4]).operate(
597 		(audiomain->palette)[B_FILTER2],
598 		voice,
599 		(*baudio->sound[4]).param,
600 		voice->locals[voice->index][4]);
601 /* FILTER - DONE */
602 
603 /* FINAL STAGE */
604 	/*
605 	 * Run the ADSR for the final stage amplifier, reusing the startbuf.
606 	 */
607 	audiomain->palette[(*baudio->sound[5]).index]->specs->io[0].buf = adsrbuf;
608 	(*baudio->sound[5]).operate(
609 		(audiomain->palette)[1],
610 		voice,
611 		(*baudio->sound[5]).param,
612 		voice->locals[voice->index][5]);
613 	if (baudio->mixflags & O_TREM)
614 		bufmerge(lfo, ((pmods *) baudio->mixlocals)->d_mod2 * 0.4,
615 			adsrbuf, 1.0, samplecount);
616 	/*
617 	 * Run the mixed oscillators into the amplifier. Input and output buffers
618 	 * are the same.
619 	 */
620 	audiomain->palette[(*baudio->sound[6]).index]->specs->io[0].buf = filtbuf;
621 	audiomain->palette[(*baudio->sound[6]).index]->specs->io[1].buf = adsrbuf;
622 	audiomain->palette[(*baudio->sound[6]).index]->specs->io[2].buf =
623 		baudio->leftbuf;
624 	(*baudio->sound[6]).operate(
625 		(audiomain->palette)[2],
626 		voice,
627 		(*baudio->sound[6]).param,
628 		voice->locals[voice->index][6]);
629 /* FINAL STAGE - DONE */
630 	return(0);
631 }
632 
633 int
operateOBXPostops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)634 operateOBXPostops(audioMain *audiomain, Baudio *baudio,
635 bristolVoice *voice, register float *startbuf)
636 {
637 /* Panning - this is for the OBX only. If pan is zero we don't have to do */
638 /* anything. */
639 	register int samplecount = audiomain->samplecount;
640 	register float *lbuf = baudio->leftbuf;
641 	register float *rbuf = baudio->rightbuf;
642 	register float g = ((pmods *) baudio->mixlocals)->pan;
643 
644 	/*
645 	 * Gain into the rightbuf, adjust the leftbuf;
646 	 */
647 	for (;samplecount > 0; samplecount-=8)
648 	{
649 		*rbuf++ = *lbuf++ * g * 2;
650 		*rbuf++ = *lbuf++ * g * 2;
651 		*rbuf++ = *lbuf++ * g * 2;
652 		*rbuf++ = *lbuf++ * g * 2;
653 		*rbuf++ = *lbuf++ * g * 2;
654 		*rbuf++ = *lbuf++ * g * 2;
655 		*rbuf++ = *lbuf++ * g * 2;
656 		*rbuf++ = *lbuf++ * g * 2;
657 	}
658 
659 	samplecount = audiomain->samplecount;
660 	g = (1.0f - g) * 2;
661 	lbuf = baudio->leftbuf;
662 	for (;samplecount > 0; samplecount-=8)
663 	{
664 		*lbuf++ *= g;
665 		*lbuf++ *= g;
666 		*lbuf++ *= g;
667 		*lbuf++ *= g;
668 		*lbuf++ *= g;
669 		*lbuf++ *= g;
670 		*lbuf++ *= g;
671 		*lbuf++ *= g;
672 	}
673 	return(0);
674 }
675 
676 int
bristolOBXDestroy(audioMain * audiomain,Baudio * baudio)677 bristolOBXDestroy(audioMain *audiomain, Baudio *baudio)
678 {
679 	printf("removing one obx\n");
680 
681 	/*
682 	 * We need to leave these, we may have multiple invocations running
683 	 */
684 	return(0);
685 
686 /*
687  * This ought to be fixed, these should be removed but since they are common
688  * to the synth then that will break with multiple invocations such as the
689  * OB-Xa and Prophet-10
690  */
691 	if (freqbuf != NULL) {
692 		bristolfree(freqbuf);
693 		freqbuf = NULL;
694 	}
695 	if (freq != NULL) {
696 		bristolfree(freq);
697 		freq = NULL;
698 	}
699     if (scratchbuf != NULL) {
700 		bristolfree(scratchbuf);
701 		scratchbuf = NULL;
702 	}
703     if (adsrbuf != NULL) {
704 		bristolfree(adsrbuf);
705 		adsrbuf = NULL;
706 	}
707     if (filtbuf != NULL) {
708 		bristolfree(filtbuf);
709 		filtbuf = NULL;
710 	}
711     if (oscbbuf != NULL) {
712 		bristolfree(oscbbuf);
713 		oscbbuf = NULL;
714 	}
715     if (oscabuf != NULL) {
716 		bristolfree(oscabuf);
717 		oscabuf = NULL;
718 	}
719 	/* lots of lfo bufs missed out here.... */
720 	return(0);
721 }
722 
723 int
bristolOBXInit(audioMain * audiomain,Baudio * baudio)724 bristolOBXInit(audioMain *audiomain, Baudio *baudio)
725 {
726 	printf("initialising one obx\n");
727 	/*
728 	 * The OBX is relatively straightforward in terms of operators, the real
729 	 * strength of the synth is the routing that is used to beef up the sound.
730 	 *
731 	 * We will need the following and will use those from the prophet:
732 	 *	LFO
733 	 *	Two DCO
734 	 *	Filter
735 	 *	Two ENV
736 	 *	Amplifier
737 	 */
738 	baudio->soundCount = 9; /* Number of operators in this voice (MM) */
739 	/*
740 	 * Assign an array of sound pointers.
741 	 */
742 	baudio->sound = (bristolSound **)
743 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
744 	baudio->effect = (bristolSound **)
745 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
746 
747 	/*
748 	 * Two OSC:
749 	 */
750 	initSoundAlgo(8, 0, baudio, audiomain, baudio->sound);
751 	initSoundAlgo(8, 1, baudio, audiomain, baudio->sound);
752 	/* LFO */
753 	initSoundAlgo(16, 2, baudio, audiomain, baudio->sound);
754 	/* An ADSR */
755 	initSoundAlgo(1, 3, baudio, audiomain, baudio->sound);
756 	/* A filter */
757 	initSoundAlgo(B_FILTER2, 4, baudio, audiomain, baudio->sound);
758 	/* Another ADSR */
759 	initSoundAlgo(1, 5, baudio, audiomain, baudio->sound);
760 	/* An amplifier */
761 	initSoundAlgo(2, 6, baudio, audiomain, baudio->sound);
762 	/* An noise source */
763 	initSoundAlgo(4, 7, baudio, audiomain, baudio->sound);
764 	/* Second LFO for mods */
765 	initSoundAlgo(16, 8, baudio, audiomain, baudio->sound);
766 
767 	baudio->param = obxController;
768 	baudio->destroy = bristolOBXDestroy;
769 	baudio->operate = operateOneOBX;
770 	baudio->preops = operateOBXPreops;
771 	baudio->postops = operateOBXPostops;
772 
773 	if (freq == 0)
774 		freq = (float *) bristolmalloc0(audiomain->segmentsize);
775 	if (freqbuf == 0)
776 		freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
777 	if (scratchbuf == 0)
778 		scratchbuf = (float *) bristolmalloc0(audiomain->segmentsize);
779 	if (adsrbuf == 0)
780 		adsrbuf = (float *) bristolmalloc0(audiomain->segmentsize);
781 	if (filtbuf == 0)
782 		filtbuf = (float *) bristolmalloc0(audiomain->segmentsize);
783 	if (oscbbuf == 0)
784 		oscbbuf = (float *) bristolmalloc0(audiomain->segmentsize);
785 	if (oscabuf == 0)
786 		oscabuf = (float *) bristolmalloc0(audiomain->segmentsize);
787 
788 	if (lfo == 0)
789 		lfo = (float *) bristolmalloc0(audiomain->segmentsize);
790 	if (modsine == 0)
791 		modsine = (float *) bristolmalloc0(audiomain->segmentsize);
792 	if (lfosine == 0)
793 		lfosine = (float *) bristolmalloc0(audiomain->segmentsize);
794 	if (lfosqr == 0)
795 		lfosqr = (float *) bristolmalloc0(audiomain->segmentsize);
796 	if (lfosh == 0)
797 		lfosh = (float *) bristolmalloc0(audiomain->segmentsize);
798 
799 	baudio->mixlocals = (float *) bristolmalloc0(sizeof(pmods));
800 	/*
801 	 * For the OB-X this should be central panning as it is a mono synth. For
802 	 * the OB-Xa this will be configured from the GUI
803 	 */
804 	((pmods *) baudio->mixlocals)->pan = 0.5f;
805 	((pmods *) baudio->mixlocals)->voicecount = baudio->voicecount;
806 	baudio->mixflags |= BRISTOL_STEREO;
807 	baudio->mixflags |= O_UNISON;
808 	return(0);
809 }
810 
811