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