1 /*
2  *  Diverse Bristol audio routines.
3  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 3 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 /*
22  * This will be a granular synthesiser. We need to build an efficient method to
23  * generate a potentially very large number of grains, each of which will take
24  *
25  *	a gain curve, initially an inverted, normalised cosine or gaussian envelope
26  *	a wave table
27  *
28  * The wavetable will be resampled to a given frequency at some extraction of
29  * the given note, and its gain will be defined by a multiple of the resampled
30  * gain curve. The multiple will be partially randomised by parameterisation.
31  * We should allow for glissando of the waveforms. Grain time shall be from 2
32  * to 100ms.
33  *
34  * Wave tables should be the usual suspects to start with.
35  *
36  * The result should go through an envelope generator and amp.
37  */
38 
39 /* #define DEBUG */
40 
41 #include "bristol.h"
42 #include "granular.h"
43 
44 static float *freqbuf = (float *) NULL;
45 
46 static float *zerobuf = (float *) NULL;
47 
48 static float *lfobuf = (float *) NULL;
49 static float *noisebuf = (float *) NULL;
50 
51 static float *adsrbuf = (float *) NULL;
52 
53 static float *bus1buf = (float *) NULL;
54 static float *bus2buf = (float *) NULL;
55 static float *bus3buf = (float *) NULL;
56 static float *bus4buf = (float *) NULL;
57 static float *bus5buf = (float *) NULL;
58 static float *bus6buf = (float *) NULL;
59 static float *bus7buf = (float *) NULL;
60 static float *bus8buf = (float *) NULL;
61 static float *bus9buf = (float *) NULL;
62 
63 static float *busbuf[9];
64 
65 extern int bristolGlobalController(struct BAudio *, u_char, u_char, float);
66 extern int buildCurrentTable(Baudio *, float);
67 
68 int
granularGlobalController(Baudio * baudio,u_char operator,u_char controller,float value)69 granularGlobalController(Baudio *baudio, u_char operator,
70 u_char controller, float value)
71 {
72 	/*
73 	 * Granular global controller code. We will need to control the effects
74 	 * chain and global tuning from here.
75 printf("granularGlobalController(%x, %i, %i, %f)\n",
76 baudio, controller, operator, value);
77 	 */
78 
79 	/*
80 	 * 98 will be the dimension D
81 	 */
82 	if (operator == 98)
83 	{
84 		baudio->effect[1]->param->param[controller].float_val = value;
85 		return(0);
86 	}
87 
88 	/*
89 	 * Reverb
90 	 */
91 	if (operator == 99)
92 	{
93 		if (controller == 0)
94 		{
95 			baudio->effect[0]->param->param[controller].float_val = value;
96 			baudio->effect[0]->param->param[controller].int_val = 1;
97 		} else
98 			baudio->effect[0]->param->param[controller].float_val = value;
99 /*
100 printf("F %f, C %f, W %f, G %f ? %f\n",
101 baudio->effect[0]->param->param[1].float_val,
102 baudio->effect[0]->param->param[2].float_val,
103 baudio->effect[0]->param->param[3].float_val,
104 baudio->effect[0]->param->param[4].float_val,
105 baudio->effect[0]->param->param[5].float_val);
106 */
107 
108 		return(0);
109 	}
110 
111 	if (operator != 126)
112 		return(0);
113 
114 	switch (controller) {
115 		case 0:
116 			baudio->glide = value * value * baudio->glidemax;
117 			break;
118 		case 1:
119 			baudio->gtune = 1.0
120 				+ (baudio->note_diff - 1)
121 				* (value * 2 - 1);
122 
123 			buildCurrentTable(baudio, baudio->gtune);
124 			alterAllNotes(baudio);
125 			break;
126 		case 3:
127 			if (value == 0.0)
128 				baudio->mixflags &= ~KEY_TRACKING;
129 			else
130 				baudio->mixflags |= KEY_TRACKING;
131 			break;
132 		case 4:
133 			if (value == 0.0)
134 				baudio->mixflags &= ~MULTI_LFO;
135 			else
136 				baudio->mixflags |= MULTI_LFO;
137 			break;
138 		case 10:
139 			/*
140 			 * Mod routing Env1
141 			 */
142 			((granularmods *) baudio->mixlocals)->env1mod =
143 				value * CONTROLLER_RANGE;
144 printf("env 1 flags are %i\n", (int) (value * CONTROLLER_RANGE));
145 			break;
146 		case 11:
147 			/*
148 			 * Mod routing Env2
149 			 */
150 			((granularmods *) baudio->mixlocals)->env2mod =
151 				value * CONTROLLER_RANGE;
152 printf("env 2 flags are %i\n", (int) (value * CONTROLLER_RANGE));
153 			break;
154 		case 12:
155 			/*
156 			 * Mod routing Env3
157 			 */
158 			((granularmods *) baudio->mixlocals)->env3mod =
159 				value * CONTROLLER_RANGE;
160 printf("env 3 flags are %i\n", (int) (value * CONTROLLER_RANGE));
161 			break;
162 		case 13:
163 			/*
164 			 * Mod routing LFO
165 			 */
166 			((granularmods *) baudio->mixlocals)->lfomod =
167 				value * CONTROLLER_RANGE;
168 printf("lfo flags are %i\n", (int) (value * CONTROLLER_RANGE));
169 			break;
170 		case 14:
171 			/*
172 			 * Mod routing Noise
173 			 */
174 			((granularmods *) baudio->mixlocals)->noisemod =
175 				value * CONTROLLER_RANGE;
176 printf("noise flags are %i\n", (int) (value * CONTROLLER_RANGE));
177 			break;
178 	}
179 	return(0);
180 }
181 
182 int
operateGranularPreops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)183 operateGranularPreops(audioMain *audiomain, Baudio *baudio,
184 bristolVoice *voice, register float *startbuf)
185 {
186 #ifdef DEBUG
187 	printf("operateGranularPreops(%x, %x, %x) %i\n",
188 		baudio, voice, startbuf, baudio->cvoices);
189 #endif
190 
191 	if (lfobuf == NULL)
192 		return(0);
193 
194 	if ((baudio->mixflags & MULTI_LFO) == 0)
195 	{
196 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[0].buf
197 			= NULL;
198 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[1].buf
199 			= lfobuf;
200 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[2].buf
201 			= NULL;
202 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[3].buf
203 			= NULL;
204 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[4].buf
205 			= NULL;
206 		(*baudio->sound[4]).operate(
207 			(audiomain->palette)[16],
208 			voice,
209 			(*baudio->sound[4]).param,
210 			baudio->locals[voice->index][4]);
211 
212 		bufmerge(zerobuf, 0.0,
213 			lfobuf, baudio->contcontroller[1], audiomain->samplecount);
214 	}
215 
216 	return(0);
217 }
218 
219 static void
modRoute(float * source,unsigned int flags,int sc)220 modRoute(float *source, unsigned int flags, int sc)
221 {
222 	int i;
223 
224 	for (i = 0; i < 9; i++)
225 		if ((flags & (1 << i)) != 0)
226 			bufmerge(source, 1.0, busbuf[i], 1.0, sc);
227 }
228 
229 /*
230  * Operate one granular voice.
231  */
232 int
operateOneGranularVoice(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)233 operateOneGranularVoice(audioMain *audiomain, Baudio *baudio,
234 bristolVoice *voice, register float *startbuf)
235 {
236 	int samplecount = audiomain->samplecount;
237 	int i;
238 	granularmods *mods = (granularmods *) baudio->mixlocals;
239 
240 #ifdef DEBUG
241 	printf("operateOneGranularVoice(%x, %x, %x)\n", baudio, voice, startbuf);
242 #endif
243 
244 	for (i = 0; i < 9; i++)
245 		bristolbzero(busbuf[i], audiomain->segmentsize);
246 
247 	bristolbzero(startbuf, audiomain->segmentsize);
248 
249 	if (lfobuf == NULL)
250 		return(0);
251 
252 	if ((baudio->mixflags & MULTI_LFO) != 0)
253 	{
254 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[0].buf
255 			= NULL;
256 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[1].buf
257 			= lfobuf;
258 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[2].buf
259 			= NULL;
260 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[3].buf
261 			= NULL;
262 		audiomain->palette[(*baudio->sound[4]).index]->specs->io[4].buf
263 			= NULL;
264 		(*baudio->sound[4]).operate(
265 			(audiomain->palette)[16],
266 			voice,
267 			(*baudio->sound[4]).param,
268 			baudio->locals[voice->index][4]);
269 
270 		bufmerge(zerobuf, 0.0,
271 			lfobuf, baudio->contcontroller[1], samplecount);
272 	}
273 	modRoute(lfobuf, mods->lfomod, samplecount);
274 
275 	/* Noise source */
276 	bristolbzero(noisebuf, audiomain->segmentsize);
277 	audiomain->palette[(*baudio->sound[5]).index]->specs->io[0].buf = noisebuf;
278 	(*baudio->sound[5]).operate(
279 		(audiomain->palette)[4],
280 		voice,
281 		(*baudio->sound[5]).param,
282 		voice->locals[voice->index][5]);
283 	bufmerge(zerobuf, 0.0, noisebuf, 0.01, samplecount);
284 	modRoute(noisebuf, mods->noisemod, samplecount);
285 
286 	/* ADSR 1, 2, 3 */
287 	audiomain->palette[(*baudio->sound[1]).index]->specs->io[0].buf = adsrbuf;
288 	(*baudio->sound[1]).operate(
289 		(audiomain->palette)[1],
290 		voice,
291 		(*baudio->sound[1]).param,
292 		voice->locals[voice->index][1]);
293 	modRoute(adsrbuf, mods->env1mod, samplecount);
294 
295 	(*baudio->sound[2]).operate(
296 		(audiomain->palette)[1],
297 		voice,
298 		(*baudio->sound[2]).param,
299 		voice->locals[voice->index][2]);
300 	modRoute(adsrbuf, mods->env2mod, samplecount);
301 
302 	(*baudio->sound[3]).operate(
303 		(audiomain->palette)[1],
304 		voice,
305 		(*baudio->sound[3]).param,
306 		voice->locals[voice->index][3]);
307 	modRoute(adsrbuf, mods->env3mod, samplecount);
308 
309 	/*
310 	 * Merge the freqbuf into bus3buf for key tracking, which should be optional
311 	 */
312 	if (baudio->mixflags & KEY_TRACKING) {
313 		/*
314 		 * Fill the wavetable with the correct note value, accepting glissando.
315 		 */
316 		fillFreqTable(baudio, voice, freqbuf, samplecount, 1);
317 		bufmerge(freqbuf, 1.0, bus3buf, 1.0, samplecount);
318 	}
319 
320 	/*
321 	 * Do the grains. We need to pass the mods, rbuf, lbuf
322 	 */
323 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[0].buf = freqbuf;
324 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[1].buf =
325 		baudio->leftbuf;
326 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[2].buf =
327 		baudio->rightbuf;
328 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[3].buf = bus1buf;
329 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[4].buf = bus2buf;
330 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[5].buf = bus3buf;
331 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[6].buf = bus4buf;
332 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[7].buf = bus5buf;
333 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[8].buf = bus6buf;
334 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[9].buf = bus7buf;
335 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[10].buf = bus8buf;
336 	audiomain->palette[(*baudio->sound[0]).index]->specs->io[11].buf = bus9buf;
337 
338 	(*baudio->sound[0]).operate(
339 		(audiomain->palette)[29],
340 		voice,
341 		(*baudio->sound[0]).param,
342 		voice->locals[voice->index][0]);
343 
344 	return(0);
345 }
346 
347 int
operateGranularPostops(audioMain * audiomain,Baudio * baudio,bristolVoice * voice,register float * startbuf)348 operateGranularPostops(audioMain *audiomain, Baudio *baudio,
349 bristolVoice *voice, register float *startbuf)
350 {
351 #ifdef DEBUG
352 	printf("operateGranularPostops(%x, %x, %x) %i\n",
353 		baudio, voice, startbuf, baudio->cvoices);
354 #endif
355 
356 	if (baudio->mixlocals == NULL)
357 		/* ((void *) baudio->mixlocals) = voice->locals[voice->index]; */
358 		baudio->mixlocals = (float *) voice->locals[voice->index];
359 
360 	return(0);
361 }
362 
363 int
destroyOneGranularVoice(audioMain * audiomain,Baudio * baudio)364 destroyOneGranularVoice(audioMain *audiomain, Baudio *baudio)
365 {
366 	baudio->mixlocals = NULL;
367 	return(0);
368 	if (freqbuf != NULL)
369 		bristolfree(freqbuf);
370 	freqbuf = NULL;
371 
372 	if (baudio->mixlocals != NULL)
373 		bristolfree(baudio->mixlocals);
374 
375 	baudio->mixlocals = NULL;
376 
377 	return(0);
378 }
379 
380 int
bristolGranularInit(audioMain * audiomain,Baudio * baudio)381 bristolGranularInit(audioMain *audiomain, Baudio *baudio)
382 {
383 	granularmods *mods;
384 
385 printf("initialising one granular sound\n");
386 
387 	baudio->soundCount = 6; /* Number of operators in this granular voice */
388 
389 	/*
390 	 * Assign an array of sound pointers.
391 	 */
392 	baudio->sound = (bristolSound **)
393 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
394 	baudio->effect = (bristolSound **)
395 		bristolmalloc0(sizeof(bristolOP *) * baudio->soundCount);
396 
397 	/*
398 	 * We need 3 oscillators, two for the higher frequencies and one for the
399 	 * bass. Then we need an envelope and amplifier. After that we will start
400 	 * with one effect, the flanger and may add a reverb in depending on the
401 	 * results.
402 	 *
403 	 * We will use the ARP oscillators (obviously), producing two waveforms
404 	 * each, a ramp and a square.
405 	 */
406 	initSoundAlgo( 29,	0, baudio, audiomain, baudio->sound);
407 	/* 3 ADSR */
408 	initSoundAlgo( 1,	1, baudio, audiomain, baudio->sound);
409 	initSoundAlgo( 1,	2, baudio, audiomain, baudio->sound);
410 	initSoundAlgo( 1,	3, baudio, audiomain, baudio->sound);
411 	/* LFO - preops or main ops? */
412 	initSoundAlgo(16,	4, baudio, audiomain, baudio->sound);
413 	/* Noise source */
414 	initSoundAlgo( 4,	5, baudio, audiomain, baudio->sound);
415 
416 	/*
417 	 * Add in a flanger. We could add in a reverb before or after, or even
418 	 * a second flanger to space the sound out a little more.
419 	initSoundAlgo(	22, 0, baudio, audiomain, baudio->effect);
420 	initSoundAlgo(	12,	1, baudio, audiomain, baudio->effect);
421 	 */
422 
423 	baudio->param = granularGlobalController;
424 	baudio->destroy = destroyOneGranularVoice;
425 	baudio->operate = operateOneGranularVoice;
426 	baudio->preops = operateGranularPreops;
427 	/*baudio->postops = operateGranularPostops; */
428 
429 	/*
430 	 * Get some workspace
431 	 */
432 	if (freqbuf == (float *) NULL)
433 		freqbuf = (float *) bristolmalloc0(audiomain->segmentsize);
434 	if (zerobuf == (float *) NULL)
435 		zerobuf = (float *) bristolmalloc0(audiomain->segmentsize);
436 	if (lfobuf == (float *) NULL)
437 		lfobuf = (float *) bristolmalloc0(audiomain->segmentsize);
438 	if (adsrbuf == (float *) NULL)
439 		adsrbuf = (float *) bristolmalloc0(audiomain->segmentsize);
440 	if (noisebuf == (float *) NULL)
441 		noisebuf = (float *) bristolmalloc0(audiomain->segmentsize);
442 	if (bus1buf == (float *) NULL)
443 		bus1buf = (float *) bristolmalloc0(audiomain->segmentsize);
444 	if (bus2buf == (float *) NULL)
445 		bus2buf = (float *) bristolmalloc0(audiomain->segmentsize);
446 	if (bus3buf == (float *) NULL)
447 		bus3buf = (float *) bristolmalloc0(audiomain->segmentsize);
448 	if (bus4buf == (float *) NULL)
449 		bus4buf = (float *) bristolmalloc0(audiomain->segmentsize);
450 	if (bus5buf == (float *) NULL)
451 		bus5buf = (float *) bristolmalloc0(audiomain->segmentsize);
452 	if (bus6buf == (float *) NULL)
453 		bus6buf = (float *) bristolmalloc0(audiomain->segmentsize);
454 	if (bus7buf == (float *) NULL)
455 		bus7buf = (float *) bristolmalloc0(audiomain->segmentsize);
456 	if (bus8buf == (float *) NULL)
457 		bus8buf = (float *) bristolmalloc0(audiomain->segmentsize);
458 	if (bus9buf == (float *) NULL)
459 		bus9buf = (float *) bristolmalloc0(audiomain->segmentsize);
460 
461 	busbuf[0] = bus1buf;
462 	busbuf[1] = bus2buf;
463 	busbuf[2] = bus3buf;
464 	busbuf[3] = bus4buf;
465 	busbuf[4] = bus5buf;
466 	busbuf[5] = bus6buf;
467 	busbuf[6] = bus7buf;
468 	busbuf[7] = bus8buf;
469 	busbuf[8] = bus9buf;
470 
471 	mods = (granularmods *) bristolmalloc0(sizeof(granularmods));
472 
473 	//printf("size is %i\n", sizeof(granularmods));
474 
475 	baudio->mixlocals = (float *) mods;
476 	baudio->mixflags |= BRISTOL_STEREO;
477 
478 printf("initialised one granular sound\n");
479 
480 	return(0);
481 }
482 
483