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