1 /* $OpenBSD: dev.c,v 1.17 2014/06/02 07:51:25 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 *, unsigned int); 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, 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, unsigned int vol) 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->num = dev_sndnum++; 980 981 /* 982 * XXX: below, we allocate a midi input buffer, since we don't 983 * receive raw midi data, so no need to allocate a input 984 * ibuf. Possibly set imsg & fill callbacks to NULL and 985 * use this to in midi_new() to check if buffers need to be 986 * allocated 987 */ 988 d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT); 989 midi_tag(d->midi, d->num); 990 d->path = path; 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 d->slot[i].name[0] = '\0'; 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 pmin, int pmax, int rmin, 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->hold) 1217 dev_unref(d); 1218 } 1219 1220 struct dev * 1221 dev_bynum(int num) 1222 { 1223 struct dev *d; 1224 1225 for (d = dev_list; d != NULL; d = d->next) { 1226 if (num-- == 0) 1227 return d; 1228 } 1229 return NULL; 1230 } 1231 1232 /* 1233 * Free the device 1234 */ 1235 void 1236 dev_del(struct dev *d) 1237 { 1238 struct dev **p; 1239 1240 #ifdef DEBUG 1241 if (log_level >= 3) { 1242 dev_log(d); 1243 log_puts(": deleting\n"); 1244 } 1245 #endif 1246 if (d->pstate != DEV_CFG) 1247 dev_close(d); 1248 for (p = &dev_list; *p != d; p = &(*p)->next) { 1249 #ifdef DEBUG 1250 if (*p == NULL) { 1251 dev_log(d); 1252 log_puts(": device to delete not on the list\n"); 1253 panic(); 1254 } 1255 #endif 1256 } 1257 midi_del(d->midi); 1258 *p = d->next; 1259 xfree(d); 1260 } 1261 1262 unsigned int 1263 dev_roundof(struct dev *d, unsigned int newrate) 1264 { 1265 return (d->round * newrate + d->rate / 2) / d->rate; 1266 } 1267 1268 /* 1269 * If the device is paused, then resume it. 1270 */ 1271 void 1272 dev_wakeup(struct dev *d) 1273 { 1274 if (d->pstate == DEV_INIT) { 1275 if (log_level >= 2) { 1276 dev_log(d); 1277 log_puts(": device started\n"); 1278 } 1279 if (d->mode & MODE_PLAY) { 1280 d->prime = d->bufsz; 1281 } else { 1282 d->prime = 0; 1283 } 1284 d->poffs = 0; 1285 1286 /* 1287 * empty cycles don't increment delta, so it's ok to 1288 * start at 0 1289 **/ 1290 d->delta = 0; 1291 1292 d->pstate = DEV_RUN; 1293 dev_sio_start(d); 1294 } 1295 } 1296 1297 /* 1298 * check that all clients controlled by MMC are ready to start, if so, 1299 * attach them all at the same position 1300 */ 1301 void 1302 dev_sync_attach(struct dev *d) 1303 { 1304 int i; 1305 struct slot *s; 1306 1307 if (d->tstate != MMC_START) { 1308 if (log_level >= 2) { 1309 dev_log(d); 1310 log_puts(": not started by mmc yet, waiting...\n"); 1311 } 1312 return; 1313 } 1314 for (i = 0; i < DEV_NSLOT; i++) { 1315 s = d->slot + i; 1316 if (!s->ops || s->tstate == MMC_OFF) 1317 continue; 1318 if (s->tstate != MMC_START || s->pstate != SLOT_READY) { 1319 #ifdef DEBUG 1320 if (log_level >= 3) { 1321 slot_log(s); 1322 log_puts(": not ready, start delayed\n"); 1323 } 1324 #endif 1325 return; 1326 } 1327 } 1328 if (!dev_ref(d)) 1329 return; 1330 for (i = 0; i < DEV_NSLOT; i++) { 1331 s = d->slot + i; 1332 if (!s->ops) 1333 continue; 1334 if (s->tstate == MMC_START) { 1335 #ifdef DEBUG 1336 if (log_level >= 3) { 1337 slot_log(s); 1338 log_puts(": started\n"); 1339 } 1340 #endif 1341 s->tstate = MMC_RUN; 1342 slot_attach(s); 1343 } 1344 } 1345 d->tstate = MMC_RUN; 1346 dev_midi_full(d); 1347 dev_wakeup(d); 1348 } 1349 1350 /* 1351 * start all slots simultaneously 1352 */ 1353 void 1354 dev_mmcstart(struct dev *d) 1355 { 1356 if (d->tstate == MMC_STOP) { 1357 d->tstate = MMC_START; 1358 dev_sync_attach(d); 1359 #ifdef DEBUG 1360 } else { 1361 if (log_level >= 3) { 1362 dev_log(d); 1363 log_puts(": ignoring mmc start\n"); 1364 } 1365 #endif 1366 } 1367 } 1368 1369 /* 1370 * stop all slots simultaneously 1371 */ 1372 void 1373 dev_mmcstop(struct dev *d) 1374 { 1375 switch (d->tstate) { 1376 case MMC_START: 1377 d->tstate = MMC_STOP; 1378 return; 1379 case MMC_RUN: 1380 d->tstate = MMC_STOP; 1381 dev_unref(d); 1382 break; 1383 default: 1384 #ifdef DEBUG 1385 if (log_level >= 3) { 1386 dev_log(d); 1387 log_puts(": ignored mmc stop\n"); 1388 } 1389 #endif 1390 return; 1391 } 1392 } 1393 1394 /* 1395 * relocate all slots simultaneously 1396 */ 1397 void 1398 dev_mmcloc(struct dev *d, unsigned int origin) 1399 { 1400 if (log_level >= 2) { 1401 dev_log(d); 1402 log_puts(": relocated to "); 1403 log_putu(origin); 1404 log_puts("\n"); 1405 } 1406 if (d->tstate == MMC_RUN) 1407 dev_mmcstop(d); 1408 d->mtc.origin = origin; 1409 if (d->tstate == MMC_RUN) 1410 dev_mmcstart(d); 1411 } 1412 1413 /* 1414 * allocate a new slot and register the given call-backs 1415 */ 1416 struct slot * 1417 slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) 1418 { 1419 char *p; 1420 char name[SLOT_NAMEMAX]; 1421 unsigned int i, unit, umap = 0; 1422 unsigned int ser, bestser, bestidx; 1423 struct slot *s; 1424 1425 /* 1426 * create a ``valid'' control name (lowcase, remove [^a-z], trucate) 1427 */ 1428 for (i = 0, p = who; ; p++) { 1429 if (i == SLOT_NAMEMAX - 1 || *p == '\0') { 1430 name[i] = '\0'; 1431 break; 1432 } else if (*p >= 'A' && *p <= 'Z') { 1433 name[i++] = *p + 'a' - 'A'; 1434 } else if (*p >= 'a' && *p <= 'z') 1435 name[i++] = *p; 1436 } 1437 if (i == 0) 1438 strlcpy(name, "noname", SLOT_NAMEMAX); 1439 1440 /* 1441 * find the first unused "unit" number for this name 1442 */ 1443 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1444 if (s->ops == NULL) 1445 continue; 1446 if (strcmp(s->name, name) == 0) 1447 umap |= (1 << s->unit); 1448 } 1449 for (unit = 0; ; unit++) { 1450 if ((umap & (1 << unit)) == 0) 1451 break; 1452 } 1453 1454 /* 1455 * find a xfree controller slot with the same name/unit 1456 */ 1457 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1458 if (s->ops == NULL && 1459 strcmp(s->name, name) == 0 && 1460 s->unit == unit) { 1461 #ifdef DEBUG 1462 if (log_level >= 3) { 1463 log_puts(name); 1464 log_putu(unit); 1465 log_puts(": reused\n"); 1466 } 1467 #endif 1468 goto found; 1469 } 1470 } 1471 1472 /* 1473 * couldn't find a matching slot, pick oldest xfree slot 1474 * and set its name/unit 1475 */ 1476 bestser = 0; 1477 bestidx = DEV_NSLOT; 1478 for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { 1479 if (s->ops != NULL) 1480 continue; 1481 ser = d->serial - s->serial; 1482 if (ser > bestser) { 1483 bestser = ser; 1484 bestidx = i; 1485 } 1486 } 1487 if (bestidx == DEV_NSLOT) { 1488 if (log_level >= 1) { 1489 log_puts(name); 1490 log_putu(unit); 1491 log_puts(": out of sub-device slots\n"); 1492 } 1493 return NULL; 1494 } 1495 s = d->slot + bestidx; 1496 if (s->name[0] != '\0') 1497 s->vol = MIDI_MAXCTL; 1498 strlcpy(s->name, name, SLOT_NAMEMAX); 1499 s->serial = d->serial++; 1500 s->unit = unit; 1501 #ifdef DEBUG 1502 if (log_level >= 3) { 1503 log_puts(name); 1504 log_putu(unit); 1505 log_puts(": overwritten slot "); 1506 log_putu(bestidx); 1507 log_puts("\n"); 1508 } 1509 #endif 1510 1511 found: 1512 if (!dev_ref(d)) 1513 return NULL; 1514 s->dev = d; 1515 s->ops = ops; 1516 s->arg = arg; 1517 s->pstate = SLOT_INIT; 1518 s->tstate = MMC_OFF; 1519 1520 if ((mode & s->dev->mode) != mode) { 1521 if (log_level >= 1) { 1522 slot_log(s); 1523 log_puts(": requested mode not supported\n"); 1524 } 1525 return 0; 1526 } 1527 s->mode = mode; 1528 aparams_init(&s->par); 1529 if (s->mode & MODE_PLAY) { 1530 s->mix.slot_cmin = s->mix.dev_cmin = 0; 1531 s->mix.slot_cmax = s->mix.dev_cmax = d->pchan - 1; 1532 } 1533 if (s->mode & MODE_RECMASK) { 1534 s->sub.slot_cmin = s->sub.dev_cmin = 0; 1535 s->sub.slot_cmax = s->sub.dev_cmax = 1536 ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1; 1537 } 1538 s->xrun = XRUN_IGNORE; 1539 s->dup = 0; 1540 s->appbufsz = d->bufsz; 1541 s->round = d->round; 1542 s->rate = d->rate; 1543 s->mix.maxweight = ADATA_UNIT; 1544 dev_midi_slotdesc(d, s); 1545 dev_midi_vol(d, s); 1546 return s; 1547 } 1548 1549 /* 1550 * release the given slot 1551 */ 1552 void 1553 slot_del(struct slot *s) 1554 { 1555 s->arg = s; 1556 s->ops = &zomb_slotops; 1557 switch (s->pstate) { 1558 case SLOT_INIT: 1559 s->ops = NULL; 1560 break; 1561 case SLOT_START: 1562 case SLOT_READY: 1563 case SLOT_RUN: 1564 slot_stop(s); 1565 /* PASSTHROUGH */ 1566 case SLOT_STOP: 1567 break; 1568 } 1569 dev_unref(s->dev); 1570 s->dev = NULL; 1571 } 1572 1573 /* 1574 * change the slot play volume; called either by the slot or by MIDI 1575 */ 1576 void 1577 slot_setvol(struct slot *s, unsigned int vol) 1578 { 1579 #ifdef DEBUG 1580 if (log_level >= 3) { 1581 slot_log(s); 1582 log_puts(": setting volume "); 1583 log_putu(vol); 1584 log_puts("\n"); 1585 } 1586 #endif 1587 s->vol = vol; 1588 if (s->ops == NULL) 1589 return; 1590 s->mix.vol = MIDI_TO_ADATA(s->vol); 1591 } 1592 1593 /* 1594 * attach the slot to the device (ie start playing & recording 1595 */ 1596 void 1597 slot_attach(struct slot *s) 1598 { 1599 struct dev *d = s->dev; 1600 unsigned int slot_nch, dev_nch; 1601 long long pos; 1602 int startpos; 1603 1604 /* 1605 * start the device if not started 1606 */ 1607 dev_wakeup(d); 1608 1609 /* 1610 * get the current position, the origin is when the first sample 1611 * played and/or recorded 1612 */ 1613 startpos = dev_getpos(d) * (int)s->round / (int)d->round; 1614 1615 /* 1616 * adjust initial clock 1617 */ 1618 pos = (long long)d->delta * s->round; 1619 s->delta = startpos + pos / (int)d->round; 1620 s->delta_rem = pos % d->round; 1621 1622 s->pstate = SLOT_RUN; 1623 #ifdef DEBUG 1624 if (log_level >= 2) { 1625 slot_log(s); 1626 log_puts(": attached at "); 1627 log_puti(startpos); 1628 log_puts(", delta = "); 1629 log_puti(d->delta); 1630 log_puts("\n"); 1631 } 1632 #endif 1633 1634 /* 1635 * We dont check whether the device is dying, 1636 * because dev_xxx() functions are supposed to 1637 * work (i.e., not to crash) 1638 */ 1639 #ifdef DEBUG 1640 if ((s->mode & d->mode) != s->mode) { 1641 slot_log(s); 1642 log_puts(": mode beyond device mode, not attaching\n"); 1643 panic(); 1644 } 1645 #endif 1646 s->next = d->slot_list; 1647 d->slot_list = s; 1648 s->skip = 0; 1649 if (s->mode & MODE_PLAY) { 1650 slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; 1651 dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1; 1652 s->mix.decbuf = NULL; 1653 s->mix.resampbuf = NULL; 1654 s->mix.join = 1; 1655 s->mix.expand = 1; 1656 if (s->dup) { 1657 if (dev_nch > slot_nch) 1658 s->mix.expand = dev_nch / slot_nch; 1659 else if (dev_nch < slot_nch) 1660 s->mix.join = slot_nch / dev_nch; 1661 } 1662 cmap_init(&s->mix.cmap, 1663 s->mix.slot_cmin, s->mix.slot_cmax, 1664 s->mix.slot_cmin, s->mix.slot_cmax, 1665 0, d->pchan - 1, 1666 s->mix.dev_cmin, s->mix.dev_cmax); 1667 if (!aparams_native(&s->par)) { 1668 dec_init(&s->mix.dec, &s->par, slot_nch); 1669 s->mix.decbuf = 1670 xmalloc(s->round * slot_nch * sizeof(adata_t)); 1671 } 1672 if (s->rate != d->rate) { 1673 resamp_init(&s->mix.resamp, s->round, d->round, 1674 slot_nch); 1675 s->mix.resampbuf = 1676 xmalloc(d->round * slot_nch * sizeof(adata_t)); 1677 } 1678 s->mix.vol = MIDI_TO_ADATA(s->vol); 1679 dev_mix_adjvol(d); 1680 } 1681 if (s->mode & MODE_RECMASK) { 1682 slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; 1683 dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1; 1684 s->sub.encbuf = NULL; 1685 s->sub.resampbuf = NULL; 1686 s->sub.join = 1; 1687 s->sub.expand = 1; 1688 if (s->dup) { 1689 if (dev_nch > slot_nch) 1690 s->sub.join = dev_nch / slot_nch; 1691 else if (dev_nch < slot_nch) 1692 s->sub.expand = slot_nch / dev_nch; 1693 } 1694 cmap_init(&s->sub.cmap, 1695 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, 1696 s->sub.dev_cmin, s->sub.dev_cmax, 1697 s->sub.slot_cmin, s->sub.slot_cmax, 1698 s->sub.slot_cmin, s->sub.slot_cmax); 1699 if (s->rate != d->rate) { 1700 resamp_init(&s->sub.resamp, d->round, s->round, 1701 slot_nch); 1702 s->sub.resampbuf = 1703 xmalloc(d->round * slot_nch * sizeof(adata_t)); 1704 } 1705 if (!aparams_native(&s->par)) { 1706 enc_init(&s->sub.enc, &s->par, slot_nch); 1707 s->sub.encbuf = 1708 xmalloc(s->round * slot_nch * sizeof(adata_t)); 1709 } 1710 1711 /* 1712 * N-th recorded block is the N-th played block 1713 */ 1714 s->sub.prime = -startpos / (int)s->round; 1715 } 1716 } 1717 1718 /* 1719 * if MMC is enabled, and try to attach all slots synchronously, else 1720 * simply attach the slot 1721 */ 1722 void 1723 slot_ready(struct slot *s) 1724 { 1725 /* 1726 * device may be disconnected, and if so we're called from 1727 * slot->ops->exit() on a closed device 1728 */ 1729 if (s->dev->pstate == DEV_CFG) 1730 return; 1731 if (s->tstate == MMC_OFF) 1732 slot_attach(s); 1733 else { 1734 s->tstate = MMC_START; 1735 dev_sync_attach(s->dev); 1736 } 1737 } 1738 1739 /* 1740 * setup buffers & conversion layers, prepare the slot to receive data 1741 * (for playback) or start (recording). 1742 */ 1743 void 1744 slot_start(struct slot *s) 1745 { 1746 unsigned int bufsz; 1747 #ifdef DEBUG 1748 struct dev *d = s->dev; 1749 1750 1751 if (s->pstate != SLOT_INIT) { 1752 slot_log(s); 1753 log_puts(": slot_start: wrong state\n"); 1754 panic(); 1755 } 1756 #endif 1757 bufsz = s->appbufsz; 1758 if (s->mode & MODE_PLAY) { 1759 #ifdef DEBUG 1760 if (log_level >= 3) { 1761 slot_log(s); 1762 log_puts(": playing "); 1763 aparams_log(&s->par); 1764 log_puts(" -> "); 1765 aparams_log(&d->par); 1766 log_puts("\n"); 1767 } 1768 #endif 1769 s->mix.bpf = s->par.bps * 1770 (s->mix.slot_cmax - s->mix.slot_cmin + 1); 1771 abuf_init(&s->mix.buf, bufsz * s->mix.bpf); 1772 } 1773 if (s->mode & MODE_RECMASK) { 1774 #ifdef DEBUG 1775 if (log_level >= 3) { 1776 slot_log(s); 1777 log_puts(": recording "); 1778 aparams_log(&s->par); 1779 log_puts(" <- "); 1780 aparams_log(&d->par); 1781 log_puts("\n"); 1782 } 1783 #endif 1784 s->sub.bpf = s->par.bps * 1785 (s->sub.slot_cmax - s->sub.slot_cmin + 1); 1786 abuf_init(&s->sub.buf, bufsz * s->sub.bpf); 1787 } 1788 s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); 1789 #ifdef DEBUG 1790 if (log_level >= 3) { 1791 slot_log(s); 1792 log_puts(": allocated "); 1793 log_putu(s->appbufsz); 1794 log_puts("/"); 1795 log_putu(SLOT_BUFSZ(s)); 1796 log_puts(" fr buffers\n"); 1797 } 1798 #endif 1799 if (s->mode & MODE_PLAY) { 1800 s->pstate = SLOT_START; 1801 } else { 1802 s->pstate = SLOT_READY; 1803 slot_ready(s); 1804 } 1805 } 1806 1807 /* 1808 * stop playback and recording, and free conversion layers 1809 */ 1810 void 1811 slot_detach(struct slot *s) 1812 { 1813 struct slot **ps; 1814 1815 #ifdef DEBUG 1816 if (log_level >= 3) { 1817 slot_log(s); 1818 log_puts(": detaching\n"); 1819 } 1820 #endif 1821 for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) { 1822 #ifdef DEBUG 1823 if (s == NULL) { 1824 slot_log(s); 1825 log_puts(": can't detach, not on list\n"); 1826 panic(); 1827 } 1828 #endif 1829 } 1830 *ps = s->next; 1831 if (s->mode & MODE_RECMASK) { 1832 if (s->sub.encbuf) 1833 xfree(s->sub.encbuf); 1834 if (s->sub.resampbuf) 1835 xfree(s->sub.resampbuf); 1836 } 1837 if (s->mode & MODE_PLAY) { 1838 if (s->mix.decbuf) 1839 xfree(s->mix.decbuf); 1840 if (s->mix.resampbuf) 1841 xfree(s->mix.resampbuf); 1842 dev_mix_adjvol(s->dev); 1843 } 1844 } 1845 1846 /* 1847 * put the slot in stopping state (draining play buffers) or 1848 * stop & detach if no data to drain. 1849 */ 1850 void 1851 slot_stop(struct slot *s) 1852 { 1853 #ifdef DEBUG 1854 if (log_level >= 3) { 1855 slot_log(s); 1856 log_puts(": stopping\n"); 1857 } 1858 #endif 1859 if (s->pstate == SLOT_START) { 1860 if (s->mode & MODE_PLAY) { 1861 s->pstate = SLOT_READY; 1862 slot_ready(s); 1863 } else 1864 s->pstate = SLOT_INIT; 1865 } 1866 if (s->mode & MODE_RECMASK) 1867 abuf_done(&s->sub.buf); 1868 if (s->pstate == SLOT_READY) { 1869 #ifdef DEBUG 1870 if (log_level >= 3) { 1871 slot_log(s); 1872 log_puts(": not drained (blocked by mmc)\n"); 1873 } 1874 #endif 1875 if (s->mode & MODE_PLAY) 1876 abuf_done(&s->mix.buf); 1877 s->ops->eof(s->arg); 1878 s->pstate = SLOT_INIT; 1879 } else { 1880 /* s->pstate == SLOT_RUN */ 1881 if (s->mode & MODE_PLAY) 1882 s->pstate = SLOT_STOP; 1883 else { 1884 slot_detach(s); 1885 s->pstate = SLOT_INIT; 1886 s->ops->eof(s->arg); 1887 } 1888 } 1889 if (s->tstate != MMC_OFF) 1890 s->tstate = MMC_STOP; 1891 } 1892 1893 void 1894 slot_skip_update(struct slot *s) 1895 { 1896 int skip; 1897 1898 skip = slot_skip(s); 1899 while (skip > 0) { 1900 #ifdef DEBUG 1901 if (log_level >= 4) { 1902 slot_log(s); 1903 log_puts(": catching skipped block\n"); 1904 } 1905 #endif 1906 if (s->mode & MODE_RECMASK) 1907 s->ops->flush(s->arg); 1908 if (s->mode & MODE_PLAY) 1909 s->ops->fill(s->arg); 1910 skip--; 1911 } 1912 } 1913 1914 /* 1915 * notify the slot that we just wrote in the play buffer, must be called 1916 * after each write 1917 */ 1918 void 1919 slot_write(struct slot *s) 1920 { 1921 if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) { 1922 #ifdef DEBUG 1923 if (log_level >= 4) { 1924 slot_log(s); 1925 log_puts(": switching to READY state\n"); 1926 } 1927 #endif 1928 s->pstate = SLOT_READY; 1929 slot_ready(s); 1930 } 1931 slot_skip_update(s); 1932 } 1933 1934 /* 1935 * notify the slot that we freed some space in the rec buffer 1936 */ 1937 void 1938 slot_read(struct slot *s) 1939 { 1940 slot_skip_update(s); 1941 } 1942