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