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