1 /* $OpenBSD: dev.c,v 1.26 2016/05/25 05:34:23 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 "sysex.h" 27 #include "utils.h" 28 29 void zomb_onmove(void *); 30 void zomb_onvol(void *); 31 void zomb_fill(void *); 32 void zomb_flush(void *); 33 void zomb_eof(void *); 34 void zomb_exit(void *); 35 36 void dev_log(struct dev *); 37 void dev_midi_qfr(struct dev *, int); 38 void dev_midi_full(struct dev *); 39 void dev_midi_vol(struct dev *, struct slot *); 40 void dev_midi_master(struct dev *); 41 void dev_midi_slotdesc(struct dev *, struct slot *); 42 void dev_midi_dump(struct dev *); 43 void dev_midi_imsg(void *, unsigned char *, int); 44 void dev_midi_omsg(void *, unsigned char *, int); 45 void dev_midi_fill(void *, int); 46 void dev_midi_exit(void *); 47 48 int play_filt_resamp(struct slot *, void *, void *, int); 49 int play_filt_dec(struct slot *, void *, void *, int); 50 void dev_mix_badd(struct dev *, struct slot *); 51 void dev_mix_adjvol(struct dev *); 52 int rec_filt_resamp(struct slot *, void *, void *, int); 53 int rec_filt_enc(struct slot *, void *, void *, int); 54 void dev_sub_bcopy(struct dev *, struct slot *); 55 56 void dev_onmove(struct dev *, int); 57 void dev_master(struct dev *, unsigned int); 58 void dev_cycle(struct dev *); 59 int dev_getpos(struct dev *); 60 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, 61 unsigned int, unsigned int, unsigned int, unsigned int); 62 void dev_adjpar(struct dev *, int, int, int); 63 int dev_open(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_log(struct slot *); 79 struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int); 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_start(struct slot *); 85 void slot_detach(struct slot *); 86 void slot_stop(struct slot *); 87 void slot_skip_update(struct slot *); 88 void slot_write(struct slot *); 89 void slot_read(struct slot *); 90 int slot_skip(struct slot *); 91 92 struct midiops dev_midiops = { 93 dev_midi_imsg, 94 dev_midi_omsg, 95 dev_midi_fill, 96 dev_midi_exit 97 }; 98 99 struct slotops zomb_slotops = { 100 zomb_onmove, 101 zomb_onvol, 102 zomb_fill, 103 zomb_flush, 104 zomb_eof, 105 zomb_exit 106 }; 107 108 struct dev *dev_list = NULL; 109 unsigned int dev_sndnum = 0; 110 111 void 112 dev_log(struct dev *d) 113 { 114 #ifdef DEBUG 115 static char *pstates[] = { 116 "cfg", "ini", "run" 117 }; 118 #endif 119 log_puts("snd"); 120 log_putu(d->num); 121 #ifdef DEBUG 122 if (log_level >= 3) { 123 log_puts(" pst="); 124 log_puts(pstates[d->pstate]); 125 } 126 #endif 127 } 128 129 void 130 slot_log(struct slot *s) 131 { 132 #ifdef DEBUG 133 static char *pstates[] = { 134 "ini", "sta", "rdy", "run", "stp", "mid" 135 }; 136 static char *tstates[] = { 137 "off", "sta", "run", "stp" 138 }; 139 #endif 140 log_puts(s->name); 141 log_putu(s->unit); 142 #ifdef DEBUG 143 if (log_level >= 3) { 144 log_puts(" vol="); 145 log_putu(s->vol); 146 if (s->ops) { 147 log_puts(",pst="); 148 log_puts(pstates[s->pstate]); 149 log_puts(",mmc="); 150 log_puts(tstates[s->tstate]); 151 } 152 } 153 #endif 154 } 155 156 void 157 zomb_onmove(void *arg) 158 { 159 } 160 161 void 162 zomb_onvol(void *arg) 163 { 164 } 165 166 void 167 zomb_fill(void *arg) 168 { 169 } 170 171 void 172 zomb_flush(void *arg) 173 { 174 } 175 176 void 177 zomb_eof(void *arg) 178 { 179 struct slot *s = arg; 180 181 #ifdef DEBUG 182 if (log_level >= 3) { 183 slot_log(s); 184 log_puts(": zomb_eof\n"); 185 } 186 #endif 187 s->ops = NULL; 188 } 189 190 void 191 zomb_exit(void *arg) 192 { 193 #ifdef DEBUG 194 struct slot *s = arg; 195 196 if (log_level >= 3) { 197 slot_log(s); 198 log_puts(": zomb_exit\n"); 199 } 200 #endif 201 } 202 203 /* 204 * send a quarter frame MTC message 205 */ 206 void 207 dev_midi_qfr(struct dev *d, int delta) 208 { 209 unsigned char buf[2]; 210 unsigned int data; 211 int qfrlen; 212 213 d->mtc.delta += delta * MTC_SEC; 214 qfrlen = d->rate * (MTC_SEC / (4 * d->mtc.fps)); 215 while (d->mtc.delta >= qfrlen) { 216 switch (d->mtc.qfr) { 217 case 0: 218 data = d->mtc.fr & 0xf; 219 break; 220 case 1: 221 data = d->mtc.fr >> 4; 222 break; 223 case 2: 224 data = d->mtc.sec & 0xf; 225 break; 226 case 3: 227 data = d->mtc.sec >> 4; 228 break; 229 case 4: 230 data = d->mtc.min & 0xf; 231 break; 232 case 5: 233 data = d->mtc.min >> 4; 234 break; 235 case 6: 236 data = d->mtc.hr & 0xf; 237 break; 238 case 7: 239 data = (d->mtc.hr >> 4) | (d->mtc.fps_id << 1); 240 /* 241 * tick messages are sent 2 frames ahead 242 */ 243 d->mtc.fr += 2; 244 if (d->mtc.fr < d->mtc.fps) 245 break; 246 d->mtc.fr -= d->mtc.fps; 247 d->mtc.sec++; 248 if (d->mtc.sec < 60) 249 break; 250 d->mtc.sec = 0; 251 d->mtc.min++; 252 if (d->mtc.min < 60) 253 break; 254 d->mtc.min = 0; 255 d->mtc.hr++; 256 if (d->mtc.hr < 24) 257 break; 258 d->mtc.hr = 0; 259 break; 260 default: 261 /* NOTREACHED */ 262 data = 0; 263 } 264 buf[0] = 0xf1; 265 buf[1] = (d->mtc.qfr << 4) | data; 266 d->mtc.qfr++; 267 d->mtc.qfr &= 7; 268 midi_send(d->midi, buf, 2); 269 d->mtc.delta -= qfrlen; 270 } 271 } 272 273 /* 274 * send a full frame MTC message 275 */ 276 void 277 dev_midi_full(struct dev *d) 278 { 279 struct sysex x; 280 unsigned int fps; 281 282 d->mtc.delta = MTC_SEC * dev_getpos(d); 283 if (d->rate % (30 * 4 * d->round) == 0) { 284 d->mtc.fps_id = MTC_FPS_30; 285 d->mtc.fps = 30; 286 } else if (d->rate % (25 * 4 * d->round) == 0) { 287 d->mtc.fps_id = MTC_FPS_25; 288 d->mtc.fps = 25; 289 } else { 290 d->mtc.fps_id = MTC_FPS_24; 291 d->mtc.fps = 24; 292 } 293 #ifdef DEBUG 294 if (log_level >= 3) { 295 dev_log(d); 296 log_puts(": mtc full frame at "); 297 log_puti(d->mtc.delta); 298 log_puts(", "); 299 log_puti(d->mtc.fps); 300 log_puts(" fps\n"); 301 } 302 #endif 303 fps = d->mtc.fps; 304 d->mtc.hr = (d->mtc.origin / (MTC_SEC * 3600)) % 24; 305 d->mtc.min = (d->mtc.origin / (MTC_SEC * 60)) % 60; 306 d->mtc.sec = (d->mtc.origin / (MTC_SEC)) % 60; 307 d->mtc.fr = (d->mtc.origin / (MTC_SEC / fps)) % fps; 308 309 x.start = SYSEX_START; 310 x.type = SYSEX_TYPE_RT; 311 x.dev = SYSEX_DEV_ANY; 312 x.id0 = SYSEX_MTC; 313 x.id1 = SYSEX_MTC_FULL; 314 x.u.full.hr = d->mtc.hr | (d->mtc.fps_id << 5); 315 x.u.full.min = d->mtc.min; 316 x.u.full.sec = d->mtc.sec; 317 x.u.full.fr = d->mtc.fr; 318 x.u.full.end = SYSEX_END; 319 d->mtc.qfr = 0; 320 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full)); 321 } 322 323 /* 324 * send a volume change MIDI message 325 */ 326 void 327 dev_midi_vol(struct dev *d, struct slot *s) 328 { 329 unsigned char msg[3]; 330 331 msg[0] = MIDI_CTL | (s - d->slot); 332 msg[1] = MIDI_CTL_VOL; 333 msg[2] = s->vol; 334 midi_send(d->midi, msg, 3); 335 } 336 337 /* 338 * send a master volume MIDI message 339 */ 340 void 341 dev_midi_master(struct dev *d) 342 { 343 struct sysex x; 344 345 memset(&x, 0, sizeof(struct sysex)); 346 x.start = SYSEX_START; 347 x.type = SYSEX_TYPE_RT; 348 x.dev = SYSEX_DEV_ANY; 349 x.id0 = SYSEX_CONTROL; 350 x.id1 = SYSEX_MASTER; 351 x.u.master.fine = 0; 352 x.u.master.coarse = d->master; 353 x.u.master.end = SYSEX_END; 354 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master)); 355 } 356 357 /* 358 * send a sndiod-specific slot description MIDI message 359 */ 360 void 361 dev_midi_slotdesc(struct dev *d, struct slot *s) 362 { 363 struct sysex x; 364 365 memset(&x, 0, sizeof(struct sysex)); 366 x.start = SYSEX_START; 367 x.type = SYSEX_TYPE_EDU; 368 x.dev = SYSEX_DEV_ANY; 369 x.id0 = SYSEX_AUCAT; 370 x.id1 = SYSEX_AUCAT_SLOTDESC; 371 if (*s->name != '\0') { 372 snprintf((char *)x.u.slotdesc.name, SYSEX_NAMELEN, 373 "%s%u", s->name, s->unit); 374 } 375 x.u.slotdesc.chan = s - d->slot; 376 x.u.slotdesc.end = SYSEX_END; 377 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc)); 378 } 379 380 void 381 dev_midi_dump(struct dev *d) 382 { 383 struct sysex x; 384 struct slot *s; 385 int i; 386 387 dev_midi_master(d); 388 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 389 dev_midi_slotdesc(d, s); 390 dev_midi_vol(d, s); 391 } 392 x.start = SYSEX_START; 393 x.type = SYSEX_TYPE_EDU; 394 x.dev = SYSEX_DEV_ANY; 395 x.id0 = SYSEX_AUCAT; 396 x.id1 = SYSEX_AUCAT_DUMPEND; 397 x.u.dumpend.end = SYSEX_END; 398 midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend)); 399 } 400 401 void 402 dev_midi_imsg(void *arg, unsigned char *msg, int len) 403 { 404 #ifdef DEBUG 405 struct dev *d = arg; 406 407 dev_log(d); 408 log_puts(": can't receive midi messages\n"); 409 panic(); 410 #endif 411 } 412 413 void 414 dev_midi_omsg(void *arg, unsigned char *msg, int len) 415 { 416 struct dev *d = arg; 417 struct sysex *x; 418 unsigned int fps, chan; 419 420 if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) { 421 chan = msg[0] & MIDI_CHANMASK; 422 if (chan >= DEV_NSLOT) 423 return; 424 slot_setvol(d->slot + chan, msg[2]); 425 return; 426 } 427 x = (struct sysex *)msg; 428 if (x->start != SYSEX_START) 429 return; 430 if (len < SYSEX_SIZE(empty)) 431 return; 432 switch (x->type) { 433 case SYSEX_TYPE_RT: 434 if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) { 435 if (len == SYSEX_SIZE(master)) 436 dev_master(d, x->u.master.coarse); 437 return; 438 } 439 if (x->id0 != SYSEX_MMC) 440 return; 441 switch (x->id1) { 442 case SYSEX_MMC_STOP: 443 if (len != SYSEX_SIZE(stop)) 444 return; 445 if (log_level >= 2) { 446 dev_log(d); 447 log_puts(": mmc stop\n"); 448 } 449 dev_mmcstop(d); 450 break; 451 case SYSEX_MMC_START: 452 if (len != SYSEX_SIZE(start)) 453 return; 454 if (log_level >= 2) { 455 dev_log(d); 456 log_puts(": mmc start\n"); 457 } 458 dev_mmcstart(d); 459 break; 460 case SYSEX_MMC_LOC: 461 if (len != SYSEX_SIZE(loc) || 462 x->u.loc.len != SYSEX_MMC_LOC_LEN || 463 x->u.loc.cmd != SYSEX_MMC_LOC_CMD) 464 return; 465 switch (x->u.loc.hr >> 5) { 466 case MTC_FPS_24: 467 fps = 24; 468 break; 469 case MTC_FPS_25: 470 fps = 25; 471 break; 472 case MTC_FPS_30: 473 fps = 30; 474 break; 475 default: 476 dev_mmcstop(d); 477 return; 478 } 479 dev_mmcloc(d, 480 (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC + 481 x->u.loc.min * 60 * MTC_SEC + 482 x->u.loc.sec * MTC_SEC + 483 x->u.loc.fr * (MTC_SEC / fps) + 484 x->u.loc.cent * (MTC_SEC / 100 / fps)); 485 break; 486 } 487 break; 488 case SYSEX_TYPE_EDU: 489 if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ) 490 return; 491 if (len != SYSEX_SIZE(dumpreq)) 492 return; 493 dev_midi_dump(d); 494 break; 495 } 496 } 497 498 void 499 dev_midi_fill(void *arg, int count) 500 { 501 /* nothing to do */ 502 } 503 504 void 505 dev_midi_exit(void *arg) 506 { 507 struct dev *d = arg; 508 509 if (log_level >= 1) { 510 dev_log(d); 511 log_puts(": midi end point died\n"); 512 } 513 if (d->pstate != DEV_CFG) 514 dev_close(d); 515 } 516 517 int 518 slot_skip(struct slot *s) 519 { 520 unsigned char *data = (unsigned char *)0xdeadbeef; /* please gcc */ 521 int max, count; 522 523 max = s->skip; 524 while (s->skip > 0) { 525 if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) { 526 data = abuf_wgetblk(&s->sub.buf, &count); 527 if (count < s->round * s->sub.bpf) 528 break; 529 } 530 if (s->mode & MODE_PLAY) { 531 if (s->mix.buf.used < s->round * s->mix.bpf) 532 break; 533 } 534 #ifdef DEBUG 535 if (log_level >= 4) { 536 slot_log(s); 537 log_puts(": skipped a cycle\n"); 538 } 539 #endif 540 if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) { 541 if (s->sub.encbuf) 542 enc_sil_do(&s->sub.enc, data, s->round); 543 else 544 memset(data, 0, s->round * s->sub.bpf); 545 abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf); 546 } 547 if (s->mode & MODE_PLAY) { 548 abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); 549 } 550 s->skip--; 551 } 552 return max - s->skip; 553 } 554 555 int 556 play_filt_resamp(struct slot *s, void *res_in, void *out, int todo) 557 { 558 int i, offs, vol, nch; 559 void *in; 560 561 if (s->mix.resampbuf) { 562 todo = resamp_do(&s->mix.resamp, 563 res_in, s->mix.resampbuf, todo); 564 in = s->mix.resampbuf; 565 } else 566 in = res_in; 567 568 nch = s->mix.cmap.nch; 569 vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join; 570 cmap_add(&s->mix.cmap, in, out, vol, todo); 571 572 offs = 0; 573 for (i = s->mix.join - 1; i > 0; i--) { 574 offs += nch; 575 cmap_add(&s->mix.cmap, (adata_t *)in + offs, out, vol, todo); 576 } 577 offs = 0; 578 for (i = s->mix.expand - 1; i > 0; i--) { 579 offs += nch; 580 cmap_add(&s->mix.cmap, in, (adata_t *)out + offs, vol, todo); 581 } 582 return todo; 583 } 584 585 int 586 play_filt_dec(struct slot *s, void *in, void *out, int todo) 587 { 588 void *tmp; 589 590 tmp = s->mix.decbuf; 591 if (tmp) 592 dec_do(&s->mix.dec, in, tmp, todo); 593 return play_filt_resamp(s, tmp ? tmp : in, out, todo); 594 } 595 596 /* 597 * mix "todo" frames from the input block over the output block; if 598 * there are frames to drop, less frames are consumed from the input 599 */ 600 void 601 dev_mix_badd(struct dev *d, struct slot *s) 602 { 603 adata_t *idata, *odata; 604 int icount; 605 606 odata = DEV_PBUF(d); 607 idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount); 608 #ifdef DEBUG 609 if (icount < s->round * s->mix.bpf) { 610 slot_log(s); 611 log_puts(": not enough data to mix ("); 612 log_putu(icount); 613 log_puts("bytes)\n"); 614 panic(); 615 } 616 #endif 617 play_filt_dec(s, idata, odata, s->round); 618 abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); 619 } 620 621 /* 622 * Normalize input levels. 623 */ 624 void 625 dev_mix_adjvol(struct dev *d) 626 { 627 unsigned int n; 628 struct slot *i, *j; 629 int weight; 630 631 for (i = d->slot_list; i != NULL; i = i->next) { 632 if (!(i->mode & MODE_PLAY)) 633 continue; 634 weight = ADATA_UNIT; 635 if (d->autovol) { 636 /* 637 * count the number of inputs that have 638 * overlapping channel sets 639 */ 640 n = 0; 641 for (j = d->slot_list; j != NULL; j = j->next) { 642 if (!(j->mode & MODE_PLAY)) 643 continue; 644 if (i->mix.slot_cmin <= j->mix.slot_cmax && 645 i->mix.slot_cmax >= j->mix.slot_cmin) 646 n++; 647 } 648 weight /= n; 649 } 650 if (weight > i->mix.maxweight) 651 weight = i->mix.maxweight; 652 i->mix.weight = ADATA_MUL(weight, MIDI_TO_ADATA(d->master)); 653 #ifdef DEBUG 654 if (log_level >= 3) { 655 slot_log(i); 656 log_puts(": set weight: "); 657 log_puti(i->mix.weight); 658 log_puts("/"); 659 log_puti(i->mix.maxweight); 660 log_puts("\n"); 661 } 662 #endif 663 } 664 } 665 666 int 667 rec_filt_resamp(struct slot *s, void *in, void *res_out, int todo) 668 { 669 int i, vol, offs, nch; 670 void *out = res_out; 671 672 out = (s->sub.resampbuf) ? s->sub.resampbuf : res_out; 673 674 nch = s->sub.cmap.nch; 675 vol = ADATA_UNIT / s->sub.join; 676 cmap_copy(&s->sub.cmap, in, out, vol, todo); 677 678 offs = 0; 679 for (i = s->sub.join - 1; i > 0; i--) { 680 offs += nch; 681 cmap_add(&s->sub.cmap, (adata_t *)in + offs, out, vol, todo); 682 } 683 offs = 0; 684 for (i = s->sub.expand - 1; i > 0; i--) { 685 offs += nch; 686 cmap_copy(&s->sub.cmap, in, (adata_t *)out + offs, vol, todo); 687 } 688 if (s->sub.resampbuf) { 689 todo = resamp_do(&s->sub.resamp, 690 s->sub.resampbuf, res_out, todo); 691 } 692 return todo; 693 } 694 695 int 696 rec_filt_enc(struct slot *s, void *in, void *out, int todo) 697 { 698 void *tmp; 699 700 tmp = s->sub.encbuf; 701 todo = rec_filt_resamp(s, in, tmp ? tmp : out, todo); 702 if (tmp) 703 enc_do(&s->sub.enc, tmp, out, todo); 704 return todo; 705 } 706 707 /* 708 * Copy data from slot to device 709 */ 710 void 711 dev_sub_bcopy(struct dev *d, struct slot *s) 712 { 713 adata_t *idata, *odata; 714 int ocount, moffs; 715 716 if (s->mode & MODE_MON) { 717 moffs = d->poffs + d->round; 718 if (moffs == d->psize) 719 moffs = 0; 720 idata = d->pbuf + moffs * d->pchan; 721 } else 722 idata = d->rbuf; 723 odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount); 724 #ifdef DEBUG 725 if (ocount < s->round * s->sub.bpf) { 726 log_puts("dev_sub_bcopy: not enough space\n"); 727 panic(); 728 } 729 #endif 730 ocount = rec_filt_enc(s, idata, odata, d->round); 731 abuf_wcommit(&s->sub.buf, ocount * s->sub.bpf); 732 } 733 734 /* 735 * run a one block cycle: consume one recorded block from 736 * rbuf and produce one play block in pbuf 737 */ 738 void 739 dev_cycle(struct dev *d) 740 { 741 struct slot *s, **ps; 742 unsigned char *base; 743 int nsamp; 744 745 /* 746 * check if the device is actually used. If it isn't, 747 * then close it 748 */ 749 if (d->slot_list == NULL && d->tstate != MMC_RUN) { 750 if (log_level >= 2) { 751 dev_log(d); 752 log_puts(": device stopped\n"); 753 } 754 dev_sio_stop(d); 755 d->pstate = DEV_INIT; 756 if (d->refcnt == 0) 757 dev_close(d); 758 return; 759 } 760 761 if (d->prime > 0) { 762 #ifdef DEBUG 763 if (log_level >= 4) { 764 dev_log(d); 765 log_puts(": empty cycle, prime = "); 766 log_putu(d->prime); 767 log_puts("\n"); 768 } 769 #endif 770 base = (unsigned char *)DEV_PBUF(d); 771 nsamp = d->round * d->pchan; 772 memset(base, 0, nsamp * sizeof(adata_t)); 773 if (d->encbuf) { 774 enc_do(&d->enc, (unsigned char *)DEV_PBUF(d), 775 d->encbuf, d->round); 776 } 777 d->prime -= d->round; 778 return; 779 } 780 781 d->delta -= d->round; 782 #ifdef DEBUG 783 if (log_level >= 4) { 784 dev_log(d); 785 log_puts(": full cycle: delta = "); 786 log_puti(d->delta); 787 if (d->mode & MODE_PLAY) { 788 log_puts(", poffs = "); 789 log_puti(d->poffs); 790 } 791 log_puts("\n"); 792 } 793 #endif 794 if (d->mode & MODE_PLAY) { 795 base = (unsigned char *)DEV_PBUF(d); 796 nsamp = d->round * d->pchan; 797 memset(base, 0, nsamp * sizeof(adata_t)); 798 } 799 if ((d->mode & MODE_REC) && d->decbuf) 800 dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round); 801 ps = &d->slot_list; 802 while ((s = *ps) != NULL) { 803 #ifdef DEBUG 804 if (log_level >= 4) { 805 slot_log(s); 806 log_puts(": running"); 807 log_puts(", skip = "); 808 log_puti(s->skip); 809 log_puts("\n"); 810 } 811 #endif 812 /* 813 * skip cycles for XRUN_SYNC correction 814 */ 815 slot_skip(s); 816 if (s->skip < 0) { 817 s->skip++; 818 ps = &s->next; 819 continue; 820 } 821 822 #ifdef DEBUG 823 if (s->pstate == SLOT_STOP && !(s->mode & MODE_PLAY)) { 824 slot_log(s); 825 log_puts(": rec-only slots can't be drained\n"); 826 panic(); 827 } 828 #endif 829 /* 830 * check if stopped stream finished draining 831 */ 832 if (s->pstate == SLOT_STOP && 833 s->mix.buf.used < s->round * s->mix.bpf) { 834 /* 835 * partial blocks are zero-filled by socket 836 * layer, so s->mix.buf.used == 0 and we can 837 * destroy the buffer 838 */ 839 s->pstate = SLOT_INIT; 840 abuf_done(&s->mix.buf); 841 if (s->mix.decbuf) 842 xfree(s->mix.decbuf); 843 if (s->mix.resampbuf) 844 xfree(s->mix.resampbuf); 845 s->ops->eof(s->arg); 846 *ps = s->next; 847 dev_mix_adjvol(d); 848 continue; 849 } 850 851 /* 852 * check for xruns 853 */ 854 if (((s->mode & MODE_PLAY) && 855 s->mix.buf.used < s->round * s->mix.bpf) || 856 ((s->mode & MODE_RECMASK) && 857 s->sub.buf.len - s->sub.buf.used < 858 s->round * s->sub.bpf)) { 859 860 #ifdef DEBUG 861 if (log_level >= 3) { 862 slot_log(s); 863 log_puts(": xrun, pause cycle\n"); 864 } 865 #endif 866 if (s->xrun == XRUN_IGNORE) { 867 s->delta -= s->round; 868 ps = &s->next; 869 } else if (s->xrun == XRUN_SYNC) { 870 s->skip++; 871 ps = &s->next; 872 } else if (s->xrun == XRUN_ERROR) { 873 s->ops->exit(s->arg); 874 *ps = s->next; 875 } else { 876 #ifdef DEBUG 877 slot_log(s); 878 log_puts(": bad xrun mode\n"); 879 panic(); 880 #endif 881 } 882 continue; 883 } 884 if ((s->mode & MODE_RECMASK) && !(s->pstate == SLOT_STOP)) { 885 if (s->sub.prime == 0) { 886 dev_sub_bcopy(d, s); 887 s->ops->flush(s->arg); 888 } else { 889 #ifdef DEBUG 890 if (log_level >= 3) { 891 slot_log(s); 892 log_puts(": prime = "); 893 log_puti(s->sub.prime); 894 log_puts("\n"); 895 } 896 #endif 897 s->sub.prime--; 898 } 899 } 900 if (s->mode & MODE_PLAY) { 901 dev_mix_badd(d, s); 902 if (s->pstate != SLOT_STOP) 903 s->ops->fill(s->arg); 904 } 905 ps = &s->next; 906 } 907 if ((d->mode & MODE_PLAY) && d->encbuf) { 908 enc_do(&d->enc, (unsigned char *)DEV_PBUF(d), 909 d->encbuf, d->round); 910 } 911 } 912 913 /* 914 * called at every clock tick by the device 915 */ 916 void 917 dev_onmove(struct dev *d, int delta) 918 { 919 long long pos; 920 struct slot *s, *snext; 921 922 d->delta += delta; 923 924 for (s = d->slot_list; s != NULL; s = snext) { 925 /* 926 * s->ops->onmove() may remove the slot 927 */ 928 snext = s->next; 929 pos = (long long)delta * s->round + s->delta_rem; 930 s->delta_rem = pos % d->round; 931 s->delta += pos / (int)d->round; 932 if (s->delta >= 0) 933 s->ops->onmove(s->arg); 934 } 935 if (d->tstate == MMC_RUN) 936 dev_midi_qfr(d, delta); 937 } 938 939 void 940 dev_master(struct dev *d, unsigned int master) 941 { 942 if (log_level >= 2) { 943 dev_log(d); 944 log_puts(": master volume set to "); 945 log_putu(master); 946 log_puts("\n"); 947 } 948 d->master = master; 949 if (d->mode & MODE_PLAY) 950 dev_mix_adjvol(d); 951 } 952 953 /* 954 * return the latency that a stream would have if it's attached 955 */ 956 int 957 dev_getpos(struct dev *d) 958 { 959 return (d->mode & MODE_PLAY) ? -d->bufsz : 0; 960 } 961 962 /* 963 * Create a sndio device 964 */ 965 struct dev * 966 dev_new(char *path, struct aparams *par, 967 unsigned int mode, unsigned int bufsz, unsigned int round, 968 unsigned int rate, unsigned int hold, unsigned int autovol) 969 { 970 struct dev *d; 971 unsigned int i; 972 973 if (dev_sndnum == DEV_NMAX) { 974 if (log_level >= 1) 975 log_puts("too many devices\n"); 976 return NULL; 977 } 978 d = xmalloc(sizeof(struct dev)); 979 d->path = xstrdup(path); 980 d->num = dev_sndnum++; 981 982 /* 983 * XXX: below, we allocate a midi input buffer, since we don't 984 * receive raw midi data, so no need to allocate a input 985 * ibuf. Possibly set imsg & fill callbacks to NULL and 986 * use this to in midi_new() to check if buffers need to be 987 * allocated 988 */ 989 d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT); 990 midi_tag(d->midi, d->num); 991 d->reqpar = *par; 992 d->reqmode = mode; 993 d->reqpchan = d->reqrchan = 0; 994 d->reqbufsz = bufsz; 995 d->reqround = round; 996 d->reqrate = rate; 997 d->hold = hold; 998 d->autovol = autovol; 999 d->refcnt = 0; 1000 d->pstate = DEV_CFG; 1001 d->serial = 0; 1002 for (i = 0; i < DEV_NSLOT; i++) { 1003 d->slot[i].unit = i; 1004 d->slot[i].ops = NULL; 1005 d->slot[i].vol = MIDI_MAXCTL; 1006 d->slot[i].tstate = MMC_OFF; 1007 d->slot[i].serial = d->serial++; 1008 strlcpy(d->slot[i].name, "prog", SLOT_NAMEMAX); 1009 } 1010 d->slot_list = NULL; 1011 d->master = MIDI_MAXCTL; 1012 d->mtc.origin = 0; 1013 d->tstate = MMC_STOP; 1014 d->next = dev_list; 1015 dev_list = d; 1016 return d; 1017 } 1018 1019 /* 1020 * adjust device parameters and mode 1021 */ 1022 void 1023 dev_adjpar(struct dev *d, int mode, 1024 int pmax, int rmax) 1025 { 1026 d->reqmode |= mode & MODE_AUDIOMASK; 1027 if (mode & MODE_PLAY) { 1028 if (d->reqpchan < pmax + 1) 1029 d->reqpchan = pmax + 1; 1030 } 1031 if (mode & MODE_REC) { 1032 if (d->reqrchan < rmax + 1) 1033 d->reqrchan = rmax + 1; 1034 } 1035 } 1036 1037 /* 1038 * Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer, 1039 * monitor, midi control, and any necessary conversions. 1040 */ 1041 int 1042 dev_open(struct dev *d) 1043 { 1044 d->mode = d->reqmode; 1045 d->round = d->reqround; 1046 d->bufsz = d->reqbufsz; 1047 d->rate = d->reqrate; 1048 d->pchan = d->reqpchan; 1049 d->rchan = d->reqrchan; 1050 d->par = d->reqpar; 1051 if (d->pchan == 0) 1052 d->pchan = 2; 1053 if (d->rchan == 0) 1054 d->rchan = 2; 1055 if (!dev_sio_open(d)) { 1056 if (log_level >= 1) { 1057 dev_log(d); 1058 log_puts(": "); 1059 log_puts(d->path); 1060 log_puts(": failed to open audio device\n"); 1061 } 1062 return 0; 1063 } 1064 if (d->mode & MODE_REC) { 1065 /* 1066 * Create device <-> demuxer buffer 1067 */ 1068 d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t)); 1069 1070 /* 1071 * Insert a converter, if needed. 1072 */ 1073 if (!aparams_native(&d->par)) { 1074 dec_init(&d->dec, &d->par, d->rchan); 1075 d->decbuf = xmalloc(d->round * d->rchan * d->par.bps); 1076 } else 1077 d->decbuf = NULL; 1078 } 1079 if (d->mode & MODE_PLAY) { 1080 /* 1081 * Create device <-> mixer buffer 1082 */ 1083 d->poffs = 0; 1084 d->psize = d->bufsz + d->round; 1085 d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t)); 1086 d->mode |= MODE_MON; 1087 1088 /* 1089 * Append a converter, if needed. 1090 */ 1091 if (!aparams_native(&d->par)) { 1092 enc_init(&d->enc, &d->par, d->pchan); 1093 d->encbuf = xmalloc(d->round * d->pchan * d->par.bps); 1094 } else 1095 d->encbuf = NULL; 1096 } 1097 d->pstate = DEV_INIT; 1098 if (log_level >= 2) { 1099 dev_log(d); 1100 log_puts(": "); 1101 log_putu(d->rate); 1102 log_puts("Hz, "); 1103 aparams_log(&d->par); 1104 if (d->mode & MODE_PLAY) { 1105 log_puts(", play 0:"); 1106 log_puti(d->pchan - 1); 1107 } 1108 if (d->mode & MODE_REC) { 1109 log_puts(", rec 0:"); 1110 log_puti(d->rchan - 1); 1111 } 1112 log_puts(", "); 1113 log_putu(d->bufsz / d->round); 1114 log_puts(" blocks of "); 1115 log_putu(d->round); 1116 log_puts(" frames\n"); 1117 } 1118 return 1; 1119 } 1120 1121 /* 1122 * force the device to go in DEV_CFG state, the caller is supposed to 1123 * ensure buffers are drained 1124 */ 1125 void 1126 dev_close(struct dev *d) 1127 { 1128 int i; 1129 struct slot *s; 1130 1131 #ifdef DEBUG 1132 if (log_level >= 3) { 1133 dev_log(d); 1134 log_puts(": closing\n"); 1135 } 1136 #endif 1137 d->pstate = DEV_CFG; 1138 for (s = d->slot, i = DEV_NSLOT; i > 0; i--, s++) { 1139 if (s->ops) 1140 s->ops->exit(s->arg); 1141 s->ops = NULL; 1142 } 1143 d->slot_list = NULL; 1144 dev_sio_close(d); 1145 if (d->mode & MODE_PLAY) { 1146 if (d->encbuf != NULL) 1147 xfree(d->encbuf); 1148 xfree(d->pbuf); 1149 } 1150 if (d->mode & MODE_REC) { 1151 if (d->decbuf != NULL) 1152 xfree(d->decbuf); 1153 xfree(d->rbuf); 1154 } 1155 } 1156 1157 int 1158 dev_ref(struct dev *d) 1159 { 1160 #ifdef DEBUG 1161 if (log_level >= 3) { 1162 dev_log(d); 1163 log_puts(": device requested\n"); 1164 } 1165 #endif 1166 if (d->pstate == DEV_CFG && !dev_open(d)) 1167 return 0; 1168 d->refcnt++; 1169 return 1; 1170 } 1171 1172 void 1173 dev_unref(struct dev *d) 1174 { 1175 #ifdef DEBUG 1176 if (log_level >= 3) { 1177 dev_log(d); 1178 log_puts(": device released\n"); 1179 } 1180 #endif 1181 d->refcnt--; 1182 if (d->refcnt == 0 && d->pstate == DEV_INIT) 1183 dev_close(d); 1184 } 1185 1186 /* 1187 * initialize the device with the current parameters 1188 */ 1189 int 1190 dev_init(struct dev *d) 1191 { 1192 if ((d->reqmode & MODE_AUDIOMASK) == 0) { 1193 #ifdef DEBUG 1194 dev_log(d); 1195 log_puts(": has no streams\n"); 1196 #endif 1197 return 0; 1198 } 1199 if (d->hold && !dev_ref(d)) 1200 return 0; 1201 return 1; 1202 } 1203 1204 /* 1205 * Unless the device is already in process of closing, request it to close 1206 */ 1207 void 1208 dev_done(struct dev *d) 1209 { 1210 #ifdef DEBUG 1211 if (log_level >= 3) { 1212 dev_log(d); 1213 log_puts(": draining\n"); 1214 } 1215 #endif 1216 if (d->tstate != MMC_STOP) 1217 dev_mmcstop(d); 1218 if (d->hold) 1219 dev_unref(d); 1220 } 1221 1222 struct dev * 1223 dev_bynum(int num) 1224 { 1225 struct dev *d; 1226 1227 for (d = dev_list; d != NULL; d = d->next) { 1228 if (d->num == num) 1229 return d; 1230 } 1231 return NULL; 1232 } 1233 1234 /* 1235 * Free the device 1236 */ 1237 void 1238 dev_del(struct dev *d) 1239 { 1240 struct dev **p; 1241 1242 #ifdef DEBUG 1243 if (log_level >= 3) { 1244 dev_log(d); 1245 log_puts(": deleting\n"); 1246 } 1247 #endif 1248 if (d->pstate != DEV_CFG) 1249 dev_close(d); 1250 for (p = &dev_list; *p != d; p = &(*p)->next) { 1251 #ifdef DEBUG 1252 if (*p == NULL) { 1253 dev_log(d); 1254 log_puts(": device to delete not on the list\n"); 1255 panic(); 1256 } 1257 #endif 1258 } 1259 midi_del(d->midi); 1260 *p = d->next; 1261 xfree(d->path); 1262 xfree(d); 1263 } 1264 1265 unsigned int 1266 dev_roundof(struct dev *d, unsigned int newrate) 1267 { 1268 return (d->round * newrate + d->rate / 2) / d->rate; 1269 } 1270 1271 /* 1272 * If the device is paused, then resume it. 1273 */ 1274 void 1275 dev_wakeup(struct dev *d) 1276 { 1277 if (d->pstate == DEV_INIT) { 1278 if (log_level >= 2) { 1279 dev_log(d); 1280 log_puts(": device started\n"); 1281 } 1282 if (d->mode & MODE_PLAY) { 1283 d->prime = d->bufsz; 1284 } else { 1285 d->prime = 0; 1286 } 1287 d->poffs = 0; 1288 1289 /* 1290 * empty cycles don't increment delta, so it's ok to 1291 * start at 0 1292 **/ 1293 d->delta = 0; 1294 1295 d->pstate = DEV_RUN; 1296 dev_sio_start(d); 1297 } 1298 } 1299 1300 /* 1301 * check that all clients controlled by MMC are ready to start, if so, 1302 * attach them all at the same position 1303 */ 1304 void 1305 dev_sync_attach(struct dev *d) 1306 { 1307 int i; 1308 struct slot *s; 1309 1310 if (d->tstate != MMC_START) { 1311 if (log_level >= 2) { 1312 dev_log(d); 1313 log_puts(": not started by mmc yet, waiting...\n"); 1314 } 1315 return; 1316 } 1317 for (i = 0; i < DEV_NSLOT; i++) { 1318 s = d->slot + i; 1319 if (!s->ops || s->tstate == MMC_OFF) 1320 continue; 1321 if (s->tstate != MMC_START || s->pstate != SLOT_READY) { 1322 #ifdef DEBUG 1323 if (log_level >= 3) { 1324 slot_log(s); 1325 log_puts(": not ready, start delayed\n"); 1326 } 1327 #endif 1328 return; 1329 } 1330 } 1331 if (!dev_ref(d)) 1332 return; 1333 for (i = 0; i < DEV_NSLOT; i++) { 1334 s = d->slot + i; 1335 if (!s->ops) 1336 continue; 1337 if (s->tstate == MMC_START) { 1338 #ifdef DEBUG 1339 if (log_level >= 3) { 1340 slot_log(s); 1341 log_puts(": started\n"); 1342 } 1343 #endif 1344 s->tstate = MMC_RUN; 1345 slot_attach(s); 1346 } 1347 } 1348 d->tstate = MMC_RUN; 1349 dev_midi_full(d); 1350 dev_wakeup(d); 1351 } 1352 1353 /* 1354 * start all slots simultaneously 1355 */ 1356 void 1357 dev_mmcstart(struct dev *d) 1358 { 1359 if (d->tstate == MMC_STOP) { 1360 d->tstate = MMC_START; 1361 dev_sync_attach(d); 1362 #ifdef DEBUG 1363 } else { 1364 if (log_level >= 3) { 1365 dev_log(d); 1366 log_puts(": ignoring mmc start\n"); 1367 } 1368 #endif 1369 } 1370 } 1371 1372 /* 1373 * stop all slots simultaneously 1374 */ 1375 void 1376 dev_mmcstop(struct dev *d) 1377 { 1378 switch (d->tstate) { 1379 case MMC_START: 1380 d->tstate = MMC_STOP; 1381 return; 1382 case MMC_RUN: 1383 d->tstate = MMC_STOP; 1384 dev_unref(d); 1385 break; 1386 default: 1387 #ifdef DEBUG 1388 if (log_level >= 3) { 1389 dev_log(d); 1390 log_puts(": ignored mmc stop\n"); 1391 } 1392 #endif 1393 return; 1394 } 1395 } 1396 1397 /* 1398 * relocate all slots simultaneously 1399 */ 1400 void 1401 dev_mmcloc(struct dev *d, unsigned int origin) 1402 { 1403 if (log_level >= 2) { 1404 dev_log(d); 1405 log_puts(": relocated to "); 1406 log_putu(origin); 1407 log_puts("\n"); 1408 } 1409 if (d->tstate == MMC_RUN) 1410 dev_mmcstop(d); 1411 d->mtc.origin = origin; 1412 if (d->tstate == MMC_RUN) 1413 dev_mmcstart(d); 1414 } 1415 1416 /* 1417 * allocate a new slot and register the given call-backs 1418 */ 1419 struct slot * 1420 slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) 1421 { 1422 char *p; 1423 char name[SLOT_NAMEMAX]; 1424 unsigned int i, unit, umap = 0; 1425 unsigned int ser, bestser, bestidx; 1426 struct slot *s; 1427 1428 /* 1429 * create a ``valid'' control name (lowcase, remove [^a-z], trucate) 1430 */ 1431 for (i = 0, p = who; ; p++) { 1432 if (i == SLOT_NAMEMAX - 1 || *p == '\0') { 1433 name[i] = '\0'; 1434 break; 1435 } else if (*p >= 'A' && *p <= 'Z') { 1436 name[i++] = *p + 'a' - 'A'; 1437 } else if (*p >= 'a' && *p <= 'z') 1438 name[i++] = *p; 1439 } 1440 if (i == 0) 1441 strlcpy(name, "noname", SLOT_NAMEMAX); 1442 1443 /* 1444 * find the first unused "unit" number for this name 1445 */ 1446 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1447 if (s->ops == NULL) 1448 continue; 1449 if (strcmp(s->name, name) == 0) 1450 umap |= (1 << s->unit); 1451 } 1452 for (unit = 0; ; unit++) { 1453 if ((umap & (1 << unit)) == 0) 1454 break; 1455 } 1456 1457 /* 1458 * find a free controller slot with the same name/unit 1459 */ 1460 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1461 if (s->ops == NULL && 1462 strcmp(s->name, name) == 0 && 1463 s->unit == unit) { 1464 #ifdef DEBUG 1465 if (log_level >= 3) { 1466 log_puts(name); 1467 log_putu(unit); 1468 log_puts(": reused\n"); 1469 } 1470 #endif 1471 goto found; 1472 } 1473 } 1474 1475 /* 1476 * couldn't find a matching slot, pick oldest free slot 1477 * and set its name/unit 1478 */ 1479 bestser = 0; 1480 bestidx = DEV_NSLOT; 1481 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1482 if (s->ops != NULL) 1483 continue; 1484 ser = d->serial - s->serial; 1485 if (ser > bestser) { 1486 bestser = ser; 1487 bestidx = i; 1488 } 1489 } 1490 if (bestidx == DEV_NSLOT) { 1491 if (log_level >= 1) { 1492 log_puts(name); 1493 log_putu(unit); 1494 log_puts(": out of sub-device slots\n"); 1495 } 1496 return NULL; 1497 } 1498 s = d->slot + bestidx; 1499 if (s->name[0] != '\0') 1500 s->vol = MIDI_MAXCTL; 1501 strlcpy(s->name, name, SLOT_NAMEMAX); 1502 s->serial = d->serial++; 1503 s->unit = unit; 1504 #ifdef DEBUG 1505 if (log_level >= 3) { 1506 log_puts(name); 1507 log_putu(unit); 1508 log_puts(": overwritten slot "); 1509 log_putu(bestidx); 1510 log_puts("\n"); 1511 } 1512 #endif 1513 1514 found: 1515 if (!dev_ref(d)) 1516 return NULL; 1517 s->dev = d; 1518 s->ops = ops; 1519 s->arg = arg; 1520 s->pstate = SLOT_INIT; 1521 s->tstate = MMC_OFF; 1522 1523 if ((mode & s->dev->mode) != mode) { 1524 if (log_level >= 1) { 1525 slot_log(s); 1526 log_puts(": requested mode not supported\n"); 1527 } 1528 return 0; 1529 } 1530 s->mode = mode; 1531 aparams_init(&s->par); 1532 if (s->mode & MODE_PLAY) { 1533 s->mix.slot_cmin = s->mix.dev_cmin = 0; 1534 s->mix.slot_cmax = s->mix.dev_cmax = d->pchan - 1; 1535 } 1536 if (s->mode & MODE_RECMASK) { 1537 s->sub.slot_cmin = s->sub.dev_cmin = 0; 1538 s->sub.slot_cmax = s->sub.dev_cmax = 1539 ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1; 1540 } 1541 s->xrun = XRUN_IGNORE; 1542 s->dup = 0; 1543 s->appbufsz = d->bufsz; 1544 s->round = d->round; 1545 s->rate = d->rate; 1546 s->mix.maxweight = ADATA_UNIT; 1547 dev_midi_slotdesc(d, s); 1548 dev_midi_vol(d, s); 1549 return s; 1550 } 1551 1552 /* 1553 * release the given slot 1554 */ 1555 void 1556 slot_del(struct slot *s) 1557 { 1558 s->arg = s; 1559 s->ops = &zomb_slotops; 1560 switch (s->pstate) { 1561 case SLOT_INIT: 1562 s->ops = NULL; 1563 break; 1564 case SLOT_START: 1565 case SLOT_READY: 1566 case SLOT_RUN: 1567 slot_stop(s); 1568 /* PASSTHROUGH */ 1569 case SLOT_STOP: 1570 break; 1571 } 1572 dev_unref(s->dev); 1573 s->dev = NULL; 1574 } 1575 1576 /* 1577 * change the slot play volume; called either by the slot or by MIDI 1578 */ 1579 void 1580 slot_setvol(struct slot *s, unsigned int vol) 1581 { 1582 #ifdef DEBUG 1583 if (log_level >= 3) { 1584 slot_log(s); 1585 log_puts(": setting volume "); 1586 log_putu(vol); 1587 log_puts("\n"); 1588 } 1589 #endif 1590 s->vol = vol; 1591 if (s->ops == NULL) 1592 return; 1593 s->mix.vol = MIDI_TO_ADATA(s->vol); 1594 } 1595 1596 /* 1597 * attach the slot to the device (ie start playing & recording 1598 */ 1599 void 1600 slot_attach(struct slot *s) 1601 { 1602 struct dev *d = s->dev; 1603 unsigned int slot_nch, dev_nch; 1604 long long pos; 1605 int startpos; 1606 1607 /* 1608 * start the device if not started 1609 */ 1610 dev_wakeup(d); 1611 1612 /* 1613 * get the current position, the origin is when the first sample 1614 * played and/or recorded 1615 */ 1616 startpos = dev_getpos(d) * (int)s->round / (int)d->round; 1617 1618 /* 1619 * adjust initial clock 1620 */ 1621 pos = (long long)d->delta * s->round; 1622 s->delta = startpos + pos / (int)d->round; 1623 s->delta_rem = pos % d->round; 1624 1625 s->pstate = SLOT_RUN; 1626 #ifdef DEBUG 1627 if (log_level >= 2) { 1628 slot_log(s); 1629 log_puts(": attached at "); 1630 log_puti(startpos); 1631 log_puts(", delta = "); 1632 log_puti(d->delta); 1633 log_puts("\n"); 1634 } 1635 #endif 1636 1637 /* 1638 * We dont check whether the device is dying, 1639 * because dev_xxx() functions are supposed to 1640 * work (i.e., not to crash) 1641 */ 1642 #ifdef DEBUG 1643 if ((s->mode & d->mode) != s->mode) { 1644 slot_log(s); 1645 log_puts(": mode beyond device mode, not attaching\n"); 1646 panic(); 1647 } 1648 #endif 1649 s->next = d->slot_list; 1650 d->slot_list = s; 1651 s->skip = 0; 1652 if (s->mode & MODE_PLAY) { 1653 slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; 1654 dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1; 1655 s->mix.decbuf = NULL; 1656 s->mix.resampbuf = NULL; 1657 s->mix.join = 1; 1658 s->mix.expand = 1; 1659 if (s->dup) { 1660 if (dev_nch > slot_nch) 1661 s->mix.expand = dev_nch / slot_nch; 1662 else if (dev_nch < slot_nch) 1663 s->mix.join = slot_nch / dev_nch; 1664 } 1665 cmap_init(&s->mix.cmap, 1666 s->mix.slot_cmin, s->mix.slot_cmax, 1667 s->mix.slot_cmin, s->mix.slot_cmax, 1668 0, d->pchan - 1, 1669 s->mix.dev_cmin, s->mix.dev_cmax); 1670 if (!aparams_native(&s->par)) { 1671 dec_init(&s->mix.dec, &s->par, slot_nch); 1672 s->mix.decbuf = 1673 xmalloc(s->round * slot_nch * sizeof(adata_t)); 1674 } 1675 if (s->rate != d->rate) { 1676 resamp_init(&s->mix.resamp, s->round, d->round, 1677 slot_nch); 1678 s->mix.resampbuf = 1679 xmalloc(d->round * slot_nch * sizeof(adata_t)); 1680 } 1681 s->mix.vol = MIDI_TO_ADATA(s->vol); 1682 dev_mix_adjvol(d); 1683 } 1684 if (s->mode & MODE_RECMASK) { 1685 slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; 1686 dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1; 1687 s->sub.encbuf = NULL; 1688 s->sub.resampbuf = NULL; 1689 s->sub.join = 1; 1690 s->sub.expand = 1; 1691 if (s->dup) { 1692 if (dev_nch > slot_nch) 1693 s->sub.join = dev_nch / slot_nch; 1694 else if (dev_nch < slot_nch) 1695 s->sub.expand = slot_nch / dev_nch; 1696 } 1697 cmap_init(&s->sub.cmap, 1698 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, 1699 s->sub.dev_cmin, s->sub.dev_cmax, 1700 s->sub.slot_cmin, s->sub.slot_cmax, 1701 s->sub.slot_cmin, s->sub.slot_cmax); 1702 if (s->rate != d->rate) { 1703 resamp_init(&s->sub.resamp, d->round, s->round, 1704 slot_nch); 1705 s->sub.resampbuf = 1706 xmalloc(d->round * slot_nch * sizeof(adata_t)); 1707 } 1708 if (!aparams_native(&s->par)) { 1709 enc_init(&s->sub.enc, &s->par, slot_nch); 1710 s->sub.encbuf = 1711 xmalloc(s->round * slot_nch * sizeof(adata_t)); 1712 } 1713 1714 /* 1715 * N-th recorded block is the N-th played block 1716 */ 1717 s->sub.prime = -startpos / (int)s->round; 1718 } 1719 } 1720 1721 /* 1722 * if MMC is enabled, and try to attach all slots synchronously, else 1723 * simply attach the slot 1724 */ 1725 void 1726 slot_ready(struct slot *s) 1727 { 1728 /* 1729 * device may be disconnected, and if so we're called from 1730 * slot->ops->exit() on a closed device 1731 */ 1732 if (s->dev->pstate == DEV_CFG) 1733 return; 1734 if (s->tstate == MMC_OFF) 1735 slot_attach(s); 1736 else { 1737 s->tstate = MMC_START; 1738 dev_sync_attach(s->dev); 1739 } 1740 } 1741 1742 /* 1743 * setup buffers & conversion layers, prepare the slot to receive data 1744 * (for playback) or start (recording). 1745 */ 1746 void 1747 slot_start(struct slot *s) 1748 { 1749 unsigned int bufsz; 1750 #ifdef DEBUG 1751 struct dev *d = s->dev; 1752 1753 1754 if (s->pstate != SLOT_INIT) { 1755 slot_log(s); 1756 log_puts(": slot_start: wrong state\n"); 1757 panic(); 1758 } 1759 #endif 1760 bufsz = s->appbufsz; 1761 if (s->mode & MODE_PLAY) { 1762 #ifdef DEBUG 1763 if (log_level >= 3) { 1764 slot_log(s); 1765 log_puts(": playing "); 1766 aparams_log(&s->par); 1767 log_puts(" -> "); 1768 aparams_log(&d->par); 1769 log_puts("\n"); 1770 } 1771 #endif 1772 s->mix.bpf = s->par.bps * 1773 (s->mix.slot_cmax - s->mix.slot_cmin + 1); 1774 abuf_init(&s->mix.buf, bufsz * s->mix.bpf); 1775 } 1776 if (s->mode & MODE_RECMASK) { 1777 #ifdef DEBUG 1778 if (log_level >= 3) { 1779 slot_log(s); 1780 log_puts(": recording "); 1781 aparams_log(&s->par); 1782 log_puts(" <- "); 1783 aparams_log(&d->par); 1784 log_puts("\n"); 1785 } 1786 #endif 1787 s->sub.bpf = s->par.bps * 1788 (s->sub.slot_cmax - s->sub.slot_cmin + 1); 1789 abuf_init(&s->sub.buf, bufsz * s->sub.bpf); 1790 } 1791 s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); 1792 #ifdef DEBUG 1793 if (log_level >= 3) { 1794 slot_log(s); 1795 log_puts(": allocated "); 1796 log_putu(s->appbufsz); 1797 log_puts("/"); 1798 log_putu(SLOT_BUFSZ(s)); 1799 log_puts(" fr buffers\n"); 1800 } 1801 #endif 1802 if (s->mode & MODE_PLAY) { 1803 s->pstate = SLOT_START; 1804 } else { 1805 s->pstate = SLOT_READY; 1806 slot_ready(s); 1807 } 1808 } 1809 1810 /* 1811 * stop playback and recording, and free conversion layers 1812 */ 1813 void 1814 slot_detach(struct slot *s) 1815 { 1816 struct slot **ps; 1817 1818 #ifdef DEBUG 1819 if (log_level >= 3) { 1820 slot_log(s); 1821 log_puts(": detaching\n"); 1822 } 1823 #endif 1824 for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) { 1825 #ifdef DEBUG 1826 if (s == NULL) { 1827 slot_log(s); 1828 log_puts(": can't detach, not on list\n"); 1829 panic(); 1830 } 1831 #endif 1832 } 1833 *ps = s->next; 1834 if (s->mode & MODE_RECMASK) { 1835 if (s->sub.encbuf) 1836 xfree(s->sub.encbuf); 1837 if (s->sub.resampbuf) 1838 xfree(s->sub.resampbuf); 1839 } 1840 if (s->mode & MODE_PLAY) { 1841 if (s->mix.decbuf) 1842 xfree(s->mix.decbuf); 1843 if (s->mix.resampbuf) 1844 xfree(s->mix.resampbuf); 1845 dev_mix_adjvol(s->dev); 1846 } 1847 } 1848 1849 /* 1850 * put the slot in stopping state (draining play buffers) or 1851 * stop & detach if no data to drain. 1852 */ 1853 void 1854 slot_stop(struct slot *s) 1855 { 1856 #ifdef DEBUG 1857 if (log_level >= 3) { 1858 slot_log(s); 1859 log_puts(": stopping\n"); 1860 } 1861 #endif 1862 if (s->pstate == SLOT_START) { 1863 if (s->mode & MODE_PLAY) { 1864 s->pstate = SLOT_READY; 1865 slot_ready(s); 1866 } else 1867 s->pstate = SLOT_INIT; 1868 } 1869 if (s->mode & MODE_RECMASK) 1870 abuf_done(&s->sub.buf); 1871 if (s->pstate == SLOT_READY) { 1872 #ifdef DEBUG 1873 if (log_level >= 3) { 1874 slot_log(s); 1875 log_puts(": not drained (blocked by mmc)\n"); 1876 } 1877 #endif 1878 if (s->mode & MODE_PLAY) 1879 abuf_done(&s->mix.buf); 1880 s->ops->eof(s->arg); 1881 s->pstate = SLOT_INIT; 1882 } else { 1883 /* s->pstate == SLOT_RUN */ 1884 if (s->mode & MODE_PLAY) 1885 s->pstate = SLOT_STOP; 1886 else { 1887 slot_detach(s); 1888 s->pstate = SLOT_INIT; 1889 s->ops->eof(s->arg); 1890 } 1891 } 1892 if (s->tstate != MMC_OFF) 1893 s->tstate = MMC_STOP; 1894 } 1895 1896 void 1897 slot_skip_update(struct slot *s) 1898 { 1899 int skip; 1900 1901 skip = slot_skip(s); 1902 while (skip > 0) { 1903 #ifdef DEBUG 1904 if (log_level >= 4) { 1905 slot_log(s); 1906 log_puts(": catching skipped block\n"); 1907 } 1908 #endif 1909 if (s->mode & MODE_RECMASK) 1910 s->ops->flush(s->arg); 1911 if (s->mode & MODE_PLAY) 1912 s->ops->fill(s->arg); 1913 skip--; 1914 } 1915 } 1916 1917 /* 1918 * notify the slot that we just wrote in the play buffer, must be called 1919 * after each write 1920 */ 1921 void 1922 slot_write(struct slot *s) 1923 { 1924 if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) { 1925 #ifdef DEBUG 1926 if (log_level >= 4) { 1927 slot_log(s); 1928 log_puts(": switching to READY state\n"); 1929 } 1930 #endif 1931 s->pstate = SLOT_READY; 1932 slot_ready(s); 1933 } 1934 slot_skip_update(s); 1935 } 1936 1937 /* 1938 * notify the slot that we freed some space in the rec buffer 1939 */ 1940 void 1941 slot_read(struct slot *s) 1942 { 1943 slot_skip_update(s); 1944 } 1945