1 /* $OpenBSD: dev.c,v 1.77 2020/07/19 11:13:35 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 <string.h> 19 20 #include "abuf.h" 21 #include "defs.h" 22 #include "dev.h" 23 #include "dsp.h" 24 #include "siofile.h" 25 #include "midi.h" 26 #include "opt.h" 27 #include "sysex.h" 28 #include "utils.h" 29 30 void zomb_onmove(void *); 31 void zomb_onvol(void *); 32 void zomb_fill(void *); 33 void zomb_flush(void *); 34 void zomb_eof(void *); 35 void zomb_exit(void *); 36 37 void dev_log(struct dev *); 38 void dev_midi_qfr(struct dev *, int); 39 void dev_midi_full(struct dev *); 40 void dev_midi_vol(struct dev *, struct slot *); 41 void dev_midi_master(struct dev *); 42 void dev_midi_slotdesc(struct dev *, struct slot *); 43 void dev_midi_dump(struct dev *); 44 void dev_midi_imsg(void *, unsigned char *, int); 45 void dev_midi_omsg(void *, unsigned char *, int); 46 void dev_midi_fill(void *, int); 47 void dev_midi_exit(void *); 48 49 void dev_mix_badd(struct dev *, struct slot *); 50 void dev_mix_adjvol(struct dev *); 51 void dev_sub_bcopy(struct dev *, struct slot *); 52 53 void dev_onmove(struct dev *, int); 54 void dev_master(struct dev *, unsigned int); 55 void dev_cycle(struct dev *); 56 int dev_getpos(struct dev *); 57 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, 58 unsigned int, unsigned int, unsigned int, unsigned int); 59 void dev_adjpar(struct dev *, int, int, int); 60 int dev_allocbufs(struct dev *); 61 int dev_open(struct dev *); 62 void dev_freebufs(struct dev *); 63 void dev_close(struct dev *); 64 int dev_ref(struct dev *); 65 void dev_unref(struct dev *); 66 int dev_init(struct dev *); 67 void dev_done(struct dev *); 68 struct dev *dev_bynum(int); 69 void dev_del(struct dev *); 70 void dev_setalt(struct dev *, unsigned int); 71 unsigned int dev_roundof(struct dev *, unsigned int); 72 void dev_wakeup(struct dev *); 73 void dev_sync_attach(struct dev *); 74 void dev_mmcstart(struct dev *); 75 void dev_mmcstop(struct dev *); 76 void dev_mmcloc(struct dev *, unsigned int); 77 78 void slot_ctlname(struct slot *, char *, size_t); 79 void slot_log(struct slot *); 80 void slot_del(struct slot *); 81 void slot_setvol(struct slot *, unsigned int); 82 void slot_attach(struct slot *); 83 void slot_ready(struct slot *); 84 void slot_allocbufs(struct slot *); 85 void slot_freebufs(struct slot *); 86 void slot_initconv(struct slot *); 87 void slot_start(struct slot *); 88 void slot_detach(struct slot *); 89 void slot_stop(struct slot *); 90 void slot_skip_update(struct slot *); 91 void slot_write(struct slot *); 92 void slot_read(struct slot *); 93 int slot_skip(struct slot *); 94 95 void ctl_node_log(struct ctl_node *); 96 void ctl_log(struct ctl *); 97 98 struct midiops dev_midiops = { 99 dev_midi_imsg, 100 dev_midi_omsg, 101 dev_midi_fill, 102 dev_midi_exit 103 }; 104 105 struct slotops zomb_slotops = { 106 zomb_onmove, 107 zomb_onvol, 108 zomb_fill, 109 zomb_flush, 110 zomb_eof, 111 zomb_exit 112 }; 113 114 struct dev *dev_list = NULL; 115 unsigned int dev_sndnum = 0; 116 117 void 118 dev_log(struct dev *d) 119 { 120 #ifdef DEBUG 121 static char *pstates[] = { 122 "cfg", "ini", "run" 123 }; 124 #endif 125 log_puts("snd"); 126 log_putu(d->num); 127 #ifdef DEBUG 128 if (log_level >= 3) { 129 log_puts(" pst="); 130 log_puts(pstates[d->pstate]); 131 } 132 #endif 133 } 134 135 void 136 slot_ctlname(struct slot *s, char *name, size_t size) 137 { 138 snprintf(name, size, "%s%u", s->name, s->unit); 139 } 140 141 void 142 slot_log(struct slot *s) 143 { 144 char name[CTL_NAMEMAX]; 145 #ifdef DEBUG 146 static char *pstates[] = { 147 "ini", "sta", "rdy", "run", "stp", "mid" 148 }; 149 #endif 150 slot_ctlname(s, name, CTL_NAMEMAX); 151 log_puts(name); 152 #ifdef DEBUG 153 if (log_level >= 3) { 154 log_puts(" vol="); 155 log_putu(s->vol); 156 if (s->ops) { 157 log_puts(",pst="); 158 log_puts(pstates[s->pstate]); 159 } 160 } 161 #endif 162 } 163 164 void 165 zomb_onmove(void *arg) 166 { 167 } 168 169 void 170 zomb_onvol(void *arg) 171 { 172 } 173 174 void 175 zomb_fill(void *arg) 176 { 177 } 178 179 void 180 zomb_flush(void *arg) 181 { 182 } 183 184 void 185 zomb_eof(void *arg) 186 { 187 struct slot *s = arg; 188 189 #ifdef DEBUG 190 if (log_level >= 3) { 191 slot_log(s); 192 log_puts(": zomb_eof\n"); 193 } 194 #endif 195 s->ops = NULL; 196 } 197 198 void 199 zomb_exit(void *arg) 200 { 201 #ifdef DEBUG 202 struct slot *s = arg; 203 204 if (log_level >= 3) { 205 slot_log(s); 206 log_puts(": zomb_exit\n"); 207 } 208 #endif 209 } 210 211 /* 212 * send a quarter frame MTC message 213 */ 214 void 215 dev_midi_qfr(struct dev *d, int delta) 216 { 217 unsigned char buf[2]; 218 unsigned int data; 219 int qfrlen; 220 221 d->mtc.delta += delta * MTC_SEC; 222 qfrlen = d->rate * (MTC_SEC / (4 * d->mtc.fps)); 223 while (d->mtc.delta >= qfrlen) { 224 switch (d->mtc.qfr) { 225 case 0: 226 data = d->mtc.fr & 0xf; 227 break; 228 case 1: 229 data = d->mtc.fr >> 4; 230 break; 231 case 2: 232 data = d->mtc.sec & 0xf; 233 break; 234 case 3: 235 data = d->mtc.sec >> 4; 236 break; 237 case 4: 238 data = d->mtc.min & 0xf; 239 break; 240 case 5: 241 data = d->mtc.min >> 4; 242 break; 243 case 6: 244 data = d->mtc.hr & 0xf; 245 break; 246 case 7: 247 data = (d->mtc.hr >> 4) | (d->mtc.fps_id << 1); 248 /* 249 * tick messages are sent 2 frames ahead 250 */ 251 d->mtc.fr += 2; 252 if (d->mtc.fr < d->mtc.fps) 253 break; 254 d->mtc.fr -= d->mtc.fps; 255 d->mtc.sec++; 256 if (d->mtc.sec < 60) 257 break; 258 d->mtc.sec = 0; 259 d->mtc.min++; 260 if (d->mtc.min < 60) 261 break; 262 d->mtc.min = 0; 263 d->mtc.hr++; 264 if (d->mtc.hr < 24) 265 break; 266 d->mtc.hr = 0; 267 break; 268 default: 269 /* NOTREACHED */ 270 data = 0; 271 } 272 buf[0] = 0xf1; 273 buf[1] = (d->mtc.qfr << 4) | data; 274 d->mtc.qfr++; 275 d->mtc.qfr &= 7; 276 midi_send(d->midi, buf, 2); 277 d->mtc.delta -= qfrlen; 278 } 279 } 280 281 /* 282 * send a full frame MTC message 283 */ 284 void 285 dev_midi_full(struct dev *d) 286 { 287 struct sysex x; 288 unsigned int fps; 289 290 d->mtc.delta = MTC_SEC * dev_getpos(d); 291 if (d->rate % (30 * 4 * d->round) == 0) { 292 d->mtc.fps_id = MTC_FPS_30; 293 d->mtc.fps = 30; 294 } else if (d->rate % (25 * 4 * d->round) == 0) { 295 d->mtc.fps_id = MTC_FPS_25; 296 d->mtc.fps = 25; 297 } else { 298 d->mtc.fps_id = MTC_FPS_24; 299 d->mtc.fps = 24; 300 } 301 #ifdef DEBUG 302 if (log_level >= 3) { 303 dev_log(d); 304 log_puts(": mtc full frame at "); 305 log_puti(d->mtc.delta); 306 log_puts(", "); 307 log_puti(d->mtc.fps); 308 log_puts(" fps\n"); 309 } 310 #endif 311 fps = d->mtc.fps; 312 d->mtc.hr = (d->mtc.origin / (MTC_SEC * 3600)) % 24; 313 d->mtc.min = (d->mtc.origin / (MTC_SEC * 60)) % 60; 314 d->mtc.sec = (d->mtc.origin / (MTC_SEC)) % 60; 315 d->mtc.fr = (d->mtc.origin / (MTC_SEC / fps)) % fps; 316 317 x.start = SYSEX_START; 318 x.type = SYSEX_TYPE_RT; 319 x.dev = SYSEX_DEV_ANY; 320 x.id0 = SYSEX_MTC; 321 x.id1 = SYSEX_MTC_FULL; 322 x.u.full.hr = d->mtc.hr | (d->mtc.fps_id << 5); 323 x.u.full.min = d->mtc.min; 324 x.u.full.sec = d->mtc.sec; 325 x.u.full.fr = d->mtc.fr; 326 x.u.full.end = SYSEX_END; 327 d->mtc.qfr = 0; 328 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full)); 329 } 330 331 /* 332 * send a volume change MIDI message 333 */ 334 void 335 dev_midi_vol(struct dev *d, struct slot *s) 336 { 337 unsigned char msg[3]; 338 339 msg[0] = MIDI_CTL | (s - d->slot); 340 msg[1] = MIDI_CTL_VOL; 341 msg[2] = s->vol; 342 midi_send(d->midi, msg, 3); 343 } 344 345 /* 346 * send a master volume MIDI message 347 */ 348 void 349 dev_midi_master(struct dev *d) 350 { 351 struct ctl *c; 352 unsigned int master, v; 353 struct sysex x; 354 355 if (d->master_enabled) 356 master = d->master; 357 else { 358 master = 0; 359 for (c = d->ctl_list; c != NULL; c = c->next) { 360 if (c->type != CTL_NUM || 361 strcmp(c->group, "") != 0 || 362 strcmp(c->node0.name, "output") != 0 || 363 strcmp(c->func, "level") != 0) 364 continue; 365 v = (c->curval * 127 + c->maxval / 2) / c->maxval; 366 if (master < v) 367 master = v; 368 } 369 } 370 371 memset(&x, 0, sizeof(struct sysex)); 372 x.start = SYSEX_START; 373 x.type = SYSEX_TYPE_RT; 374 x.dev = SYSEX_DEV_ANY; 375 x.id0 = SYSEX_CONTROL; 376 x.id1 = SYSEX_MASTER; 377 x.u.master.fine = 0; 378 x.u.master.coarse = master; 379 x.u.master.end = SYSEX_END; 380 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master)); 381 } 382 383 /* 384 * send a sndiod-specific slot description MIDI message 385 */ 386 void 387 dev_midi_slotdesc(struct dev *d, struct slot *s) 388 { 389 struct sysex x; 390 391 memset(&x, 0, sizeof(struct sysex)); 392 x.start = SYSEX_START; 393 x.type = SYSEX_TYPE_EDU; 394 x.dev = SYSEX_DEV_ANY; 395 x.id0 = SYSEX_AUCAT; 396 x.id1 = SYSEX_AUCAT_SLOTDESC; 397 if (*s->name != '\0') 398 slot_ctlname(s, (char *)x.u.slotdesc.name, SYSEX_NAMELEN); 399 x.u.slotdesc.chan = s - d->slot; 400 x.u.slotdesc.end = SYSEX_END; 401 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc)); 402 } 403 404 void 405 dev_midi_dump(struct dev *d) 406 { 407 struct sysex x; 408 struct slot *s; 409 int i; 410 411 dev_midi_master(d); 412 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 413 dev_midi_slotdesc(d, s); 414 dev_midi_vol(d, s); 415 } 416 x.start = SYSEX_START; 417 x.type = SYSEX_TYPE_EDU; 418 x.dev = SYSEX_DEV_ANY; 419 x.id0 = SYSEX_AUCAT; 420 x.id1 = SYSEX_AUCAT_DUMPEND; 421 x.u.dumpend.end = SYSEX_END; 422 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend)); 423 } 424 425 void 426 dev_midi_imsg(void *arg, unsigned char *msg, int len) 427 { 428 #ifdef DEBUG 429 struct dev *d = arg; 430 431 dev_log(d); 432 log_puts(": can't receive midi messages\n"); 433 panic(); 434 #endif 435 } 436 437 void 438 dev_midi_omsg(void *arg, unsigned char *msg, int len) 439 { 440 struct dev *d = arg; 441 struct sysex *x; 442 unsigned int fps, chan; 443 444 if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) { 445 chan = msg[0] & MIDI_CHANMASK; 446 if (chan >= DEV_NSLOT) 447 return; 448 slot_setvol(d->slot + chan, msg[2]); 449 dev_onval(d, CTLADDR_SLOT_LEVEL(chan), msg[2]); 450 return; 451 } 452 x = (struct sysex *)msg; 453 if (x->start != SYSEX_START) 454 return; 455 if (len < SYSEX_SIZE(empty)) 456 return; 457 switch (x->type) { 458 case SYSEX_TYPE_RT: 459 if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) { 460 if (len == SYSEX_SIZE(master)) { 461 dev_master(d, x->u.master.coarse); 462 if (d->master_enabled) { 463 dev_onval(d, CTLADDR_MASTER, 464 x->u.master.coarse); 465 } 466 } 467 return; 468 } 469 if (x->id0 != SYSEX_MMC) 470 return; 471 switch (x->id1) { 472 case SYSEX_MMC_STOP: 473 if (len != SYSEX_SIZE(stop)) 474 return; 475 if (log_level >= 2) { 476 dev_log(d); 477 log_puts(": mmc stop\n"); 478 } 479 dev_mmcstop(d); 480 break; 481 case SYSEX_MMC_START: 482 if (len != SYSEX_SIZE(start)) 483 return; 484 if (log_level >= 2) { 485 dev_log(d); 486 log_puts(": mmc start\n"); 487 } 488 dev_mmcstart(d); 489 break; 490 case SYSEX_MMC_LOC: 491 if (len != SYSEX_SIZE(loc) || 492 x->u.loc.len != SYSEX_MMC_LOC_LEN || 493 x->u.loc.cmd != SYSEX_MMC_LOC_CMD) 494 return; 495 switch (x->u.loc.hr >> 5) { 496 case MTC_FPS_24: 497 fps = 24; 498 break; 499 case MTC_FPS_25: 500 fps = 25; 501 break; 502 case MTC_FPS_30: 503 fps = 30; 504 break; 505 default: 506 dev_mmcstop(d); 507 return; 508 } 509 dev_mmcloc(d, 510 (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC + 511 x->u.loc.min * 60 * MTC_SEC + 512 x->u.loc.sec * MTC_SEC + 513 x->u.loc.fr * (MTC_SEC / fps)); 514 break; 515 } 516 break; 517 case SYSEX_TYPE_EDU: 518 if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ) 519 return; 520 if (len != SYSEX_SIZE(dumpreq)) 521 return; 522 dev_midi_dump(d); 523 break; 524 } 525 } 526 527 void 528 dev_midi_fill(void *arg, int count) 529 { 530 /* nothing to do */ 531 } 532 533 void 534 dev_midi_exit(void *arg) 535 { 536 struct dev *d = arg; 537 538 if (log_level >= 1) { 539 dev_log(d); 540 log_puts(": midi end point died\n"); 541 } 542 if (d->pstate != DEV_CFG) 543 dev_close(d); 544 } 545 546 int 547 slot_skip(struct slot *s) 548 { 549 unsigned char *data = (unsigned char *)0xdeadbeef; /* please gcc */ 550 int max, count; 551 552 max = s->skip; 553 while (s->skip > 0) { 554 if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) { 555 data = abuf_wgetblk(&s->sub.buf, &count); 556 if (count < s->round * s->sub.bpf) 557 break; 558 } 559 if (s->mode & MODE_PLAY) { 560 if (s->mix.buf.used < s->round * s->mix.bpf) 561 break; 562 } 563 #ifdef DEBUG 564 if (log_level >= 4) { 565 slot_log(s); 566 log_puts(": skipped a cycle\n"); 567 } 568 #endif 569 if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) { 570 if (s->sub.encbuf) 571 enc_sil_do(&s->sub.enc, data, s->round); 572 else 573 memset(data, 0, s->round * s->sub.bpf); 574 abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf); 575 } 576 if (s->mode & MODE_PLAY) { 577 abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); 578 } 579 s->skip--; 580 } 581 return max - s->skip; 582 } 583 584 /* 585 * Mix the slot input block over the output block 586 */ 587 void 588 dev_mix_badd(struct dev *d, struct slot *s) 589 { 590 adata_t *idata, *odata, *in; 591 int icount, i, offs, vol, nch; 592 593 odata = DEV_PBUF(d); 594 idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount); 595 #ifdef DEBUG 596 if (icount < s->round * s->mix.bpf) { 597 slot_log(s); 598 log_puts(": not enough data to mix ("); 599 log_putu(icount); 600 log_puts("bytes)\n"); 601 panic(); 602 } 603 #endif 604 605 /* 606 * Apply the following processing chain: 607 * 608 * dec -> resamp-> cmap 609 * 610 * where the first two are optional. 611 */ 612 613 in = idata; 614 615 if (s->mix.decbuf) { 616 dec_do(&s->mix.dec, (void *)in, s->mix.decbuf, s->round); 617 in = s->mix.decbuf; 618 } 619 620 if (s->mix.resampbuf) { 621 resamp_do(&s->mix.resamp, in, s->mix.resampbuf, s->round); 622 in = s->mix.resampbuf; 623 } 624 625 nch = s->mix.cmap.nch; 626 vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join; 627 cmap_add(&s->mix.cmap, in, odata, vol, d->round); 628 629 offs = 0; 630 for (i = s->mix.join - 1; i > 0; i--) { 631 offs += nch; 632 cmap_add(&s->mix.cmap, in + offs, odata, vol, d->round); 633 } 634 635 offs = 0; 636 for (i = s->mix.expand - 1; i > 0; i--) { 637 offs += nch; 638 cmap_add(&s->mix.cmap, in, odata + offs, vol, d->round); 639 } 640 641 abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); 642 } 643 644 /* 645 * Normalize input levels. 646 */ 647 void 648 dev_mix_adjvol(struct dev *d) 649 { 650 unsigned int n; 651 struct slot *i, *j; 652 int jcmax, icmax, weight; 653 654 for (i = d->slot_list; i != NULL; i = i->next) { 655 if (!(i->mode & MODE_PLAY)) 656 continue; 657 icmax = i->opt->pmin + i->mix.nch - 1; 658 weight = ADATA_UNIT; 659 if (d->autovol) { 660 /* 661 * count the number of inputs that have 662 * overlapping channel sets 663 */ 664 n = 0; 665 for (j = d->slot_list; j != NULL; j = j->next) { 666 if (!(j->mode & MODE_PLAY)) 667 continue; 668 jcmax = j->opt->pmin + j->mix.nch - 1; 669 if (i->opt->pmin <= jcmax && 670 icmax >= j->opt->pmin) 671 n++; 672 } 673 weight /= n; 674 } 675 if (weight > i->opt->maxweight) 676 weight = i->opt->maxweight; 677 i->mix.weight = d->master_enabled ? 678 ADATA_MUL(weight, MIDI_TO_ADATA(d->master)) : weight; 679 #ifdef DEBUG 680 if (log_level >= 3) { 681 slot_log(i); 682 log_puts(": set weight: "); 683 log_puti(i->mix.weight); 684 log_puts("/"); 685 log_puti(i->opt->maxweight); 686 log_puts("\n"); 687 } 688 #endif 689 } 690 } 691 692 /* 693 * Copy data from slot to device 694 */ 695 void 696 dev_sub_bcopy(struct dev *d, struct slot *s) 697 { 698 adata_t *idata, *enc_out, *resamp_out, *cmap_out; 699 void *odata; 700 int ocount, moffs; 701 702 int i, vol, offs, nch; 703 704 705 if (s->mode & MODE_MON) { 706 moffs = d->poffs + d->round; 707 if (moffs == d->psize) 708 moffs = 0; 709 idata = d->pbuf + moffs * d->pchan; 710 } else 711 idata = d->rbuf; 712 odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount); 713 #ifdef DEBUG 714 if (ocount < s->round * s->sub.bpf) { 715 log_puts("dev_sub_bcopy: not enough space\n"); 716 panic(); 717 } 718 #endif 719 720 /* 721 * Apply the following processing chain: 722 * 723 * cmap -> resamp -> enc 724 * 725 * where the last two are optional. 726 */ 727 728 enc_out = odata; 729 resamp_out = s->sub.encbuf ? s->sub.encbuf : enc_out; 730 cmap_out = s->sub.resampbuf ? s->sub.resampbuf : resamp_out; 731 732 nch = s->sub.cmap.nch; 733 vol = ADATA_UNIT / s->sub.join; 734 cmap_copy(&s->sub.cmap, idata, cmap_out, vol, d->round); 735 736 offs = 0; 737 for (i = s->sub.join - 1; i > 0; i--) { 738 offs += nch; 739 cmap_add(&s->sub.cmap, idata + offs, cmap_out, vol, d->round); 740 } 741 742 offs = 0; 743 for (i = s->sub.expand - 1; i > 0; i--) { 744 offs += nch; 745 cmap_copy(&s->sub.cmap, idata, cmap_out + offs, vol, d->round); 746 } 747 748 if (s->sub.resampbuf) { 749 resamp_do(&s->sub.resamp, 750 s->sub.resampbuf, resamp_out, d->round); 751 } 752 753 if (s->sub.encbuf) 754 enc_do(&s->sub.enc, s->sub.encbuf, (void *)enc_out, s->round); 755 756 abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf); 757 } 758 759 /* 760 * run a one block cycle: consume one recorded block from 761 * rbuf and produce one play block in pbuf 762 */ 763 void 764 dev_cycle(struct dev *d) 765 { 766 struct slot *s, **ps; 767 unsigned char *base; 768 int nsamp; 769 770 /* 771 * check if the device is actually used. If it isn't, 772 * then close it 773 */ 774 if (d->slot_list == NULL && d->tstate != MMC_RUN) { 775 if (log_level >= 2) { 776 dev_log(d); 777 log_puts(": device stopped\n"); 778 } 779 dev_sio_stop(d); 780 d->pstate = DEV_INIT; 781 if (d->refcnt == 0) 782 dev_close(d); 783 return; 784 } 785 786 if (d->prime > 0) { 787 #ifdef DEBUG 788 if (log_level >= 4) { 789 dev_log(d); 790 log_puts(": empty cycle, prime = "); 791 log_putu(d->prime); 792 log_puts("\n"); 793 } 794 #endif 795 base = (unsigned char *)DEV_PBUF(d); 796 nsamp = d->round * d->pchan; 797 memset(base, 0, nsamp * sizeof(adata_t)); 798 if (d->encbuf) { 799 enc_do(&d->enc, (unsigned char *)DEV_PBUF(d), 800 d->encbuf, d->round); 801 } 802 d->prime -= d->round; 803 return; 804 } 805 806 d->delta -= d->round; 807 #ifdef DEBUG 808 if (log_level >= 4) { 809 dev_log(d); 810 log_puts(": full cycle: delta = "); 811 log_puti(d->delta); 812 if (d->mode & MODE_PLAY) { 813 log_puts(", poffs = "); 814 log_puti(d->poffs); 815 } 816 log_puts("\n"); 817 } 818 #endif 819 if (d->mode & MODE_PLAY) { 820 base = (unsigned char *)DEV_PBUF(d); 821 nsamp = d->round * d->pchan; 822 memset(base, 0, nsamp * sizeof(adata_t)); 823 } 824 if ((d->mode & MODE_REC) && d->decbuf) 825 dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round); 826 ps = &d->slot_list; 827 while ((s = *ps) != NULL) { 828 #ifdef DEBUG 829 if (log_level >= 4) { 830 slot_log(s); 831 log_puts(": running"); 832 log_puts(", skip = "); 833 log_puti(s->skip); 834 log_puts("\n"); 835 } 836 #endif 837 /* 838 * skip cycles for XRUN_SYNC correction 839 */ 840 slot_skip(s); 841 if (s->skip < 0) { 842 s->skip++; 843 ps = &s->next; 844 continue; 845 } 846 847 #ifdef DEBUG 848 if (s->pstate == SLOT_STOP && !(s->mode & MODE_PLAY)) { 849 slot_log(s); 850 log_puts(": rec-only slots can't be drained\n"); 851 panic(); 852 } 853 #endif 854 /* 855 * check if stopped stream finished draining 856 */ 857 if (s->pstate == SLOT_STOP && 858 s->mix.buf.used < s->round * s->mix.bpf) { 859 /* 860 * partial blocks are zero-filled by socket 861 * layer, so s->mix.buf.used == 0 and we can 862 * destroy the buffer 863 */ 864 *ps = s->next; 865 s->pstate = SLOT_INIT; 866 s->ops->eof(s->arg); 867 slot_freebufs(s); 868 dev_mix_adjvol(d); 869 #ifdef DEBUG 870 if (log_level >= 3) { 871 slot_log(s); 872 log_puts(": drained\n"); 873 } 874 #endif 875 continue; 876 } 877 878 /* 879 * check for xruns 880 */ 881 if (((s->mode & MODE_PLAY) && 882 s->mix.buf.used < s->round * s->mix.bpf) || 883 ((s->mode & MODE_RECMASK) && 884 s->sub.buf.len - s->sub.buf.used < 885 s->round * s->sub.bpf)) { 886 887 #ifdef DEBUG 888 if (log_level >= 3) { 889 slot_log(s); 890 log_puts(": xrun, pause cycle\n"); 891 } 892 #endif 893 if (s->xrun == XRUN_IGNORE) { 894 s->delta -= s->round; 895 ps = &s->next; 896 } else if (s->xrun == XRUN_SYNC) { 897 s->skip++; 898 ps = &s->next; 899 } else if (s->xrun == XRUN_ERROR) { 900 s->ops->exit(s->arg); 901 *ps = s->next; 902 } else { 903 #ifdef DEBUG 904 slot_log(s); 905 log_puts(": bad xrun mode\n"); 906 panic(); 907 #endif 908 } 909 continue; 910 } 911 if ((s->mode & MODE_RECMASK) && !(s->pstate == SLOT_STOP)) { 912 if (s->sub.prime == 0) { 913 dev_sub_bcopy(d, s); 914 s->ops->flush(s->arg); 915 } else { 916 #ifdef DEBUG 917 if (log_level >= 3) { 918 slot_log(s); 919 log_puts(": prime = "); 920 log_puti(s->sub.prime); 921 log_puts("\n"); 922 } 923 #endif 924 s->sub.prime--; 925 } 926 } 927 if (s->mode & MODE_PLAY) { 928 dev_mix_badd(d, s); 929 if (s->pstate != SLOT_STOP) 930 s->ops->fill(s->arg); 931 } 932 ps = &s->next; 933 } 934 if ((d->mode & MODE_PLAY) && d->encbuf) { 935 enc_do(&d->enc, (unsigned char *)DEV_PBUF(d), 936 d->encbuf, d->round); 937 } 938 } 939 940 /* 941 * called at every clock tick by the device 942 */ 943 void 944 dev_onmove(struct dev *d, int delta) 945 { 946 long long pos; 947 struct slot *s, *snext; 948 949 d->delta += delta; 950 951 for (s = d->slot_list; s != NULL; s = snext) { 952 /* 953 * s->ops->onmove() may remove the slot 954 */ 955 snext = s->next; 956 pos = (long long)delta * s->round + s->delta_rem; 957 s->delta_rem = pos % d->round; 958 s->delta += pos / (int)d->round; 959 if (s->delta >= 0) 960 s->ops->onmove(s->arg); 961 } 962 if (d->tstate == MMC_RUN) 963 dev_midi_qfr(d, delta); 964 } 965 966 void 967 dev_master(struct dev *d, unsigned int master) 968 { 969 struct ctl *c; 970 unsigned int v; 971 972 if (log_level >= 2) { 973 dev_log(d); 974 log_puts(": master volume set to "); 975 log_putu(master); 976 log_puts("\n"); 977 } 978 if (d->master_enabled) { 979 d->master = master; 980 if (d->mode & MODE_PLAY) 981 dev_mix_adjvol(d); 982 } else { 983 for (c = d->ctl_list; c != NULL; c = c->next) { 984 if (c->type != CTL_NUM || 985 strcmp(c->group, "") != 0 || 986 strcmp(c->node0.name, "output") != 0 || 987 strcmp(c->func, "level") != 0) 988 continue; 989 v = (master * c->maxval + 64) / 127; 990 dev_setctl(d, c->addr, v); 991 } 992 } 993 } 994 995 /* 996 * return the latency that a stream would have if it's attached 997 */ 998 int 999 dev_getpos(struct dev *d) 1000 { 1001 return (d->mode & MODE_PLAY) ? -d->bufsz : 0; 1002 } 1003 1004 /* 1005 * Create a sndio device 1006 */ 1007 struct dev * 1008 dev_new(char *path, struct aparams *par, 1009 unsigned int mode, unsigned int bufsz, unsigned int round, 1010 unsigned int rate, unsigned int hold, unsigned int autovol) 1011 { 1012 struct dev *d; 1013 unsigned int i; 1014 1015 if (dev_sndnum == DEV_NMAX) { 1016 if (log_level >= 1) 1017 log_puts("too many devices\n"); 1018 return NULL; 1019 } 1020 d = xmalloc(sizeof(struct dev)); 1021 d->alt_list = NULL; 1022 dev_addname(d,path); 1023 d->num = dev_sndnum++; 1024 d->opt_list = NULL; 1025 d->alt_num = -1; 1026 1027 /* 1028 * XXX: below, we allocate a midi input buffer, since we don't 1029 * receive raw midi data, so no need to allocate a input 1030 * ibuf. Possibly set imsg & fill callbacks to NULL and 1031 * use this to in midi_new() to check if buffers need to be 1032 * allocated 1033 */ 1034 d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT); 1035 midi_tag(d->midi, d->num); 1036 d->reqpar = *par; 1037 d->reqmode = mode; 1038 d->reqpchan = d->reqrchan = 0; 1039 d->reqbufsz = bufsz; 1040 d->reqround = round; 1041 d->reqrate = rate; 1042 d->hold = hold; 1043 d->autovol = autovol; 1044 d->refcnt = 0; 1045 d->pstate = DEV_CFG; 1046 d->serial = 0; 1047 for (i = 0; i < DEV_NSLOT; i++) { 1048 d->slot[i].unit = i; 1049 d->slot[i].ops = NULL; 1050 d->slot[i].vol = MIDI_MAXCTL; 1051 d->slot[i].serial = d->serial++; 1052 memset(d->slot[i].name, 0, SLOT_NAMEMAX); 1053 } 1054 for (i = 0; i < DEV_NCTLSLOT; i++) { 1055 d->ctlslot[i].ops = NULL; 1056 d->ctlslot[i].dev = d; 1057 d->ctlslot[i].mask = 0; 1058 d->ctlslot[i].mode = 0; 1059 } 1060 d->slot_list = NULL; 1061 d->master = MIDI_MAXCTL; 1062 d->mtc.origin = 0; 1063 d->tstate = MMC_STOP; 1064 d->ctl_list = NULL; 1065 d->next = dev_list; 1066 dev_list = d; 1067 return d; 1068 } 1069 1070 /* 1071 * add a alternate name 1072 */ 1073 int 1074 dev_addname(struct dev *d, char *name) 1075 { 1076 struct dev_alt *a; 1077 1078 if (d->alt_list != NULL && d->alt_list->idx == DEV_NMAX - 1) { 1079 log_puts(name); 1080 log_puts(": too many alternate names\n"); 1081 return 0; 1082 } 1083 a = xmalloc(sizeof(struct dev_alt)); 1084 a->name = name; 1085 a->idx = (d->alt_list == NULL) ? 0 : d->alt_list->idx + 1; 1086 a->next = d->alt_list; 1087 d->alt_list = a; 1088 return 1; 1089 } 1090 1091 /* 1092 * set prefered alt device name 1093 */ 1094 void 1095 dev_setalt(struct dev *d, unsigned int idx) 1096 { 1097 struct dev_alt **pa, *a; 1098 1099 /* find alt with given index */ 1100 for (pa = &d->alt_list; (a = *pa)->idx != idx; pa = &a->next) 1101 ; 1102 1103 /* detach from list */ 1104 *pa = a->next; 1105 1106 /* attach at head */ 1107 a->next = d->alt_list; 1108 d->alt_list = a; 1109 1110 /* reopen device with the new alt */ 1111 if (idx != d->alt_num) 1112 dev_reopen(d); 1113 } 1114 1115 /* 1116 * adjust device parameters and mode 1117 */ 1118 void 1119 dev_adjpar(struct dev *d, int mode, 1120 int pmax, int rmax) 1121 { 1122 d->reqmode |= mode & MODE_AUDIOMASK; 1123 if (mode & MODE_PLAY) { 1124 if (d->reqpchan < pmax + 1) 1125 d->reqpchan = pmax + 1; 1126 } 1127 if (mode & MODE_REC) { 1128 if (d->reqrchan < rmax + 1) 1129 d->reqrchan = rmax + 1; 1130 } 1131 } 1132 1133 /* 1134 * Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer, 1135 * monitor, midi control, and any necessary conversions. 1136 */ 1137 int 1138 dev_allocbufs(struct dev *d) 1139 { 1140 if (d->mode & MODE_REC) { 1141 /* 1142 * Create device <-> demuxer buffer 1143 */ 1144 d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t)); 1145 1146 /* 1147 * Insert a converter, if needed. 1148 */ 1149 if (!aparams_native(&d->par)) { 1150 dec_init(&d->dec, &d->par, d->rchan); 1151 d->decbuf = xmalloc(d->round * d->rchan * d->par.bps); 1152 } else 1153 d->decbuf = NULL; 1154 } 1155 if (d->mode & MODE_PLAY) { 1156 /* 1157 * Create device <-> mixer buffer 1158 */ 1159 d->poffs = 0; 1160 d->psize = d->bufsz + d->round; 1161 d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t)); 1162 d->mode |= MODE_MON; 1163 1164 /* 1165 * Append a converter, if needed. 1166 */ 1167 if (!aparams_native(&d->par)) { 1168 enc_init(&d->enc, &d->par, d->pchan); 1169 d->encbuf = xmalloc(d->round * d->pchan * d->par.bps); 1170 } else 1171 d->encbuf = NULL; 1172 } 1173 if (log_level >= 2) { 1174 dev_log(d); 1175 log_puts(": "); 1176 log_putu(d->rate); 1177 log_puts("Hz, "); 1178 aparams_log(&d->par); 1179 if (d->mode & MODE_PLAY) { 1180 log_puts(", play 0:"); 1181 log_puti(d->pchan - 1); 1182 } 1183 if (d->mode & MODE_REC) { 1184 log_puts(", rec 0:"); 1185 log_puti(d->rchan - 1); 1186 } 1187 log_puts(", "); 1188 log_putu(d->bufsz / d->round); 1189 log_puts(" blocks of "); 1190 log_putu(d->round); 1191 log_puts(" frames\n"); 1192 } 1193 return 1; 1194 } 1195 1196 /* 1197 * Reset parameters and open the device. 1198 */ 1199 int 1200 dev_open(struct dev *d) 1201 { 1202 int i; 1203 char name[CTL_NAMEMAX]; 1204 struct dev_alt *a; 1205 1206 d->master_enabled = 0; 1207 d->mode = d->reqmode; 1208 d->round = d->reqround; 1209 d->bufsz = d->reqbufsz; 1210 d->rate = d->reqrate; 1211 d->pchan = d->reqpchan; 1212 d->rchan = d->reqrchan; 1213 d->par = d->reqpar; 1214 if (d->pchan == 0) 1215 d->pchan = 2; 1216 if (d->rchan == 0) 1217 d->rchan = 2; 1218 if (!dev_sio_open(d)) { 1219 if (log_level >= 1) { 1220 dev_log(d); 1221 log_puts(": failed to open audio device\n"); 1222 } 1223 return 0; 1224 } 1225 if (!dev_allocbufs(d)) 1226 return 0; 1227 1228 for (i = 0; i < DEV_NSLOT; i++) { 1229 if (d->slot[i].name[0] == 0) 1230 continue; 1231 slot_ctlname(&d->slot[i], name, CTL_NAMEMAX); 1232 dev_addctl(d, "app", CTL_NUM, 1233 CTLADDR_SLOT_LEVEL(i), 1234 name, -1, "level", 1235 NULL, -1, 127, d->slot[i].vol); 1236 } 1237 1238 /* if there are multiple alt devs, add server.device knob */ 1239 if (d->alt_list->next != NULL) { 1240 for (a = d->alt_list; a != NULL; a = a->next) { 1241 snprintf(name, sizeof(name), "%d", a->idx); 1242 dev_addctl(d, "", CTL_SEL, 1243 CTLADDR_ALT_SEL + a->idx, 1244 "server", -1, "device", 1245 name, -1, 1, a->idx == d->alt_num); 1246 } 1247 } 1248 1249 d->pstate = DEV_INIT; 1250 return 1; 1251 } 1252 1253 /* 1254 * Force all slots to exit and close device, called after an error 1255 */ 1256 void 1257 dev_abort(struct dev *d) 1258 { 1259 int i; 1260 struct slot *s; 1261 struct ctlslot *c; 1262 1263 for (s = d->slot, i = DEV_NSLOT; i > 0; i--, s++) { 1264 if (s->ops) 1265 s->ops->exit(s->arg); 1266 s->ops = NULL; 1267 } 1268 d->slot_list = NULL; 1269 1270 for (c = d->ctlslot, i = DEV_NCTLSLOT; i > 0; i--, c++) { 1271 if (c->ops) 1272 c->ops->exit(c->arg); 1273 c->ops = NULL; 1274 } 1275 1276 if (d->pstate != DEV_CFG) 1277 dev_close(d); 1278 } 1279 1280 /* 1281 * force the device to go in DEV_CFG state, the caller is supposed to 1282 * ensure buffers are drained 1283 */ 1284 void 1285 dev_freebufs(struct dev *d) 1286 { 1287 #ifdef DEBUG 1288 if (log_level >= 3) { 1289 dev_log(d); 1290 log_puts(": closing\n"); 1291 } 1292 #endif 1293 if (d->mode & MODE_PLAY) { 1294 if (d->encbuf != NULL) 1295 xfree(d->encbuf); 1296 xfree(d->pbuf); 1297 } 1298 if (d->mode & MODE_REC) { 1299 if (d->decbuf != NULL) 1300 xfree(d->decbuf); 1301 xfree(d->rbuf); 1302 } 1303 } 1304 1305 /* 1306 * Close the device and exit all slots 1307 */ 1308 void 1309 dev_close(struct dev *d) 1310 { 1311 struct ctl *c; 1312 1313 d->pstate = DEV_CFG; 1314 dev_sio_close(d); 1315 dev_freebufs(d); 1316 1317 /* there are no clients, just free remaining local controls */ 1318 while ((c = d->ctl_list) != NULL) { 1319 d->ctl_list = c->next; 1320 xfree(c); 1321 } 1322 } 1323 1324 /* 1325 * Close the device, but attempt to migrate everything to a new sndio 1326 * device. 1327 */ 1328 int 1329 dev_reopen(struct dev *d) 1330 { 1331 struct slot *s; 1332 long long pos; 1333 unsigned int pstate; 1334 int delta; 1335 1336 /* not opened */ 1337 if (d->pstate == DEV_CFG) 1338 return 1; 1339 1340 /* save state */ 1341 delta = d->delta; 1342 pstate = d->pstate; 1343 1344 if (!dev_sio_reopen(d)) 1345 return 0; 1346 1347 /* reopen returns a stopped device */ 1348 d->pstate = DEV_INIT; 1349 1350 /* reallocate new buffers, with new parameters */ 1351 dev_freebufs(d); 1352 dev_allocbufs(d); 1353 1354 /* 1355 * adjust time positions, make anything go back delta ticks, so 1356 * that the new device can start at zero 1357 */ 1358 for (s = d->slot_list; s != NULL; s = s->next) { 1359 pos = (long long)s->delta * d->round + s->delta_rem; 1360 pos -= (long long)delta * s->round; 1361 s->delta_rem = pos % (int)d->round; 1362 s->delta = pos / (int)d->round; 1363 if (log_level >= 3) { 1364 slot_log(s); 1365 log_puts(": adjusted: delta -> "); 1366 log_puti(s->delta); 1367 log_puts(", delta_rem -> "); 1368 log_puti(s->delta_rem); 1369 log_puts("\n"); 1370 } 1371 1372 /* reinitilize the format conversion chain */ 1373 slot_initconv(s); 1374 } 1375 if (d->tstate == MMC_RUN) { 1376 d->mtc.delta -= delta * MTC_SEC; 1377 if (log_level >= 2) { 1378 dev_log(d); 1379 log_puts(": adjusted mtc: delta ->"); 1380 log_puti(d->mtc.delta); 1381 log_puts("\n"); 1382 } 1383 } 1384 1385 /* remove old controls and add new ones */ 1386 dev_sioctl_close(d); 1387 dev_sioctl_open(d); 1388 1389 /* start the device if needed */ 1390 if (pstate == DEV_RUN) 1391 dev_wakeup(d); 1392 1393 return 1; 1394 } 1395 1396 int 1397 dev_ref(struct dev *d) 1398 { 1399 #ifdef DEBUG 1400 if (log_level >= 3) { 1401 dev_log(d); 1402 log_puts(": device requested\n"); 1403 } 1404 #endif 1405 if (d->pstate == DEV_CFG && !dev_open(d)) 1406 return 0; 1407 d->refcnt++; 1408 return 1; 1409 } 1410 1411 void 1412 dev_unref(struct dev *d) 1413 { 1414 #ifdef DEBUG 1415 if (log_level >= 3) { 1416 dev_log(d); 1417 log_puts(": device released\n"); 1418 } 1419 #endif 1420 d->refcnt--; 1421 if (d->refcnt == 0 && d->pstate == DEV_INIT) 1422 dev_close(d); 1423 } 1424 1425 /* 1426 * initialize the device with the current parameters 1427 */ 1428 int 1429 dev_init(struct dev *d) 1430 { 1431 if ((d->reqmode & MODE_AUDIOMASK) == 0) { 1432 #ifdef DEBUG 1433 dev_log(d); 1434 log_puts(": has no streams\n"); 1435 #endif 1436 return 0; 1437 } 1438 if (d->hold && !dev_ref(d)) 1439 return 0; 1440 return 1; 1441 } 1442 1443 /* 1444 * Unless the device is already in process of closing, request it to close 1445 */ 1446 void 1447 dev_done(struct dev *d) 1448 { 1449 #ifdef DEBUG 1450 if (log_level >= 3) { 1451 dev_log(d); 1452 log_puts(": draining\n"); 1453 } 1454 #endif 1455 if (d->tstate != MMC_STOP) 1456 dev_mmcstop(d); 1457 if (d->hold) 1458 dev_unref(d); 1459 } 1460 1461 struct dev * 1462 dev_bynum(int num) 1463 { 1464 struct dev *d; 1465 1466 for (d = dev_list; d != NULL; d = d->next) { 1467 if (d->num == num) 1468 return d; 1469 } 1470 return NULL; 1471 } 1472 1473 /* 1474 * Free the device 1475 */ 1476 void 1477 dev_del(struct dev *d) 1478 { 1479 struct dev **p; 1480 struct dev_alt *a; 1481 1482 #ifdef DEBUG 1483 if (log_level >= 3) { 1484 dev_log(d); 1485 log_puts(": deleting\n"); 1486 } 1487 #endif 1488 while (d->opt_list != NULL) 1489 opt_del(d, d->opt_list); 1490 if (d->pstate != DEV_CFG) 1491 dev_close(d); 1492 for (p = &dev_list; *p != d; p = &(*p)->next) { 1493 #ifdef DEBUG 1494 if (*p == NULL) { 1495 dev_log(d); 1496 log_puts(": device to delete not on the list\n"); 1497 panic(); 1498 } 1499 #endif 1500 } 1501 midi_del(d->midi); 1502 *p = d->next; 1503 while ((a = d->alt_list) != NULL) { 1504 d->alt_list = a->next; 1505 xfree(a); 1506 } 1507 xfree(d); 1508 } 1509 1510 unsigned int 1511 dev_roundof(struct dev *d, unsigned int newrate) 1512 { 1513 return (d->round * newrate + d->rate / 2) / d->rate; 1514 } 1515 1516 /* 1517 * If the device is paused, then resume it. 1518 */ 1519 void 1520 dev_wakeup(struct dev *d) 1521 { 1522 if (d->pstate == DEV_INIT) { 1523 if (log_level >= 2) { 1524 dev_log(d); 1525 log_puts(": device started\n"); 1526 } 1527 if (d->mode & MODE_PLAY) { 1528 d->prime = d->bufsz; 1529 } else { 1530 d->prime = 0; 1531 } 1532 d->poffs = 0; 1533 1534 /* 1535 * empty cycles don't increment delta, so it's ok to 1536 * start at 0 1537 **/ 1538 d->delta = 0; 1539 1540 d->pstate = DEV_RUN; 1541 dev_sio_start(d); 1542 } 1543 } 1544 1545 /* 1546 * check that all clients controlled by MMC are ready to start, if so, 1547 * attach them all at the same position 1548 */ 1549 void 1550 dev_sync_attach(struct dev *d) 1551 { 1552 int i; 1553 struct slot *s; 1554 1555 if (d->tstate != MMC_START) { 1556 if (log_level >= 2) { 1557 dev_log(d); 1558 log_puts(": not started by mmc yet, waiting...\n"); 1559 } 1560 return; 1561 } 1562 for (i = 0; i < DEV_NSLOT; i++) { 1563 s = d->slot + i; 1564 if (!s->ops || !s->opt->mmc) 1565 continue; 1566 if (s->pstate != SLOT_READY) { 1567 #ifdef DEBUG 1568 if (log_level >= 3) { 1569 slot_log(s); 1570 log_puts(": not ready, start delayed\n"); 1571 } 1572 #endif 1573 return; 1574 } 1575 } 1576 if (!dev_ref(d)) 1577 return; 1578 for (i = 0; i < DEV_NSLOT; i++) { 1579 s = d->slot + i; 1580 if (!s->ops || !s->opt->mmc) 1581 continue; 1582 slot_attach(s); 1583 } 1584 d->tstate = MMC_RUN; 1585 dev_midi_full(d); 1586 dev_wakeup(d); 1587 } 1588 1589 /* 1590 * start all slots simultaneously 1591 */ 1592 void 1593 dev_mmcstart(struct dev *d) 1594 { 1595 if (d->tstate == MMC_STOP) { 1596 d->tstate = MMC_START; 1597 dev_sync_attach(d); 1598 #ifdef DEBUG 1599 } else { 1600 if (log_level >= 3) { 1601 dev_log(d); 1602 log_puts(": ignoring mmc start\n"); 1603 } 1604 #endif 1605 } 1606 } 1607 1608 /* 1609 * stop all slots simultaneously 1610 */ 1611 void 1612 dev_mmcstop(struct dev *d) 1613 { 1614 switch (d->tstate) { 1615 case MMC_START: 1616 d->tstate = MMC_STOP; 1617 return; 1618 case MMC_RUN: 1619 d->tstate = MMC_STOP; 1620 dev_unref(d); 1621 break; 1622 default: 1623 #ifdef DEBUG 1624 if (log_level >= 3) { 1625 dev_log(d); 1626 log_puts(": ignored mmc stop\n"); 1627 } 1628 #endif 1629 return; 1630 } 1631 } 1632 1633 /* 1634 * relocate all slots simultaneously 1635 */ 1636 void 1637 dev_mmcloc(struct dev *d, unsigned int origin) 1638 { 1639 if (log_level >= 2) { 1640 dev_log(d); 1641 log_puts(": relocated to "); 1642 log_putu(origin); 1643 log_puts("\n"); 1644 } 1645 if (d->tstate == MMC_RUN) 1646 dev_mmcstop(d); 1647 d->mtc.origin = origin; 1648 if (d->tstate == MMC_RUN) 1649 dev_mmcstart(d); 1650 } 1651 1652 /* 1653 * allocate buffers & conversion chain 1654 */ 1655 void 1656 slot_initconv(struct slot *s) 1657 { 1658 unsigned int dev_nch; 1659 struct dev *d = s->dev; 1660 1661 if (s->mode & MODE_PLAY) { 1662 cmap_init(&s->mix.cmap, 1663 s->opt->pmin, s->opt->pmin + s->mix.nch - 1, 1664 s->opt->pmin, s->opt->pmin + s->mix.nch - 1, 1665 0, d->pchan - 1, 1666 s->opt->pmin, s->opt->pmax); 1667 if (!aparams_native(&s->par)) { 1668 dec_init(&s->mix.dec, &s->par, s->mix.nch); 1669 } 1670 if (s->rate != d->rate) { 1671 resamp_init(&s->mix.resamp, s->round, d->round, 1672 s->mix.nch); 1673 } 1674 s->mix.join = 1; 1675 s->mix.expand = 1; 1676 if (s->opt->dup && s->mix.cmap.nch > 0) { 1677 dev_nch = d->pchan < (s->opt->pmax + 1) ? 1678 d->pchan - s->opt->pmin : 1679 s->opt->pmax - s->opt->pmin + 1; 1680 if (dev_nch > s->mix.nch) 1681 s->mix.expand = dev_nch / s->mix.nch; 1682 else if (s->mix.nch > dev_nch) 1683 s->mix.join = s->mix.nch / dev_nch; 1684 } 1685 } 1686 1687 if (s->mode & MODE_RECMASK) { 1688 unsigned int outchan = (s->mode & MODE_MON) ? 1689 d->pchan : d->rchan; 1690 1691 cmap_init(&s->sub.cmap, 1692 0, outchan - 1, 1693 s->opt->rmin, s->opt->rmax, 1694 s->opt->rmin, s->opt->rmin + s->sub.nch - 1, 1695 s->opt->rmin, s->opt->rmin + s->sub.nch - 1); 1696 if (s->rate != d->rate) { 1697 resamp_init(&s->sub.resamp, d->round, s->round, 1698 s->sub.nch); 1699 } 1700 if (!aparams_native(&s->par)) { 1701 enc_init(&s->sub.enc, &s->par, s->sub.nch); 1702 } 1703 s->sub.join = 1; 1704 s->sub.expand = 1; 1705 if (s->opt->dup && s->sub.cmap.nch > 0) { 1706 dev_nch = outchan < (s->opt->rmax + 1) ? 1707 outchan - s->opt->rmin : 1708 s->opt->rmax - s->opt->rmin + 1; 1709 if (dev_nch > s->sub.nch) 1710 s->sub.join = dev_nch / s->sub.nch; 1711 else if (s->sub.nch > dev_nch) 1712 s->sub.expand = s->sub.nch / dev_nch; 1713 } 1714 1715 /* 1716 * cmap_copy() doesn't write samples in all channels, 1717 * for instance when mono->stereo conversion is 1718 * disabled. So we have to prefill cmap_copy() output 1719 * with silence. 1720 */ 1721 if (s->sub.resampbuf) { 1722 memset(s->sub.resampbuf, 0, 1723 d->round * s->sub.nch * sizeof(adata_t)); 1724 } else if (s->sub.encbuf) { 1725 memset(s->sub.encbuf, 0, 1726 s->round * s->sub.nch * sizeof(adata_t)); 1727 } else { 1728 memset(s->sub.buf.data, 0, 1729 s->appbufsz * s->sub.nch * sizeof(adata_t)); 1730 } 1731 } 1732 } 1733 1734 /* 1735 * allocate buffers & conversion chain 1736 */ 1737 void 1738 slot_allocbufs(struct slot *s) 1739 { 1740 struct dev *d = s->dev; 1741 1742 if (s->mode & MODE_PLAY) { 1743 s->mix.bpf = s->par.bps * s->mix.nch; 1744 abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf); 1745 1746 s->mix.decbuf = NULL; 1747 s->mix.resampbuf = NULL; 1748 if (!aparams_native(&s->par)) { 1749 s->mix.decbuf = 1750 xmalloc(s->round * s->mix.nch * sizeof(adata_t)); 1751 } 1752 if (s->rate != d->rate) { 1753 s->mix.resampbuf = 1754 xmalloc(d->round * s->mix.nch * sizeof(adata_t)); 1755 } 1756 } 1757 1758 if (s->mode & MODE_RECMASK) { 1759 s->sub.bpf = s->par.bps * s->sub.nch; 1760 abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf); 1761 1762 s->sub.encbuf = NULL; 1763 s->sub.resampbuf = NULL; 1764 if (s->rate != d->rate) { 1765 s->sub.resampbuf = 1766 xmalloc(d->round * s->sub.nch * sizeof(adata_t)); 1767 } 1768 if (!aparams_native(&s->par)) { 1769 s->sub.encbuf = 1770 xmalloc(s->round * s->sub.nch * sizeof(adata_t)); 1771 } 1772 } 1773 1774 slot_initconv(s); 1775 1776 #ifdef DEBUG 1777 if (log_level >= 3) { 1778 slot_log(s); 1779 log_puts(": allocated "); 1780 log_putu(s->appbufsz); 1781 log_puts("/"); 1782 log_putu(SLOT_BUFSZ(s)); 1783 log_puts(" fr buffers\n"); 1784 } 1785 #endif 1786 } 1787 1788 /* 1789 * free buffers & conversion chain 1790 */ 1791 void 1792 slot_freebufs(struct slot *s) 1793 { 1794 if (s->mode & MODE_RECMASK) { 1795 abuf_done(&s->sub.buf); 1796 if (s->sub.encbuf) 1797 xfree(s->sub.encbuf); 1798 if (s->sub.resampbuf) 1799 xfree(s->sub.resampbuf); 1800 } 1801 1802 if (s->mode & MODE_PLAY) { 1803 abuf_done(&s->mix.buf); 1804 if (s->mix.decbuf) 1805 xfree(s->mix.decbuf); 1806 if (s->mix.resampbuf) 1807 xfree(s->mix.resampbuf); 1808 } 1809 } 1810 1811 /* 1812 * allocate a new slot and register the given call-backs 1813 */ 1814 struct slot * 1815 slot_new(struct dev *d, struct opt *opt, unsigned int id, char *who, 1816 struct slotops *ops, void *arg, int mode) 1817 { 1818 char *p; 1819 char name[SLOT_NAMEMAX]; 1820 unsigned int i, ser, bestser, bestidx; 1821 struct slot *unit[DEV_NSLOT]; 1822 struct slot *s; 1823 1824 /* 1825 * create a ``valid'' control name (lowcase, remove [^a-z], truncate) 1826 */ 1827 for (i = 0, p = who; ; p++) { 1828 if (i == SLOT_NAMEMAX - 1 || *p == '\0') { 1829 name[i] = '\0'; 1830 break; 1831 } else if (*p >= 'A' && *p <= 'Z') { 1832 name[i++] = *p + 'a' - 'A'; 1833 } else if (*p >= 'a' && *p <= 'z') 1834 name[i++] = *p; 1835 } 1836 if (i == 0) 1837 strlcpy(name, "noname", SLOT_NAMEMAX); 1838 1839 /* 1840 * build a unit-to-slot map for this name 1841 */ 1842 for (i = 0; i < DEV_NSLOT; i++) 1843 unit[i] = NULL; 1844 for (i = 0; i < DEV_NSLOT; i++) { 1845 s = d->slot + i; 1846 if (strcmp(s->name, name) == 0) 1847 unit[s->unit] = s; 1848 } 1849 1850 /* 1851 * find the free slot with the least unit number and same id 1852 */ 1853 for (i = 0; i < DEV_NSLOT; i++) { 1854 s = unit[i]; 1855 if (s != NULL && s->ops == NULL && s->id == id) 1856 goto found; 1857 } 1858 1859 /* 1860 * find the free slot with the least unit number 1861 */ 1862 for (i = 0; i < DEV_NSLOT; i++) { 1863 s = unit[i]; 1864 if (s != NULL && s->ops == NULL) { 1865 s->id = id; 1866 goto found; 1867 } 1868 } 1869 1870 /* 1871 * couldn't find a matching slot, pick oldest free slot 1872 * and set its name/unit 1873 */ 1874 bestser = 0; 1875 bestidx = DEV_NSLOT; 1876 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1877 if (s->ops != NULL) 1878 continue; 1879 ser = d->serial - s->serial; 1880 if (ser > bestser) { 1881 bestser = ser; 1882 bestidx = i; 1883 } 1884 } 1885 if (bestidx != DEV_NSLOT) { 1886 s = d->slot + bestidx; 1887 s->vol = MIDI_MAXCTL; 1888 strlcpy(s->name, name, SLOT_NAMEMAX); 1889 s->serial = d->serial++; 1890 for (i = 0; unit[i] != NULL; i++) 1891 ; /* nothing */ 1892 s->unit = i; 1893 s->id = id; 1894 goto found; 1895 } 1896 1897 if (log_level >= 1) { 1898 log_puts(name); 1899 log_puts(": out of sub-device slots\n"); 1900 } 1901 return NULL; 1902 1903 found: 1904 if ((mode & MODE_REC) && (opt->mode & MODE_MON)) { 1905 mode |= MODE_MON; 1906 mode &= ~MODE_REC; 1907 } 1908 if ((mode & opt->mode) != mode) { 1909 if (log_level >= 1) { 1910 slot_log(s); 1911 log_puts(": requested mode not allowed\n"); 1912 } 1913 return 0; 1914 } 1915 if (!dev_ref(d)) 1916 return NULL; 1917 dev_label(d, s - d->slot); 1918 if ((mode & d->mode) != mode) { 1919 if (log_level >= 1) { 1920 slot_log(s); 1921 log_puts(": requested mode not supported\n"); 1922 } 1923 dev_unref(d); 1924 return NULL; 1925 } 1926 s->dev = d; 1927 s->opt = opt; 1928 s->ops = ops; 1929 s->arg = arg; 1930 s->pstate = SLOT_INIT; 1931 s->mode = mode; 1932 aparams_init(&s->par); 1933 if (s->mode & MODE_PLAY) 1934 s->mix.nch = s->opt->pmax - s->opt->pmin + 1; 1935 if (s->mode & MODE_RECMASK) 1936 s->sub.nch = s->opt->rmax - s->opt->rmin + 1; 1937 s->xrun = s->opt->mmc ? XRUN_SYNC : XRUN_IGNORE; 1938 s->appbufsz = d->bufsz; 1939 s->round = d->round; 1940 s->rate = d->rate; 1941 dev_midi_slotdesc(d, s); 1942 dev_midi_vol(d, s); 1943 #ifdef DEBUG 1944 if (log_level >= 3) { 1945 slot_log(s); 1946 log_puts(": using "); 1947 dev_log(d); 1948 log_puts("."); 1949 log_puts(opt->name); 1950 log_puts(", mode = "); 1951 log_putx(mode); 1952 log_puts("\n"); 1953 } 1954 #endif 1955 return s; 1956 } 1957 1958 /* 1959 * release the given slot 1960 */ 1961 void 1962 slot_del(struct slot *s) 1963 { 1964 s->arg = s; 1965 s->ops = &zomb_slotops; 1966 switch (s->pstate) { 1967 case SLOT_INIT: 1968 s->ops = NULL; 1969 break; 1970 case SLOT_START: 1971 case SLOT_READY: 1972 case SLOT_RUN: 1973 slot_stop(s); 1974 /* PASSTHROUGH */ 1975 case SLOT_STOP: 1976 break; 1977 } 1978 dev_unref(s->dev); 1979 s->dev = NULL; 1980 } 1981 1982 /* 1983 * change the slot play volume; called either by the slot or by MIDI 1984 */ 1985 void 1986 slot_setvol(struct slot *s, unsigned int vol) 1987 { 1988 #ifdef DEBUG 1989 if (log_level >= 3) { 1990 slot_log(s); 1991 log_puts(": setting volume "); 1992 log_putu(vol); 1993 log_puts("\n"); 1994 } 1995 #endif 1996 s->vol = vol; 1997 s->mix.vol = MIDI_TO_ADATA(s->vol); 1998 } 1999 2000 /* 2001 * attach the slot to the device (ie start playing & recording 2002 */ 2003 void 2004 slot_attach(struct slot *s) 2005 { 2006 struct dev *d = s->dev; 2007 long long pos; 2008 int startpos; 2009 2010 /* 2011 * start the device if not started 2012 */ 2013 dev_wakeup(d); 2014 2015 /* 2016 * get the current position, the origin is when the first sample 2017 * played and/or recorded 2018 */ 2019 startpos = dev_getpos(d) * (int)s->round / (int)d->round; 2020 2021 /* 2022 * adjust initial clock 2023 */ 2024 pos = (long long)d->delta * s->round; 2025 s->delta = startpos + pos / (int)d->round; 2026 s->delta_rem = pos % d->round; 2027 2028 s->pstate = SLOT_RUN; 2029 #ifdef DEBUG 2030 if (log_level >= 2) { 2031 slot_log(s); 2032 log_puts(": attached at "); 2033 log_puti(startpos); 2034 log_puts(", delta = "); 2035 log_puti(d->delta); 2036 log_puts("\n"); 2037 } 2038 #endif 2039 2040 /* 2041 * We dont check whether the device is dying, 2042 * because dev_xxx() functions are supposed to 2043 * work (i.e., not to crash) 2044 */ 2045 #ifdef DEBUG 2046 if ((s->mode & d->mode) != s->mode) { 2047 slot_log(s); 2048 log_puts(": mode beyond device mode, not attaching\n"); 2049 panic(); 2050 } 2051 #endif 2052 s->next = d->slot_list; 2053 d->slot_list = s; 2054 if (s->mode & MODE_PLAY) { 2055 s->mix.vol = MIDI_TO_ADATA(s->vol); 2056 dev_mix_adjvol(d); 2057 } 2058 } 2059 2060 /* 2061 * if MMC is enabled, and try to attach all slots synchronously, else 2062 * simply attach the slot 2063 */ 2064 void 2065 slot_ready(struct slot *s) 2066 { 2067 /* 2068 * device may be disconnected, and if so we're called from 2069 * slot->ops->exit() on a closed device 2070 */ 2071 if (s->dev->pstate == DEV_CFG) 2072 return; 2073 if (!s->opt->mmc) 2074 slot_attach(s); 2075 else 2076 dev_sync_attach(s->dev); 2077 } 2078 2079 /* 2080 * setup buffers & conversion layers, prepare the slot to receive data 2081 * (for playback) or start (recording). 2082 */ 2083 void 2084 slot_start(struct slot *s) 2085 { 2086 #ifdef DEBUG 2087 if (s->pstate != SLOT_INIT) { 2088 slot_log(s); 2089 log_puts(": slot_start: wrong state\n"); 2090 panic(); 2091 } 2092 if (s->mode & MODE_PLAY) { 2093 if (log_level >= 3) { 2094 slot_log(s); 2095 log_puts(": playing "); 2096 aparams_log(&s->par); 2097 log_puts(" -> "); 2098 aparams_log(&s->dev->par); 2099 log_puts("\n"); 2100 } 2101 } 2102 if (s->mode & MODE_RECMASK) { 2103 if (log_level >= 3) { 2104 slot_log(s); 2105 log_puts(": recording "); 2106 aparams_log(&s->par); 2107 log_puts(" <- "); 2108 aparams_log(&s->dev->par); 2109 log_puts("\n"); 2110 } 2111 } 2112 #endif 2113 slot_allocbufs(s); 2114 2115 if (s->mode & MODE_RECMASK) { 2116 /* 2117 * N-th recorded block is the N-th played block 2118 */ 2119 s->sub.prime = -dev_getpos(s->dev) / s->dev->round; 2120 } 2121 s->skip = 0; 2122 2123 if (s->mode & MODE_PLAY) { 2124 s->pstate = SLOT_START; 2125 } else { 2126 s->pstate = SLOT_READY; 2127 slot_ready(s); 2128 } 2129 } 2130 2131 /* 2132 * stop playback and recording, and free conversion layers 2133 */ 2134 void 2135 slot_detach(struct slot *s) 2136 { 2137 struct slot **ps; 2138 2139 #ifdef DEBUG 2140 if (log_level >= 3) { 2141 slot_log(s); 2142 log_puts(": detaching\n"); 2143 } 2144 #endif 2145 for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) { 2146 #ifdef DEBUG 2147 if (*ps == NULL) { 2148 slot_log(s); 2149 log_puts(": can't detach, not on list\n"); 2150 panic(); 2151 } 2152 #endif 2153 } 2154 *ps = s->next; 2155 if (s->mode & MODE_PLAY) 2156 dev_mix_adjvol(s->dev); 2157 } 2158 2159 /* 2160 * put the slot in stopping state (draining play buffers) or 2161 * stop & detach if no data to drain. 2162 */ 2163 void 2164 slot_stop(struct slot *s) 2165 { 2166 #ifdef DEBUG 2167 if (log_level >= 3) { 2168 slot_log(s); 2169 log_puts(": stopping\n"); 2170 } 2171 #endif 2172 if (s->pstate == SLOT_START) { 2173 /* 2174 * If in rec-only mode, we're already in the READY or 2175 * RUN states. We're here because the play buffer was 2176 * not full enough, try to start so it's drained. 2177 */ 2178 s->pstate = SLOT_READY; 2179 slot_ready(s); 2180 } 2181 2182 if (s->pstate == SLOT_RUN) { 2183 if (s->mode & MODE_PLAY) { 2184 /* 2185 * Don't detach, dev_cycle() will do it for us 2186 * when the buffer is drained. 2187 */ 2188 s->pstate = SLOT_STOP; 2189 return; 2190 } 2191 slot_detach(s); 2192 } else { 2193 #ifdef DEBUG 2194 if (log_level >= 3) { 2195 slot_log(s); 2196 log_puts(": not drained (blocked by mmc)\n"); 2197 } 2198 #endif 2199 } 2200 2201 s->pstate = SLOT_INIT; 2202 s->ops->eof(s->arg); 2203 slot_freebufs(s); 2204 } 2205 2206 void 2207 slot_skip_update(struct slot *s) 2208 { 2209 int skip; 2210 2211 skip = slot_skip(s); 2212 while (skip > 0) { 2213 #ifdef DEBUG 2214 if (log_level >= 4) { 2215 slot_log(s); 2216 log_puts(": catching skipped block\n"); 2217 } 2218 #endif 2219 if (s->mode & MODE_RECMASK) 2220 s->ops->flush(s->arg); 2221 if (s->mode & MODE_PLAY) 2222 s->ops->fill(s->arg); 2223 skip--; 2224 } 2225 } 2226 2227 /* 2228 * notify the slot that we just wrote in the play buffer, must be called 2229 * after each write 2230 */ 2231 void 2232 slot_write(struct slot *s) 2233 { 2234 if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) { 2235 #ifdef DEBUG 2236 if (log_level >= 4) { 2237 slot_log(s); 2238 log_puts(": switching to READY state\n"); 2239 } 2240 #endif 2241 s->pstate = SLOT_READY; 2242 slot_ready(s); 2243 } 2244 slot_skip_update(s); 2245 } 2246 2247 /* 2248 * notify the slot that we freed some space in the rec buffer 2249 */ 2250 void 2251 slot_read(struct slot *s) 2252 { 2253 slot_skip_update(s); 2254 } 2255 2256 /* 2257 * allocate at control slot 2258 */ 2259 struct ctlslot * 2260 ctlslot_new(struct dev *d, struct ctlops *ops, void *arg) 2261 { 2262 struct ctlslot *s; 2263 struct ctl *c; 2264 int i; 2265 2266 i = 0; 2267 for (;;) { 2268 if (i == DEV_NCTLSLOT) 2269 return NULL; 2270 s = d->ctlslot + i; 2271 if (s->ops == NULL) 2272 break; 2273 i++; 2274 } 2275 s->dev = d; 2276 s->mask = 1 << i; 2277 if (!dev_ref(d)) 2278 return NULL; 2279 s->ops = ops; 2280 s->arg = arg; 2281 for (c = d->ctl_list; c != NULL; c = c->next) 2282 c->refs_mask |= s->mask; 2283 return s; 2284 } 2285 2286 /* 2287 * free control slot 2288 */ 2289 void 2290 ctlslot_del(struct ctlslot *s) 2291 { 2292 struct ctl *c, **pc; 2293 2294 pc = &s->dev->ctl_list; 2295 while ((c = *pc) != NULL) { 2296 c->refs_mask &= ~s->mask; 2297 if (c->refs_mask == 0) { 2298 *pc = c->next; 2299 xfree(c); 2300 } else 2301 pc = &c->next; 2302 } 2303 s->ops = NULL; 2304 dev_unref(s->dev); 2305 } 2306 2307 void 2308 ctl_node_log(struct ctl_node *c) 2309 { 2310 log_puts(c->name); 2311 if (c->unit >= 0) 2312 log_putu(c->unit); 2313 } 2314 2315 void 2316 ctl_log(struct ctl *c) 2317 { 2318 if (c->group[0] != 0) { 2319 log_puts(c->group); 2320 log_puts("/"); 2321 } 2322 ctl_node_log(&c->node0); 2323 log_puts("."); 2324 log_puts(c->func); 2325 log_puts("="); 2326 switch (c->type) { 2327 case CTL_NONE: 2328 log_puts("none"); 2329 break; 2330 case CTL_NUM: 2331 case CTL_SW: 2332 log_putu(c->curval); 2333 break; 2334 case CTL_VEC: 2335 case CTL_LIST: 2336 case CTL_SEL: 2337 ctl_node_log(&c->node1); 2338 log_puts(":"); 2339 log_putu(c->curval); 2340 } 2341 log_puts(" at "); 2342 log_putu(c->addr); 2343 } 2344 2345 /* 2346 * add a ctl 2347 */ 2348 struct ctl * 2349 dev_addctl(struct dev *d, char *gstr, int type, int addr, 2350 char *str0, int unit0, char *func, char *str1, int unit1, int maxval, int val) 2351 { 2352 struct ctl *c, **pc; 2353 int i; 2354 2355 c = xmalloc(sizeof(struct ctl)); 2356 c->type = type; 2357 strlcpy(c->func, func, CTL_NAMEMAX); 2358 strlcpy(c->group, gstr, CTL_NAMEMAX); 2359 strlcpy(c->node0.name, str0, CTL_NAMEMAX); 2360 c->node0.unit = unit0; 2361 if (c->type == CTL_VEC || c->type == CTL_LIST || c->type == CTL_SEL) { 2362 strlcpy(c->node1.name, str1, CTL_NAMEMAX); 2363 c->node1.unit = unit1; 2364 } else 2365 memset(&c->node1, 0, sizeof(struct ctl_node)); 2366 c->addr = addr; 2367 c->maxval = maxval; 2368 c->val_mask = ~0; 2369 c->desc_mask = ~0; 2370 c->curval = val; 2371 c->dirty = 0; 2372 c->refs_mask = 0; 2373 for (i = 0; i < DEV_NCTLSLOT; i++) { 2374 c->refs_mask |= CTL_DEVMASK; 2375 if (d->ctlslot[i].ops != NULL) 2376 c->refs_mask |= 1 << i; 2377 } 2378 for (pc = &d->ctl_list; *pc != NULL; pc = &(*pc)->next) 2379 ; /* nothing */ 2380 c->next = NULL; 2381 *pc = c; 2382 #ifdef DEBUG 2383 if (log_level >= 3) { 2384 dev_log(d); 2385 log_puts(": adding "); 2386 ctl_log(c); 2387 log_puts("\n"); 2388 } 2389 #endif 2390 return c; 2391 } 2392 2393 void 2394 dev_rmctl(struct dev *d, int addr) 2395 { 2396 struct ctl *c, **pc; 2397 2398 pc = &d->ctl_list; 2399 for (;;) { 2400 c = *pc; 2401 if (c == NULL) 2402 return; 2403 if (c->type != CTL_NONE && c->addr == addr) 2404 break; 2405 pc = &c->next; 2406 } 2407 c->type = CTL_NONE; 2408 #ifdef DEBUG 2409 if (log_level >= 3) { 2410 dev_log(d); 2411 log_puts(": removing "); 2412 ctl_log(c); 2413 log_puts(", refs_mask = 0x"); 2414 log_putx(c->refs_mask); 2415 log_puts("\n"); 2416 } 2417 #endif 2418 c->refs_mask &= ~CTL_DEVMASK; 2419 if (c->refs_mask == 0) { 2420 *pc = c->next; 2421 xfree(c); 2422 return; 2423 } 2424 c->desc_mask = ~0; 2425 } 2426 2427 void 2428 dev_ctlsync(struct dev *d) 2429 { 2430 struct ctl *c; 2431 struct ctlslot *s; 2432 int found, i; 2433 2434 found = 0; 2435 for (c = d->ctl_list; c != NULL; c = c->next) { 2436 if (c->addr != CTLADDR_MASTER && 2437 c->type == CTL_NUM && 2438 strcmp(c->group, "") == 0 && 2439 strcmp(c->node0.name, "output") == 0 && 2440 strcmp(c->func, "level") == 0) 2441 found = 1; 2442 } 2443 2444 if (d->master_enabled && found) { 2445 if (log_level >= 2) { 2446 dev_log(d); 2447 log_puts(": software master level control disabled\n"); 2448 } 2449 d->master_enabled = 0; 2450 dev_rmctl(d, CTLADDR_MASTER); 2451 } else if (!d->master_enabled && !found) { 2452 if (log_level >= 2) { 2453 dev_log(d); 2454 log_puts(": software master level control enabled\n"); 2455 } 2456 d->master_enabled = 1; 2457 dev_addctl(d, "", CTL_NUM, CTLADDR_MASTER, 2458 "output", -1, "level", NULL, -1, 127, d->master); 2459 } 2460 2461 for (s = d->ctlslot, i = DEV_NCTLSLOT; i > 0; i--, s++) { 2462 if (s->ops) 2463 s->ops->sync(s->arg); 2464 } 2465 } 2466 2467 int 2468 dev_setctl(struct dev *d, int addr, int val) 2469 { 2470 struct ctl *c; 2471 int num; 2472 2473 c = d->ctl_list; 2474 for (;;) { 2475 if (c == NULL) { 2476 if (log_level >= 3) { 2477 dev_log(d); 2478 log_puts(": "); 2479 log_putu(addr); 2480 log_puts(": no such ctl address\n"); 2481 } 2482 return 0; 2483 } 2484 if (c->type != CTL_NONE && c->addr == addr) 2485 break; 2486 c = c->next; 2487 } 2488 if (c->curval == val) { 2489 if (log_level >= 3) { 2490 ctl_log(c); 2491 log_puts(": already set\n"); 2492 } 2493 return 1; 2494 } 2495 if (val < 0 || val > c->maxval) { 2496 if (log_level >= 3) { 2497 dev_log(d); 2498 log_puts(": "); 2499 log_putu(val); 2500 log_puts(": ctl val out of bounds\n"); 2501 } 2502 return 0; 2503 } 2504 if (addr >= CTLADDR_END) { 2505 if (log_level >= 3) { 2506 ctl_log(c); 2507 log_puts(": marked as dirty\n"); 2508 } 2509 c->dirty = 1; 2510 dev_ref(d); 2511 } else { 2512 if (addr >= CTLADDR_ALT_SEL) { 2513 if (val) { 2514 num = addr - CTLADDR_ALT_SEL; 2515 dev_setalt(d, num); 2516 } 2517 return 1; 2518 } else if (addr == CTLADDR_MASTER) { 2519 if (d->master_enabled) { 2520 dev_master(d, val); 2521 dev_midi_master(d); 2522 } 2523 } else { 2524 num = addr - CTLADDR_SLOT_LEVEL(0); 2525 slot_setvol(d->slot + num, val); 2526 dev_midi_vol(d, d->slot + num); 2527 } 2528 c->val_mask = ~0U; 2529 } 2530 c->curval = val; 2531 return 1; 2532 } 2533 2534 int 2535 dev_onval(struct dev *d, int addr, int val) 2536 { 2537 struct ctl *c; 2538 2539 c = d->ctl_list; 2540 for (;;) { 2541 if (c == NULL) 2542 return 0; 2543 if (c->type != CTL_NONE && c->addr == addr) 2544 break; 2545 c = c->next; 2546 } 2547 c->curval = val; 2548 c->val_mask = ~0U; 2549 return 1; 2550 } 2551 2552 void 2553 dev_label(struct dev *d, int i) 2554 { 2555 struct ctl *c; 2556 char name[CTL_NAMEMAX]; 2557 2558 slot_ctlname(&d->slot[i], name, CTL_NAMEMAX); 2559 2560 c = d->ctl_list; 2561 for (;;) { 2562 if (c == NULL) { 2563 dev_addctl(d, "app", CTL_NUM, 2564 CTLADDR_SLOT_LEVEL(i), 2565 name, -1, "level", 2566 NULL, -1, 127, d->slot[i].vol); 2567 return; 2568 } 2569 if (c->addr == CTLADDR_SLOT_LEVEL(i)) 2570 break; 2571 c = c->next; 2572 } 2573 if (strcmp(c->node0.name, name) == 0) 2574 return; 2575 strlcpy(c->node0.name, name, CTL_NAMEMAX); 2576 c->desc_mask = ~0; 2577 } 2578 2579 int 2580 dev_nctl(struct dev *d) 2581 { 2582 struct ctl *c; 2583 int n; 2584 2585 n = 0; 2586 for (c = d->ctl_list; c != NULL; c = c->next) 2587 n++; 2588 return n; 2589 } 2590