1 
2 /*
3  *  Diverse Bristol audio routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /* ARP AXXE algorithm - we use two OSC, need one compound. FFS. */
23 
24 /*#define DEBUG */
25 
26 #include "bristol.h"
27 #include "bristolmm.h"
28 #include "bristolaxxe.h"
29 
30 /*
31  * Use of these axxe 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 *filtbuf = (float *) NULL;
37 static float *noisebuf = (float *) NULL;
38 static float *adsrbuf = (float *) NULL;
39 static float *lfosh = (float *) NULL;
40 static float *lfosine = (float *) NULL;
41 static float *lfosquare = (float *) NULL;
42 static float *osc1buf = (float *) NULL;
43 static float *osc2buf = (float *) NULL;
44 static float *scratch = (float *) NULL;
45 
46 int
axxeController(Baudio * baudio,u_char operator,u_char controller,float value)47 axxeController(Baudio *baudio, u_char operator, u_char controller, float value)
48 {
49 	int ivalue = value * CONTROLLER_RANGE;
50 
51 #ifdef DEBUG
52 	printf("bristolAxxeControl(%i, %i, %f)\n", operator, controller, value);
53 #endif
54 
55 	if (operator != 126)
56 		return(0);
57 
58 	switch (controller) {
59 		case 0:
60 			baudio->glide = value * value * baudio->glidemax;
61 			break;
62 		case 1:
63 			baudio->gtune = 1.0
64 				+ (baudio->note_diff - 1)
65 				* (value * 2 - 1);
66 
67 			buildCurrentTable(baudio, baudio->gtune);
68 			alterAllNotes(baudio);
69 			break;
70 		case 2:
71 			((axxemods *) baudio->mixlocals)->o_f_sine = value;
72 			break;
73 		case 3:
74 			((axxemods *) baudio->mixlocals)->o_f_square = value;
75 			break;
76 		case 4:
77 			((axxemods *) baudio->mixlocals)->o_f_sh = value / 16;
78 			break;
79 		case 5:
80 			((axxemods *) baudio->mixlocals)->o_f_adsr = value;
81 			break;
82 		case 6:
83 			((axxemods *) baudio->mixlocals)->o_pwm_sine = value * 512;
84 			break;
85 		case 7:
86 			((axxemods *) baudio->mixlocals)->o_pwm_adsr = value * 100;
87 			break;
88 		case 8:
89 			((axxemods *) baudio->mixlocals)->m_noise = value;
90 			break;
91 		case 9:
92 			((axxemods *) baudio->mixlocals)->m_ramp = value;
93 			break;
94 		case 10:
95 			((axxemods *) baudio->mixlocals)->m_square = value * 96.0;
96 			break;
97 		case 11:
98 			((axxemods *) baudio->mixlocals)->f_sine = value;
99 			break;
100 		case 12:
101 			((axxemods *) baudio->mixlocals)->f_adsr = value;
102 			break;
103 		case 13:
104 			((axxemods *) baudio->mixlocals)->a_gain = value;
105 			break;
106 		case 14:
107 			((axxemods *) baudio->mixlocals)->a_adsr = value;
108 			break;
109 		case 15:
110 			if (baudio->voicecount == 1)
111 			{
112 				/* Multi Env trigger */
113 				if (ivalue == 0)
114 					baudio->mixflags &= ~BRISTOL_MULTITRIG;
115 				else
116 					baudio->mixflags |= BRISTOL_MULTITRIG;
117 			} else {
118 				/*
119 				 * Else multi lfo
120 				 */
121 				if (ivalue)
122 					baudio->mixflags &= ~A_LFO_MULTI;
123 				else
124 					baudio->mixflags |= A_LFO_MULTI;
125 			}
126 			break;
127 		case 16:
128 			/* PPC Flatten */
129 			if (ivalue)
130 				ivalue = -1;
131 			else
132 				ivalue = 0;
133 			baudio->gtune = 1.0
134 				+ (baudio->note_diff - 1) * (ivalue * 2);
135 
136 			buildCurrentTable(baudio, baudio->gtune);
137 			alterAllNotes(baudio);
138 			break;
139 		case 17:
140 			/* PPC trill */
141 			if (ivalue)
142 				baudio->mixflags |= A_LFO_TRILL;
143 			else
144 				baudio->mixflags &= ~A_LFO_TRILL;
145 			break;
146 		case 18:
147 			/* PPC Sharpen */
148 			if (ivalue)
149 				ivalue = 1;
150 			else
151 				ivalue = 0;
152 			baudio->gtune = 1.0
153 				+ (baudio->note_diff - 1) * (ivalue * 2);
154 
155 			buildCurrentTable(baudio, baudio->gtune);
156 			alterAllNotes(baudio);
157 			break;
158 		case 19:
159 			/* Auto Env repeat. */
160 			if (ivalue == 0) {
161 				((axxemods *) baudio->mixlocals)->lfoAuto = -1;
162 			} else {
163 				float low;
164 
165 				/*
166 				 * We have been given a value between 0 and 1.0.
167 				 *	0 = 0.1Hz
168 				 *  1 = 10 Hz
169 				 *
170 				 * The delays are only going to be based on sample buffer
171 				 * delays, so find out the nearest number of buffers for any
172 				 * given rate.
173 				 *
174 				 * Buffer time = samplecount / samplerate.
175 				 *
176 				 *	Low = 0.1 / btime
177 				 *	High = 10 / btime (= 100 * Low)
178 				 *
179 				 * Rate is the value between these.
180 				 *
181 				 *	count = Low + 100 * Low  * (1 - value)
182 				low = 0.1 / ( ((float) audiomain->samplecount)
183 					/ ((float) audiomain->samplerate));
184 				 *
185 				 * Bums, don't have easy access to sc and sr.
186 				 */
187 				value = gainTable[
188 					(int) ((1 - value) * (CONTROLLER_RANGE - 1))].gain;
189 				low = 0.1 / ( ((float) 256)
190 					/ ((float) baudio->samplerate));
191 				((axxemods *) baudio->mixlocals)->lfoAuto =
192 					low + 100 * low * value;
193 			}
194 			break;
195 	}
196 	return(0);
197 }
198 
199 int
axxePreops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)200 axxePreops(audioMain *audiomain, Baudio *baudio,
201 bristolVoice *voice, register float *startbuf)
202 {
203 	if (((axxemods *) baudio->mixlocals)->lfolocals == 0)
204 	{
205 		((axxemods *) baudio->mixlocals)->lfolocals =
206 			baudio->locals[voice->index][2];
207 	}
208 
209 /* NOISE */
210 	bristolbzero(noisebuf, audiomain->segmentsize);
211 	audiomain->palette[(*baudio->sound[6]).index]->specs->io[0].buf = noisebuf;
212 	(*baudio->sound[6]).operate(
213 		(audiomain->palette)[4],
214 		voice,
215 		(*baudio->sound[6]).param,
216 		voice->locals[voice->index][6]);
217 /* NOISE DONE */
218 
219 /* LFO produces 3 outputs, sine, square and S/H */
220 	if ((baudio->mixflags & A_LFO_MULTI) == 0)
221 	{
222 		/*
223 		 * Operate LFO if we have one per voice.
224 		 */
225 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[0].buf
226 			= noisebuf;
227 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[4].buf
228 			= lfosine;
229 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[2].buf
230 			= lfosquare;
231 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[3].buf
232 			= lfosh;
233 		(*baudio->sound[2]).operate(
234 			(audiomain->palette)[16],
235 			voice,
236 			(*baudio->sound[2]).param,
237 			((axxemods *) baudio->mixlocals)->lfolocals);
238 	}
239 
240 	if (((axxemods *) baudio->mixlocals)->lfoAuto >= 0)
241 	{
242 		if (++((axxemods *) baudio->mixlocals)->lfoAutoCount
243 			>= ((axxemods *) baudio->mixlocals)->lfoAuto)
244 			((axxemods *) baudio->mixlocals)->lfoAutoCount = 0;
245 	}
246 /* */
247 	return(0);
248 }
249 
250 int
operateOneAxxe(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)251 operateOneAxxe(audioMain *audiomain, Baudio *baudio,
252 bristolVoice *voice, register float *startbuf)
253 {
254 	axxemods *mods = (axxemods *) baudio->mixlocals;
255 	int sc = audiomain->samplecount, flags;
256 
257 /*printf("operateOneAxxe(%i, %x, %x)\n", voice->index, audiomain, baudio); */
258 
259 	bristolbzero(freqbuf, audiomain->segmentsize);
260 	bristolbzero(osc1buf, audiomain->segmentsize);
261 	bristolbzero(osc2buf, audiomain->segmentsize);
262 	bristolbzero(filtbuf, audiomain->segmentsize);
263 	bristolbzero(scratch, audiomain->segmentsize);
264 	/*
265 	 * There are a lot of mods in this synth, each operator will produce its
266 	 * output buffer, and then they will modulate eachother.
267 	 *
268 	 * Noise is done, run the LFO and ADSR.
269 	 */
270 
271 /* LFO produces 3 outputs, sine, square and S/H */
272 	if (baudio->mixflags & A_LFO_MULTI)
273 	{
274 		/*
275 		 * Operate LFO if we have one per voice.
276 		 */
277 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[0].buf
278 			= noisebuf;
279 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[4].buf
280 			= lfosine;
281 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[2].buf
282 			= lfosquare;
283 		audiomain->palette[(*baudio->sound[2]).index]->specs->io[3].buf
284 			= lfosh;
285 		(*baudio->sound[2]).operate(
286 			(audiomain->palette)[16],
287 			voice,
288 			(*baudio->sound[2]).param,
289 			baudio->locals[voice->index][2]);
290 	}
291 
292 	if (mods->lfoAuto >= 0)
293 	{
294 		if (mods->lfoAutoCount == 0)
295 		{
296 			if ((voice->flags & (BRISTOL_KEYOFF|BRISTOL_KEYOFFING)) == 0)
297 				voice->flags |= BRISTOL_KEYREON;
298 /*			if ((voice->flags & (BRISTOL_KEYOFF|BRISTOL_KEYOFFING)) == 0) */
299 /*			{ */
300 /*				voice->flags |= BRISTOL_KEYREON; */
301 /*			} */
302 		}
303 	}
304 /* */
305 
306 /* ADSR */
307 	/*
308 	 * Run the ADSR.
309 	 */
310 	audiomain->palette[(*baudio->sound[4]).index]->specs->io[0].buf = adsrbuf;
311 	(*baudio->sound[4]).operate(
312 		(audiomain->palette)[1],
313 		voice,
314 		(*baudio->sound[4]).param,
315 		voice->locals[voice->index][4]);
316 /* ADSR - OVER */
317 
318 	/*
319 	 * We now have our mods, Noise, ADSR, S/H, Sine, Square.
320 	 *
321 	 * Run the oscillators.
322 	 */
323 /* OSC */
324 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[0].buf = freqbuf;
325 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[1].buf = 0;
326 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[2].buf = osc1buf;
327 
328 	fillFreqTable(baudio, voice, freqbuf, sc, 1);
329 
330 	/*
331 	 * Put in any desired mods. There are two, MG and Wheel mod. Wheel mod is
332 	 * actually quite week, takes the LFO to freqbuf, same as MG without the
333 	 * env. Hm.
334 	 */
335 	if (baudio->mixflags & A_LFO_TRILL)
336 		bufmerge(lfosine, 0.2, freqbuf, 1.0, sc);
337 	if (mods->o_f_sine != 0.0f)
338 		bufmerge(lfosine, mods->o_f_sine, freqbuf, 1.0, sc);
339 	if (mods->o_f_square != 0.0f)
340 		bufmerge(lfosquare, mods->o_f_square, freqbuf, 1.0, sc);
341 	if (mods->o_f_sh != 0.0f)
342 		bufmerge(lfosh, mods->o_f_sh, freqbuf, 1.0, sc);
343 	if (mods->o_f_adsr != 0.0f)
344 		bufmerge(adsrbuf, mods->o_f_adsr, freqbuf, 1.0, sc);
345 
346 	(*baudio->sound[0]).operate(
347 		(audiomain->palette)[8],
348 		voice,
349 		(*baudio->sound[0]).param,
350 		voice->locals[voice->index][0]);
351 
352 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[0].buf = freqbuf;
353 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[1].buf = scratch;
354 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[2].buf = osc2buf;
355 
356 	if (mods->o_pwm_sine != 0.0f)
357 		bufmerge(lfosine, mods->o_pwm_sine, scratch, 0.0, sc);
358 	if (mods->o_pwm_adsr != 0.0f)
359 		bufmerge(adsrbuf, mods->o_pwm_adsr, scratch, 1.0, sc);
360 
361 	/*
362 	 * This was called with sound 0 rather than 1, so had two different freq
363 	 * and mixed output buffers. Sounded like ring mod.
364 	 */
365 	(*baudio->sound[1]).operate(
366 		(audiomain->palette)[8],
367 		voice,
368 		(*baudio->sound[1]).param,
369 		voice->locals[voice->index][1]);
370 /* OSC done */
371 
372 /* Mixer */
373 	bufmerge(noisebuf, mods->m_noise, osc1buf, mods->m_ramp, sc);
374 	bufmerge(osc2buf, mods->m_square, osc1buf, 96.0, sc);
375 /* */
376 
377 /* Filter */
378 	audiomain->palette[(*baudio->sound[3]).index]->specs->io[0].buf
379 		= osc1buf;
380 	audiomain->palette[(*baudio->sound[3]).index]->specs->io[1].buf
381 		= scratch;
382 	audiomain->palette[(*baudio->sound[3]).index]->specs->io[2].buf
383 		= baudio->rightbuf;;
384 
385 	bristolbzero(scratch, audiomain->segmentsize);
386 	if (mods->f_sine != 0.0f)
387 		bufmerge(lfosine, mods->f_sine, scratch, 0.0, sc);
388 	if (mods->f_adsr != 0.0f)
389 		bufmerge(adsrbuf, mods->f_adsr, scratch, 1.0, sc);
390 
391 	(*baudio->sound[3]).operate(
392 		(audiomain->palette)[3],
393 		voice,
394 		(*baudio->sound[3]).param,
395 		voice->locals[voice->index][3]);
396 /* Filter DONE */
397 
398 /* AMP */
399 	/*
400 	 * Reworked this for dual envelope mix - key grooming - reusing the lfosine
401 	 * buffer....
402 	bufmerge(lfosine, 0.0, adsrbuf, mods->a_adsr, sc);
403 	{
404 		register float gain = mods->a_gain, *ab = adsrbuf;
405 		register int i = 0;
406 
407 		for (; i < sc; i += 8)
408 		{
409 			*ab++ += gain;
410 			*ab++ += gain;
411 			*ab++ += gain;
412 			*ab++ += gain;
413 			*ab++ += gain;
414 			*ab++ += gain;
415 			*ab++ += gain;
416 			*ab++ += gain;
417 		}
418 	}
419 	 */
420 
421 	flags = voice->flags;
422 	audiomain->palette[(*baudio->sound[7]).index]->specs->io[0].buf = lfosine;
423 	(*baudio->sound[7]).operate(
424 		(audiomain->palette)[1],
425 		voice,
426 		(*baudio->sound[7]).param,
427 		voice->locals[voice->index][7]);
428 	voice->flags = flags;
429 
430 	bufmerge(lfosine, mods->a_gain, adsrbuf, mods->a_adsr, sc);
431 
432 	audiomain->palette[(*baudio->sound[5]).index]->specs->io[0].buf
433 		= baudio->rightbuf;
434 	audiomain->palette[(*baudio->sound[5]).index]->specs->io[1].buf
435 		= adsrbuf;
436 	audiomain->palette[(*baudio->sound[5]).index]->specs->io[2].buf =
437 		baudio->leftbuf;
438 
439 	(*baudio->sound[5]).operate(
440 		(audiomain->palette)[2],
441 		voice,
442 		(*baudio->sound[5]).param,
443 		voice->locals[voice->index][5]);
444 /* AMP OVER */
445 	/*
446 	 * It is bad practice to use the rightbuf. It can be done, but must be
447 	 * zeroed - most efficiently in postOps but otherwise.....
448 	 */
449 	bristolbzero(baudio->rightbuf, audiomain->segmentsize);
450 
451 	return(0);
452 }
453 
454 static int
bristolAxxeDestroy(audioMain * audiomain,Baudio * baudio)455 bristolAxxeDestroy(audioMain *audiomain, Baudio *baudio)
456 {
457 printf("removing one axxe\n");
458 	return(0);
459 	bristolfree(freqbuf);
460 	bristolfree(filtbuf);
461 	bristolfree(noisebuf);
462 	bristolfree(adsrbuf);
463 	bristolfree(lfosine);
464 	bristolfree(lfosquare);
465 	bristolfree(lfosh);
466 	bristolfree(osc1buf);
467 	bristolfree(osc1buf);
468 
469 	return(0);
470 }
471 
472 int
bristolAxxeInit(audioMain * audiomain,Baudio * baudio)473 bristolAxxeInit(audioMain *audiomain, Baudio *baudio)
474 {
475 printf("initialising one axxe\n");
476 	baudio->soundCount = 8; /* Number of operators in this voice */
477 	/*
478 	 * Assign an array of sound pointers.
479 	 */
480 	baudio->sound = (bristolSound **)
481 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
482 	baudio->effect = (bristolSound **)
483 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
484 
485 	/* Ramp oscillator */
486 	initSoundAlgo(8, 0, baudio, audiomain, baudio->sound);
487 	/* Square oscillator */
488 	initSoundAlgo(8, 1, baudio, audiomain, baudio->sound);
489 	/* LFO */
490 	initSoundAlgo(16, 2, baudio, audiomain, baudio->sound);
491 	/* A filter */
492 	initSoundAlgo(3, 3, baudio, audiomain, baudio->sound);
493 	/* Single ADSR */
494 	initSoundAlgo(1, 4, baudio, audiomain, baudio->sound);
495 	/* An amplifier */
496 	initSoundAlgo(2, 5, baudio, audiomain, baudio->sound);
497 	/* An noise source */
498 	initSoundAlgo(4, 6, baudio, audiomain, baudio->sound);
499 	/* A grooming env for direct gain to amp */
500 	initSoundAlgo(1, 7, baudio, audiomain, baudio->sound);
501 
502 	baudio->param = axxeController;
503 	baudio->destroy = bristolAxxeDestroy;
504 	baudio->operate = operateOneAxxe;
505 	baudio->preops = axxePreops;
506 
507 	if (freqbuf == NULL)
508 		freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
509 	if (filtbuf == NULL)
510 		filtbuf = (float *) bristolmalloc0(audiomain->segmentsize);
511 	if (noisebuf == NULL)
512 		noisebuf = (float *) bristolmalloc0(audiomain->segmentsize);
513 	if (adsrbuf == NULL)
514 		adsrbuf = (float *) bristolmalloc0(audiomain->segmentsize);
515 	if (lfosh == NULL)
516 		lfosh = (float *) bristolmalloc0(audiomain->segmentsize);
517 	if (lfosquare == NULL)
518 		lfosquare = (float *) bristolmalloc0(audiomain->segmentsize);
519 	if (lfosine == NULL)
520 		lfosine = (float *) bristolmalloc0(audiomain->segmentsize);
521 	if (osc1buf == NULL)
522 		osc1buf = (float *) bristolmalloc0(audiomain->segmentsize);
523 	if (osc2buf == NULL)
524 		osc2buf = (float *) bristolmalloc0(audiomain->segmentsize);
525 	if (scratch == NULL)
526 		scratch = (float *) bristolmalloc0(audiomain->segmentsize);
527 
528 	baudio->mixlocals = (float *) bristolmalloc0(sizeof(axxemods));
529 
530 	return(0);
531 }
532 
533