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