1 /* $OpenBSD: midi.c,v 1.23 2020/01/23 05:27:17 ratchov Exp $ */ 2 /* 3 * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #include "abuf.h" 22 #include "defs.h" 23 #include "dev.h" 24 #include "file.h" 25 #include "midi.h" 26 #include "miofile.h" 27 #include "sysex.h" 28 #include "utils.h" 29 30 int port_open(struct port *); 31 void port_imsg(void *, unsigned char *, int); 32 void port_omsg(void *, unsigned char *, int); 33 void port_fill(void *, int); 34 void port_exit(void *); 35 void port_exitall(struct port *); 36 37 struct midiops port_midiops = { 38 port_imsg, 39 port_omsg, 40 port_fill, 41 port_exit 42 }; 43 44 #define MIDI_NEP 32 45 struct midi midi_ep[MIDI_NEP]; 46 struct port *port_list = NULL; 47 unsigned int midi_portnum = 0; 48 49 struct midithru { 50 unsigned int txmask, rxmask; 51 #define MIDITHRU_NMAX 32 52 } midithru[MIDITHRU_NMAX]; 53 54 /* 55 * length of voice and common messages (status byte included) 56 */ 57 unsigned int voice_len[] = { 3, 3, 3, 3, 2, 2, 3 }; 58 unsigned int common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 }; 59 60 void 61 midi_log(struct midi *ep) 62 { 63 log_puts("midi"); 64 log_putu(ep - midi_ep); 65 } 66 67 void 68 midi_init(void) 69 { 70 } 71 72 void 73 midi_done(void) 74 { 75 } 76 77 struct midi * 78 midi_new(struct midiops *ops, void *arg, int mode) 79 { 80 int i; 81 struct midi *ep; 82 83 for (i = 0, ep = midi_ep;; i++, ep++) { 84 if (i == MIDI_NEP) 85 return NULL; 86 if (ep->ops == NULL) 87 break; 88 } 89 ep->ops = ops; 90 ep->arg = arg; 91 ep->used = 0; 92 ep->len = 0; 93 ep->idx = 0; 94 ep->st = 0; 95 ep->last_st = 0; 96 ep->txmask = 0; 97 ep->self = 1 << i; 98 ep->tickets = 0; 99 ep->mode = mode; 100 101 /* 102 * the output buffer is the client input 103 */ 104 if (ep->mode & MODE_MIDIIN) 105 abuf_init(&ep->obuf, MIDI_BUFSZ); 106 midi_tickets(ep); 107 return ep; 108 } 109 110 void 111 midi_del(struct midi *ep) 112 { 113 int i; 114 struct midi *peer; 115 116 ep->txmask = 0; 117 for (i = 0; i < MIDI_NEP; i++) { 118 peer = midi_ep + i; 119 if (peer->txmask & ep->self) { 120 peer->txmask &= ~ep->self; 121 midi_tickets(peer); 122 } 123 } 124 for (i = 0; i < MIDITHRU_NMAX; i++) { 125 midithru[i].txmask &= ~ep->self; 126 midithru[i].rxmask &= ~ep->self; 127 } 128 ep->ops = NULL; 129 if (ep->mode & MODE_MIDIIN) { 130 abuf_done(&ep->obuf); 131 } 132 } 133 134 /* 135 * connect two midi endpoints 136 */ 137 void 138 midi_link(struct midi *ep, struct midi *peer) 139 { 140 if (ep->mode & MODE_MIDIOUT) { 141 ep->txmask |= peer->self; 142 midi_tickets(ep); 143 } 144 if (ep->mode & MODE_MIDIIN) { 145 #ifdef DEBUG 146 if (ep->obuf.used > 0) { 147 midi_log(ep); 148 log_puts(": linked with non-empty buffer\n"); 149 panic(); 150 } 151 #endif 152 /* ep has empty buffer, so no need to call midi_tickets() */ 153 peer->txmask |= ep->self; 154 } 155 } 156 157 /* 158 * add the midi endpoint in the ``tag'' midi thru box 159 */ 160 void 161 midi_tag(struct midi *ep, unsigned int tag) 162 { 163 struct midi *peer; 164 struct midithru *t = midithru + tag; 165 int i; 166 167 if (ep->mode & MODE_MIDIOUT) { 168 ep->txmask |= t->txmask; 169 midi_tickets(ep); 170 } 171 if (ep->mode & MODE_MIDIIN) { 172 #ifdef DEBUG 173 if (ep->obuf.used > 0) { 174 midi_log(ep); 175 log_puts(": tagged with non-empty buffer\n"); 176 panic(); 177 } 178 #endif 179 for (i = 0; i < MIDI_NEP; i++) { 180 if (!(t->rxmask & (1 << i))) 181 continue; 182 peer = midi_ep + i; 183 peer->txmask |= ep->self; 184 } 185 } 186 if (ep->mode & MODE_MIDIOUT) 187 t->rxmask |= ep->self; 188 if (ep->mode & MODE_MIDIIN) 189 t->txmask |= ep->self; 190 } 191 192 /* 193 * broadcast the given message to other endpoints 194 */ 195 void 196 midi_send(struct midi *iep, unsigned char *msg, int size) 197 { 198 struct midi *oep; 199 int i; 200 201 #ifdef DEBUG 202 if (log_level >= 4) { 203 midi_log(iep); 204 log_puts(": sending:"); 205 for (i = 0; i < size; i++) { 206 log_puts(" "); 207 log_putx(msg[i]); 208 } 209 log_puts("\n"); 210 } 211 #endif 212 for (i = 0; i < MIDI_NEP ; i++) { 213 if ((iep->txmask & (1 << i)) == 0) 214 continue; 215 oep = midi_ep + i; 216 if (msg[0] <= 0x7f) { 217 if (oep->owner != iep) 218 continue; 219 } else if (msg[0] <= 0xf7) 220 oep->owner = iep; 221 #ifdef DEBUG 222 if (log_level >= 4) { 223 midi_log(iep); 224 log_puts(" -> "); 225 midi_log(oep); 226 log_puts("\n"); 227 } 228 #endif 229 oep->ops->omsg(oep->arg, msg, size); 230 } 231 } 232 233 /* 234 * determine if we have gained more input tickets, and if so call the 235 * fill() call-back to notify the i/o layer that it can send more data 236 */ 237 void 238 midi_tickets(struct midi *iep) 239 { 240 int i, tickets, avail, maxavail; 241 struct midi *oep; 242 243 /* 244 * don't request iep->ops->fill() too often as it generates 245 * useless network traffic: wait until we reach half of the 246 * max tickets count. As in the worst case (see comment below) 247 * one ticket may consume two bytes, the max ticket count is 248 * BUFSZ / 2 and halt of it is simply BUFSZ / 4. 249 */ 250 if (iep->tickets >= MIDI_BUFSZ / 4) 251 return; 252 253 maxavail = MIDI_BUFSZ; 254 for (i = 0; i < MIDI_NEP ; i++) { 255 if ((iep->txmask & (1 << i)) == 0) 256 continue; 257 oep = midi_ep + i; 258 avail = oep->obuf.len - oep->obuf.used; 259 if (maxavail > avail) 260 maxavail = avail; 261 } 262 263 /* 264 * in the worst case output message is twice the 265 * input message (2-byte messages with running status) 266 */ 267 tickets = maxavail / 2 - iep->tickets; 268 if (tickets > 0) { 269 iep->tickets += tickets; 270 iep->ops->fill(iep->arg, tickets); 271 } 272 } 273 274 /* 275 * recalculate tickets of endpoints sending data to this one 276 */ 277 void 278 midi_fill(struct midi *oep) 279 { 280 int i; 281 struct midi *iep; 282 283 for (i = 0; i < MIDI_NEP; i++) { 284 iep = midi_ep + i; 285 if (iep->txmask & oep->self) 286 midi_tickets(iep); 287 } 288 } 289 290 /* 291 * parse then give data chunk, and calling imsg() for each message 292 */ 293 void 294 midi_in(struct midi *iep, unsigned char *idata, int icount) 295 { 296 int i; 297 unsigned char c; 298 299 for (i = 0; i < icount; i++) { 300 c = *idata++; 301 if (c >= 0xf8) { 302 if (c != MIDI_ACK) 303 iep->ops->imsg(iep->arg, &c, 1); 304 } else if (c == SYSEX_END) { 305 if (iep->st == SYSEX_START) { 306 iep->msg[iep->idx++] = c; 307 iep->ops->imsg(iep->arg, iep->msg, iep->idx); 308 } 309 310 /* 311 * There are bogus MIDI sources that keep 312 * state across sysex; Linux virmidi ports fed 313 * by the sequencer is an example. We 314 * workaround this by saving the current 315 * status and restoring it at the end of the 316 * sysex. 317 */ 318 iep->st = iep->last_st; 319 if (iep->st) 320 iep->len = voice_len[(iep->st >> 4) & 7]; 321 iep->idx = 0; 322 } else if (c >= 0xf0) { 323 iep->msg[0] = c; 324 iep->len = common_len[c & 7]; 325 iep->st = c; 326 iep->idx = 1; 327 } else if (c >= 0x80) { 328 iep->msg[0] = c; 329 iep->len = voice_len[(c >> 4) & 7]; 330 iep->last_st = iep->st = c; 331 iep->idx = 1; 332 } else if (iep->st) { 333 if (iep->idx == 0 && iep->st != SYSEX_START) 334 iep->msg[iep->idx++] = iep->st; 335 iep->msg[iep->idx++] = c; 336 if (iep->idx == iep->len) { 337 iep->ops->imsg(iep->arg, iep->msg, iep->idx); 338 if (iep->st >= 0xf0) 339 iep->st = 0; 340 iep->idx = 0; 341 } else if (iep->idx == MIDI_MSGMAX) { 342 /* sysex continued */ 343 iep->ops->imsg(iep->arg, iep->msg, iep->idx); 344 iep->idx = 0; 345 } 346 } 347 } 348 iep->tickets -= icount; 349 if (iep->tickets < 0) 350 iep->tickets = 0; 351 midi_tickets(iep); 352 } 353 354 /* 355 * store the given message in the output buffer 356 */ 357 void 358 midi_out(struct midi *oep, unsigned char *idata, int icount) 359 { 360 unsigned char *odata; 361 int ocount; 362 #ifdef DEBUG 363 int i; 364 #endif 365 366 while (icount > 0) { 367 if (oep->obuf.used == oep->obuf.len) { 368 #ifdef DEBUG 369 if (log_level >= 2) { 370 midi_log(oep); 371 log_puts(": too slow, discarding "); 372 log_putu(oep->obuf.used); 373 log_puts(" bytes\n"); 374 } 375 #endif 376 abuf_rdiscard(&oep->obuf, oep->obuf.used); 377 oep->owner = NULL; 378 return; 379 } 380 odata = abuf_wgetblk(&oep->obuf, &ocount); 381 if (ocount > icount) 382 ocount = icount; 383 memcpy(odata, idata, ocount); 384 #ifdef DEBUG 385 if (log_level >= 4) { 386 midi_log(oep); 387 log_puts(": out: "); 388 for (i = 0; i < ocount; i++) { 389 log_puts(" "); 390 log_putx(odata[i]); 391 } 392 log_puts("\n"); 393 } 394 #endif 395 abuf_wcommit(&oep->obuf, ocount); 396 icount -= ocount; 397 idata += ocount; 398 } 399 } 400 401 void 402 port_log(struct port *p) 403 { 404 midi_log(p->midi); 405 } 406 407 void 408 port_imsg(void *arg, unsigned char *msg, int size) 409 { 410 struct port *p = arg; 411 412 midi_send(p->midi, msg, size); 413 } 414 415 416 void 417 port_omsg(void *arg, unsigned char *msg, int size) 418 { 419 struct port *p = arg; 420 421 midi_out(p->midi, msg, size); 422 } 423 424 void 425 port_fill(void *arg, int count) 426 { 427 /* no flow control */ 428 } 429 430 void 431 port_exit(void *arg) 432 { 433 #ifdef DEBUG 434 struct port *p = arg; 435 436 if (log_level >= 3) { 437 port_log(p); 438 log_puts(": port exit\n"); 439 panic(); 440 } 441 #endif 442 } 443 444 /* 445 * create a new midi port 446 */ 447 struct port * 448 port_new(char *path, unsigned int mode, int hold) 449 { 450 struct port *c; 451 452 c = xmalloc(sizeof(struct port)); 453 c->path_list = NULL; 454 namelist_add(&c->path_list, path); 455 c->state = PORT_CFG; 456 c->hold = hold; 457 c->midi = midi_new(&port_midiops, c, mode); 458 c->num = midi_portnum++; 459 c->next = port_list; 460 port_list = c; 461 return c; 462 } 463 464 /* 465 * destroy the given midi port 466 */ 467 void 468 port_del(struct port *c) 469 { 470 struct port **p; 471 472 if (c->state != PORT_CFG) 473 port_close(c); 474 midi_del(c->midi); 475 for (p = &port_list; *p != c; p = &(*p)->next) { 476 #ifdef DEBUG 477 if (*p == NULL) { 478 log_puts("port to delete not on list\n"); 479 panic(); 480 } 481 #endif 482 } 483 *p = c->next; 484 namelist_clear(&c->path_list); 485 xfree(c); 486 } 487 488 int 489 port_ref(struct port *c) 490 { 491 #ifdef DEBUG 492 if (log_level >= 3) { 493 port_log(c); 494 log_puts(": port requested\n"); 495 } 496 #endif 497 if (c->state == PORT_CFG && !port_open(c)) 498 return 0; 499 return 1; 500 } 501 502 void 503 port_unref(struct port *c) 504 { 505 int i, rxmask; 506 507 #ifdef DEBUG 508 if (log_level >= 3) { 509 port_log(c); 510 log_puts(": port released\n"); 511 } 512 #endif 513 for (rxmask = 0, i = 0; i < MIDI_NEP; i++) 514 rxmask |= midi_ep[i].txmask; 515 if ((rxmask & c->midi->self) == 0 && c->midi->txmask == 0 && 516 c->state == PORT_INIT && !c->hold) 517 port_drain(c); 518 } 519 520 struct port * 521 port_bynum(int num) 522 { 523 struct port *p; 524 525 for (p = port_list; p != NULL; p = p->next) { 526 if (p->num == num) 527 return p; 528 } 529 return NULL; 530 } 531 532 int 533 port_open(struct port *c) 534 { 535 if (!port_mio_open(c)) { 536 if (log_level >= 1) { 537 port_log(c); 538 log_puts(": failed to open midi port\n"); 539 } 540 return 0; 541 } 542 c->state = PORT_INIT; 543 return 1; 544 } 545 546 void 547 port_exitall(struct port *c) 548 { 549 int i; 550 struct midi *ep; 551 552 for (i = 0; i < MIDI_NEP; i++) { 553 ep = midi_ep + i; 554 if ((ep->txmask & c->midi->self) || 555 (c->midi->txmask & ep->self)) 556 ep->ops->exit(ep->arg); 557 } 558 } 559 560 int 561 port_close(struct port *c) 562 { 563 #ifdef DEBUG 564 if (c->state == PORT_CFG) { 565 port_log(c); 566 log_puts(": can't close port (not opened)\n"); 567 panic(); 568 } 569 #endif 570 c->state = PORT_CFG; 571 port_mio_close(c); 572 573 port_exitall(c); 574 return 1; 575 } 576 577 void 578 port_drain(struct port *c) 579 { 580 struct midi *ep = c->midi; 581 582 if (!(ep->mode & MODE_MIDIOUT) || ep->obuf.used == 0) 583 port_close(c); 584 else { 585 c->state = PORT_DRAIN; 586 #ifdef DEBUG 587 if (log_level >= 3) { 588 port_log(c); 589 log_puts(": draining\n"); 590 } 591 #endif 592 } 593 } 594 595 int 596 port_init(struct port *c) 597 { 598 if (c->hold) 599 return port_open(c); 600 return 1; 601 } 602 603 void 604 port_done(struct port *c) 605 { 606 if (c->state == PORT_INIT) 607 port_drain(c); 608 } 609 610 int 611 port_reopen(struct port *p) 612 { 613 if (p->state == PORT_CFG) 614 return 1; 615 616 if (!port_mio_reopen(p)) 617 return 0; 618 619 return 1; 620 } 621