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