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 <math.h>
24 #include "bristol.h"
25 #include "bristolmm.h"
26 #include "bristolcs80.h"
27
28 extern void mapVelocityCurve(int, float []);
29
30 /*
31 * Use of these cs80 global buffers will be an issue with use of multiple
32 * audio threads, unless we ensure a single thread deals with any given algo
33 * type, since then they are only used sequentially.
34 */
35 static float *freqbuf = (float *) NULL;
36 static float *adsr1buf = (float *) NULL;
37 static float *adsr2buf = (float *) NULL;
38 static float *filtbuf = (float *) NULL;
39 static float *dco1buf = (float *) NULL;
40 static float *zerobuf = (float *) NULL;
41 static float *outbuf = (float *) NULL;
42 static float *lfo1buf = (float *) NULL;
43 static float *lfo2buf = (float *) NULL;
44 static float *noisebuf = (float *) NULL;
45 static float *scratchbuf = (float *) NULL;
46 static float *pwmbuf = (float *) NULL;
47 static float *sinebuf = (float *) NULL;
48 static float *modbuf = (float *) NULL;
49
50 /*
51 * These need to go into some local structure for multiple instances
52 * of the cs80 - malloc()ed into the baudio->mixlocals.
53 */
54 #define CS80_LOWER_LAYER 0x00000001
55 #define CS80_NOISE_MULTI 0x00000002
56 #define CS80_LFO1_MULTI 0x00000004
57 #define CS80_LFO1_MASK 0x000001F0
58 #define CS80_LFO1_TRI 0x00000010
59 #define CS80_LFO1_RAMP 0x00000020
60 #define CS80_LFO1_SQR 0x00000040
61 #define CS80_LFO1_SH 0x00000080
62 #define CS80_LFO1_SAW 0x00000100
63
64 int
cs80Controller(Baudio * baudio,u_char operator,u_char controller,float value)65 cs80Controller(Baudio *baudio, u_char operator,
66 u_char controller, float value)
67 {
68 int tval = value * CONTROLLER_RANGE;
69
70 #ifdef DEBUG
71 printf("bristolcs80Control(%i, %i, %f)\n", operator, controller, value);
72 #endif
73 printf("bristolcs80Control(%i, %i, %f)\n", operator, controller, value);
74
75 if (operator != 126)
76 return(0);
77
78 switch (controller) {
79 case 0:
80 baudio->glide = value * value * baudio->glidemax;
81 break;
82 case 1:
83 baudio->gtune = 1.0
84 + (baudio->note_diff - 1)
85 * (value * 2 - 1);
86
87 buildCurrentTable(baudio, baudio->gtune);
88 alterAllNotes(baudio);
89 break;
90 case 2:
91 ((csmods *) baudio->mixlocals)->gain = value * 4;
92 break;
93 case 3:
94 /*
95 * Since we are using here 'lpan = 1.0 - rpan' we could consider
96 * just using one value. It is maintained as two since we may still
97 * reinvoke the midi spec panning at some point.
98 */
99 ((csmods *) baudio->mixlocals)->lpan[CH_I] = (1.0 - value);
100 ((csmods *) baudio->mixlocals)->rpan[CH_I] = value;
101 /*
102 if (tval == 0)
103 value += 1.0f/CONTROLLER_RANGE;
104 else if (tval == CONTROLLER_RANGE)
105 value -= 1.0f/CONTROLLER_RANGE;
106
107 ((csmods *) baudio->mixlocals)->lpan =
108 -log10f(sinf(M_PI/2.0f * value));
109 ((csmods *) baudio->mixlocals)->rpan =
110 -log10f(cosf(M_PI/2.0f * value));
111 */
112 break;
113 case 4:
114 ((csmods *) baudio->mixlocals)->lpan[CH_II] = (1.0 - value);
115 ((csmods *) baudio->mixlocals)->rpan[CH_II] = value;
116 break;
117 case 5:
118 /*
119 * This is a correct midi paninng calculation roughly as taken from
120 * MMA corrective notes for stereo panning. It does not work
121 * too well for an L/R mix though as it applies a constant power
122 * algorithm and gets very unbalanced at full throws.
123 *
124 if (tval == 0)
125 value += 1.0f/CONTROLLER_RANGE;
126 else if (tval == CONTROLLER_RANGE)
127 value -= 1.0f/CONTROLLER_RANGE;
128
129 ((csmods *) baudio->mixlocals)->channelmix = 20 *
130 log10f(cosf(M_PI/2.0f * value));
131 ((csmods *) baudio->mixlocals)->rmix = 20 *
132 log10f(sinf(M_PI/2.0f * value));
133
134 printf("mix now %f/%f\n",
135 ((csmods *) baudio->mixlocals)->channelmix,
136 ((csmods *) baudio->mixlocals)->rmix);
137 */
138
139 ((csmods *) baudio->mixlocals)->channelmix = value;
140 // ((csmods *) baudio->mixlocals)->rmix = value;
141 break;
142 case 6:
143 ((csmods *) baudio->mixlocals)->brilliance = value;
144 break;
145 case 7:
146 ((csmods *) baudio->mixlocals)->brillianceL = value;
147 break;
148 case 8:
149 ((csmods *) baudio->mixlocals)->brillianceH = value;
150 break;
151 case 9:
152 ((csmods *) baudio->mixlocals)->levelL = value;
153 break;
154 case 10:
155 ((csmods *) baudio->mixlocals)->levelH = value;
156 break;
157 case 11:
158 ((csmods *) baudio->mixlocals)->chanmods[CH_I].brilliance = value;
159 break;
160 case 12:
161 ((csmods *) baudio->mixlocals)->chanmods[CH_I].level = value;
162 break;
163 case 13:
164 ((csmods *) baudio->mixlocals)->chanmods[CH_I].polybrilliance
165 = value;
166 break;
167 case 14:
168 ((csmods *) baudio->mixlocals)->chanmods[CH_I].polylevel = value;
169 break;
170 case 15:
171 ((csmods *) baudio->mixlocals)->chanmods[CH_II].brilliance = value;
172 break;
173 case 16:
174 ((csmods *) baudio->mixlocals)->chanmods[CH_II].level = value;
175 break;
176 case 17:
177 ((csmods *) baudio->mixlocals)->chanmods[CH_II].polybrilliance
178 = value;
179 break;
180 case 18:
181 ((csmods *) baudio->mixlocals)->chanmods[CH_II].polylevel = value;
182 break;
183 /*
184 #define CS80_LFO1_MASK 0x000001F0
185 #define CS80_LFO1_TRI 0x00000010
186 #define CS80_LFO1_RAMP 0x00000020
187 #define CS80_LFO1_SQR 0x00000040
188 #define CS80_LFO1_SH 0x00000080
189 #define CS80_LFO1_SAW 0x00000100
190 */
191 case 20:
192 switch (tval)
193 {
194 case 0:
195 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
196 ((csmods *) baudio->mixlocals)->flags |= CS80_LFO1_TRI;
197 break;
198 case 1:
199 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
200 ((csmods *) baudio->mixlocals)->flags |= CS80_LFO1_RAMP;
201 break;
202 case 2:
203 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
204 ((csmods *) baudio->mixlocals)->flags |= CS80_LFO1_SAW;
205 break;
206 case 3:
207 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
208 ((csmods *) baudio->mixlocals)->flags |= CS80_LFO1_SQR;
209 break;
210 case 4:
211 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
212 ((csmods *) baudio->mixlocals)->flags |= CS80_LFO1_SH;
213 break;
214 case 5:
215 ((csmods *) baudio->mixlocals)->flags &= ~CS80_LFO1_MASK;
216 break;
217 }
218 break;
219 case 21:
220 ((csmods *) baudio->mixlocals)->lfo2vco = value;
221 break;
222 case 22:
223 ((csmods *) baudio->mixlocals)->lfo2vcf = value;
224 break;
225 case 23:
226 ((csmods *) baudio->mixlocals)->lfo2vca = value;
227 break;
228 case 24:
229 ((csmods *) baudio->mixlocals)->chanmods[CH_I].pwmdepth
230 = value * 1000;
231 break;
232 case 25:
233 ((csmods *) baudio->mixlocals)->chanmods[CH_II].pwmdepth
234 = value * 1000;
235 break;
236 case 26:
237 ((csmods *) baudio->mixlocals)->chanmods[CH_I].noiselevel
238 = value * 48;
239 break;
240 case 27:
241 ((csmods *) baudio->mixlocals)->chanmods[CH_II].noiselevel
242 = value * 48;
243 break;
244 case 28:
245 ((csmods *) baudio->mixlocals)->chanmods[CH_I].filterlevel = value;
246 break;
247 case 29:
248 ((csmods *) baudio->mixlocals)->chanmods[CH_II].filterlevel = value;
249 break;
250 case 30:
251 ((csmods *) baudio->mixlocals)->chanmods[CH_I].filterbrill = value;
252 break;
253 case 31:
254 ((csmods *) baudio->mixlocals)->chanmods[CH_II].filterbrill = value;
255 break;
256 case 101:
257 /* This is the dummy entry */
258 break;
259 }
260
261 /*
262 if (controller >= 6)
263 printf("Brill: %1.2f %1.2f %1.2f %1.2f %1.2f %1.2f %1.2f\n\
264 Level: %1.2f %1.2f %1.2f %1.2f %1.2f %1.2f\n",
265 ((csmods *) baudio->mixlocals)->brilliance,
266 ((csmods *) baudio->mixlocals)->brillianceL,
267 ((csmods *) baudio->mixlocals)->brillianceH,
268 ((csmods *) baudio->mixlocals)->chanmods[CH_I].brilliance,
269 ((csmods *) baudio->mixlocals)->chanmods[CH_I].polybrilliance,
270 ((csmods *) baudio->mixlocals)->chanmods[CH_II].brilliance,
271 ((csmods *) baudio->mixlocals)->chanmods[CH_II].polybrilliance,
272
273 ((csmods *) baudio->mixlocals)->levelL,
274 ((csmods *) baudio->mixlocals)->levelH,
275 ((csmods *) baudio->mixlocals)->chanmods[CH_I].level,
276 ((csmods *) baudio->mixlocals)->chanmods[CH_II].polylevel,
277 ((csmods *) baudio->mixlocals)->chanmods[CH_II].level,
278 ((csmods *) baudio->mixlocals)->chanmods[CH_I].polylevel);
279 */
280
281 return(0);
282 }
283
284 /*
285 * Bristol preops are given a sometimes arbitrary voice selection, something
286 * that will affect the operation of the LFO-2 and LFO-1 when configured
287 * as UNI. Also, the LFO should only run once per pair of layers so that
288 * the same LFO is applied to both of them. This cannot only be run in the
289 * lower layer even though we do have a layer flag available for the simple
290 * reason that the lower layer may not actually undergo preops (if no keys
291 * from the lower layer are being played). For that reason we use the rather
292 * ugly lfo1exclusion flag. The semi arbitrary voice is actually the 1st one on
293 * the playlist for this emulation, typically the most recent key pressed except
294 * when seconding has been applied. This means we will mostly get the LFO to
295 * track the most recent velocity at the expense of envelope retriggers. At
296 * steady state the envelope should continue to open as expected.
297 */
298 int
cs80Preops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)299 cs80Preops(audioMain *audiomain, Baudio *baudio,
300 bristolVoice *voice, register float *startbuf)
301 {
302 if (freqbuf == NULL)
303 return(0);
304
305 bristolbzero(((csmods *) baudio->mixlocals)->lout, audiomain->segmentsize);
306 bristolbzero(((csmods *) baudio->mixlocals)->rout, audiomain->segmentsize);
307
308 audiomain->palette[16]->specs->io[0].buf = NULL;
309 audiomain->palette[16]->specs->io[1].buf = NULL;
310 audiomain->palette[16]->specs->io[2].buf = NULL;
311 audiomain->palette[16]->specs->io[3].buf = NULL;
312 audiomain->palette[16]->specs->io[4].buf = pwmbuf;
313 audiomain->palette[16]->specs->io[5].buf = NULL;
314 audiomain->palette[16]->specs->io[6].buf = NULL;
315
316 /*
317 * This will eventually manage LFO_MULTI options, separately per LFO.
318 */
319 if (((csmods *) baudio->mixlocals)->flags & CS80_NOISE_MULTI)
320 {
321 bristolbzero(noisebuf, audiomain->segmentsize);
322
323 audiomain->palette[4]->specs->io[0].buf = noisebuf;
324 (*baudio->sound[16]).operate(
325 (audiomain->palette)[4],
326 voice,
327 (*baudio->sound[16]).param,
328 voice->locals[voice->index][16]);
329 }
330
331 /*
332 * LFO. We need to review flags to decide where to place our buffers, kick
333 * off with a sine wave and take it from there (sine should be the default
334 * if all others are deselected?).
335 * There are actually two global LFO, the second one is just for the ring
336 * modulator and that ones uses an env.
337 */
338 if (((csmods *) baudio->mixlocals)->flags & CS80_LFO1_MULTI)
339 {
340 bristolbzero(scratchbuf, audiomain->segmentsize);
341
342 audiomain->palette[16]->specs->io[0].buf = noisebuf;
343 audiomain->palette[16]->specs->io[1].buf = 0;
344 audiomain->palette[16]->specs->io[2].buf = 0;
345 audiomain->palette[16]->specs->io[3].buf = 0;
346 audiomain->palette[16]->specs->io[4].buf = 0;
347 audiomain->palette[16]->specs->io[5].buf = 0;
348
349 switch (((csmods *) baudio->mixlocals)->flags & CS80_LFO1_MASK) {
350 case CS80_LFO1_TRI:
351 audiomain->palette[16]->specs->io[1].buf = lfo1buf;
352 break;
353 case CS80_LFO1_SAW:
354 audiomain->palette[16]->specs->io[6].buf = lfo1buf;
355 break;
356 case CS80_LFO1_RAMP:
357 audiomain->palette[16]->specs->io[5].buf = lfo1buf;
358 break;
359 case CS80_LFO1_SQR:
360 audiomain->palette[16]->specs->io[2].buf = lfo1buf;
361 break;
362 case CS80_LFO1_SH:
363 audiomain->palette[16]->specs->io[3].buf = lfo1buf;
364 break;
365 default: /* Sine */
366 audiomain->palette[16]->specs->io[4].buf = lfo1buf;
367 break;
368 }
369
370 (*baudio->sound[15]).operate(
371 (audiomain->palette)[16],
372 voice,
373 (*baudio->sound[15]).param,
374 baudio->locals[voice->index][15]);
375 }
376
377 return(0);
378 }
379
380 void
operateOneCs80Channel(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,bristolSound ** sound,int channel)381 operateOneCs80Channel(audioMain *audiomain, Baudio *baudio,
382 bristolVoice *voice, bristolSound **sound, int channel)
383 {
384 csmods *csmod = ((csmods *) baudio->mixlocals);
385 int layer;
386 float bkey = voice->key.key - 24, lkey;
387
388 layer = channel == CH_I? 0: 6;
389 csmod->channel = channel;
390
391 /*
392 * There are several sources of brilliance and level, all of which act
393 * together and which need to be consolidated down to a single pair of
394 * values for the channel.
395 *
396 * Brilliance Inputs are:
397 *
398 * Key ID, normalised to GUI range and affected by KeyRange parameters
399 * Velocity affected by Initial control.
400 * PolyPressure affected by After control.
401 * Overall brilliance
402 *
403 * Level Inputs are:
404 *
405 * Key ID, normalised to GUI range and affected by KeyRange parameters
406 * Velocity affected by Initial control.
407 * PolyPressure affected by After control.
408 *
409 * We need some defined method to pass these values to the filter, ADSR
410 * and oscillator. I may be lazy and used a shared structure? Better to
411 * reference the voice->baudio->mixlocals->csMods[voice->index] though.
412 *
413 * The KeyID stuff used a unity at mid keyboard and then a gradual change
414 * up to the outer limits using the parameters, something that means we
415 * have to split the calculation up a little bit.
416 *
417 * Need to make sure the filters work to expectation as well since the
418 * brilliance value also widens the bandpass apeture.
419 */
420 if (bkey <= 30) {
421 if (bkey <= 0) {
422 lkey = csmod->levelL;
423 bkey = csmod->brillianceL;
424 } else {
425 lkey = 0.5 + (csmod->levelL - 0.5) * (30 - bkey) / 30;
426 bkey = 0.5 + (csmod->brillianceL - 0.5) * (30 - bkey) / 30;
427 }
428 } else if (bkey >= 60) {
429 lkey = csmod->levelH;
430 bkey = csmod->brillianceH;
431 } else {
432 lkey = 0.5 + (csmod->levelH - 0.5) * (bkey - 30) / 30;
433 bkey = 0.5 + (csmod->brillianceH - 0.5) * (bkey - 30) / 30;
434 }
435
436 csmod->chanmods[channel].keybrill[voice->index] =
437 csmod->brilliance *
438 (
439 /* Key brilliance equalisation */
440 bkey
441 +
442 /* Velocity */
443 voice->velocity * csmod->chanmods[channel].brilliance
444 +
445 /* Poly/pressure */
446 (voice->chanpressure + voice->press)
447 * csmod->chanmods[channel].polybrilliance
448 );
449
450 csmod->chanmods[channel].keylevel[voice->index] =
451 (
452 /* Key volume equalisation */
453 lkey
454 +
455 /* Velocity */
456 voice->velocity * csmod->chanmods[channel].level
457 +
458 /* Poly/pressure */
459 (voice->chanpressure + voice->press)
460 * csmod->chanmods[channel].polylevel
461 );
462
463 /*
464 if (voice->flags & (BRISTOL_KEYON|BRISTOL_KEYREON))
465 printf("Voice %i %i: %1.2f/%1.2f %1.2f/%1.2f\n", voice->key.key, voice->key.key - 24,
466 csmod->chanmods[channel].keybrill[voice->index],
467 csmod->chanmods[channel].keylevel[voice->index],
468 bkey, lkey);
469 */
470
471 /* DONE Brilliance and level evaluation */
472
473 /* DCO MOD processing */
474 bufmerge(freqbuf, 1.0, scratchbuf, 0.0, audiomain->samplecount);
475
476 audiomain->palette[16]->specs->io[0].buf = NULL;
477 audiomain->palette[16]->specs->io[1].buf = NULL;
478 audiomain->palette[16]->specs->io[2].buf = NULL;
479 audiomain->palette[16]->specs->io[3].buf = NULL;
480 audiomain->palette[16]->specs->io[4].buf = pwmbuf;
481 audiomain->palette[16]->specs->io[5].buf = NULL;
482 audiomain->palette[16]->specs->io[6].buf = NULL;
483 /*
484 * Run PWM LFO and put out a sine wave
485 */
486 (*baudio->sound[0 + layer]).operate(
487 (audiomain->palette)[16],
488 voice,
489 (*baudio->sound[0 + layer]).param,
490 baudio->locals[voice->index][0 + layer]);
491 bufmerge(pwmbuf, 0.0, pwmbuf, csmod->chanmods[channel].pwmdepth,
492 audiomain->samplecount);
493
494 /* Put in an amount of LFO1 mod if configured */
495 bufmerge(lfo1buf, csmod->lfo2vco, scratchbuf, 1.0, audiomain->samplecount);
496 /* End DCO-1 MOD processing */
497
498 /* DCO-1 processing */
499 bristolbzero(sinebuf, audiomain->segmentsize);
500 bristolbzero(dco1buf, audiomain->segmentsize);
501 /*
502 * Run DCO-1.
503 */
504 audiomain->palette[31]->specs->io[0].buf = scratchbuf;
505 audiomain->palette[31]->specs->io[1].buf = dco1buf;
506 audiomain->palette[31]->specs->io[2].buf = pwmbuf; /* PWM buff */
507 audiomain->palette[31]->specs->io[3].buf = sinebuf;
508
509 (*baudio->sound[1 + layer]).operate(
510 (audiomain->palette)[31],
511 voice,
512 (*baudio->sound[1 + layer]).param,
513 voice->locals[voice->index][1 + layer]);
514 /* End of DCO-1 processing */
515
516 bufmerge(noisebuf, csmod->chanmods[channel].noiselevel,
517 dco1buf, 96.0, audiomain->samplecount);
518
519 /* ADSR Processing - first the filter env, then the AMP env */
520 audiomain->palette[1]->specs->io[0].buf = adsr1buf;
521 (*baudio->sound[4 + layer]).operate(
522 (audiomain->palette)[1],
523 voice,
524 (*baudio->sound[4 + layer]).param,
525 voice->locals[voice->index][4 + layer]);
526 audiomain->palette[1]->specs->io[0].buf = adsr2buf;
527 (*baudio->sound[5 + layer]).operate(
528 (audiomain->palette)[1],
529 voice,
530 (*baudio->sound[5 + layer]).param,
531 voice->locals[voice->index][5 + layer]);
532 /* End of ADSR Processing */
533
534 /* Filter processing */
535 bufmerge(lfo1buf, csmod->lfo2vcf, adsr1buf, 1.0, audiomain->samplecount);
536 bristolbzero(filtbuf, audiomain->segmentsize);
537 bristolbzero(scratchbuf, audiomain->segmentsize);
538 bufadd(adsr1buf,
539 csmod->chanmods[channel].filterbrill
540 * csmod->chanmods[channel].keybrill[voice->index],
541 audiomain->samplecount);
542 // dummy filter:
543 audiomain->palette[3]->specs->io[0].buf = dco1buf;
544 audiomain->palette[3]->specs->io[1].buf = adsr1buf;
545 audiomain->palette[3]->specs->io[2].buf = scratchbuf;
546 (*baudio->sound[2 + layer]).operate(
547 (audiomain->palette)[3],
548 voice,
549 (*baudio->sound[2 + layer]).param,
550 baudio->locals[voice->index][2 + layer]);
551 audiomain->palette[3]->specs->io[0].buf = scratchbuf;
552 audiomain->palette[3]->specs->io[1].buf = adsr1buf;
553 audiomain->palette[3]->specs->io[2].buf = filtbuf;
554 (*baudio->sound[3 + layer]).operate(
555 (audiomain->palette)[3],
556 voice,
557 (*baudio->sound[3 + layer]).param,
558 baudio->locals[voice->index][3 + layer]);
559 /* End of Filter processing */
560
561 /* VCA processing */
562 bristolbzero(outbuf, audiomain->segmentsize);
563
564 bufmerge(sinebuf, 1.0,
565 filtbuf, csmod->chanmods[channel].filterlevel, audiomain->samplecount);
566
567 /* Put in an amount of LFO1 mod if configured */
568 bufmerge(lfo1buf, csmod->lfo2vca, adsr2buf, 5.0, audiomain->samplecount);
569
570 audiomain->palette[2]->specs->io[0].buf = filtbuf;
571 audiomain->palette[2]->specs->io[1].buf = adsr2buf;
572 audiomain->palette[2]->specs->io[2].buf = outbuf;
573 (*baudio->sound[17]).operate(
574 (audiomain->palette)[2],
575 voice,
576 (*baudio->sound[17]).param,
577 baudio->locals[voice->index][17]);
578 /* VCA processing */
579 }
580
581 int
operateOneCs80(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,float * startbuf)582 operateOneCs80(audioMain *audiomain, Baudio *baudio,
583 bristolVoice *voice, float *startbuf)
584 {
585 csmods *mixlocal = (csmods *) baudio->mixlocals;
586 int koflag = 0;
587
588 if (freqbuf == NULL)
589 return(0);
590
591 if ((mixlocal->flags & CS80_NOISE_MULTI) == 0)
592 {
593 bristolbzero(noisebuf, audiomain->segmentsize);
594
595 audiomain->palette[4]->specs->io[0].buf = noisebuf;
596 (*baudio->sound[16]).operate(
597 (audiomain->palette)[4],
598 voice,
599 (*baudio->sound[16]).param,
600 voice->locals[voice->index][16]);
601 }
602
603 /* One LFO MULTI */
604 /*
605 * LFO. We need to review flags to decide where to place our buffers, kick
606 * off with a sine wave and take it from there (sine should be the default
607 * if all others are deselected?).
608 */
609 if ((mixlocal->flags & CS80_LFO1_MULTI) == 0)
610 {
611 /* bristolbzero(scratchbuf, audiomain->segmentsize); */
612 audiomain->palette[16]->specs->io[0].buf = noisebuf;
613 audiomain->palette[16]->specs->io[1].buf = 0;
614 audiomain->palette[16]->specs->io[2].buf = 0;
615 audiomain->palette[16]->specs->io[3].buf = 0;
616 audiomain->palette[16]->specs->io[4].buf = 0;
617 audiomain->palette[16]->specs->io[5].buf = 0;
618
619 switch (mixlocal->flags & CS80_LFO1_MASK) {
620 case CS80_LFO1_TRI:
621 audiomain->palette[16]->specs->io[1].buf = lfo1buf;
622 break;
623 case CS80_LFO1_RAMP:
624 audiomain->palette[16]->specs->io[5].buf = lfo1buf;
625 break;
626 case CS80_LFO1_SAW:
627 audiomain->palette[16]->specs->io[6].buf = lfo1buf;
628 break;
629 case CS80_LFO1_SQR:
630 audiomain->palette[16]->specs->io[2].buf = lfo1buf;
631 break;
632 case CS80_LFO1_SH:
633 audiomain->palette[16]->specs->io[3].buf = lfo1buf;
634 break;
635 default:
636 audiomain->palette[16]->specs->io[4].buf = lfo1buf;
637 break;
638 }
639
640 (*baudio->sound[15]).operate(
641 (audiomain->palette)[16],
642 voice,
643 (*baudio->sound[15]).param,
644 baudio->locals[voice->index][15]);
645 }
646
647 fillFreqTable(baudio, voice, freqbuf, audiomain->samplecount, 1);
648
649 /*
650 * I need logic here to know when both layers have finished before setting
651 * the layer flags to DONE. The layers do not need their own logic for the
652 * two envelope they manage since the filter envelope only uses KEYON/REON
653 * events, it never closes the voice.
654 */
655 operateOneCs80Channel(audiomain, baudio, voice, &(baudio->sound[0]), CH_I);
656 bufmerge(outbuf, mixlocal->channelmix * mixlocal->lpan[CH_I],
657 mixlocal->lout, 1.0,
658 audiomain->samplecount);
659 bufmerge(outbuf, mixlocal->channelmix * mixlocal->rpan[CH_I],
660 mixlocal->rout, 1.0,
661 audiomain->samplecount);
662 if (voice->flags & BRISTOL_KEYDONE)
663 koflag++;
664
665 operateOneCs80Channel(audiomain, baudio, voice, &(baudio->sound[6]), CH_II);
666 bufmerge(outbuf, (1.0 - mixlocal->channelmix) * mixlocal->lpan[CH_II],
667 mixlocal->lout, 1.0,
668 audiomain->samplecount);
669 bufmerge(outbuf, (1.0 - mixlocal->channelmix) * mixlocal->rpan[CH_II],
670 mixlocal->rout, 1.0,
671 audiomain->samplecount);
672 if (voice->flags & BRISTOL_KEYDONE)
673 koflag++;
674
675 if (koflag != 2)
676 voice->flags &= ~BRISTOL_KEYDONE;
677
678 return(0);
679 }
680
681 int
cs80Postops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)682 cs80Postops(audioMain *audiomain, Baudio *baudio,
683 bristolVoice *voice, register float *startbuf)
684 {
685 if (freqbuf == NULL)
686 return(0);
687
688 /*
689 * Panning and global effects. Note that the layers also have pan so as the
690 * FX kick in the stereo positioning will get damaged due to the vibraChorus
691 * being mono.
692 */
693 bufmerge(((csmods *) baudio->mixlocals)->lout,
694 ((csmods *) baudio->mixlocals)->gain,
695 baudio->leftbuf, 1.0,
696 audiomain->samplecount);
697 bufmerge(((csmods *) baudio->mixlocals)->rout,
698 ((csmods *) baudio->mixlocals)->gain,
699 baudio->rightbuf, 1.0,
700 audiomain->samplecount);
701
702 return(0);
703 }
704
705 int
bristolCs80Destroy(audioMain * audiomain,Baudio * baudio)706 static bristolCs80Destroy(audioMain *audiomain, Baudio *baudio)
707 {
708 /*
709 * The following can be left up to the library. If we free this here then
710 * we do need to NULL the pointer otherwise glibc may get picky.
711 *
712 * We do need to clean this up, though.
713 */
714 bristolfree(((csmods *) baudio->mixlocals)->chanmods[CH_I].keybrill);
715 bristolfree(((csmods *) baudio->mixlocals)->chanmods[CH_II].keybrill);
716 bristolfree(((csmods *) baudio->mixlocals)->chanmods[CH_I].keylevel);
717 bristolfree(((csmods *) baudio->mixlocals)->chanmods[CH_II].keylevel);
718
719 bristolfree(((csmods *) baudio->mixlocals)->lout);
720 bristolfree(((csmods *) baudio->mixlocals)->rout);
721
722 return(0);
723
724 if (freqbuf != NULL)
725 bristolfree(freqbuf);
726 if (adsr1buf != NULL)
727 bristolfree(adsr1buf);
728 if (adsr2buf != NULL)
729 bristolfree(adsr2buf);
730 if (filtbuf != NULL)
731 bristolfree(filtbuf);
732 if (dco1buf != NULL)
733 bristolfree(dco1buf);
734 if (zerobuf != NULL)
735 bristolfree(zerobuf);
736 if (outbuf != NULL)
737 bristolfree(outbuf);
738 if (lfo2buf != NULL)
739 bristolfree(lfo2buf);
740 if (lfo1buf != NULL)
741 bristolfree(lfo1buf);
742 if (noisebuf != NULL)
743 bristolfree(noisebuf);
744 if (scratchbuf != NULL)
745 bristolfree(scratchbuf);
746 if (sinebuf != NULL)
747 bristolfree(sinebuf);
748 if (modbuf != NULL)
749 bristolfree(modbuf);
750
751 freqbuf = NULL;
752 adsr1buf = NULL;
753 adsr2buf = NULL;
754 filtbuf = NULL;
755 dco1buf = NULL;
756 zerobuf = NULL;
757 outbuf = NULL;
758 lfo1buf = NULL;
759 lfo2buf = NULL;
760 noisebuf = NULL;
761 scratchbuf = NULL;
762 pwmbuf = NULL;
763 modbuf = NULL;
764 sinebuf = NULL;
765 }
766
767 int
bristolCs80Init(audioMain * audiomain,Baudio * baudio)768 bristolCs80Init(audioMain *audiomain, Baudio *baudio)
769 {
770 printf("initialising cs80: %i voices\n", baudio->voicecount);
771
772 /*
773 * This is going to be quite a big list since the synth effectively has
774 * two layers however since it is not split or double then we are going
775 * to process it as a single entity.
776 *
777 * Channel operators:
778 *
779 * LFO - PWM
780 * DCO - modified bitone oscillator.
781 * VCF - two, one HP onoe LP
782 * ENV - two, filter and amp. One needs some mods for IL
783 *
784 * Global operators:
785 *
786 * Noise source - just insert a single source.
787 * RingMod
788 * LFO - subosc modifier.
789 * VibraChorus
790 * Tremelo
791 *
792 * We need to work on ensuring that brilliance is implemented and that
793 * polyphonic aftertouch is emulated. Brilliance should affect serveral
794 * components:
795 *
796 * Filter cutoff should be adjusted
797 * VCO harmoonics should be layred in
798 *
799 * The brilliance also has several options that probably need to be totalled
800 * up to a maximum value then applies:
801 *
802 * Global setting
803 * Key Velocity setting
804 * Polyphonic pressure setting
805 * Keyboard span setting
806 *
807 * Keyboard response also has its own modifiers from low to high. Touch also
808 * drives into the global LFO speed and moification depths but need to find
809 * out if this was velocity or polypressure.
810 */
811 baudio->soundCount = 19; /* Number of operators in this voice */
812
813 /*
814 * Assign an array of sound pointers.
815 */
816 baudio->sound = (bristolSound **)
817 bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
818 baudio->effect = (bristolSound **)
819 bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
820
821 /*
822 * Two layer parameters each in turn to allow us to put is some routines
823 * Will use a single noise source.
824 */
825 /* LFO for PWM */
826 initSoundAlgo(16, 0, baudio, audiomain, baudio->sound);
827 /* One oscillator - modified bitone osc for brilliance */
828 initSoundAlgo(31, 1, baudio, audiomain, baudio->sound);
829 /* two filter with ADSR */
830 initSoundAlgo( 3, 2, baudio, audiomain, baudio->sound);
831 initSoundAlgo( 3, 3, baudio, audiomain, baudio->sound);
832 initSoundAlgo(32, 4, baudio, audiomain, baudio->sound);
833 /* Amp ADSR */
834 initSoundAlgo( 1, 5, baudio, audiomain, baudio->sound);
835
836 /* LFO for PWM */
837 initSoundAlgo(16, 6, baudio, audiomain, baudio->sound);
838 /* One oscillator - these still need harmonic mods */
839 initSoundAlgo(31, 7, baudio, audiomain, baudio->sound);
840 /* Two filter with ADSR */
841 initSoundAlgo( 3, 8, baudio, audiomain, baudio->sound);
842 initSoundAlgo( 3, 9, baudio, audiomain, baudio->sound);
843 initSoundAlgo(32, 10, baudio, audiomain, baudio->sound);
844 /* Amp ADSR */
845 initSoundAlgo( 1, 11, baudio, audiomain, baudio->sound);
846
847 /* LFO/Env and RingMod Effects section */
848 initSoundAlgo(16, 12, baudio, audiomain, baudio->sound);
849 initSoundAlgo( 1, 13, baudio, audiomain, baudio->sound);
850 initSoundAlgo(20, 14, baudio, audiomain, baudio->sound);
851
852 /* GP LFO */
853 initSoundAlgo(16, 15, baudio, audiomain, baudio->sound);
854
855 /* Noise */
856 initSoundAlgo(4, 16, baudio, audiomain, baudio->sound);
857
858 /* AMP */
859 initSoundAlgo(2, 17, baudio, audiomain, baudio->sound);
860
861 /* VibraChorus - Tremelo is an osc that gets mixed in with the AMP ADSR */
862 initSoundAlgo(16, 18, baudio, audiomain, baudio->sound);
863
864 baudio->param = cs80Controller;
865 baudio->destroy = bristolCs80Destroy;
866 baudio->operate = operateOneCs80;
867 baudio->preops = cs80Preops;
868 baudio->postops = cs80Postops;
869
870 /*
871 * Put in integrated effects here.
872 initSoundAlgo(12, 0, baudio, audiomain, baudio->effect);
873 */
874
875 baudio->mixlocals = (float *) bristolmalloc0(sizeof(csmods));
876
877 /*
878 * If we were the first requested emulation then this is the lower layer
879 * and needs to be flagged here to ensure correct 'stereo' panning.
880 */
881 ((csmods *) baudio->mixlocals)->chanmods[CH_I].keybrill = (float *)
882 bristolmalloc0(sizeof(float) * BRISTOL_MAXVOICECOUNT);
883 ((csmods *) baudio->mixlocals)->chanmods[CH_II].keybrill = (float *)
884 bristolmalloc0(sizeof(float) * BRISTOL_MAXVOICECOUNT);
885 ((csmods *) baudio->mixlocals)->chanmods[CH_I].keylevel = (float *)
886 bristolmalloc0(sizeof(float) * BRISTOL_MAXVOICECOUNT);
887 ((csmods *) baudio->mixlocals)->chanmods[CH_II].keylevel = (float *)
888 bristolmalloc0(sizeof(float) * BRISTOL_MAXVOICECOUNT);
889
890 ((csmods *) baudio->mixlocals)->lout =
891 (float *) bristolmalloc0(audiomain->segmentsize);
892 ((csmods *) baudio->mixlocals)->rout =
893 (float *) bristolmalloc0(audiomain->segmentsize);
894
895 /*
896 * And request any buffer space we want
897 */
898 if (freqbuf == NULL)
899 freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
900 if (adsr1buf == NULL)
901 adsr1buf = (float *) bristolmalloc0(audiomain->segmentsize);
902 if (adsr2buf == NULL)
903 adsr2buf = (float *) bristolmalloc0(audiomain->segmentsize);
904 if (filtbuf == NULL)
905 filtbuf = (float *) bristolmalloc0(audiomain->segmentsize);
906 if (dco1buf == NULL)
907 dco1buf = (float *) bristolmalloc0(audiomain->segmentsize);
908 if (zerobuf == NULL)
909 zerobuf = (float *) bristolmalloc0(audiomain->segmentsize);
910 if (outbuf == NULL)
911 outbuf = (float *) bristolmalloc0(audiomain->segmentsize);
912 if (noisebuf == NULL)
913 noisebuf = (float *) bristolmalloc0(audiomain->segmentsize);
914 if (lfo2buf == NULL)
915 lfo2buf = (float *) bristolmalloc0(audiomain->segmentsize);
916 if (lfo1buf == NULL)
917 lfo1buf = (float *) bristolmalloc0(audiomain->segmentsize);
918 if (scratchbuf == NULL)
919 scratchbuf = (float *) bristolmalloc0(audiomain->segmentsize);
920 if (pwmbuf == NULL)
921 pwmbuf = (float *) bristolmalloc0(audiomain->segmentsize);
922 if (sinebuf == NULL)
923 sinebuf = (float *) bristolmalloc0(audiomain->segmentsize);
924 if (modbuf == NULL)
925 modbuf = (float *) bristolmalloc0(audiomain->segmentsize);
926
927 baudio->mixflags |= BRISTOL_STEREO;
928
929 return(0);
930 }
931
932