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 <stdlib.h>
25 #include <math.h>
26 #include "bristol.h"
27
28 extern bristolMidiHandler bristolMidiRoutines;
29
30 int rbMidiNoteOn(audioMain *, bristolMidiMsg *);
31 int rbMidiNoteOff(audioMain *, bristolMidiMsg *);
32
33 /*
34 * Monophonic voice logic
35 */
36 static int
doMNL(bristolVoice * voice,int key,int velocity,int action,int offset)37 doMNL(bristolVoice *voice, int key, int velocity, int action, int offset)
38 {
39 Baudio *baudio = voice->baudio;
40 int mn = -1;
41
42 offset = 99;
43 if (voice->baudio == NULL)
44 return(0);
45
46 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG1)
47 printf("monophonic note logic (%i %i)\n", key, action);
48
49 if (action == BRISTOL_ALL_NOTES_OFF)
50 {
51 /*
52 * Clear out our table
53 */
54 for (mn = 0; mn < 128; mn++)
55 baudio->notemap.key[mn] = 0;
56 baudio->notemap.count = 0;
57 voice->flags &= ~BRISTOL_KEYSUSTAIN;
58 return(0);
59 }
60
61 if ((voice->baudio->notemap.flags & (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)) == 0)
62 return(-1);
63
64 /* We never use this, the key actually stays on all the time anyway */
65 voice->flags &= ~BRISTOL_KEYSUSTAIN;
66
67 baudio->notemap.key[key] = action * key;
68 baudio->notemap.velocity[key] = velocity;
69
70 baudio->notemap.low = 127;
71 baudio->notemap.high = 0;
72 baudio->notemap.count = 0;
73
74 for (mn = 0; mn < 128; mn++)
75 {
76 if (baudio->notemap.key[mn] != 0)
77 {
78 baudio->notemap.count++;
79 if (mn < baudio->notemap.low) baudio->notemap.low = mn;
80 if (mn > baudio->notemap.high) baudio->notemap.high = mn;
81 }
82 }
83
84 if (baudio->notemap.flags & BRISTOL_MNL_LNP)
85 {
86 if ((baudio->notemap.extreme <= 0)
87 || (baudio->notemap.extreme < baudio->notemap.high))
88 baudio->notemap.extreme = baudio->notemap.high;
89
90 if ((baudio->notemap.count == 0)
91 && (baudio->contcontroller[BRISTOL_CC_HOLD1] < 0.5))
92 {
93 voice->flags |= BRISTOL_KEYOFF;
94 return(-1);
95 }
96
97 if (key > baudio->notemap.low)
98 {
99 /*
100 * There is an issue here: If I get a note on then a note off in
101 * the same sample period then the first note correctly sets the
102 * keyon flags, the second one incorrectly clears them. Now I am
103 * in the audio thread here so there is nothing to signal to the
104 * audio process to find out if it has seen my flags yet.
105 * The question is, why would I clear these flags on note off that
106 * is not in my key range?
107 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
108 */
109 return(-1);
110 }
111
112 mn = baudio->notemap.low;
113 } else {
114 if ((baudio->notemap.extreme <= 0)
115 || (baudio->notemap.extreme > baudio->notemap.low))
116 baudio->notemap.extreme = baudio->notemap.low;
117
118 if ((baudio->notemap.count == 0)
119 && (baudio->contcontroller[BRISTOL_CC_HOLD1] < 0.5))
120 {
121 voice->flags |= BRISTOL_KEYOFF;
122 return(-1);
123 }
124
125 if (key < baudio->notemap.high)
126 {
127 /*
128 * See above notes - this key should not do anything, at all
129 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
130 */
131 return(-1);
132 }
133
134 mn = baudio->notemap.high;
135 }
136
137 if (baudio->notemap.count == 0)
138 mn = baudio->notemap.extreme;
139
140 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2)
141 printf("(%i) mn %i, key %i\n", baudio->notemap.count, mn, key);
142
143 mn += baudio->transpose;
144
145 while (mn > 127)
146 mn -= 12;
147 while (mn < 0)
148 mn += 12;
149
150 voice->lastkey = voice->key.key;
151 voice->keyid = key;
152 voice->key.key = mn;
153
154 if (baudio->microtonalmap[mn].step > 0.0) {
155 voice->dFreq = baudio->microtonalmap[mn].step;
156 voice->dfreq = baudio->microtonalmap[mn].freq;
157 } else if (bristolMidiRoutines.bmr[7].floatmap[mn] > 0.0) {
158 /*
159 * This is the synth private microtonal map (eg, scala file)
160 voice->dFreq = bristolMidiRoutines.freq[mn].step;
161 voice->dfreq = bristolMidiRoutines.freq[mn].freq;
162 */
163 voice->dFreq = bristolMidiRoutines.bmr[7].floatmap[mn];
164 voice->dfreq = baudio->samplerate * voice->dFreq / ((float) 1024.0);
165 } else {
166 voice->dFreq = baudio->ctab[mn].step;
167 voice->dfreq = baudio->ctab[mn].freq;
168 }
169
170 if (baudio->glide == 0)
171 {
172 voice->cFreq = voice->dFreq;
173 voice->cfreq = voice->dfreq;
174 voice->cFreqmult = voice->cfreqmult = 0;
175 } else {
176 voice->cFreqmult = powf(M_E, logf(voice->dFreq/voice->cFreq)
177 / (baudio->glide * baudio->samplerate));
178 voice->cfreqmult = powf(M_E, logf(voice->dfreq/voice->cfreq)
179 / (baudio->glide * baudio->samplerate));
180 }
181
182 if (action == 1) {
183 /*
184 * See if this was the first voice in which case we need to flag 'on'
185 * rather than a restrike. Also configure the velocity if we are set to
186 * do legato velocity.
187 */
188 if (baudio->notemap.count == 1)
189 {
190 /* Legato velocity, only configure it on the first keystroke */
191 if (baudio->notemap.flags & BRISTOL_MNL_VELOC)
192 {
193 voice->key.velocity = velocity;
194 voice->velocity = baudio->velocitymap[velocity];
195 }
196
197 voice->flags |= BRISTOL_KEYON|BRISTOL_KEYREON;
198
199 /* Pro-1 does not glide on first note, if selected */
200 if (baudio->mixflags & BRISTOL_GLIDE_AUTO)
201 {
202 voice->cFreq = voice->dFreq;
203 voice->cfreq = voice->dfreq;
204 voice->cFreqmult = voice->cfreqmult = 0;
205 }
206 } else {
207 if (baudio->notemap.flags & BRISTOL_MNL_TRIG)
208 voice->flags |= BRISTOL_KEYREON;
209
210 /*
211 * This means legato notes will follow each note velocity. Not sure
212 * if that is really desirable, it might be better to have just the
213 * first note define velocity?
214 */
215 if ((baudio->notemap.flags & BRISTOL_MNL_VELOC) == 0)
216 {
217 voice->key.velocity = velocity;
218 voice->velocity = baudio->velocitymap[velocity];
219 }
220 }
221 voice->flags &= ~(BRISTOL_KEYOFF|BRISTOL_KEYOFFING|BRISTOL_KEYDONE);
222 } else if (baudio->notemap.flags & BRISTOL_MNL_TRIG) {
223 /* If we don't have legato velocity we apply velocity here */
224 if ((baudio->notemap.flags & BRISTOL_MNL_VELOC) == 0)
225 {
226 voice->key.velocity = baudio->notemap.velocity[mn];
227 voice->velocity = baudio->velocitymap[voice->key.velocity];
228 }
229 /* Flag note off events as a gate for envelope retrigger */
230 voice->flags |= BRISTOL_KEYREON;
231 }
232
233 if ((offset >= baudio->samplecount) || (offset < 0))
234 voice->offset = 0;
235 else
236 voice->offset = offset;
237
238 return(mn);
239 }
240
241 void
printPlayList(audioMain * audiomain)242 printPlayList(audioMain *audiomain)
243 {
244 bristolVoice *v = audiomain->playlist;
245
246 printf("printPlayList(%p, %p)\n", audiomain->playlist, audiomain->playlast);
247
248 while (v != NULL)
249 {
250 printf("%p<-%p->%p: %i, %i, 0x%x (%p)\n",
251 v->last, v, v->next, v->index, v->key.key, v->flags, v->baudio);
252
253 v = v->next;
254 }
255
256 if ((v = audiomain->newlist) != NULL)
257 {
258 printf("printNewlist(%p)\n", v);
259 while (v != NULL)
260 {
261 printf("%p<-%p->%p: %i, %i, 0x%x\n",
262 v->last,
263 v,
264 v->next,
265 v->index,
266 v->key.key,
267 v->flags
268 );
269
270 v = v->next;
271 }
272 }
273 }
274
275 /*
276 * There will be a lot of processing involved with MIDI note on/off management,
277 * so it has been pulled into a separate file.
278 */
279 int
midiNoteOff(audioMain * audiomain,bristolMidiMsg * msg)280 midiNoteOff(audioMain *audiomain, bristolMidiMsg *msg)
281 {
282
283 /*
284 printf("midiNoteOff %i\n", msg->params.key.key);
285 * If we get a note off, then find that note, and configure it for done. If
286 * we have sustain active then just set the BRISTOL_SUSTAIN flag, the key
287 * will be released when the sustain pedal is released.
288 *
289 * We need to take the long semaphore here to prevent the engine from
290 * doing anything we don't want it to with the playlist or newlist. Since
291 * we may be playing with newlist we minimally need the short semaphore, and
292 * if we want to take things from the newlist to the freelist then we need
293 * the long semaphore too. Hence we just request the long one as it covers
294 * both needs.
295 */
296 #ifdef BRISTOL_SEMAPHORE
297 bristolVoice *voice, *v;
298 sem_wait(audiomain->sem_long);
299 #else
300 if ((msg->params.key.flags & BRISTOL_KF_JACK)
301 && (~audiomain->flags & BRISTOL_JACK_DUAL))
302 {
303 /*
304 * The message came from Jack and we have selected a single registration
305 * which means we are actually in the audio thread and can conginue with
306 * the note on event.
307 */
308 if ((audiomain->debuglevel & BRISTOL_DEBUG_MASK) > BRISTOL_DEBUG2)
309 printf("direct off call\n");
310 return(rbMidiNoteOff(audiomain, msg));
311 } if (jack_ringbuffer_write_space(audiomain->rb) >= sizeof(bristolMidiMsg))
312 jack_ringbuffer_write(audiomain->rb, (char *) msg,
313 sizeof(bristolMidiMsg));
314 else
315 printf("ringbuffer exhausted, note off event dropped\n");
316
317 return(0);
318 }
319
320 int
321 rbMidiNoteOff(audioMain *audiomain, bristolMidiMsg *msg)
322 {
323 bristolVoice *voice, *v;
324 #endif
325
326 msg->offset = 101;
327 voice = audiomain->playlist;
328
329 while (voice != NULL)
330 {
331 if ((voice->baudio == NULL)
332 || ((voice->baudio->mixflags & (BRISTOL_HOLDDOWN|BRISTOL_REMOVE)))
333 || (voice->baudio->mixflags & BRISTOL_KEYHOLD))
334 {
335 voice = voice->next;
336 continue;
337 }
338
339 /*
340 * Check monophonic note logic. If we have monophonic note logic
341 * selected then see if there is another note currently on, then
342 * rather than remove this note from the list just modify its
343 * parameters.
344 */
345 if ((voice->baudio->voicecount == 1)
346 && ((voice->baudio->midichannel == msg->channel)
347 || (voice->baudio->midichannel == BRISTOL_CHAN_OMNI))
348 && (voice->baudio->notemap.flags & (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)))
349 {
350 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG1)
351 bristolMidiPrint(msg);
352 doMNL(voice, msg->params.key.key, -1, 0, msg->offset);
353 voice = voice->next;
354 continue;
355 }
356
357 if ((voice->keyid == msg->params.key.key)
358 && ((voice->baudio->midichannel == msg->channel)
359 || (voice->baudio->midichannel == BRISTOL_CHAN_OMNI)))
360 {
361 /* can't print the message until we know if there is debug on */
362 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG1)
363 bristolMidiPrint(msg);
364
365 if ((voice->baudio->contcontroller[BRISTOL_CC_HOLD1] > 0.5)
366 && (voice->baudio->voicecount > 1))
367 voice->flags |= BRISTOL_KEYSUSTAIN;
368 else {
369 /*
370 * Do not put the note off velocity in the key velocity, it can
371 * cause pops and clicks if it used to control the gain.
372 * It should be seen as a separate control parameter.
373 *
374 * Took the next line out. It is basically a damaged part of
375 * the specification - if the note off is sent with default
376 * velocity of 64, or for that matter any other velocity, it
377 * can cause jumps in the envelope tracking and any other
378 * code using velocity. We should merge it into another
379 * location.
380 voice->velocity =
381 voice->baudio->velocitymap[msg->params.key.velocity];
382 */
383 voice->keyoff.velocity = msg->params.key.velocity;
384 voice->flags |= BRISTOL_KEYOFF;
385
386 bristolArpeggiatorNoteEvent(voice->baudio, msg);
387 }
388 }
389
390 voice = voice->next;
391 }
392
393 /*
394 * Scan the newlist to make sure this was not a spurious short event,
395 * prevents us from having notes sticking.
396 */
397 voice = audiomain->newlist;
398 while (voice != NULL)
399 {
400 if ((voice->baudio == NULL)
401 || (voice->baudio->mixflags & BRISTOL_KEYHOLD))
402 {
403 voice = voice->next;
404 continue;
405 }
406
407 if ((voice->keyid == msg->params.key.key)
408 /* || (voice->baudio->voicecount == 1)) This caused Mono issues */
409 && ((voice->baudio->midichannel == msg->channel)
410 || (voice->baudio->midichannel == BRISTOL_CHAN_OMNI)))
411 {
412 /*
413 * Just take it off the newlist and put on the freelist. This was
414 * damaged for a while as it assumed we were looking at the head
415 * of the newlist and it was not doubly linked.
416 *
417 * I think this causes clicks due to forced close of the envelope.
418 * Changed the logic from remove from list to KEYOFF
419 */
420 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
421
422 if (voice->baudio->voicecount > 1)
423 {
424 v = voice->next;
425
426 if (voice->next != NULL)
427 voice->next->last = voice->last;
428 else
429 audiomain->newlast = voice->last;
430 if (voice->last != NULL)
431 voice->last->next = voice->next;
432 else
433 audiomain->newlist = voice->next;
434
435 if ((voice->next = audiomain->freelist) == NULL)
436 audiomain->freelast = voice;
437 else
438 voice->next->last = voice;
439 voice->last = NULL;
440 audiomain->freelist = voice;
441
442 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2)
443 printf("mt: off: removed %p/%i from newlist\n",
444 voice, voice->keyid);
445
446 voice = v;
447 continue;
448 } else {
449 voice->flags |=
450 BRISTOL_KEYOFF|BRISTOL_KEYSUSTAIN|BRISTOL_KEYREOFF;
451 if (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2)
452 printf("mt: off: %p->%p/%i was on newlist\n",
453 voice, voice->next, voice->keyid);
454 }
455 }
456
457 voice = voice->next;
458 }
459
460 #ifdef BRISTOL_SEMAPHORE
461 sem_post(audiomain->sem_long);
462 #endif
463
464 //printf("sl: ");printPlayList(audiomain);
465
466 return(0);
467 }
468
469 static int arbitrary = 0x12365302;
470 static int nx1 = 0x67452301;
471 static int nx2 = 0xefcdab89;
472
473 /*
474 * Find a free voice, or take one off the current playlist.
475 *
476 * Need to converge in the correct locals list before we can assign a voice,
477 * and find an associated baudio structure. Consideration will have to be made
478 * for the ability to do layering.
479 */
480 int
doMidiNoteOn(audioMain * audiomain,bristolMidiMsg * msg,Baudio * baudio,int key)481 doMidiNoteOn(audioMain *audiomain, bristolMidiMsg *msg, Baudio *baudio, int key)
482 {
483 bristolVoice *voice, *last = NULL, *donevoice = NULL;
484 int lastkey, transposedkey, velocity, offset;
485 float cFreq, dFreq, dTune = 0.0, cFreqmult = 0, mappedvelocity;
486 float cfreq, dfreq, cfreqmult;
487
488 /*
489 * locals
490 * Keyid
491 * Transposed key id, check for bounds
492 * Velocity and mapped velocity
493 * dFreq/dfreq from frequency maps
494 * dTune
495 * cFreqmult
496 */
497 if (baudio->midiflags & BRISTOL_MIDI_DEBUG1)
498 {
499 printf("doMidiNoteOn()\n");
500 bristolMidiPrint(msg);
501 }
502
503 if (baudio->midiflags & BRISTOL_MIDI_DEBUG2)
504 printPlayList(audiomain);
505
506 /*
507 * We may have to do some foldback however steps of 12 would only work for
508 * western scales so there may be scala file issues. This only happens at
509 * the edges though.
510 */
511 if ((transposedkey = msg->params.key.key + baudio->transpose) > 127)
512 while (transposedkey > 127)
513 transposedkey -= 12;
514
515 while (transposedkey < 0)
516 transposedkey += 12;
517
518 if ((offset = msg->offset) >= audiomain->samplecount)
519 offset = 0;
520
521 /*
522 * Get some operational values ready for the voice structures.
523 */
524 velocity = msg->params.key.velocity;
525 mappedvelocity = baudio->velocitymap[msg->params.key.velocity];
526
527 /*
528 * Stack up the last key structure for portamento. Glide starts at the
529 * current glide of the last played note. This will fail in multitimbral
530 * mode, since next key may be for a different voice!
531 * Also need to cater for single voice synths.
532 *
533 * These need to come from baudio.
534 */
535 lastkey = baudio->lastkey;
536 baudio->lastkey = transposedkey;
537
538 /*
539 * Have been requested to implement this feature as a part of Unison/Mono
540 * mode of the diverse poly instruments. This should be possible with an
541 * OR operation on the UNISON flag however this is currently handled in the
542 * calling routine, not here.
543 */
544 if ((baudio->voicecount == 1) && (baudio->lvoices != 0)
545 && ((voice = audiomain->playlist) != NULL)
546 && (baudio->notemap.flags & (BRISTOL_MNL_LNP|BRISTOL_MNL_HNP)))
547 {
548 while (voice->baudio != baudio)
549 if ((voice = voice->next) == NULL)
550 return(0);
551
552 doMNL(voice, key, velocity, 1, msg->offset);
553 return(0);
554 }
555
556 /* This needs to be stuff the first time around only really */
557 baudio->notemap.key[key] = key;
558 baudio->notemap.velocity[key] = msg->params.key.velocity;
559 baudio->notemap.count++;
560
561 /*
562 * This is the main point at which voice note settings take place. We are
563 * going to introduce a random detune per voice that will vary each time
564 * a note is played within a reasonably small (configurable) range. This
565 * will be used to emulate temperature sensitivity of the old synths.
566 * It should be configurable per synth so perhaps we will make it a MIDI
567 * unassigned opererator? The engine should respond to this operator, the
568 * GUI will sent it, and any other arbitrary control may send it to the
569 * engine as well.
570 */
571 if (baudio->microtonalmap[transposedkey].step > 0.0) {
572 /*
573 * This is the synth private microtonal map. This should really
574 * contain frequencies rather than the internal adjusted values?
575 */
576 dFreq = baudio->microtonalmap[transposedkey].step;
577 dfreq = baudio->microtonalmap[transposedkey].freq;
578 } else if (bristolMidiRoutines.bmr[7].floatmap[transposedkey] > 0.0) {
579 /*
580 * This is the synth global microtonal map
581 dFreq = bristolMidiRoutines.freq[transposedkey].step;
582 dfreq = bristolMidiRoutines.freq[transposedkey].freq;
583 */
584 dfreq = bristolMidiRoutines.bmr[7].floatmap[transposedkey];
585 dFreq = ((float) 1024.0) * dfreq / baudio->samplerate;
586 } else {
587 /*
588 * Otherwise this is the default ET internal map 'currentTable'.
589 */
590 dFreq = baudio->ctab[transposedkey].step;
591 dfreq = baudio->ctab[transposedkey].freq;
592 }
593
594 if (baudio->detune != 0)
595 {
596 /*
597 * We take a random number. If it is < RAND_MAX/2 then it will be used
598 * to reduce the frequency by a fraction of the dTune, otherwise it will
599 * increase the frequency
600 arbitrary = rand();
601 *
602 * This is a noise generator and is cheaper than rand?
603 */
604 nx1 ^= nx2;
605 arbitrary += nx2;
606 nx2 += nx1;
607
608 if (arbitrary > (RAND_MAX>>1))
609 {
610 dTune = 1.0 + baudio->detune
611 * ((float) arbitrary) / ((float) RAND_MAX);
612 } else {
613 dTune = 1.0 - baudio->detune
614 * ((float) arbitrary) / ((float) RAND_MAX);
615 }
616
617 dFreq *= dTune;
618 dfreq *= dTune;
619
620 /*printf("tempering key by %1.4f, was %1.4f, is %1.4f\n", */
621 /*dTune, voice->baudio->ctab[transposedkey].step, voice->dFreq); */
622 }
623 /* printf(" detune %f\n", baudio->detune); */
624
625 if ((baudio->voicecount == 1) || (audiomain->playlist == NULL)) {
626 cFreq = baudio->ctab[lastkey].step;
627 cfreq = baudio->ctab[lastkey].freq;
628 } else {
629 cFreq = audiomain->playlist->cFreq;
630 cfreq = audiomain->playlist->cfreq;
631 }
632
633 /*
634 * This is the Pro-1 Glide option:
635 * If this is the first key and we are Auto then skip the glide.
636 *
637 */
638 if ((baudio->glide == 0) ||
639 ((baudio->lvoices == 0) && (baudio->mixflags & BRISTOL_GLIDE_AUTO)))
640 {
641 cFreq = dFreq;
642 cfreq = dfreq;
643 cFreqmult = cfreqmult = 0;
644 } else {
645 /*
646 * cFreqstep was an incrementer to the cFreq float, which gave constant
647 * glide times but it is also arguably incorrect as it should be a
648 * multiplier that is applied a given number of times - that way the
649 * glide is also constant per octave, not the case with the original
650 * linear incrementor:
651 */
652 cFreqmult = powf(M_E, logf(dFreq/cFreq)
653 / (baudio->glide * audiomain->samplerate));
654 cfreqmult = powf(M_E, logf(dfreq/cfreq)
655 / (baudio->glide * audiomain->samplerate));
656 }
657
658 /*
659 * We have evaluated all the parameters we want for this voice:
660 *
661 * baudio
662 * locals
663 * Lastkey for portamento
664 * Keyid
665 * Transposed key id, check for bounds
666 * Velocity and mapped velocity
667 * dFreq from frequency maps
668 * dTune
669 * cFreqmult
670 *
671 * See how many voices were last running on this emulator.
672 *
673 * If under the voice limit and freelist is not empty
674 * Request semaphore-1: the short semaphore
675 * Unlink the head of the freelist, relink that list
676 * Stuff the pre-evaluated parameters
677 * Link to tail of the newlist
678 * Relinquish semaphore-1
679 * Return;
680 *
681 * Request semaphore-2: the long semaphore over the Poly process
682 * take last playlist entry for this emulator or bump the last entry
683 * Stuff the pre-evaluated parameters
684 * Unlink the selected voice and rejoin the list it was taken from.
685 * Link to tail of the newlist
686 * Relinquish semaphore-2
687 *
688 * Another case we may need to look at is whether this note is already
689 * audible and then take case #2.
690 */
691 if ((baudio->lvoices < baudio->voicecount) && (audiomain->freelist != NULL))
692 {
693 /*
694 * Stuff the new information into the head of the freelist, then wait
695 * for the semaphore to put it on the newlist.
696 */
697 voice = audiomain->freelist;
698 voice->baudio = baudio;
699 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
700 voice->offset = offset;
701 voice->locals = baudio->locals;
702 voice->keyid = key;
703 voice->key.key = transposedkey;
704 voice->key.velocity = velocity;
705 voice->velocity = mappedvelocity;
706 voice->lastkey = lastkey;
707 voice->dFreq = dFreq;
708 voice->cFreq = cFreq;
709 voice->cFreqmult = cFreqmult;
710 voice->dfreq = dfreq;
711 voice->cfreq = cfreq;
712 voice->cfreqmult = cfreqmult;
713 voice->detune = dTune;
714
715 #ifdef BRISTOL_SEMAPHORE
716 sem_wait(audiomain->sem_short);
717 #endif
718
719 /*
720 * Short piece of critical code
721 *
722 * Relink the head of the freelist (which may now be empty)
723 */
724 if ((audiomain->freelist = voice->next) != NULL)
725 voice->next->last = NULL;
726 else
727 audiomain->freelast = NULL;
728
729 /*
730 * Link voice into the newlist
731 */
732 if ((voice->next = audiomain->newlist) != NULL)
733 voice->next->last = voice;
734 else
735 audiomain->newlast = voice;
736 audiomain->newlist = voice;
737 voice->last = NULL;
738
739 //printf("ss: ");printPlayList(audiomain);
740
741 #ifdef BRISTOL_SEMAPHORE
742 sem_post(audiomain->sem_short);
743 #endif
744
745 return(0);
746 }
747
748 #ifdef BRISTOL_SEMAPHORE
749 sem_wait(audiomain->sem_long);
750 #endif
751
752 /*
753 * We have the semaphore, search for the voice. There are several cases
754 * that we should check for: single voice, last voice, matching key/baudio.
755 */
756 voice = audiomain->playlist;
757 while (voice != NULL)
758 {
759 if (voice->baudio == NULL) {
760 voice = voice->next;
761 continue;
762 }
763
764 /*
765 * Then see if it's also my key. If it is my key break, otherwise take
766 * this as the 'last' entry and continue. We do not need to check the
767 * channel as that has already been done.
768 */
769 if (voice->baudio == baudio)
770 {
771 /*
772 * So, it's my baudio but not the same note, keep it as possible
773 * 'last' key to be stolen later.
774 */
775 last = voice;
776
777 /*
778 * If we only have a single voice available and this is it, use it
779 */
780 if (baudio->voicecount == 1)
781 {
782 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYDONE|BRISTOL_KEYOFF);
783 //|BRISTOL_KEYOFFING);
784 voice->flags |= BRISTOL_KEYREON;
785
786 voice->keyid = key;
787 voice->offset = offset;
788 voice->key.key = transposedkey;
789 voice->key.velocity = velocity;
790 voice->velocity = mappedvelocity;
791 voice->lastkey = lastkey;
792 voice->dFreq = dFreq;
793 voice->cFreq = cFreq;
794 voice->cFreqmult = cFreqmult;
795 voice->dfreq = dfreq;
796 voice->cfreq = cfreq;
797 voice->cfreqmult = cfreqmult;
798 voice->detune = dTune;
799
800 #ifdef BRISTOL_SEMAPHORE
801 sem_post(audiomain->sem_long);
802 #endif
803 return(0);
804 }
805
806 if (voice->keyid == msg->params.key.key)
807 break;
808 }
809
810
811 if (voice->flags & (BRISTOL_DONE|BRISTOL_KEYOFFING))
812 donevoice = voice;
813
814 voice = voice->next;
815 }
816
817 /*
818 * If we did not find a voice see if we found a 'last' voice, if not just
819 * take the last playlist entry
820 */
821 if (voice == NULL) {
822 if (donevoice != NULL) // Take a voice that is going off
823 voice = donevoice;
824 else if (last != NULL) // Take the last voice for this synth
825 voice = last;
826 else // Steal the oldest note
827 voice = audiomain->playlast;
828 }
829
830 if (voice != NULL)
831 {
832 /*
833 * Unlink this voice, refill it, put it on the head of the newlist.
834 */
835 if (voice->next != NULL)
836 voice->next->last = voice->last;
837 else
838 audiomain->playlast = voice->last;
839
840 if (voice->last != NULL)
841 voice->last->next = voice->next;
842 else
843 audiomain->playlist = voice->next;
844
845 if ((voice->next = audiomain->newlist) != NULL)
846 voice->next->last = voice;
847 else
848 audiomain->newlast = voice;
849 audiomain->newlist = voice;
850 voice->last = NULL;
851
852 voice->flags &= ~(BRISTOL_KEYON|BRISTOL_KEYREON);
853 if (voice->baudio == baudio)
854 voice->flags |= BRISTOL_KEYREON;
855
856 voice->keyid = key;
857 voice->offset = offset;
858 voice->key.key = transposedkey;
859 voice->key.velocity = velocity;
860 voice->velocity = mappedvelocity;
861 voice->lastkey = lastkey;
862 voice->dFreq = dFreq;
863 voice->cFreq = cFreq;
864 voice->cFreqmult = cFreqmult;
865 voice->dfreq = dfreq;
866 voice->cfreq = cfreq;
867 voice->cfreqmult = cfreqmult;
868 voice->detune = dTune;
869 } else
870 if (baudio->midiflags & BRISTOL_MIDI_DEBUG2)
871 printf("voicecount exceeded\n");
872
873 #ifdef BRISTOL_SEMAPHORE
874 sem_post(audiomain->sem_long);
875 #endif
876
877 //printf("sl: ");printPlayList(audiomain);
878
879 return(0);
880 }
881
882 int
midiNoteOn(audioMain * audiomain,bristolMidiMsg * msg)883 midiNoteOn(audioMain *audiomain, bristolMidiMsg *msg)
884 {
885 #ifdef BRISTOL_SEMAPHORE
886 Baudio *baudio = audiomain->audiolist;
887 #else
888
889 if (msg->params.key.velocity == 0)
890 {
891 msg->command = MIDI_NOTE_OFF|(msg->command & MIDI_CHAN_MASK);
892 msg->params.key.velocity = 64;
893 return(midiNoteOff(audiomain, msg));
894 }
895
896 /*
897 * So, if this came from a jack handle, and we are single open then don't
898 * dump this in the ringbuffer - call the handler directly
899 *
900 * The JDO flags is straightforward. We then need to check if 'from' is
901 * a jack handle.
902 */
903 if ((msg->params.key.flags & BRISTOL_KF_JACK)
904 && (~audiomain->flags & BRISTOL_JACK_DUAL))
905 {
906 /*
907 * The message came from Jack and we have selected a single registration
908 * which means we are actually in the audio thread and can conginue with
909 * the note on event.
910 */
911 if ((audiomain->debuglevel & BRISTOL_DEBUG_MASK) > BRISTOL_DEBUG2)
912 printf("direct on call\n");
913 return(rbMidiNoteOn(audiomain, msg));
914 } if (jack_ringbuffer_write_space(audiomain->rb) >= sizeof(bristolMidiMsg))
915 jack_ringbuffer_write(audiomain->rb, (char *) msg,
916 sizeof(bristolMidiMsg));
917 else
918 printf("ringbuffer exhausted, note on event dropped\n");
919
920 return(0);
921 }
922
923 int
924 rbMidiNoteOn(audioMain *audiomain, bristolMidiMsg *msg)
925 {
926 Baudio *baudio = audiomain->audiolist;
927 #endif
928 /*
929 * Hm, if we have already applied a velocity curve then this value that
930 * was zero can now be something else, and that would lead to unexpected
931 * results
932 */
933 if (msg->params.key.velocity == 0)
934 {
935 msg->command = MIDI_NOTE_OFF|(msg->command & MIDI_CHAN_MASK);
936 msg->params.key.velocity = 64;
937 #ifndef BRISTOL_SEMAPHORE
938 return(rbMidiNoteOff(audiomain, msg));
939 #endif
940 }
941
942 /*
943 * Find an associated baudio structure. We have to go through the
944 * baudio lists, and find the correct midi channel. Link up the locals
945 * list.
946 */
947 while (baudio != (Baudio *) NULL)
948 {
949 if (baudio->mixflags & (BRISTOL_HOLDDOWN|BRISTOL_REMOVE))
950 {
951 baudio = baudio->next;
952 continue;
953 }
954
955 if (((baudio->midichannel == msg->channel)
956 || (baudio->midichannel == BRISTOL_CHAN_OMNI))
957 && (baudio->lowkey <= msg->params.key.key)
958 && (baudio->highkey >= msg->params.key.key))
959 {
960 int voices = 1;
961 int key = msg->params.key.key;
962 int chordindex = 0;
963
964 /*
965 * If we have Unison then we will send the same note on event to
966 * every voice on this emulation. If we have Chord enabled then we
967 * will send a different key number to each of the voices.
968 */
969 if (baudio->mixflags & (BRISTOL_V_UNISON|BRISTOL_CHORD))
970 voices = baudio->voicecount;
971
972 bristolArpeggiatorNoteEvent(baudio, msg);
973
974 /*
975 * We could avoid this, since we have the correct baudio
976 * pointer.
977 */
978 for (;voices > 0; voices--)
979 {
980 if (baudio->mixflags & BRISTOL_CHORD)
981 {
982 /*
983 * There is no key bounds check here, that happens when the
984 * note gets allocated a voice later, as a part of the
985 * transpose operation.
986 */
987 msg->params.key.key
988 = key + baudio->arpeggio.c.notes[chordindex].k;
989
990 /*
991 * We could consider two modes here:
992 *
993 * Roll around the notes list and assign something to
994 * every available voice.
995 *
996 * Break such that we just have one voice assigned per
997 * arpeggiator note (assuming we have enough voices).
998 *
999 * I prefer the latter, we can build chord of 4 notes, for
1000 * example, and still have polyphony of these chords.
1001 *
1002 * This should actually be a call into the arpeggiator.c
1003 * code, it would be a lot cleaner. Overhead is not great
1004 * as its only for note on events. There is no reason why
1005 * the arpeggiator should not actually call the shots here
1006 * and request the doMidiNoteOn() back to this code.
1007 printf("chord: %x %i %i\n",
1008 (size_t) baudio,
1009 baudio->arpeggio.c.max,
1010 baudio->arpeggio.c.notes[chordindex - 1].k);
1011 */
1012 if (++chordindex > baudio->arpeggio.c.max)
1013 break;
1014 }
1015 doMidiNoteOn(audiomain, msg, baudio, key);
1016 }
1017 }
1018
1019 baudio = baudio->next;
1020 }
1021 return(0);
1022 }
1023
1024 void
sustainedNotesOff(audioMain * audiomain,int channel)1025 sustainedNotesOff(audioMain *audiomain, int channel)
1026 {
1027 bristolVoice *voice = audiomain->playlist;
1028
1029 while (voice != NULL)
1030 {
1031 if ((channel == -1)
1032 || ((voice->baudio != NULL)
1033 && (voice->flags & BRISTOL_KEYSUSTAIN)
1034 && ((voice->baudio->midichannel == channel)
1035 || (voice->baudio->midichannel == BRISTOL_CHAN_OMNI))))
1036 voice->flags |= BRISTOL_KEYOFF;
1037 voice = voice->next;
1038 }
1039
1040 if ((voice != NULL) && (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2))
1041 printf("midi sustained notes off\n");
1042 }
1043
1044 void
allNotesOff(audioMain * audiomain,int channel)1045 allNotesOff(audioMain *audiomain, int channel)
1046 {
1047 bristolVoice *voice = audiomain->playlist;
1048
1049 while (voice != NULL)
1050 {
1051 if ((channel == -1)
1052 || ((voice->baudio != NULL)
1053 && ((voice->baudio->midichannel == channel)
1054 || (voice->baudio->midichannel == BRISTOL_CHAN_OMNI))))
1055 {
1056 voice->flags = BRISTOL_KEYOFF|BRISTOL_KEYDONE;
1057 //voice->flags &= ~(BRISTOL_KEYSUSTAIN;
1058 }
1059
1060 doMNL(voice, 0, 0, BRISTOL_ALL_NOTES_OFF, 0);
1061 voice = voice->next;
1062 }
1063
1064 if ((voice != NULL) && (voice->baudio->midiflags & BRISTOL_MIDI_DEBUG2))
1065 printf("midi all notes off\n");
1066 }
1067
1068 #ifndef BRISTOL_SEMAPHORE
1069 void
rbMidiNote(audioMain * audiomain,bristolMidiMsg * msg)1070 rbMidiNote(audioMain *audiomain, bristolMidiMsg *msg)
1071 {
1072 if ((audiomain->debuglevel & BRISTOL_DEBUG_MASK) > BRISTOL_DEBUG2)
1073 printf("rbMidiNote(%x) %x\n", msg->command, msg->params.key.flags);
1074
1075 if ((msg->command & MIDI_COMMAND_MASK) == MIDI_NOTE_ON)
1076 rbMidiNoteOn(audiomain, msg);
1077 else if ((msg->command & MIDI_COMMAND_MASK) == MIDI_NOTE_OFF)
1078 rbMidiNoteOff(audiomain, msg);
1079 }
1080 #endif
1081
1082