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