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 /*#define DEBUG */
23 
24 #include <math.h>
25 #include <assert.h>
26 
27 #include "bristol.h"
28 //#include "bristolmm.h"
29 
30 #include "dco.h"
31 
32 extern tableEntry defaultTable[];
33 extern void freeBristolAudio();
34 static void a440();
35 
36 #ifndef BRISTOL_SEMAPHORE
37 extern void rbMidiNote(audioMain *, bristolMidiMsg *);
38 #endif
39 
40 /*
41  * Used by the a440 sine generator.
42  */
43 int s440holder = 0;
44 
45 static void
bristolUnlinkVoice(audioMain * audiomain,bristolVoice * v)46 bristolUnlinkVoice(audioMain *audiomain, bristolVoice *v)
47 {
48 	bristolVoice *vtp;
49 
50 	/*
51 	 * See if this is a monophonic voice with note preference
52 	 */
53 	if ((v->baudio != NULL) && (v->baudio->voicecount == 1)
54 		&& (v->baudio->notemap.flags & (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)))
55 	{
56 		v->flags &= ~BRISTOL_KEYDONE;
57 		v = v->next;
58 		return;
59 	}
60 
61 	/*
62 	 * Move to the tail of the freelist, unlink it first:
63 	 */
64 	if (v->next != NULL)
65 		v->next->last = v->last;
66 	else
67 		audiomain->playlast = v->last;
68 
69 	if (v->last != NULL)
70 		v->last->next = v->next;
71 	else
72 		audiomain->playlist = v->next;
73 
74 	vtp = v;
75 	/* We have to move this to the next entry now */
76 	v = v->next;
77 
78 	/* Unlinked, put it on the tail of the freelist */
79 	vtp->next = NULL;
80 	if ((vtp->last = audiomain->freelast) != NULL)
81 		vtp->last->next = vtp;
82 	else
83 		audiomain->freelist = vtp;
84 	audiomain->freelast = vtp;
85 }
86 
87 /*
88  * This should be organised to be a callback for the Jack and DSSI interfaces.
89  * there may be issues of internal buffering that will have to be reviewed, and
90  * potentially if we are called with less than our desired number of samples
91  * then we buffer them internally and return data slightly behind the real
92  * time requests.
93  *
94  * The syntax for the callback will have to accord to the API specifications
95  * which means audiomain will be implicit.
96  *
97  * doAudioOps() should take at least 4 bufs? Arrays of buf pointers? Whatever
98  * the final specification this should no longer take a pair of interleaved
99  * sample buffers. Optimally have each synth just use its own output buffers
100  * and pair of input buffers. The calling routine can decide how to mix them
101  * down and what inputs to provide.
102  */
103 int
doAudioOps(audioMain * audiomain,float * outbuf,float * startbuf)104 doAudioOps(audioMain *audiomain, float *outbuf, float *startbuf)
105 {
106 	register bristolVoice *voice;
107 	register int i;
108 	register Baudio *thisaudio;
109 	register float *extmult, *leftch, *rightch, gain;
110 	bristolMidiMsg msg;
111 
112 	/*
113 	 * Clear the output buffer at this point.
114 	 */
115 	bristolbzero(outbuf, audiomain->segmentsize * 2);
116 
117 #ifdef DEBUG
118 	if ((audiomain->debuglevel & BRISTOL_DEBUG_MASK) > BRISTOL_DEBUG5)
119 		printf("doAudioOps\n");
120 #endif
121 
122 	/*
123 	 * Configure flags to force one iteration of the preops, and to enable
124 	 * postops if a voice is active.
125 	 */
126 	if ((thisaudio = audiomain->audiolist) == NULL)
127 	{
128 #ifndef BRISTOL_SEMAPHORE
129 		/*
130 		 * This is not threadsafe. We should flag the rb as inactive.
131 		 */
132 		jack_ringbuffer_stop(audiomain->rb);
133 		jack_ringbuffer_reset(audiomain->rb);
134 #endif
135 		return(0);
136 	}
137 
138 #ifndef BRISTOL_SEMAPHORE
139 	while (jack_ringbuffer_read_space(audiomain->rb) >= sizeof(bristolMidiMsg))
140 	{
141 		jack_ringbuffer_read(audiomain->rb, (char *) &msg,
142 			sizeof(bristolMidiMsg));
143 
144 		rbMidiNote(audiomain, &msg);
145 	}
146 #endif
147 
148 	while (thisaudio != NULL)
149 	{
150 		if (bristolActiveSenseCheck(audiomain, thisaudio) == 0)
151 			thisaudio->mixflags |= BRISTOL_REMOVE;
152 
153 		/*
154 		 * See if we are finished with the baudio (typically gui has exit).
155 		 */
156 		if (thisaudio->mixflags & BRISTOL_REMOVE)
157 		{
158 			Baudio *holder = thisaudio;
159 			bristolVoice *vl;
160 
161 #ifdef BRISTOL_SEMAPHORE
162 			sem_wait(audiomain->sem_long);
163 #endif
164 
165 			thisaudio = thisaudio->next;
166 
167 			freeBristolAudio(audiomain, holder);
168 
169 			if ((audiomain->audiolist == NULL)
170 				&& (audiomain->flags & BRISTOL_MIDI_WAIT))
171 			{
172 				if (audiomain->debuglevel > 5)
173 					printf("Terminate\n");
174 
175 				audiomain->atStatus = BRISTOL_TERM;
176 				holder->mixflags &= ~BRISTOL_REMOVE;
177 				return(0);
178 			}
179 
180 			/*
181 			 * Otherwise we need to make sure none of the voices are using this
182 			 * removed audio.
183 			 */
184 			for (vl = audiomain->playlist; vl != NULL; vl = vl->next)
185 				if (vl->baudio == holder)
186 					vl->baudio = NULL;
187 
188 			for (vl = audiomain->newlist; vl != NULL; vl = vl->next)
189 				if (vl->baudio == holder)
190 					vl->baudio = NULL;
191 
192 			holder->mixflags &= ~BRISTOL_REMOVE;
193 
194 #ifdef BRISTOL_SEMAPHORE
195 			sem_post(audiomain->sem_long);
196 #endif
197 
198 			continue;
199 		}
200 
201 		thisaudio->mixflags |= BRISTOL_MUST_PRE;
202 		thisaudio->mixflags &= ~BRISTOL_HAVE_OPED;
203 		thisaudio->lvoices = thisaudio->cvoices;
204 		thisaudio->cvoices = 0;
205 
206 		/*
207 		 * See if we need to wind this emulation arpeggiator counters along
208 		 */
209 		bristolArpegReAudio(audiomain, thisaudio);
210 
211 		thisaudio = thisaudio->next;
212 	}
213 
214 	/*
215 	 * a440 has to be done here, since it must be active even when no keys
216 	 * are pressed.
217 	 */
218 	if ((audiomain->audiolist != NULL)
219 			&& (audiomain->audiolist->mixflags & A_440))
220 		a440(audiomain, outbuf, audiomain->samplecount);
221 
222 	/*
223 	 * Get the long semaphore over the whole polyphonic process. We need to
224 	 * replace this with some message passing algorithms using something that
225 	 * is a bit less risky. Minimally we should just have a short_sem that
226 	 * covers management of a secure messaging list. That can wait though, this
227 	 * code is already pretty recent (0.40 stream).
228 	 */
229 #ifdef BRISTOL_SEMAPHORE
230 	sem_wait(audiomain->sem_long);
231 #endif
232 
233 	if (audiomain->newlist != NULL)
234 	{
235 		bristolVoice *v = audiomain->playlist, *vtp;
236 
237 		/*
238 		 * Get the short semaphore over the new voice management sequences
239 		 */
240 #ifdef BRISTOL_SEMAPHORE
241 		sem_wait(audiomain->sem_short);
242 #endif
243 
244 		/*
245 		 * Do a scan of the playlist and see if there is anything to be moved
246 		 * to the freelist (KEYDONE).
247 		 */
248 		while (v != NULL)
249 		{
250 #ifdef NOT_ANDROID_NATIVE_LIBRARY
251 #warning ANDROID PATCH, MAY HAVE TO BACK IT OUT
252 			if (v->flags & (BRISTOL_KEYON|BRISTOL_KEYREON))
253 				v->flags &= ~BRISTOL_KEYDONE;
254 			else
255 #endif
256 			if (v->flags & BRISTOL_KEYDONE)
257 			{
258 //printf("remove %x->%x/%x (0x%04x)\n", (size_t) v, (size_t) v->last,
259 //(size_t) v->next, v->flags);
260 
261 				/*
262 				 * See if this is a monophonic voice with note preference
263 				 */
264 				if ((v->baudio != NULL) && (v->baudio->voicecount == 1)
265 					&& (v->baudio->notemap.flags &
266 						(BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)))
267 				{
268 					v->flags &= ~BRISTOL_KEYDONE;
269 					v = v->next;
270 					continue;
271 				}
272 
273 				v->flags &= ~BRISTOL_KEYOFFING;
274 				/*
275 				 * Move to the tail of the freelist, unlink it first:
276 				 */
277 				if (v->next != NULL)
278 					v->next->last = v->last;
279 				else
280 					audiomain->playlast = v->last;
281 
282 				if (v->last != NULL)
283 					v->last->next = v->next;
284 				else
285 					audiomain->playlist = v->next;
286 
287 				vtp = v;
288 				/* We have to move this to the next entry now */
289 				v = v->next;
290 
291 				/* Unlinked, put it on the tail of the freelist */
292 				vtp->next = NULL;
293 				if ((vtp->last = audiomain->freelast) != NULL)
294 					vtp->last->next = vtp;
295 				else
296 					audiomain->freelist = vtp;
297 				audiomain->freelast = vtp;
298 
299 				continue;
300 			}
301 			v->offset = 0;
302 			v = v->next;
303 		}
304 
305 		/*
306 		 * The newlist is doubly linked but we don't care about that since we
307 		 * own access at the moment and are going to move all members across.
308 		 */
309 		while (audiomain->newlist != NULL)
310 		{
311 			v = audiomain->newlist;
312 			audiomain->newlist = v->next;
313 
314 			if ((v->next = audiomain->playlist) != NULL)
315 				v->next->last = v;
316 			else
317 				audiomain->playlast = v;
318 			v->last = NULL;
319 			audiomain->playlist = v;
320 
321 			v->flags &= ~(BRISTOL_KEYDONE
322 				|BRISTOL_KEYOFF
323 				|BRISTOL_KEYOFFING
324 				|BRISTOL_KEYSUSTAIN);
325 
326 			if ((v->flags & BRISTOL_KEYREON) == 0)
327 				v->flags |= BRISTOL_KEYON;
328 
329 			if (v->flags & BRISTOL_KEYREOFF)
330 			{
331 				v->flags &= ~BRISTOL_KEYREOFF;
332 				v->flags |= BRISTOL_KEYOFF|BRISTOL_KEYSUSTAIN;
333 			}
334 		}
335 
336 		audiomain->newlast = NULL;
337 
338 		/*
339 		 * Free the short semaphore over the new voice management sequences
340 		 */
341 #ifdef BRISTOL_SEMAPHORE
342 		sem_post(audiomain->sem_short);
343 #endif
344 	}
345 
346 	voice = audiomain->playlist;
347 
348 	/*
349 	 * We need to look through our voice list, and see if any are active. If
350 	 * so then start running the voice structures through the sound structures.
351 	 *
352 	 * This is the polyphonic mixing process.
353 	 */
354 	while (voice != NULL)
355 	{
356 		if ((voice->baudio == NULL)
357 			|| (voice->baudio->operate == NULL))
358 		{
359 			if ((voice->baudio != NULL)
360 				&& (voice->baudio->operate == NULL))
361 			{
362 				printf("this emulator is not implemented\n");
363 				voice->baudio->notemap.flags
364 					&= ~(BRISTOL_MNL_LNP|BRISTOL_MNL_HNP);
365 			}
366 			/*
367 			 * Unlink this voice
368 			 */
369 			bristolUnlinkVoice(audiomain, voice);
370 			voice = voice->next;
371 			continue;
372 		}
373 
374 		if (voice->baudio->mixflags & (BRISTOL_HOLDDOWN|BRISTOL_REMOVE))
375 		{
376 			voice = voice->next;
377 			continue;
378 		}
379 
380 		if (~voice->flags & BRISTOL_KEYDONE)
381 		{
382 			/*
383 			 * If this audio is mono, and count is zero and SUSTAIN is not
384 			 * active then signal KEY_OFF, clear extreme note;
385 			 */
386 			if ((voice->baudio->voicecount == 1)
387 				&& (voice->baudio->notemap.flags
388 					& (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP))
389 				&& (voice->baudio->notemap.count == 0)
390 				&& (voice->baudio->notemap.extreme >= 0)
391 				&& (voice->baudio->contcontroller[BRISTOL_CC_HOLD1] < 0.5))
392 			{
393 				if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG1)
394 					printf("engine cleared MNL note\n");
395 				voice->baudio->notemap.extreme = -1;
396 				voice->flags |= BRISTOL_KEYOFF;
397 				voice->flags &= ~BRISTOL_KEYSUSTAIN;
398 			}
399 
400 			if (voice->baudio->mixflags & BRISTOL_MUST_PRE)
401 			{
402 				if (voice->baudio->preops)
403 					voice->baudio->preops(audiomain,
404 						voice->baudio, voice, startbuf);
405 
406 				/*
407 				 * Keep a pointer to the first voice that was active on any
408 				 * given bristolAudio sound. This is the most recent keypress.
409 				 */
410 				voice->baudio->firstVoice = voice;
411 				voice->baudio->mixflags &= ~BRISTOL_MUST_PRE;
412 				voice->baudio->mixflags |= BRISTOL_HAVE_OPED;
413 			}
414 
415 			/*
416 			 * Do something - find the buffers and put them in the IO structures
417 			 * then get the locals and params, and call the operator, summing
418 			 * the outputs into our single float buf.
419 			 *
420 			 * Each voice, or channel if you want, has its own independant
421 			 * limit on voice counts. This strange hack works only if we have
422 			 * allocated a new voice to the head of the list. If we stole an
423 			 * existing voice or two it may fail however that is unlikely
424 			 * since it requires a full set of notes for a single emulation
425 			 * and most of them only request a subset of those available.
426 			 * Having said that, if we steal voices then the count does not
427 			 * increase anyway.
428 			 */
429 			if (++voice->baudio->cvoices > voice->baudio->voicecount)
430 			{
431 				/*
432 				 * This looks a bit brutal however the assignement code should
433 				 * avoid this situation.
434 				 */
435 				if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2)
436 					printf("overvoice keydone\n");
437 
438 				voice->flags |= BRISTOL_KEYOFF;
439 				voice = voice->next;
440 				continue;
441 			}
442 
443 			/*
444 			 * If we are arpeggiating or sequencing we need to check on rolling
445 			 * this voice along, and need a couple of sanity checks.
446 			 */
447 			if (((voice->baudio->mixflags
448 				& (BRISTOL_SEQUENCE|BRISTOL_ARPEGGIATE))
449 				&& (bristolArpegReVoice(voice->baudio, voice,
450 					(float) audiomain->samplerate) < 0))
451 				|| ((voice->locals == 0) || (voice->locals[voice->index] == 0)))
452 			{
453 				voice = voice->next;
454 				continue;
455 			}
456 
457 			voice->baudio->operate(audiomain,
458 				voice->baudio, voice, startbuf);
459 
460 			if ((voice->baudio->voicecount == 1)
461 				&& (voice->baudio->notemap.flags
462 					& (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)))
463 				voice->flags &= ~BRISTOL_KEYDONE;
464 
465 			/*
466 			 * We should not do this, startbuf should be maintained across
467 			 * all synths.....
468 			 */
469 			bristolbzero(startbuf, audiomain->iosize);
470 		}
471 
472 		voice = voice->next;
473 	}
474 
475 	/*
476 	 * See if any of the voices have postoperators configured.
477 	 */
478 	thisaudio = audiomain->audiolist;
479 	while (thisaudio != NULL)
480 	{
481 		if (thisaudio->postops != NULL)
482 		{
483 			if (((thisaudio->mixflags & (BRISTOL_HOLDDOWN|BRISTOL_REMOVE)) == 0)
484 				&& (thisaudio->mixflags & BRISTOL_HAVE_OPED))
485 				thisaudio->postops(audiomain,
486 					thisaudio, thisaudio->firstVoice, startbuf);
487 		}
488 		thisaudio = thisaudio->next;
489 	}
490 
491 	voice = audiomain->playlist;
492 	while (voice != NULL)
493 	{
494 		voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
495 		voice->offset = -1;
496 		voice = voice->next;
497 	}
498 
499 	/*
500 	 * Free the long semaphore over the polyphonic process.
501 	 */
502 #ifdef BRISTOL_SEMAPHORE
503 	sem_post(audiomain->sem_long);
504 #endif
505 
506 	/*
507 	 * At this point all the voices have put their output onto the leftbuf and
508 	 * rightbuf (leftbuf only if mono). We should go through the baudio
509 	 * structures and see if we have any effects active.
510 	 *
511 	 * It is not possible to use the HAVE_OPED flag for the effects processes.
512 	 * If they use reverb and echo they need to roll on way past the end of
513 	 * poly voice processing.
514 	 */
515 	thisaudio = audiomain->audiolist;
516 
517 	while (thisaudio != NULL)
518 	{
519 		/*
520 		 * Need to ensure this audio structure is actually assigned
521 		 */
522 		if (thisaudio->mixflags & BRISTOL_HOLDDOWN)
523 		{
524 			thisaudio = thisaudio->next;
525 			continue;
526 		}
527 
528 		/*
529 		 * nc-17/06/02:
530 		 * At the moment this only works for a single effect on the list. Need
531 		 * to add another for/while loop inside this if statement.
532 		 * There are larger considerations for stereo effects - these can be
533 		 * single input or stereo input. Taking a stereo effect (in/out) into
534 		 * an effect that takes mono input will not give the anticipated
535 		 * results, obviously, but is beyond the scope of this piece of code.
536 		 */
537 		if ((thisaudio->effect != NULL) &&
538 			(thisaudio->effect[0] != NULL))
539 		{
540 			int index;
541 
542 			index = (*thisaudio->effect[0]).index;
543 			/*
544 			 * One inbuf, two outbuf. The effect should have some method of
545 			 * indicating its desired data flows - mono in/stereo out, or
546 			 * fully stereo, etc. At the moment there is one flag for stereo
547 			 * which indicates stereo in/out. Without this flag the assumption
548 			 * for an effect is mono in/stereo out.
549 			 */
550 			if (audiomain->palette[index]->flags & BRISTOL_FX_STEREO)
551 			{
552 				audiomain->palette[index]->specs->io[0].buf
553 					= thisaudio->leftbuf;
554 				audiomain->palette[index]->specs->io[1].buf
555 					= thisaudio->rightbuf;
556 				audiomain->palette[index]->specs->io[2].buf
557 					= thisaudio->leftbuf;
558 				audiomain->palette[index]->specs->io[3].buf
559 					= thisaudio->rightbuf;
560 			} else {
561 				audiomain->palette[index]->specs->io[0].buf
562 					= thisaudio->leftbuf;
563 				audiomain->palette[index]->specs->io[1].buf
564 					= thisaudio->leftbuf;
565 				audiomain->palette[index]->specs->io[2].buf
566 					= thisaudio->rightbuf;
567 			}
568 
569 			if ((thisaudio->firstVoice == NULL)
570 				|| (thisaudio->firstVoice->baudio == 0))
571 			{
572 				thisaudio = thisaudio->next;
573 				continue;
574 			}
575 #warning - this voice may have been reassigned. check midi channel
576 			if (thisaudio->firstVoice != NULL)
577 				(*thisaudio->effect[0]).operate(
578 					audiomain->palette[index],
579 					thisaudio->firstVoice,
580 					(*thisaudio->effect[0]).param,
581 					thisaudio->FXlocals[0][0]);
582 
583 			/*
584 			 * This is a quick hack to allow for two chained effects, it needs
585 			 * to be generalised for arbitrary links, but the ARP 2600 needed
586 			 * two effects.
587 			 */
588 			if (thisaudio->effect[1] != NULL)
589 			{
590 				index = (*thisaudio->effect[1]).index;
591 				/*
592 				 * One inbuf, two outbuf. The effect should have some method of
593 				 * indicating its desired data flows - mono in/stereo out, or
594 				 * fully stereo, etc.
595 				 */
596 				if (audiomain->palette[index]->flags & BRISTOL_FX_STEREO)
597 				{
598 					audiomain->palette[index]->specs->io[0].buf
599 						= thisaudio->leftbuf;
600 					audiomain->palette[index]->specs->io[1].buf
601 						= thisaudio->rightbuf;
602 					audiomain->palette[index]->specs->io[2].buf
603 						= thisaudio->leftbuf;
604 					audiomain->palette[index]->specs->io[3].buf
605 						= thisaudio->rightbuf;
606 				} else {
607 					audiomain->palette[index]->specs->io[0].buf
608 						= thisaudio->leftbuf;
609 					audiomain->palette[index]->specs->io[1].buf
610 						= thisaudio->leftbuf;
611 					audiomain->palette[index]->specs->io[2].buf
612 						= thisaudio->rightbuf;
613 				}
614 
615 				if ((thisaudio->firstVoice == NULL)
616 					|| (thisaudio->firstVoice->baudio == 0))
617 				{
618 					thisaudio = thisaudio->next;
619 					continue;
620 				}
621 #warning - this voice may have been reassigned. check midi channel
622 				if (thisaudio->firstVoice != NULL)
623 					(*thisaudio->effect[1]).operate(
624 						audiomain->palette[index],
625 						thisaudio->firstVoice,
626 						(*thisaudio->effect[1]).param,
627 						thisaudio->FXlocals[1][1]);
628 			}
629 
630 			/*
631 			 * If we have FX, apply them. They will all be stereo, and will
632 			 * eventually also be chained.
633 			 */
634 			rightch = thisaudio->rightbuf;
635 		} else {
636 			if (thisaudio->mixflags & BRISTOL_STEREO)
637 				rightch = thisaudio->rightbuf;
638 			else
639 				/*
640 				 * Otherwise the synth is mono.
641 				 */
642 				rightch = thisaudio->leftbuf;
643 		}
644 
645 		leftch = thisaudio->leftbuf;
646 
647 		extmult = outbuf;
648 
649 		gain = thisaudio->gain;
650 
651 /*
652 		if ((gain = thisaudio->gain) == 0)
653 			gain = 1.0;
654 */
655 
656 		/*
657 		 * Interleave the results for output to a stereo device.
658 		 *
659 		 * This must change. It will consist of a couple of values that are
660 		 * going to be GM-2: gain and balance. These will be used per synth to
661 		 * position the output into a pair of buffers, interleaving will be
662 		 * handled by the bristol audio library if it is needed for an audio
663 		 * device.
664 		 */
665 		for (i = 0; i < audiomain->samplecount; i+=8)
666 		{
667 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
668 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
669 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
670 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
671 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
672 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
673 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
674 			*extmult++ += *leftch++ * gain; *extmult++ += *rightch++ * gain;
675 		}
676 
677 		bristolbzero(thisaudio->leftbuf, audiomain->segmentsize);
678 		bristolbzero(thisaudio->rightbuf, audiomain->segmentsize);
679 
680 		thisaudio = thisaudio->next;
681 	}
682 	return(0);
683 }
684 
685 /*
686  * The routines fillFreqTable and fillFreqBuf need to be consolidated to one
687  * routine. Minimally cFreq/dFreq and dfreq/dfreq need to be maintained.
688  *
689  * This fills the table with frequencies. The alternative fillFreqTable() will
690  * insert sample steps through the 1K wavetable oscillators. This call is used
691  * for the tendency tables which are frequency based.
692  */
693 int
fillFreqBuf(Baudio * baudio,register bristolVoice * voice,register float * buf,register int size,int glide)694 fillFreqBuf(Baudio *baudio, register bristolVoice *voice, register float *buf,
695 	register int size, int glide)
696 {
697 	register int i;
698 
699 	/*
700 	 * Take a buffer, and fill in some frequency value to make an oscillator
701 	 * reproduce the correct note. Will cater for polyphonic portamento, and
702 	 * eventually also for some generic mods.
703 	 */
704 	if ((voice->cfreq == voice->dfreq) || (glide == 0) || (voice->lastkey == 0)
705 		|| (baudio->glide == 0.0f))
706 	{
707 		/*
708 		 * Note has no glide, just fill the table.
709 		 */
710 		for (i = 0; i < size; i+=8)
711 		{
712 			*buf++ = voice->dfreq;
713 			*buf++ = voice->dfreq;
714 			*buf++ = voice->dfreq;
715 			*buf++ = voice->dfreq;
716 			*buf++ = voice->dfreq;
717 			*buf++ = voice->dfreq;
718 			*buf++ = voice->dfreq;
719 			*buf++ = voice->dfreq;
720 		}
721 	} else {
722 		if (voice->cfreq < voice->dfreq) {
723 			/*
724 			 * Glide frequency up at some rate.
725 			 */
726 			if (voice->cfreqmult < 1.0f)
727 				/*
728 				 * Frequency inversion, probably due to pitchbend, we have to
729 				 * recalculate cfreqmult. This does lead to some stretching of
730 				 * the overall glide.
731 				 */
732 				voice->cfreqmult = powf(M_E, logf(voice->dfreq/voice->cfreq)
733 					/ (baudio->glide * baudio->samplerate));
734 
735 			if ((voice->cfreqmult >=    0.999999f)
736 				&& (voice->cfreqmult <= 1.000001f))
737 			{
738 				voice->cFreq = voice->dFreq;
739 				voice->cfreq = voice->dfreq;
740 				for (i = 0; i < size; i+=8)
741 				{
742 					*buf++ = voice->dfreq;
743 					*buf++ = voice->dfreq;
744 					*buf++ = voice->dfreq;
745 					*buf++ = voice->dfreq;
746 					*buf++ = voice->dfreq;
747 					*buf++ = voice->dfreq;
748 					*buf++ = voice->dfreq;
749 					*buf++ = voice->dfreq;
750 				}
751 				return(0);
752 			}
753 
754 			for (i = 0; i < size; i++)
755 			{
756 				if (voice->cfreq > voice->dfreq)
757 				{
758 					voice->cfreq = voice->dfreq;
759 					voice->cFreq = voice->dFreq;
760 					for (; i < size; i++)
761 						*buf++ = voice->cfreq;
762 					break;
763 				}
764 				/*
765 				 * Hm, this is incorrect, it should be a multiplier.....
766 				 */
767 				*buf++ = (voice->cfreq *= voice->cfreqmult);
768 			}
769 		} else {
770 			/*
771 			 * Glide frequency down at some rate.
772 			 */
773 			if (voice->cfreqmult > 1.0f)
774 				/*
775 				 * Frequency inversion, probably due to pitchbend, we have to
776 				 * recalculate cfreqmult. This does lead to some stretching of
777 				 * the overall glide.
778 				 */
779 				voice->cfreqmult = powf(M_E, logf(voice->dfreq/voice->cfreq)
780 					/ (baudio->glide * baudio->samplerate));
781 
782 			if ((voice->cfreqmult >=    0.999999f)
783 				&& (voice->cfreqmult <= 1.000001f))
784 			{
785 				voice->cFreq = voice->dFreq;
786 				voice->cfreq = voice->dfreq;
787 				for (i = 0; i < size; i+=8)
788 				{
789 					*buf++ = voice->dfreq;
790 					*buf++ = voice->dfreq;
791 					*buf++ = voice->dfreq;
792 					*buf++ = voice->dfreq;
793 					*buf++ = voice->dfreq;
794 					*buf++ = voice->dfreq;
795 					*buf++ = voice->dfreq;
796 					*buf++ = voice->dfreq;
797 				}
798 				return(0);
799 			}
800 
801 			for (i = 0; i < size; i++)
802 			{
803 				if (voice->cfreq < voice->dfreq)
804 				{
805 					voice->cfreq = voice->dfreq;
806 					voice->cFreq = voice->dFreq;
807 					for (; i < size; i++)
808 						*buf++ = voice->cfreq;
809 					break;
810 				}
811 				*buf++ = (voice->cfreq *= voice->cfreqmult);
812 			}
813 		}
814 	}
815 
816 //	printf("freqbuf: %f %f %f %f %i\n",
817 //		voice->cFreq, voice->dFreq, voice->cFreqmult,
818 //		baudio->glide, baudio->samplerate);
819 
820 	return(0);
821 }
822 
823 /*
824  * The implementation of glide is actually damaged for some synths, they may
825  * call this routine more than once.
826  */
827 int
fillFreqTable(Baudio * baudio,register bristolVoice * voice,register float * buf,register int size,int glide)828 fillFreqTable(Baudio *baudio, register bristolVoice *voice, register float *buf,
829 	register int size, int glide)
830 {
831 	register int i;
832 
833 	/*
834 printf("fft %f %f %1.12f\n", voice->cFreq, voice->dFreq, voice->cFreqmult);
835 	 * Take a buffer, and fill in some frequency value to make an oscillator
836 	 * reproduce the correct note. Will cater for polyphonic portamento, and
837 	 * eventually also for some generic mods.
838 	 */
839 	if ((voice->cFreq == voice->dFreq) || (glide == 0)
840 		|| (voice->lastkey == 0) || (baudio->glide == 0.0f))
841 	{
842 //printf("fft %f %f %i\n", voice->cFreq, voice->dFreq, voice->lastkey);
843 		/*
844 		 * Note has no glide, just fill the table.
845 		 */
846 		for (i = 0; i < size; i+=8)
847 		{
848 			*buf++ = voice->dFreq;
849 			*buf++ = voice->dFreq;
850 			*buf++ = voice->dFreq;
851 			*buf++ = voice->dFreq;
852 			*buf++ = voice->dFreq;
853 			*buf++ = voice->dFreq;
854 			*buf++ = voice->dFreq;
855 			*buf++ = voice->dFreq;
856 		}
857 	} else {
858 		if (voice->cFreq < voice->dFreq) {
859 			/*
860 			 * Glide frequency up at some rate.
861 			 */
862 			if (voice->cFreqmult < 1.0f)
863 				/*
864 				 * Frequency inversion, probably due to pitchbend, we have to
865 				 * recalculate cfreqmult. This does lead to some stretching of
866 				 * the overall glide.
867 				 */
868 				voice->cFreqmult = powf(M_E, logf(voice->dFreq/voice->cFreq)
869 					/ (baudio->glide * baudio->samplerate));
870 
871 //printf("1: inversion %f %i\n", voice->cFreqmult, voice->cFreqmult == 1.0);
872 //limit 0.99999999
873 			if ((voice->cFreqmult >=    0.999999f)
874 				&& (voice->cFreqmult <= 1.000001f))
875 			{
876 				voice->cFreq = voice->dFreq;
877 				for (i = 0; i < size; i+=8)
878 				{
879 					*buf++ = voice->dFreq;
880 					*buf++ = voice->dFreq;
881 					*buf++ = voice->dFreq;
882 					*buf++ = voice->dFreq;
883 					*buf++ = voice->dFreq;
884 					*buf++ = voice->dFreq;
885 					*buf++ = voice->dFreq;
886 					*buf++ = voice->dFreq;
887 				}
888 				return(0);
889 			}
890 
891 			for (i = 0; i < size; i++)
892 			{
893 				if (voice->cFreq >= voice->dFreq)
894 				{
895 					voice->cFreq = voice->dFreq;
896 					voice->cfreq = voice->dfreq;
897 					for (; i < size; i++)
898 						*buf++ = voice->cFreq;
899 					break;
900 				}
901 				*buf++ = (voice->cFreq *= voice->cFreqmult);
902 			}
903 		} else {
904 			/*
905 			 * Glide frequency down at some rate.
906 			 */
907 			if (voice->cFreqmult > 1.0f)
908 				/*
909 				 * Frequency inversion, probably due to pitchbend, we have to
910 				 * recalculate cfreqmult. This does lead to some stretching of
911 				 * the overall glide.
912 				 */
913 				voice->cFreqmult = powf(M_E, logf(voice->dFreq/voice->cFreq)
914 					/ (baudio->glide * baudio->samplerate));
915 
916 //printf("2: inversion %f %i\n", voice->cFreqmult, voice->cFreqmult == 1.0);
917 			if ((voice->cFreqmult >=    0.999999f)
918 				&& (voice->cFreqmult <= 1.000001f))
919 			{
920 				voice->cFreq = voice->dFreq;
921 				for (i = 0; i < size; i+=8)
922 				{
923 					*buf++ = voice->dFreq;
924 					*buf++ = voice->dFreq;
925 					*buf++ = voice->dFreq;
926 					*buf++ = voice->dFreq;
927 					*buf++ = voice->dFreq;
928 					*buf++ = voice->dFreq;
929 					*buf++ = voice->dFreq;
930 					*buf++ = voice->dFreq;
931 				}
932 				return(0);
933 			}
934 
935 			for (i = 0; i < size; i++)
936 			{
937 				if (voice->cFreq < voice->dFreq)
938 				{
939 					voice->cFreq = voice->dFreq;
940 					voice->cfreq = voice->dfreq;
941 					for (; i < size; i++)
942 						*buf++ = voice->cFreq;
943 					break;
944 				}
945 				*buf++ = (voice->cFreq *= voice->cFreqmult);
946 			}
947 		}
948 	}
949 
950 //	printf("freqtab: %f %f %f %f %i\n",
951 //		voice->cFreq, voice->dFreq, voice->cFreqmult,
952 //		baudio->glide, baudio->samplerate);
953 
954 	return(0);
955 }
956 
957 /*
958  * Take a buffer and fill it with a sinewave at 440 hz.
959  */
960 static void
a440(audioMain * audiomain,float * buf,int count)961 a440(audioMain *audiomain, float *buf, int count)
962 {
963 	float *sine, index = s440holder, step;
964 	int obp;
965 
966 	/*
967 	 * There is a sine wave in buffer zero of the first operator - the DCO.
968 	 */
969 	sine = ((bristolDCO *)audiomain->palette[0]->specs)->wave[0];
970 	step = defaultTable[69].defnote;
971 
972 	for (obp = 0; obp < count * 2;)
973 	{
974 		buf[obp++] = sine[(int) index] * 48;
975 		buf[obp++] = sine[(int) index] * 48;
976 		if ((index += step) > DCO_WAVE_SZE)
977 			index -= DCO_WAVE_SZE;
978 	}
979 
980 	s440holder = index;
981 }
982 
983