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