1 
2 /*
3  *  Diverse Bristol midi 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 <sys/time.h>
25 #include <time.h>
26 #include <string.h>
27 
28 #include <bristolmidi.h>
29 #include <bristolmidieventnames.h>
30 #include "bristolmessages.h"
31 
32 extern bristolMidiMain bmidi;
33 
34 /* We should put this into a structure */
35 static int NonOrRegistered = 0, NonOrRegisteredValue = 0;
36 
37 void
bristolMidiPrintGM2(bristolMidiMsg * msg)38 bristolMidiPrintGM2(bristolMidiMsg *msg)
39 {
40 	printf("GM2: base %i from %i/%i\n",
41 		msg->GM2.c_id, msg->GM2.c_id_coarse, msg->GM2.c_id_fine);
42 	printf("	%i/%i = %i %f\n",
43 		msg->GM2.coarse, msg->GM2.fine, msg->GM2.intvalue, msg->GM2.value);
44 }
45 
46 void
bristolMsgPrint(bristolMsg * msg)47 bristolMsgPrint(bristolMsg *msg)
48 {
49 	printf("ID  0x%x%x%x%x\n", msg->SysID, msg->L, msg->a, msg->b);
50 	printf("    msgLen  %i\n", msg->msgLen);
51 	printf("    msgType %i\n", msg->msgType);
52 	printf("    channel %i\n", msg->channel);
53 	printf("    from    %i\n", msg->from);
54 	printf("    op      %i\n", msg->operator);
55 	printf("    cont    %i\n", msg->controller);
56 	printf("    MSB     %i\n", msg->valueMSB);
57 	printf("    LSB     %i\n", msg->valueLSB);
58 	printf("    value   %i/%x\n",
59 		msg->valueLSB + (msg->valueMSB<<7),
60 		msg->valueLSB + (msg->valueMSB<<7));
61 }
62 
63 void
bristolMidiPrint(bristolMidiMsg * msg)64 bristolMidiPrint(bristolMidiMsg *msg)
65 {
66 	int command = ((msg->command & MIDI_COMMAND_MASK) & ~MIDI_STATUS_MASK) >> 4;
67 
68 	switch (msg->command & MIDI_COMMAND_MASK) {
69 		case MIDI_SYSTEM:
70 			printf("system");
71 			if ((msg->params.bristol.SysID == ((bmidi.SysID >> 24) & 0x0ff))
72 				&& (msg->params.bristol.L == ((bmidi.SysID >> 16) & 0x0ff))
73 				&& (msg->params.bristol.a == ((bmidi.SysID >> 8) & 0x0ff))
74 				&& (msg->params.bristol.b == (bmidi.SysID & 0x0ff)))
75 			{
76 				printf(" bristol (%i)\n", msg->sequence);
77 				bristolMsgPrint(&msg->params.bristol);
78 			} else
79 				printf("\n");
80 			break;
81 		case MIDI_NOTE_ON:
82 			printf("%s (%i) ch %i: %i, velocity %i\n", eventNames[command],
83 				msg->sequence,
84 				msg->channel, msg->params.key.key,  msg->params.key.velocity);
85 			break;
86 		case MIDI_NOTE_OFF:
87 			printf("%s (%i) ch %i: %i, velocity %i\n", eventNames[command],
88 				msg->sequence,
89 				msg->channel, msg->params.key.key,  msg->params.key.velocity);
90 			break;
91 		case MIDI_POLY_PRESS:
92 			printf("%s (%i) ch %i: key %i, pressure %i\n", eventNames[command],
93 				msg->sequence, msg->channel,
94 				msg->params.pressure.key,  msg->params.pressure.pressure);
95 			break;
96 		case MIDI_CONTROL:
97 			if (controllerName[msg->params.controller.c_id] == NULL)
98 				printf("%s (%i) ch %i: c_id %i, c_val %i\n",
99 					eventNames[command],
100 					msg->sequence,
101 					msg->channel,
102 					msg->params.controller.c_id,
103 					msg->params.controller.c_val);
104 			else
105 				printf("%s (%i) ch %i: %s, value %i\n", eventNames[command],
106 					msg->sequence,
107 					msg->channel,
108 					controllerName[msg->params.controller.c_id],
109 					msg->params.controller.c_val);
110 			break;
111 		case MIDI_PROGRAM:
112 			printf("%s (%i) ch %i: p_id %i\n", eventNames[command],
113 				msg->sequence,
114 				msg->channel, msg->params.program.p_id);
115 			break;
116 		case MIDI_CHAN_PRESS:
117 			printf("%s (%i) ch %i: pressure %i\n", eventNames[command],
118 				msg->sequence,
119 				msg->channel, msg->params.channelpress.pressure);
120 			break;
121 		case MIDI_PITCHWHEEL:
122 			printf("%s (%i) ch %i: msb %i, lsb %i\n", eventNames[command],
123 				msg->sequence,
124 				msg->channel, msg->params.pitch.msb, msg->params.pitch.lsb);
125 			break;
126 	}
127 }
128 
129 /*
130  * This will take the specified messages and recode the GM2 portion for things
131  * such as coarse/fine controllers. It will also take the values of the coded
132  * values and turn them into a floating point value.
133  *
134  * This stuff is painful for several reasons - some GM2 values denote coarse
135  * and fine, others denote semitone and cents, etc, some are integer rather
136  * than floats. It might be better to call this later if parsing is required.
137  *
138  * We also need to have a midi controller mapping system. If a controller is
139  * remapped then we should consider it to be coarse only?
140  *
141  * The engine has a version of this code with different parameterisation. It
142  * is in midihandlers and we should pull it out into the library.
143  */
144 void
bristolMidiToGM2(int GM2values[128],int midimap[128],u_char valuemap[128][128],bristolMidiMsg * msg)145 bristolMidiToGM2(int GM2values[128], int midimap[128], u_char valuemap[128][128], bristolMidiMsg *msg)
146 {
147 	if (msg->command != MIDI_CONTROL)
148 	{
149 		/*
150 		 * This may be counter productive?
151 		 */
152 		msg->GM2.c_id = -1;
153 		msg->GM2.value = 0;
154 		return;
155 	}
156 
157 	/*
158 	 * Apply the mappings already if any are defined. This is just a controller
159 	 * mapping however we also want to apply a value mapping this early. It
160 	 * is something to the effect of the following however this table needs to
161 	 * be initialised
162 	 */
163 	if (valuemap != NULL)
164 		msg->params.controller.c_val = valuemap[msg->params.controller.c_id]
165 			[msg->params.controller.c_val];
166 	if (midimap != NULL)
167 		msg->params.controller.c_id = midimap[msg->params.controller.c_id];
168 
169 	/*
170 	 * Keep a copy of the controller setting for later use.
171 	 */
172 	GM2values[msg->params.controller.c_id] = msg->params.controller.c_val;
173 
174 	/*
175 	 * This are true for all the controllers, but the later ones may have
176 	 * specific modifications
177 	 */
178 	msg->GM2.c_id = msg->params.controller.c_id;
179 	msg->GM2.value = ((float) msg->params.controller.c_val) / 127.0f;
180 	msg->GM2.intvalue = msg->params.controller.c_val;
181 	msg->GM2.coarse = msg->params.controller.c_val;
182 	msg->GM2.fine = 0;
183 
184 	/*
185 	 * These are coarse of the course/fine controls
186 	 */
187 	if (msg->params.controller.c_id < 14)
188 	{
189 		msg->GM2.coarse = msg->params.controller.c_val;
190 		msg->GM2.fine = GM2values[msg->params.controller.c_id + 32];
191 		msg->GM2.intvalue = (msg->GM2.coarse << 7) + msg->GM2.fine;
192 		msg->GM2.value = ((float) msg->GM2.intvalue) / 16383.0f;
193 		return;
194 	}
195 
196 	if (msg->params.controller.c_id < 32)
197 		return;
198 
199 	/*
200 	 * Fine controls for the first 14 coarse/fine controllers.
201 	 */
202 	if (msg->params.controller.c_id < 46)
203 	{
204 /*		msg->GM2.c_id -= 32; */
205 		msg->GM2.fine = msg->params.controller.c_val;
206 		msg->GM2.coarse = GM2values[msg->params.controller.c_id - 32];
207 		msg->GM2.intvalue = (msg->GM2.coarse << 7) + msg->GM2.fine;
208 		msg->GM2.value = ((float) msg->GM2.intvalue) / 16383.0f;
209 		/*
210 		 * We should change the controller to be NRP/RP and the value to
211 		 * reflect the associated controller setting:
212 		 *
213 		 * c_id = N/RP
214 		 * find = N/RP value
215 		 * value/intvalue = that controller  value.
216 		 *
217 		 * In other words, never deliver a c_id 38.
218 		 */
219 		if (msg->params.controller.c_id == 38) {
220 			msg->GM2.c_id = NonOrRegistered;
221 			msg->GM2.coarse = NonOrRegisteredValue;
222 		}
223 		return;
224 	}
225 
226 	if (msg->params.controller.c_id < 80)
227 		return;
228 
229 	/*
230 	 * These are 4 buttons.
231 	if (msg->params.controller.c_id < 84)
232 	{
233 		if (msg->GM2.intvalue > 63)
234 			msg->GM2.value = 1.0;
235 		else
236 			msg->GM2.value = 0.0;
237 		return;
238 	}
239 	 */
240 
241 	if (msg->params.controller.c_id < 96)
242 		return;
243 
244 	/*
245 	 * These are 2 data entry buttons.
246 	if (msg->params.controller.c_id < 98)
247 	{
248 		if (msg->GM2.intvalue > 63)
249 			msg->GM2.value = 1.0;
250 		else
251 			msg->GM2.value = 0.0;
252 		return;
253 	}
254 	 */
255 
256 	/*
257 	 * Non Registered Parameter Numbers.
258 	 */
259 	if ((msg->params.controller.c_id == 98)
260 		|| (msg->params.controller.c_id == 99))
261 	{
262 		msg->GM2.c_id = 99;
263 		msg->GM2.fine = GM2values[98];
264 		msg->GM2.coarse = GM2values[99];
265 		msg->GM2.intvalue = (msg->GM2.coarse << 7) + msg->GM2.fine;
266 		msg->GM2.value = ((float) msg->GM2.intvalue) / 16383.0f;
267 		NonOrRegistered = MIDI_GM_NRP;
268 		NonOrRegisteredValue = msg->GM2.intvalue;
269 		return;
270 	}
271 
272 	/*
273 	 * Registered Parameter Numbers.
274 	 */
275 	if ((msg->params.controller.c_id == 100)
276 		|| (msg->params.controller.c_id == 101))
277 	{
278 		msg->GM2.c_id = 101;
279 		msg->GM2.fine = GM2values[100];
280 		msg->GM2.coarse = GM2values[101];
281 		msg->GM2.intvalue = (msg->GM2.coarse << 7) + msg->GM2.fine;
282 		msg->GM2.value = ((float) msg->GM2.intvalue) / 16383.0f;
283 		NonOrRegistered = MIDI_GM_RP;
284 		NonOrRegisteredValue = msg->GM2.intvalue;
285 		return;
286 	}
287 
288 	/*
289 	 * local Keyboard
290 	if (msg->params.controller.c_id == 122)
291 	{
292 		if (msg->GM2.intvalue > 63)
293 			msg->GM2.value = 1.0;
294 		else
295 			msg->GM2.value = 0.0;
296 		return;
297 	}
298 	 */
299 }
300 
301 char databytes[1024];
302 
303 static void
buildOneMsg(unsigned char p1,unsigned char p2,int dev,bristolMidiMsg * msg)304 buildOneMsg(unsigned char p1, unsigned char p2, int dev, bristolMidiMsg *msg)
305 {
306 #ifdef DEBUG
307 	printf("buildOneMsg(%x, %x, %i), comm %x\n", p1, p2, dev,
308 		bmidi.dev[dev].lastcommand);
309 #endif
310 
311 	gettimeofday(&(msg->timestamp), 0);
312 
313 	/*
314 	 * We have enough message capacity, put information into the message buffer
315 	 * and return.
316 	 */
317 	msg->command = bmidi.dev[dev].lastcommand;
318 	msg->channel = bmidi.dev[dev].lastchan;
319 
320 	msg->sequence = bmidi.dev[dev].sequence++;
321 
322 	if (p1 != 0xff)
323 	{
324 		msg->params.key.key = p1;
325 		msg->params.key.velocity = p2;
326 		if (bmidi.dev[dev].flags & BRISTOL_CONN_JACK)
327 			msg->params.key.flags = BRISTOL_KF_JACK;
328 		else if (bmidi.dev[dev].flags & BRISTOL_CONN_TCP)
329 			msg->params.key.flags = BRISTOL_KF_TCP;
330 		else
331 			msg->params.key.flags = BRISTOL_KF_RAW;
332 	}
333 
334 	switch (msg->command) {
335 		case MIDI_SYSTEM:
336 			if (msg->params.bristol.msgType >= 8)
337 			{
338 //				printf("T2 data: %s\n", databytes);
339 				msg->params.bristolt2.data = databytes;
340 			}
341 			break;
342 		case MIDI_NOTE_OFF:
343 		case MIDI_NOTE_ON:
344 		case MIDI_POLY_PRESS:
345 		case MIDI_CONTROL:
346 		case MIDI_PITCHWHEEL:
347 			msg->params.bristol.msgLen = 3;
348 			break;
349 		case MIDI_PROGRAM:
350 		case MIDI_CHAN_PRESS:
351 			msg->params.bristol.msgLen = 2;
352 			break;
353 	}
354 }
355 
356 static int
parseCommand(unsigned char comm,int dev)357 parseCommand(unsigned char comm, int dev)
358 {
359 #ifdef int
360 	printf("parseCommand(%x, %i)\n", comm, dev);
361 #endif
362 
363 	/*
364 	 * We have a new command, save any interesting device state infomation.
365 	 */
366 	bmidi.dev[dev].lastchan = comm & MIDI_CHAN_MASK;
367 	bmidi.dev[dev].lastcommand = comm & MIDI_COMMAND_MASK;
368 
369 	/*
370 	 * Set up how many more bytes we need.
371 	 */
372 	switch (bmidi.dev[dev].lastcommand) {
373 		case MIDI_SYSTEM:
374 			if (comm == MIDI_EOS)
375 			{
376 				/*
377 				if (bmidi.dev[dev].sysex.count != sizeof(bristolMsg))
378 					printf("Was bad sysex message (wrong length)\n");
379 				else
380 					printf("Was right length message: %x\n",
381 						bmidi.dev[dev].sysex.count);
382 				*/
383 				bmidi.dev[dev].sysex.count = 0;
384 				bmidi.dev[dev].lastcommand = 0;
385 			}
386 			if (comm == MIDI_SYSEX)
387 			{
388 				/*printf("SYSEX checks\n"); */
389 				bmidi.dev[dev].sysex.count = 0;
390 				return(1);
391 			}
392 			break;
393 		case MIDI_PROGRAM:
394 		case MIDI_CHAN_PRESS:
395 			bmidi.dev[dev].lastcommstate =
396 				BRISTOL_CHANSTATE_WAIT_1;
397 			break;
398 		case MIDI_NOTE_ON:
399 		case MIDI_NOTE_OFF:
400 		case MIDI_POLY_PRESS:
401 		case MIDI_PITCHWHEEL:
402 			bmidi.dev[dev].lastcommstate =
403 				BRISTOL_CHANSTATE_WAIT_2;
404 			break;
405 		default:
406 			break;
407 	}
408 
409 	return(0);
410 }
411 
412 int
bristolMidiRawToMsg(unsigned char * buff,int count,int index,int dev,bristolMidiMsg * msg)413 bristolMidiRawToMsg(unsigned char *buff, int count, int index, int dev,
414 	bristolMidiMsg *msg)
415 {
416 	int parsed = 0;
417 
418 	msg->command = -1;
419 	msg->offset = 0;
420 
421 	/*
422 	 * Attempt to parse a raw message buffer. If we can resolve a complete
423 	 * message then return the number we have parsed.
424 	 */
425 	if (count <= 0)
426 		return(0);
427 
428 #ifdef DEBUG
429 	printf("bristolMidiRawToMsg(%x, %i, %i, %i) [%x]\n",
430 		(size_t) buff, count, index, dev, buff[index]);
431 #endif
432 
433 	/*
434 	 * Although we know that we have buffered data, we do not know if we are
435 	 * being given complete messages by the raw interface - it could be byte by
436 	 * byte, or chunks of a large sysex. Parse the data byte by byte, and see
437 	 * if we can put together complete messages.
438 	 *
439 	 * Check out our current command in operation on this device:
440 	 */
441 	bmidi.dev[dev].sysex.count = 0;
442 	while (parsed < count)
443 	{
444 		/*
445 		 * If this is a status byte, find out what we cn do with it. Otherwise
446 		 * look for data commands.
447 		if ((bmidi.dev[dev].lastcommand != MIDI_SYSTEM) &&
448 			(buff[index] & MIDI_STATUS_MASK))
449 		 */
450 		if (buff[index] & MIDI_STATUS_MASK) {
451 			parseCommand(buff[index++], dev);
452 			return(1);
453 		} else {
454 			switch (bmidi.dev[dev].lastcommand)
455 			{
456 				/*
457 				 * Looking for one more byte. We have it, since we made it here.
458 				 */
459 				case MIDI_PROGRAM:
460 				case MIDI_CHAN_PRESS:
461 					buildOneMsg(buff[index], -1, dev, msg);
462 					return(parsed + 1);
463 				/*
464 				 * Looking for two more bytes, if they are there.
465 				 */
466 				case MIDI_NOTE_ON:
467 				case MIDI_CONTROL:
468 				case MIDI_NOTE_OFF:
469 				case MIDI_POLY_PRESS:
470 				case MIDI_PITCHWHEEL:
471 					/*
472 					 * if we do not have enough bytes, return.
473 					 */
474 					if ((count - parsed) < 2)
475 						return(0);
476 
477 					/*
478 					 * Otherwise, go get the command, checking for buffer wrap.
479 					 * We also need to make sure that the next spare byte is not
480 					 * a status byte - ie, that we have not binned a byte in the
481 					 * midi cable.
482 					 */
483 					if ((index + 1) == BRISTOL_MIDI_BUFSIZE)
484 					{
485 						if (buff[0] & MIDI_STATUS_MASK)
486 							break;
487 						else
488 							buildOneMsg(buff[index], buff[0], dev, msg);
489 					} else {
490 						if (buff[index+1] & MIDI_STATUS_MASK)
491 							break;
492 						else
493 							buildOneMsg(buff[index], buff[index+1], dev, msg);
494 					}
495 
496 					return(parsed + 2);
497 				case MIDI_SYSTEM:
498 					/*
499 					 * Sysex management requires we read bytes until we get
500 					 * a status byte, and it should minimally be blocking on
501 					 * this device. Assume, since we have been sent this, that
502 					 * it is going to be a bristolMidiMsg, and look for the
503 					 * first few bytes. If it is SLab we are OK, otherwise we
504 					 * have an issue, and should read to next status byte then
505 					 * dump the data.
506 					 *
507 					 * Looks bad? Turn the bm message into an array, and index
508 					 * it depending on which byte we have. Could do with some
509 					 * error handling!
510 					 */
511 					if (bmidi.dev[dev].sysex.count < 12)
512 						((char *) &msg->params.bristol)
513 							[bmidi.dev[dev].sysex.count] = buff[index];
514 						bmidi.dev[dev].sysex.count++;
515 
516 					if (bmidi.dev[dev].sysex.count == 4)
517 					{
518 						/*
519 						 * If this is not a SLab message, then set the
520 						 * current state to unknown.
521 						 */
522 						if ((msg->params.bristol.SysID
523 							!= ((bmidi.SysID >> 24) & 0x07f))
524 							|| (msg->params.bristol.L
525 								!= ((bmidi.SysID >> 16) & 0x07f))
526 							|| (msg->params.bristol.a
527 								!= ((bmidi.SysID >> 8) & 0x07f))
528 							|| (msg->params.bristol.b
529 								!= (bmidi.SysID & 0x07f)))
530 						{
531 							int rv = bmidi.dev[dev].sysex.count;
532 
533 							printf("unrecognised SYSEX ID %x %x %x %x (%i)\n",
534 								msg->params.bristol.SysID,
535 								msg->params.bristol.L,
536 								msg->params.bristol.a,
537 								msg->params.bristol.b,
538 								index
539 							);
540 
541 							bmidi.dev[dev].lastcommand = 0;
542 							bmidi.dev[dev].sysex.count = 0;
543 							return(rv);
544 						}
545 							//else printf("SLab SYSEX type\n");
546 					}
547 
548 					if (bmidi.dev[dev].sysex.count == sizeof(bristolMsg))
549 					{
550 						/* Might be type 2 messages */
551 						if (msg->params.bristol.msgType > 7)
552 						{
553 							//printf("Received a type 2 message\n");
554 							if ((index+=1) >= BRISTOL_MIDI_BUFSIZE)
555 								index = 0;
556 							parsed++;
557 							continue;
558 						}
559 
560 						if (bmidi.dev[dev].sysex.count
561 							== msg->params.bristol.msgLen)
562 						{
563 							// printf("Received a SLab SYSEX message\n");
564 							buildOneMsg(0xff, 0xff, dev, msg);
565 							bmidi.dev[dev].lastcommand = 0;
566 							return(msg->params.bristol.msgLen);
567 						} else {
568 							int rv = bmidi.dev[dev].sysex.count;
569 							// printf("unknown SYSEX message\n");
570 							bmidi.dev[dev].lastcommand = 0;
571 							bmidi.dev[dev].sysex.count = 0;
572 							return(rv);
573 						}
574 					}
575 
576 					if (bmidi.dev[dev].sysex.count >= sizeof(bristolMsg))
577 					{
578 						if ((msg->params.bristol.msgLen >= 1023)
579 							|| (msg->params.bristol.msgType < 8))
580 						{
581 							int rv = bmidi.dev[dev].sysex.count;
582 							printf("bad SLab SYSEX message length\n");
583 							bmidi.dev[dev].lastcommand = 0;
584 							bmidi.dev[dev].sysex.count = 0;
585 							return(rv);
586 						}
587 
588 						databytes[bmidi.dev[dev].sysex.count - 1
589 							- sizeof(bristolMsg)] = buff[index];
590 
591 						//printf("inserted %x, %s\n", buff[index], databytes);
592 
593 						if (bmidi.dev[dev].sysex.count
594 							>= msg->params.bristol.msgLen)
595 						{
596 							/* This is for strings but works generally */
597 							databytes[bmidi.dev[dev].sysex.count
598 								- sizeof(bristolMsg)] = '\0';
599 							buildOneMsg(0xff, 0xff, dev, msg);
600 							bmidi.dev[dev].lastcommand = 0;
601 							return(msg->params.bristol.msgLen);
602 						}
603 					}
604 					break;
605 				default:
606 					/*
607 					 * Looking for a recognised command:
608 					if (buff[index] & MIDI_STATUS_MASK)
609 						parseCommand(buff[index], dev);
610 					 */
611 					index++;
612 
613 					return(1);
614 			}
615 		}
616 
617 		/*
618 		 * Look after our indices
619 		 */
620 		if ((index+=1) >= BRISTOL_MIDI_BUFSIZE)
621 			index = 0;
622 
623 		parsed++;
624 	}
625 
626 	return(0);
627 }
628 
629