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 /*
23  * This code should open the midi device (working with ALSA raw midi only for
24  * the moment (9/11/01)), and read data from it. Not sure how it will be read,
25  * either buffers, events, or perhaps just raw data. At some point in the
26  * development this will become a separate thread in the synth code.
27  */
28 #include <sys/poll.h>
29 #include <stdlib.h>
30 
31 #include "bristolmidi.h"
32 
33 #define DEBUG
34 
35 extern bristolMidiMain bmidi;
36 extern int bristolFreeHandle();
37 extern int bristolFreeDevice();
38 extern int checkcallbacks();
39 
40 /*
41  * This is the ALSA code. Should separate it out already.
42  */
43 int
bristolMidiSeqOpen(char * devname,int flags,int chan,int messages,int (* callback)(),void * param,int dev,int handle)44 bristolMidiSeqOpen(char *devname, int flags, int chan, int messages,
45 int (*callback)(), void *param, int dev, int handle)
46 {
47 #if (BRISTOL_HAS_ALSA == 1)
48 	int nfds, err, caps = 0, polldir = 0;
49 	int client, queue;
50 	char linkname[256];
51 	snd_seq_port_info_t *pinfo;
52 
53 #ifdef DEBUG
54 	if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
55 		printf("bristolMidiSeqOpen(%s)\n", devname);
56 #endif
57 
58 #if (SND_LIB_MAJOR == 1)
59 	caps = SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_SYNTHESIZER | SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_SYNTH | SND_SEQ_PORT_TYPE_APPLICATION;
60 
61 	/*
62 	 * Well, we got here, so I could perhaps consider assuming that we have
63 	 * ALSA 0.9 or greater SEQ support.
64 	 */
65 	bmidi.dev[dev].flags = 0;
66 
67 /*
68 	if (flags & BRISTOL_WRONLY)
69 	{
70 		bmidi.dev[dev].flags |= SND_SEQ_OPEN_OUTPUT;
71 		caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
72 	}
73 */
74 
75 	if (flags & BRISTOL_RDONLY)
76 	{
77 		polldir |= POLLIN;
78 		bmidi.dev[dev].flags |= SND_SEQ_OPEN_INPUT;
79 		caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
80 	}
81 
82 	if (flags & BRISTOL_WRONLY)
83 	{
84 		polldir |= POLLOUT;
85 		bmidi.dev[dev].flags |= SND_SEQ_OPEN_OUTPUT;
86 		caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
87 	}
88 
89 	if (snd_seq_open(&bmidi.dev[dev].driver.seq.handle, "default",
90 		bmidi.dev[dev].flags, 0) != 0)
91 	{
92 		/*
93 		 * Print a debug message, this is problematic.
94 		 */
95 		 printf("Could not open the MIDI interface.\n");
96 		 return(BRISTOL_MIDI_DRIVER);
97 	}
98 
99 	/*
100 	 * This use of a fixed name, bristol, is broken. We can better find out our
101 	 * process name, or better still, if we are linking to from the interface
102 	 * then pass another devname option if this is a SEQ interface
103 	 */
104 	if ((err = snd_seq_set_client_name(bmidi.dev[dev].driver.seq.handle,
105 		devname)) < 0)
106 	{
107 		printf("Set client info error: %s\n", snd_strerror(err));
108 		return(BRISTOL_MIDI_DRIVER);
109 	}
110 
111 	if ((client = snd_seq_client_id(bmidi.dev[dev].driver.seq.handle)) < 0) {
112 		printf(
113 			"Cannot determine client number: %s\n", snd_strerror(client));
114 		return(BRISTOL_MIDI_DRIVER);
115 	}
116 	printf("Client ID = %i\n", client);
117 	if ((queue = snd_seq_alloc_queue(bmidi.dev[dev].driver.seq.handle)) < 0) {
118 		printf( "Cannot allocate queue: %s\n", snd_strerror(queue));
119 		return(BRISTOL_MIDI_DRIVER);
120 	}
121 	printf("Queue ID = %i\n", queue);
122 	if ((err = snd_seq_nonblock(bmidi.dev[dev].driver.seq.handle, 1)) < 0)
123 		printf( "Cannot set nonblock mode: %s\n", snd_strerror(err));
124 
125 	snd_seq_port_info_alloca(&pinfo);
126 
127 	sprintf(linkname, "%s io", devname);
128 
129 	if (~bmidi.dev[dev].flags & SND_SEQ_OPEN_INPUT)
130 		sprintf(linkname, "%s output", devname);
131 	else if (~bmidi.dev[dev].flags & SND_SEQ_OPEN_OUTPUT)
132 		sprintf(linkname, "%s input", devname);
133 
134 	snd_seq_port_info_set_name(pinfo, linkname);
135 	snd_seq_port_info_set_capability(pinfo, caps);
136     snd_seq_port_info_set_type (pinfo, caps);
137 
138 	if ((err = snd_seq_create_port(bmidi.dev[dev].driver.seq.handle, pinfo))
139 		< 0)
140 	{
141 		printf( "Cannot create input port: %s\n", snd_strerror(err));
142 		return(BRISTOL_MIDI_DRIVER);
143 	}
144 
145 /*
146 	port = snd_seq_port_info_get_port(pinfo);
147 
148 	if ((bmidi.dev[dev].flags & SND_SEQ_OPEN_INPUT)
149 		&& ((err = snd_seq_start_queue(bmidi.dev[dev].driver.seq.handle,
150 		queue, NULL)) < 0))
151 	   printf( "Timer event output error: %s\n", snd_strerror(err));
152 
153 	while (snd_seq_drain_output(bmidi.dev[dev].driver.seq.handle) > 0)
154 		sleep(1);
155 
156 	snd_seq_port_subscribe_alloca(&sub);
157 	addr.client = SND_SEQ_CLIENT_SYSTEM;
158 	addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
159 
160 	printf("Registering %i %i\n", addr.client, addr.port);
161 
162 	snd_seq_port_subscribe_set_sender(sub, &addr);
163 	addr.client = client;
164 	addr.port = port;
165 
166 	printf("Registered %i %i\n", addr.client, addr.port);
167 
168 	snd_seq_port_subscribe_set_dest(sub, &addr);
169 	snd_seq_port_subscribe_set_queue(sub, queue);
170 	snd_seq_port_subscribe_set_time_update(sub, 1);
171 	snd_seq_port_subscribe_set_time_real(sub, 1);
172 	if ((err = snd_seq_subscribe_port(bmidi.dev[dev].driver.seq.handle, sub))
173 		< 0)
174 	{
175 		printf("Cannot subscribe announce port: %s\n", snd_strerror(err));
176 		return(BRISTOL_MIDI_DRIVER);
177 	}
178 
179 	addr.client = SND_SEQ_CLIENT_SYSTEM;
180 	addr.port = SND_SEQ_PORT_SYSTEM_TIMER;
181 	snd_seq_port_subscribe_set_sender(sub, &addr);
182 	if ((err = snd_seq_subscribe_port(bmidi.dev[dev].driver.seq.handle, sub))
183 		< 0)
184 	{
185 		printf( "Cannot subscribe timer port: %s\n", snd_strerror(err));
186 		return(BRISTOL_MIDI_DRIVER);
187 	}
188 
189 	snd_seq_port_subscribe_set_time_real(sub, 0);
190 */
191 
192 		/*
193 		if (tolower(*ptr) == 'r') {
194 			snd_seq_port_subscribe_set_time_real(sub, 1);
195 			ptr++;
196 		}
197 		*/
198 
199 /*
200 	if (sscanf(devname, "%i.%i", &v1, &v2) != 2) {
201 		printf( "Device name \"%s\" did not parse, defaults 128.0\n",
202 			devname);
203 		v1 = 128;
204 		v2 = 0;
205 	}
206 	addr.client = v1;
207 	addr.port = v2;
208 
209 	snd_seq_port_subscribe_set_sender(sub, &addr);
210 	if ((err = snd_seq_subscribe_port(bmidi.dev[dev].driver.seq.handle, sub))
211 		< 0)
212 	{
213 		printf( "Cannot subscribe port %i from client %i: %s\n",
214 			v2, v1, snd_strerror(err));
215 	}
216 */
217 
218 	/*
219 	 * Now we need to find a file descriptor.
220 	 */
221 	if ((nfds = snd_seq_poll_descriptors_count(bmidi.dev[dev].driver.seq.handle,
222 		polldir)) < 1)
223 		printf("issue getting descriptors: %i\n", nfds);
224 	else {
225 		struct pollfd *pfds;
226 
227 		pfds = (struct pollfd *) malloc(sizeof (struct pollfd) * nfds);
228 		snd_seq_poll_descriptors(bmidi.dev[dev].driver.seq.handle,
229 			pfds, nfds, polldir);
230 
231 		bmidi.dev[dev].fd = pfds[0].fd;
232 
233 		free(pfds);
234 	}
235 
236 	bmidi.dev[dev].flags = BRISTOL_CONN_SEQ;
237 
238 	return(handle);
239 
240 #endif /* ADLIB version */
241 	return(BRISTOL_MIDI_DRIVER);
242 #endif /* ADLIB */
243 }
244 
245 int
bristolMidiSeqClose(int handle)246 bristolMidiSeqClose(int handle)
247 {
248 #ifdef DEBUG
249 	printf("bristolMidiSeqClose()\n");
250 #endif
251 
252 #if (BRISTOL_HAS_ALSA == 1)
253 #if (SND_LIB_MAJOR == 1)
254 	/*
255 	 * Check to see if the associated device has multiple handles associated
256 	 */
257 	if (bmidi.dev[bmidi.handle[handle].dev].handleCount > 1)
258 	{
259 		bmidi.dev[bmidi.handle[handle].dev].handleCount--;
260 		bristolFreeHandle(handle);
261 
262 		return(BRISTOL_MIDI_OK);
263 	}
264 
265 	snd_seq_close(bmidi.dev[bmidi.handle[handle].dev].driver.seq.handle);
266 
267 	bristolFreeDevice(bmidi.handle[handle].dev);
268 	bristolFreeHandle(handle);
269 #endif /* ADLIB */
270 #endif /* ADLIB */
271 	return(BRISTOL_MIDI_OK);
272 }
273 #if (BRISTOL_HAS_ALSA == 1)
274 #if (SND_LIB_MAJOR == 1)
275 /*
276 static char *event_names[256] = {
277 	[SND_SEQ_EVENT_SYSTEM]=	"System",
278 	[SND_SEQ_EVENT_RESULT]=	"Result",
279 	[SND_SEQ_EVENT_NOTE]=	"Note",
280 	[SND_SEQ_EVENT_NOTEON]=	"Note On",
281 	[SND_SEQ_EVENT_NOTEOFF]=	"Note Off",
282 	[SND_SEQ_EVENT_KEYPRESS]=	"Key Pressure",
283 	[SND_SEQ_EVENT_CONTROLLER]=	"Controller",
284 	[SND_SEQ_EVENT_PGMCHANGE]=	"Program Change",
285 	[SND_SEQ_EVENT_CHANPRESS]=	"Channel Pressure",
286 	[SND_SEQ_EVENT_PITCHBEND]=	"Pitchbend",
287 	[SND_SEQ_EVENT_CONTROL14]=	"Control14",
288 	[SND_SEQ_EVENT_NONREGPARAM]=	"Nonregparam",
289 	[SND_SEQ_EVENT_REGPARAM]=		"Regparam",
290 	[SND_SEQ_EVENT_SONGPOS]=	"Song Position",
291 	[SND_SEQ_EVENT_SONGSEL]=	"Song Select",
292 	[SND_SEQ_EVENT_QFRAME]=	"Qframe",
293 	[SND_SEQ_EVENT_TIMESIGN]=	"SMF Time Signature",
294 	[SND_SEQ_EVENT_KEYSIGN]=	"SMF Key Signature",
295 	[SND_SEQ_EVENT_START]=	"Start",
296 	[SND_SEQ_EVENT_CONTINUE]=	"Continue",
297 	[SND_SEQ_EVENT_STOP]=	"Stop",
298 	[SND_SEQ_EVENT_SETPOS_TICK]=	"Set Position Tick",
299 	[SND_SEQ_EVENT_SETPOS_TIME]=	"Set Position Time",
300 	[SND_SEQ_EVENT_TEMPO]=	"Tempo",
301 	[SND_SEQ_EVENT_CLOCK]=	"Clock",
302 	[SND_SEQ_EVENT_TICK]=	"Tick",
303 	[SND_SEQ_EVENT_TUNE_REQUEST]=	"Tune Request",
304 	[SND_SEQ_EVENT_RESET]=	"Reset",
305 	[SND_SEQ_EVENT_SENSING]=	"Active Sensing",
306 	[SND_SEQ_EVENT_ECHO]=	"Echo",
307 	[SND_SEQ_EVENT_OSS]=	"OSS",
308 	[SND_SEQ_EVENT_CLIENT_START]=	"Client Start",
309 	[SND_SEQ_EVENT_CLIENT_EXIT]=	"Client Exit",
310 	[SND_SEQ_EVENT_CLIENT_CHANGE]=	"Client Change",
311 	[SND_SEQ_EVENT_PORT_START]=	"Port Start",
312 	[SND_SEQ_EVENT_PORT_EXIT]=	"Port Exit",
313 	[SND_SEQ_EVENT_PORT_CHANGE]=	"Port Change",
314 	[SND_SEQ_EVENT_PORT_SUBSCRIBED]=	"Port Subscribed",
315 	[SND_SEQ_EVENT_PORT_UNSUBSCRIBED]=	"Port Unsubscribed",
316 	[SND_SEQ_EVENT_SAMPLE]=	"Sample",
317 	[SND_SEQ_EVENT_SAMPLE_CLUSTER]=	"Sample Cluster",
318 	[SND_SEQ_EVENT_SAMPLE_START]=	"Sample Start",
319 	[SND_SEQ_EVENT_SAMPLE_STOP]=	"Sample Stop",
320 	[SND_SEQ_EVENT_SAMPLE_FREQ]=	"Sample Freq",
321 	[SND_SEQ_EVENT_SAMPLE_VOLUME]=	"Sample Volume",
322 	[SND_SEQ_EVENT_SAMPLE_LOOP]=	"Sample Loop",
323 	[SND_SEQ_EVENT_SAMPLE_POSITION]=	"Sample Position",
324 	[SND_SEQ_EVENT_SAMPLE_PRIVATE1]=	"Sample Private1",
325 	[SND_SEQ_EVENT_USR0]=	"User 0",
326 	[SND_SEQ_EVENT_USR1]=	"User 1",
327 	[SND_SEQ_EVENT_USR2]=	"User 2",
328 	[SND_SEQ_EVENT_USR3]=	"User 3",
329 	[SND_SEQ_EVENT_USR4]=	"User 4",
330 	[SND_SEQ_EVENT_USR5]=	"User 5",
331 	[SND_SEQ_EVENT_USR6]=	"User 6",
332 	[SND_SEQ_EVENT_USR7]=	"User 7",
333 	[SND_SEQ_EVENT_USR8]=	"User 8",
334 	[SND_SEQ_EVENT_USR9]=	"User 9",
335 	[SND_SEQ_EVENT_INSTR_BEGIN]=	"Instr Begin",
336 	[SND_SEQ_EVENT_INSTR_END]=	"Instr End",
337 	[SND_SEQ_EVENT_INSTR_INFO]=	"Instr Info",
338 	[SND_SEQ_EVENT_INSTR_INFO_RESULT]=	"Instr Info Result",
339 	[SND_SEQ_EVENT_INSTR_FINFO]=	"Instr Font Info",
340 	[SND_SEQ_EVENT_INSTR_FINFO_RESULT]=	"Instr Font Info Result",
341 	[SND_SEQ_EVENT_INSTR_RESET]=	"Instr Reset",
342 	[SND_SEQ_EVENT_INSTR_STATUS]=	"Instr Status",
343 	[SND_SEQ_EVENT_INSTR_STATUS_RESULT]=	"Instr Status Result",
344 	[SND_SEQ_EVENT_INSTR_PUT]=	"Instr Put",
345 	[SND_SEQ_EVENT_INSTR_GET]=	"Instr Get",
346 	[SND_SEQ_EVENT_INSTR_GET_RESULT]=	"Instr Get Result",
347 	[SND_SEQ_EVENT_INSTR_FREE]=	"Instr Free",
348 	[SND_SEQ_EVENT_INSTR_LIST]=	"Instr List",
349 	[SND_SEQ_EVENT_INSTR_LIST_RESULT]=	"Instr List Result",
350 	[SND_SEQ_EVENT_INSTR_CLUSTER]=	"Instr Cluster",
351 	[SND_SEQ_EVENT_INSTR_CLUSTER_GET]=	"Instr Cluster Get",
352 	[SND_SEQ_EVENT_INSTR_CLUSTER_RESULT]=	"Instr Cluster Result",
353 	[SND_SEQ_EVENT_INSTR_CHANGE]=	"Instr Change",
354 	[SND_SEQ_EVENT_SYSEX]=	"Sysex",
355 	[SND_SEQ_EVENT_BOUNCE]=	"Bounce",
356 	[SND_SEQ_EVENT_USR_VAR0]=	"User Var0",
357 	[SND_SEQ_EVENT_USR_VAR1]=	"User Var1",
358 	[SND_SEQ_EVENT_USR_VAR2]=	"User Var2",
359 	[SND_SEQ_EVENT_USR_VAR3]=	"User Var3",
360 	[SND_SEQ_EVENT_USR_VAR4]=	"User Var4",
361 #if 0
362 	[SND_SEQ_EVENT_IPCSHM]=	"IPC Shm",
363 	[SND_SEQ_EVENT_USR_VARIPC0]=	"User IPC0",
364 	[SND_SEQ_EVENT_USR_VARIPC1]=	"User IPC1",
365 	[SND_SEQ_EVENT_USR_VARIPC2]=	"User IPC2",
366 	[SND_SEQ_EVENT_USR_VARIPC3]=	"User IPC3",
367 	[SND_SEQ_EVENT_USR_VARIPC4]=	"User IPC4",
368 #endif
369 	[SND_SEQ_EVENT_NONE]=	"None",
370 };
371 */
372 
373 int
translate_event(snd_seq_event_t * ev,bristolMidiMsg * msg,int dev)374 translate_event(snd_seq_event_t *ev, bristolMidiMsg *msg, int dev)
375 {
376 #ifdef DEBUG
377 	if ((bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
378 		&& (ev->type != SND_SEQ_EVENT_CLOCK)) /* Very chatty, naturally */
379 	{
380 		char *space = "	 ";
381 
382 		printf("\nEVENT>>> Type = %d, flags = 0x%x", ev->type, ev->flags);
383 
384 		switch (ev->flags & SND_SEQ_TIME_STAMP_MASK) {
385 			case SND_SEQ_TIME_STAMP_TICK:
386 				printf(", time = %d ticks", ev->time.tick);
387 				break;
388 			case SND_SEQ_TIME_STAMP_REAL:
389 				printf(", time = %d.%09d",
390 					(int)ev->time.time.tv_sec,
391 					(int)ev->time.time.tv_nsec);
392 				break;
393 		}
394 
395 		printf("\n%sSource = %d.%d, dest = %d.%d, queue = %d\n",
396 			space,
397 			ev->source.client,
398 			ev->source.port,
399 			ev->dest.client,
400 			ev->dest.port,
401 			ev->queue);
402 	}
403 #endif
404 
405 	msg->command = 0xff;
406 
407 	/*
408 	 * Go look at the event. We are only concerned for now (ns-18/06/02) with
409 	 * midi realtime messages - note on/off, controllers, pressures, pitch.
410 	 */
411 	switch (ev->type) {
412 		case SND_SEQ_EVENT_NOTE:
413 #ifdef DEBUG
414 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
415 				printf(
416 				"; ch=%d, note=%d, velocity=%d, off_velocity=%d, duration=%d\n",
417 					ev->data.note.channel,
418 					ev->data.note.note,
419 					ev->data.note.velocity,
420 					ev->data.note.off_velocity,
421 					ev->data.note.duration);
422 #endif
423 			break;
424 
425 		case SND_SEQ_EVENT_NOTEON:
426 #ifdef DEBUG
427 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
428 				printf("c%i-%02x/%02x/%02x ",
429 					dev,
430 					ev->data.note.channel,
431 					ev->data.note.note,
432 					ev->data.note.velocity);
433 #endif
434 			if (ev->data.note.velocity == 0) {
435 				msg->command = MIDI_NOTE_OFF| ev->data.note.channel;
436 				msg->params.key.velocity = 64;
437 			} else {
438 				msg->command = MIDI_NOTE_ON| ev->data.note.channel;
439 				msg->params.key.velocity = ev->data.note.velocity;
440 			}
441 			msg->channel = ev->data.note.channel;
442 			msg->params.key.key = ev->data.note.note;
443 			msg->sequence = bmidi.dev[dev].sequence++;
444 			msg->params.bristol.msgLen = 3;
445 			break;
446 
447 		case SND_SEQ_EVENT_NOTEOFF:
448 #ifdef DEBUG
449 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
450 				printf("c%i-%02x/%02x/%02x ",
451 					dev,
452 					ev->data.note.channel,
453 					ev->data.note.note,
454 					ev->data.note.velocity);
455 #endif
456 			msg->command = MIDI_NOTE_OFF| ev->data.note.channel;
457 			msg->channel = ev->data.note.channel;
458 			msg->params.key.key = ev->data.note.note,
459 			msg->params.key.velocity = ev->data.note.velocity;
460 			msg->sequence = bmidi.dev[dev].sequence++;
461 			msg->params.bristol.msgLen = 3;
462 			break;
463 
464 		case SND_SEQ_EVENT_KEYPRESS:
465 #ifdef DEBUG
466 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
467 				printf("; ch=%d, note=%d, velocity=%d\n",
468 					ev->data.note.channel,
469 					ev->data.note.note,
470 					ev->data.note.velocity);
471 #endif
472 			msg->command = MIDI_POLY_PRESS| ev->data.note.channel;
473 			msg->channel = ev->data.note.channel;
474 			msg->params.pressure.key = ev->data.note.note,
475 			msg->params.pressure.pressure = ev->data.note.velocity;
476 			msg->params.bristol.msgLen = 3;
477 			break;
478 
479 		case SND_SEQ_EVENT_CONTROLLER:
480 #ifdef DEBUG
481 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
482 				printf("c%i-%02x/%02x/%02x ",
483 					dev,
484 					ev->data.control.channel,
485 					ev->data.control.param,
486 					ev->data.control.value);
487 #endif
488 
489 			/*
490 			 * Hm, we may need to recode these to 7 bit midi values?
491 			 */
492 			msg->command = MIDI_CONTROL| ev->data.note.channel;
493 			msg->channel = ev->data.control.channel;
494 			msg->params.controller.c_id = ev->data.control.param,
495 			msg->params.controller.c_val = ev->data.control.value;
496 			msg->sequence = bmidi.dev[dev].sequence++;
497 			msg->params.bristol.msgLen = 3;
498 
499 			/*
500 			 * We should also stuff the GM-2 table for defined controller
501 			 * numbers.
502 			 */
503 /*			bristolMidiToGM2(msg); */
504 			break;
505 
506 		case SND_SEQ_EVENT_PGMCHANGE:
507 			/*
508 			 * May need to have a registered callback here from GUI.
509 			 */
510 #ifdef DEBUG
511 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
512 				printf("c%i-%02x/%02x ",
513 					dev,
514 					ev->data.control.channel,
515 					ev->data.control.value);
516 #endif
517 
518 			msg->command = MIDI_PROGRAM| ev->data.note.channel;
519 			msg->channel = ev->data.control.channel;
520 			msg->params.program.p_id = ev->data.control.value;
521 			msg->sequence = bmidi.dev[dev].sequence++;
522 			msg->params.bristol.msgLen = 2;
523 
524 			break;
525 
526 		case SND_SEQ_EVENT_CHANPRESS:
527 #ifdef DEBUG
528 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
529 				printf("c%i-%02x/%02x ",
530 					dev,
531 					ev->data.control.channel,
532 					ev->data.control.value);
533 #endif
534 			msg->command = MIDI_CHAN_PRESS;
535 			msg->channel = ev->data.control.channel;
536 			msg->params.channelpress.pressure = ev->data.control.value;
537 			msg->sequence = bmidi.dev[dev].sequence++;
538 			msg->params.bristol.msgLen = 2;
539 			break;
540 
541 		case SND_SEQ_EVENT_PITCHBEND:
542 #ifdef DEBUG
543 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
544 				printf("c%i-%02x/%02x ",
545 					dev,
546 					ev->data.control.channel,
547 					ev->data.control.value);
548 #endif
549 
550 			/*
551 			 * Hm, we may need to recode these to 7 bit midi values?
552 			 */
553 			msg->command = MIDI_PITCHWHEEL| ev->data.note.channel;
554 			msg->channel = ev->data.control.channel;
555 			ev->data.control.value += 8192;
556 			msg->params.pitch.lsb = ev->data.control.value & 0x7f;
557 			msg->params.pitch.msb = ev->data.control.value >> 7;
558 			msg->sequence = bmidi.dev[dev].sequence++;
559 			msg->params.bristol.msgLen = 3;
560 			break;
561 
562 		case SND_SEQ_EVENT_SYSEX:
563 #ifdef DEBUG
564 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
565 			{
566 				unsigned char *sysex =
567 					(unsigned char *) ev + sizeof(snd_seq_event_t);
568 				unsigned int c;
569 
570 				printf("; len=%d [", ev->data.ext.len);
571 
572 				for (c = 0; c < ev->data.ext.len; c++) {
573 					printf("%02x%s",
574 						sysex[c], c < ev->data.ext.len - 1 ? ":" : "");
575 				}
576 				printf("]\n");
577 			}
578 #endif
579 			/*
580 			 * Hm, we should at least see if this is a SLab message?
581 			 */
582 			break;
583 
584 		case SND_SEQ_EVENT_QFRAME:
585 #ifdef DEBUG
586 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
587 				printf("; frame=0x%02x\n", ev->data.control.value);
588 #endif
589 			break;
590 
591 		case SND_SEQ_EVENT_CLOCK:
592 		case SND_SEQ_EVENT_START:
593 		case SND_SEQ_EVENT_CONTINUE:
594 		case SND_SEQ_EVENT_STOP:
595 #ifdef DONT_DEBUG
596 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
597 				printf("; queue = %i\n", ev->data.queue.queue);
598 #endif
599 			break;
600 
601 		case SND_SEQ_EVENT_SENSING:
602 #ifdef DEBUG
603 		if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
604 			printf("bristol does not support active sensing\n");
605 #endif
606 			break;
607 
608 		case SND_SEQ_EVENT_ECHO:
609 #ifdef DEBUG
610 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
611 			{
612 				int i;
613 				printf("; ");
614 				for (i = 0; i < 8; i++) {
615 					printf("%02i%s", ev->data.raw8.d[i], i < 7 ? ":" : "\n");
616 				}
617 			}
618 #endif
619 			break;
620 
621 		case SND_SEQ_EVENT_CLIENT_START:
622 		case SND_SEQ_EVENT_CLIENT_EXIT:
623 		case SND_SEQ_EVENT_CLIENT_CHANGE:
624 #ifdef DEBUG
625 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
626 				printf("; client=%i\n", ev->data.addr.client);
627 #endif
628 			break;
629 
630 		case SND_SEQ_EVENT_PORT_START:
631 		case SND_SEQ_EVENT_PORT_EXIT:
632 		case SND_SEQ_EVENT_PORT_CHANGE:
633 #ifdef DEBUG
634 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
635 				printf("; client=%i, port = %i\n",
636 					ev->data.addr.client, ev->data.addr.port);
637 #endif
638 			break;
639 
640 		case SND_SEQ_EVENT_PORT_SUBSCRIBED:
641 		case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
642 #ifdef DEBUG
643 			if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
644 				printf("; %i:%i -> %i:%i\n",
645 					ev->data.connect.sender.client,
646 					ev->data.connect.sender.port,
647 					ev->data.connect.dest.client,
648 					ev->data.connect.dest.port);
649 #endif
650 			break;
651 
652 		default:
653 			printf("; not implemented\n");
654 	}
655 
656 	switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
657 		case SND_SEQ_EVENT_LENGTH_FIXED:
658 			return sizeof(snd_seq_event_t);
659 		case SND_SEQ_EVENT_LENGTH_VARIABLE:
660 			return sizeof(snd_seq_event_t) + ev->data.ext.len;
661 	}
662 
663 	return 0;
664 }
665 
666 #endif /* ADLIB */
667 #endif /* ADLIB */
668 
669 /*
670  * Note that we should not read on a handle - we should read on a device, and
671  * then forward to all the handles.
672  */
673 int
bristolMidiSeqRead(int dev,bristolMidiMsg * msg)674 bristolMidiSeqRead(int dev, bristolMidiMsg *msg)
675 {
676 #if (BRISTOL_HAS_ALSA == 1)
677 #if (SND_LIB_MAJOR == 1)
678 	snd_seq_event_t *ev;
679 	int res;
680 
681 	if (bmidi.flags & BRISTOL_BMIDI_DEBUG)
682 		printf("bristolMidiSeqRead()\n");
683 
684 	/*
685 	 * Get the message, convert its type into a bristol message. Then see if
686 	 * we have callbacks defined.
687 	 */
688 	while ((res = snd_seq_event_input(bmidi.dev[dev].driver.seq.handle, &ev))
689 		> 0)
690 	{
691 		translate_event(ev, msg,
692 			bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG? dev: 0);
693 
694 		if (bmidi.flags & BRISTOL_BMIDI_DEBUG)
695 			printf("msg->command = %02x\n", msg->command);
696 
697 		if (msg->command != 0xff)
698 		{
699 			msg->params.bristol.from = dev;
700 			/*
701 			 * See if we have callbacks.
702 			 */
703 			checkcallbacks(msg);
704 		}
705 
706 		snd_seq_free_event(ev);
707 	}
708 #endif
709 #endif
710 
711 	return(BRISTOL_MIDI_OK);
712 }
713 
714 /*
715  * Note that we should not read on a handle - we should read on a device, and
716  * then forward to all the handles.
717  */
718 int
bristolMidiSeqKeyEvent(int dev,int op,int ch,int key,int velocity)719 bristolMidiSeqKeyEvent(int dev, int op, int ch, int key, int velocity)
720 {
721 #if (BRISTOL_HAS_ALSA == 1)
722 #if (SND_LIB_MAJOR == 1)
723 	snd_seq_event_t ev;
724 
725 #ifdef DEBUG
726 	if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
727 		printf("bristolMidiSeqKeyEvent(%i, %i, %i, %i)\n",
728 			op, ch, key, velocity);
729 #endif
730 
731 	/*
732 	 * Build seq event, send it.
733 	 */
734 	snd_seq_ev_clear(&ev);
735 	if (op == BRISTOL_EVENT_KEYON)
736 		ev.type = SND_SEQ_EVENT_NOTEON;
737 	else
738 		ev.type = SND_SEQ_EVENT_NOTEOFF;
739 
740 	ev.queue = SND_SEQ_QUEUE_DIRECT;
741 
742 	ev.dest.client = ch;
743 	ev.dest.port = 0;
744 
745 	ev.data.note.channel = 0;
746 	ev.data.note.note = key;
747 	ev.data.note.velocity = velocity;
748 
749 	if (snd_seq_event_output_direct(bmidi.dev[dev].driver.seq.handle, &ev) < 0)
750 	{
751 		printf("SeqSend failed: %p\n", bmidi.dev[dev].driver.seq.handle);
752 		return(BRISTOL_MIDI_DRIVER);
753 	}
754 #endif
755 #endif
756 
757 	return(BRISTOL_MIDI_OK);
758 }
759 
760 /*
761  * Note that we should not read on a handle - we should read on a device, and
762  * then forward to all the handles.
763  */
764 int
bristolMidiSeqPPressureEvent(int dev,int op,int ch,int k,int p)765 bristolMidiSeqPPressureEvent(int dev, int op, int ch, int k, int p)
766 {
767 #if (BRISTOL_HAS_ALSA == 1)
768 #if (SND_LIB_MAJOR == 1)
769 	snd_seq_event_t ev;
770 
771 #ifdef DEBUG
772 	if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
773 		printf("bristolMidiPressureEvent(%i, %i, %i)\n",
774 			op, ch, p);
775 #endif
776 	/*
777 	 * Build seq event, send it.
778 	 */
779 	ev.type = SND_SEQ_EVENT_KEYPRESS;
780 
781 	ev.queue = SND_SEQ_QUEUE_DIRECT;
782 
783 	ev.dest.client = op;
784 	ev.dest.port = 0;
785 
786 	ev.data.control.channel = ch;
787 	ev.data.control.param = k;
788 	ev.data.control.value = p;
789 
790 	if (snd_seq_event_output_direct(bmidi.dev[dev].driver.seq.handle, &ev) < 0)
791 	{
792 		printf("SeqSend failed: %p\n", bmidi.dev[dev].driver.seq.handle);
793 		return(BRISTOL_MIDI_DRIVER);
794 	}
795 #endif
796 #endif
797 
798 	return(BRISTOL_MIDI_OK);
799 }
800 
801 /*
802  * Note that we should not read on a handle - we should read on a device, and
803  * then forward to all the handles.
804  */
805 int
bristolMidiSeqPressureEvent(int dev,int op,int ch,int p)806 bristolMidiSeqPressureEvent(int dev, int op, int ch, int p)
807 {
808 #if (BRISTOL_HAS_ALSA == 1)
809 #if (SND_LIB_MAJOR == 1)
810 	snd_seq_event_t ev;
811 
812 #ifdef DEBUG
813 	if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
814 		printf("bristolMidiPressureEvent(%i, %i, %i)\n",
815 			op, ch, p);
816 #endif
817 	/*
818 	 * Build seq event, send it.
819 	 */
820 	ev.type = SND_SEQ_EVENT_CHANPRESS;
821 
822 	ev.queue = SND_SEQ_QUEUE_DIRECT;
823 
824 	ev.dest.client = op;
825 	ev.dest.port = 0;
826 
827 	ev.data.control.channel = ch;
828 	ev.data.control.value = p;
829 
830 	if (snd_seq_event_output_direct(bmidi.dev[dev].driver.seq.handle, &ev) < 0)
831 	{
832 		printf("SeqSend failed: %p\n", bmidi.dev[dev].driver.seq.handle);
833 		return(BRISTOL_MIDI_DRIVER);
834 	}
835 #endif
836 #endif
837 
838 	return(BRISTOL_MIDI_OK);
839 }
840 
841 /*
842  * Note that we should not read on a handle - we should read on a device, and
843  * then forward to all the handles.
844  */
845 int
bristolMidiSeqCCEvent(int dev,int op,int ch,int CC,int CV)846 bristolMidiSeqCCEvent(int dev, int op, int ch, int CC, int CV)
847 {
848 #if (BRISTOL_HAS_ALSA == 1)
849 #if (SND_LIB_MAJOR == 1)
850 	snd_seq_event_t ev;
851 
852 #ifdef DEBUG
853 	if (bmidi.dev[dev].flags & _BRISTOL_MIDI_DEBUG)
854 		printf("bristolMidiCCKeyEvent(%i, %i, %i, %i)\n",
855 			op, ch, CC, CV);
856 #endif
857 
858 	/*
859 	 * Build seq event, send it.
860 	 */
861 	ev.type = SND_SEQ_EVENT_CONTROLLER;
862 
863 	ev.queue = SND_SEQ_QUEUE_DIRECT;
864 
865 	ev.dest.client = ch;
866 	ev.dest.port = 0;
867 
868 	ev.data.control.channel = 0;
869 	ev.data.control.param = CC;
870 	ev.data.control.value = CV;
871 
872 	if (snd_seq_event_output_direct(bmidi.dev[dev].driver.seq.handle, &ev) < 0)
873 	{
874 		printf("SeqSend failed: %p\n", bmidi.dev[dev].driver.seq.handle);
875 		return(BRISTOL_MIDI_DRIVER);
876 	}
877 #endif
878 #endif
879 
880 	return(BRISTOL_MIDI_OK);
881 }
882 
883