1 /*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * Portions Copyright by Luigi Rizzo - 1997-99 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include "opt_isa.h" 29 30 #include <dev/sound/pcm/sound.h> 31 32 #include "feeder_if.h" 33 34 SND_DECLARE_FILE("$FreeBSD$"); 35 36 int report_soft_formats = 1; 37 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_formats, CTLFLAG_RW, 38 &report_soft_formats, 1, "report software-emulated formats"); 39 40 int chn_latency = CHN_LATENCY_DEFAULT; 41 TUNABLE_INT("hw.snd.latency", &chn_latency); 42 43 static int 44 sysctl_hw_snd_latency(SYSCTL_HANDLER_ARGS) 45 { 46 int err, val; 47 48 val = chn_latency; 49 err = sysctl_handle_int(oidp, &val, 0, req); 50 if (err != 0 || req->newptr == NULL) 51 return err; 52 if (val < CHN_LATENCY_MIN || val > CHN_LATENCY_MAX) 53 err = EINVAL; 54 else 55 chn_latency = val; 56 57 return err; 58 } 59 SYSCTL_PROC(_hw_snd, OID_AUTO, latency, CTLTYPE_INT | CTLFLAG_RW, 60 0, sizeof(int), sysctl_hw_snd_latency, "I", 61 "buffering latency (0=low ... 10=high)"); 62 63 int chn_latency_profile = CHN_LATENCY_PROFILE_DEFAULT; 64 TUNABLE_INT("hw.snd.latency_profile", &chn_latency_profile); 65 66 static int 67 sysctl_hw_snd_latency_profile(SYSCTL_HANDLER_ARGS) 68 { 69 int err, val; 70 71 val = chn_latency_profile; 72 err = sysctl_handle_int(oidp, &val, 0, req); 73 if (err != 0 || req->newptr == NULL) 74 return err; 75 if (val < CHN_LATENCY_PROFILE_MIN || val > CHN_LATENCY_PROFILE_MAX) 76 err = EINVAL; 77 else 78 chn_latency_profile = val; 79 80 return err; 81 } 82 SYSCTL_PROC(_hw_snd, OID_AUTO, latency_profile, CTLTYPE_INT | CTLFLAG_RW, 83 0, sizeof(int), sysctl_hw_snd_latency_profile, "I", 84 "buffering latency profile (0=aggresive 1=safe)"); 85 86 static int chn_timeout = CHN_TIMEOUT; 87 TUNABLE_INT("hw.snd.timeout", &chn_timeout); 88 #ifdef SND_DEBUG 89 static int 90 sysctl_hw_snd_timeout(SYSCTL_HANDLER_ARGS) 91 { 92 int err, val; 93 94 val = chn_timeout; 95 err = sysctl_handle_int(oidp, &val, 0, req); 96 if (err != 0 || req->newptr == NULL) 97 return err; 98 if (val < CHN_TIMEOUT_MIN || val > CHN_TIMEOUT_MAX) 99 err = EINVAL; 100 else 101 chn_timeout = val; 102 103 return err; 104 } 105 SYSCTL_PROC(_hw_snd, OID_AUTO, timeout, CTLTYPE_INT | CTLFLAG_RW, 106 0, sizeof(int), sysctl_hw_snd_timeout, "I", 107 "interrupt timeout (1 - 10) seconds"); 108 #endif 109 110 static int chn_usefrags = 0; 111 TUNABLE_INT("hw.snd.usefrags", &chn_usefrags); 112 static int chn_syncdelay = -1; 113 TUNABLE_INT("hw.snd.syncdelay", &chn_syncdelay); 114 #ifdef SND_DEBUG 115 SYSCTL_INT(_hw_snd, OID_AUTO, usefrags, CTLFLAG_RW, 116 &chn_usefrags, 1, "prefer setfragments() over setblocksize()"); 117 SYSCTL_INT(_hw_snd, OID_AUTO, syncdelay, CTLFLAG_RW, 118 &chn_syncdelay, 1, 119 "append (0-1000) millisecond trailing buffer delay on each sync"); 120 #endif 121 122 /** 123 * @brief Channel sync group lock 124 * 125 * Clients should acquire this lock @b without holding any channel locks 126 * before touching syncgroups or the main syncgroup list. 127 */ 128 struct mtx snd_pcm_syncgroups_mtx; 129 MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock", MTX_DEF); 130 /** 131 * @brief syncgroups' master list 132 * 133 * Each time a channel syncgroup is created, it's added to this list. This 134 * list should only be accessed with @sa snd_pcm_syncgroups_mtx held. 135 * 136 * See SNDCTL_DSP_SYNCGROUP for more information. 137 */ 138 struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(head); 139 140 static int chn_buildfeeder(struct pcm_channel *c); 141 142 static void 143 chn_lockinit(struct pcm_channel *c, int dir) 144 { 145 switch (dir) { 146 case PCMDIR_PLAY: 147 c->lock = snd_mtxcreate(c->name, "pcm play channel"); 148 cv_init(&c->intr_cv, "pcmwr"); 149 break; 150 case PCMDIR_PLAY_VIRTUAL: 151 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); 152 cv_init(&c->intr_cv, "pcmwrv"); 153 break; 154 case PCMDIR_REC: 155 c->lock = snd_mtxcreate(c->name, "pcm record channel"); 156 cv_init(&c->intr_cv, "pcmrd"); 157 break; 158 case PCMDIR_REC_VIRTUAL: 159 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel"); 160 cv_init(&c->intr_cv, "pcmrdv"); 161 break; 162 case 0: 163 c->lock = snd_mtxcreate(c->name, "pcm fake channel"); 164 cv_init(&c->intr_cv, "pcmfk"); 165 break; 166 } 167 168 cv_init(&c->cv, "pcmchn"); 169 } 170 171 static void 172 chn_lockdestroy(struct pcm_channel *c) 173 { 174 CHN_LOCKASSERT(c); 175 176 CHN_BROADCAST(&c->cv); 177 CHN_BROADCAST(&c->intr_cv); 178 179 cv_destroy(&c->cv); 180 cv_destroy(&c->intr_cv); 181 182 snd_mtxfree(c->lock); 183 } 184 185 /** 186 * @brief Determine channel is ready for I/O 187 * 188 * @retval 1 = ready for I/O 189 * @retval 0 = not ready for I/O 190 */ 191 static int 192 chn_polltrigger(struct pcm_channel *c) 193 { 194 struct snd_dbuf *bs = c->bufsoft; 195 unsigned amt, lim; 196 197 CHN_LOCKASSERT(c); 198 if (c->flags & CHN_F_MAPPED) { 199 if (sndbuf_getprevblocks(bs) == 0) 200 return 1; 201 else 202 return (sndbuf_getblocks(bs) > sndbuf_getprevblocks(bs))? 1 : 0; 203 } else { 204 amt = (c->direction == PCMDIR_PLAY)? sndbuf_getfree(bs) : sndbuf_getready(bs); 205 #if 0 206 lim = (c->flags & CHN_F_HAS_SIZE)? sndbuf_getblksz(bs) : 1; 207 #endif 208 lim = c->lw; 209 return (amt >= lim) ? 1 : 0; 210 } 211 return 0; 212 } 213 214 static int 215 chn_pollreset(struct pcm_channel *c) 216 { 217 struct snd_dbuf *bs = c->bufsoft; 218 219 CHN_LOCKASSERT(c); 220 sndbuf_updateprevtotal(bs); 221 return 1; 222 } 223 224 static void 225 chn_wakeup(struct pcm_channel *c) 226 { 227 struct snd_dbuf *bs; 228 struct pcm_channel *ch; 229 230 CHN_LOCKASSERT(c); 231 232 bs = c->bufsoft; 233 234 if (CHN_EMPTY(c, children.busy)) { 235 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) 236 selwakeuppri(sndbuf_getsel(bs), PRIBIO); 237 if (c->flags & CHN_F_SLEEPING) { 238 /* 239 * Ok, I can just panic it right here since it is 240 * quite obvious that we never allow multiple waiters 241 * from userland. I'm too generous... 242 */ 243 CHN_BROADCAST(&c->intr_cv); 244 } 245 } else { 246 CHN_FOREACH(ch, c, children.busy) { 247 CHN_LOCK(ch); 248 chn_wakeup(ch); 249 CHN_UNLOCK(ch); 250 } 251 } 252 } 253 254 static int 255 chn_sleep(struct pcm_channel *c, int timeout) 256 { 257 int ret; 258 259 CHN_LOCKASSERT(c); 260 261 if (c->flags & CHN_F_DEAD) 262 return (EINVAL); 263 264 c->flags |= CHN_F_SLEEPING; 265 ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout); 266 c->flags &= ~CHN_F_SLEEPING; 267 268 return ((c->flags & CHN_F_DEAD) ? EINVAL : ret); 269 } 270 271 /* 272 * chn_dmaupdate() tracks the status of a dma transfer, 273 * updating pointers. 274 */ 275 276 static unsigned int 277 chn_dmaupdate(struct pcm_channel *c) 278 { 279 struct snd_dbuf *b = c->bufhard; 280 unsigned int delta, old, hwptr, amt; 281 282 KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0")); 283 CHN_LOCKASSERT(c); 284 285 old = sndbuf_gethwptr(b); 286 hwptr = chn_getptr(c); 287 delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b); 288 sndbuf_sethwptr(b, hwptr); 289 290 if (c->direction == PCMDIR_PLAY) { 291 amt = min(delta, sndbuf_getready(b)); 292 amt -= amt % sndbuf_getbps(b); 293 if (amt > 0) 294 sndbuf_dispose(b, NULL, amt); 295 } else { 296 amt = min(delta, sndbuf_getfree(b)); 297 amt -= amt % sndbuf_getbps(b); 298 if (amt > 0) 299 sndbuf_acquire(b, NULL, amt); 300 } 301 if (snd_verbose > 3 && CHN_STARTED(c) && delta == 0) { 302 device_printf(c->dev, "WARNING: %s DMA completion " 303 "too fast/slow ! hwptr=%u, old=%u " 304 "delta=%u amt=%u ready=%u free=%u\n", 305 CHN_DIRSTR(c), hwptr, old, delta, amt, 306 sndbuf_getready(b), sndbuf_getfree(b)); 307 } 308 309 return delta; 310 } 311 312 void 313 chn_wrupdate(struct pcm_channel *c) 314 { 315 int ret; 316 317 CHN_LOCKASSERT(c); 318 KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel")); 319 320 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c)) 321 return; 322 chn_dmaupdate(c); 323 ret = chn_wrfeed(c); 324 /* tell the driver we've updated the primary buffer */ 325 chn_trigger(c, PCMTRIG_EMLDMAWR); 326 DEB(if (ret) 327 printf("chn_wrupdate: chn_wrfeed returned %d\n", ret);) 328 329 } 330 331 int 332 chn_wrfeed(struct pcm_channel *c) 333 { 334 struct snd_dbuf *b = c->bufhard; 335 struct snd_dbuf *bs = c->bufsoft; 336 unsigned int ret, amt; 337 338 CHN_LOCKASSERT(c); 339 340 if ((c->flags & CHN_F_MAPPED) && !(c->flags & CHN_F_CLOSING)) 341 sndbuf_acquire(bs, NULL, sndbuf_getfree(bs)); 342 343 amt = sndbuf_getfree(b); 344 345 ret = (amt > 0) ? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC; 346 /* 347 * Possible xruns. There should be no empty space left in buffer. 348 */ 349 if (sndbuf_getfree(b) > 0) 350 c->xruns++; 351 352 if (sndbuf_getfree(b) < amt) 353 chn_wakeup(c); 354 355 return ret; 356 } 357 358 static void 359 chn_wrintr(struct pcm_channel *c) 360 { 361 int ret; 362 363 CHN_LOCKASSERT(c); 364 /* update pointers in primary buffer */ 365 chn_dmaupdate(c); 366 /* ...and feed from secondary to primary */ 367 ret = chn_wrfeed(c); 368 /* tell the driver we've updated the primary buffer */ 369 chn_trigger(c, PCMTRIG_EMLDMAWR); 370 DEB(if (ret) 371 printf("chn_wrintr: chn_wrfeed returned %d\n", ret);) 372 } 373 374 /* 375 * user write routine - uiomove data into secondary buffer, trigger if necessary 376 * if blocking, sleep, rinse and repeat. 377 * 378 * called externally, so must handle locking 379 */ 380 381 int 382 chn_write(struct pcm_channel *c, struct uio *buf) 383 { 384 struct snd_dbuf *bs = c->bufsoft; 385 void *off; 386 int ret, timeout, sz, t, p; 387 388 CHN_LOCKASSERT(c); 389 390 ret = 0; 391 timeout = chn_timeout * hz; 392 393 while (ret == 0 && buf->uio_resid > 0) { 394 sz = min(buf->uio_resid, sndbuf_getfree(bs)); 395 if (sz > 0) { 396 /* 397 * The following assumes that the free space in 398 * the buffer can never be less around the 399 * unlock-uiomove-lock sequence. 400 */ 401 while (ret == 0 && sz > 0) { 402 p = sndbuf_getfreeptr(bs); 403 t = min(sz, sndbuf_getsize(bs) - p); 404 off = sndbuf_getbufofs(bs, p); 405 CHN_UNLOCK(c); 406 ret = uiomove(off, t, buf); 407 CHN_LOCK(c); 408 sz -= t; 409 sndbuf_acquire(bs, NULL, t); 410 } 411 ret = 0; 412 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { 413 ret = chn_start(c, 0); 414 if (ret != 0) 415 c->flags |= CHN_F_DEAD; 416 } 417 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) { 418 /** 419 * @todo Evaluate whether EAGAIN is truly desirable. 420 * 4Front drivers behave like this, but I'm 421 * not sure if it at all violates the "write 422 * should be allowed to block" model. 423 * 424 * The idea is that, while set with CHN_F_NOTRIGGER, 425 * a channel isn't playing, *but* without this we 426 * end up with "interrupt timeout / channel dead". 427 */ 428 ret = EAGAIN; 429 } else { 430 ret = chn_sleep(c, timeout); 431 if (ret == EAGAIN) { 432 ret = EINVAL; 433 c->flags |= CHN_F_DEAD; 434 printf("%s: play interrupt timeout, " 435 "channel dead\n", c->name); 436 } else if (ret == ERESTART || ret == EINTR) 437 c->flags |= CHN_F_ABORTING; 438 } 439 } 440 441 return (ret); 442 } 443 444 /* 445 * Feed new data from the read buffer. Can be called in the bottom half. 446 */ 447 int 448 chn_rdfeed(struct pcm_channel *c) 449 { 450 struct snd_dbuf *b = c->bufhard; 451 struct snd_dbuf *bs = c->bufsoft; 452 unsigned int ret, amt; 453 454 CHN_LOCKASSERT(c); 455 456 if (c->flags & CHN_F_MAPPED) 457 sndbuf_dispose(bs, NULL, sndbuf_getready(bs)); 458 459 amt = sndbuf_getfree(bs); 460 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC; 461 462 amt = sndbuf_getready(b); 463 if (amt > 0) { 464 c->xruns++; 465 sndbuf_dispose(b, NULL, amt); 466 } 467 468 if (sndbuf_getready(bs) > 0) 469 chn_wakeup(c); 470 471 return ret; 472 } 473 474 void 475 chn_rdupdate(struct pcm_channel *c) 476 { 477 int ret; 478 479 CHN_LOCKASSERT(c); 480 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel")); 481 482 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c)) 483 return; 484 chn_trigger(c, PCMTRIG_EMLDMARD); 485 chn_dmaupdate(c); 486 ret = chn_rdfeed(c); 487 DEB(if (ret) 488 printf("chn_rdfeed: %d\n", ret);) 489 490 } 491 492 /* read interrupt routine. Must be called with interrupts blocked. */ 493 static void 494 chn_rdintr(struct pcm_channel *c) 495 { 496 int ret; 497 498 CHN_LOCKASSERT(c); 499 /* tell the driver to update the primary buffer if non-dma */ 500 chn_trigger(c, PCMTRIG_EMLDMARD); 501 /* update pointers in primary buffer */ 502 chn_dmaupdate(c); 503 /* ...and feed from primary to secondary */ 504 ret = chn_rdfeed(c); 505 } 506 507 /* 508 * user read routine - trigger if necessary, uiomove data from secondary buffer 509 * if blocking, sleep, rinse and repeat. 510 * 511 * called externally, so must handle locking 512 */ 513 514 int 515 chn_read(struct pcm_channel *c, struct uio *buf) 516 { 517 struct snd_dbuf *bs = c->bufsoft; 518 void *off; 519 int ret, timeout, sz, t, p; 520 521 CHN_LOCKASSERT(c); 522 523 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { 524 ret = chn_start(c, 0); 525 if (ret != 0) { 526 c->flags |= CHN_F_DEAD; 527 return (ret); 528 } 529 } 530 531 ret = 0; 532 timeout = chn_timeout * hz; 533 534 while (ret == 0 && buf->uio_resid > 0) { 535 sz = min(buf->uio_resid, sndbuf_getready(bs)); 536 if (sz > 0) { 537 /* 538 * The following assumes that the free space in 539 * the buffer can never be less around the 540 * unlock-uiomove-lock sequence. 541 */ 542 while (ret == 0 && sz > 0) { 543 p = sndbuf_getreadyptr(bs); 544 t = min(sz, sndbuf_getsize(bs) - p); 545 off = sndbuf_getbufofs(bs, p); 546 CHN_UNLOCK(c); 547 ret = uiomove(off, t, buf); 548 CHN_LOCK(c); 549 sz -= t; 550 sndbuf_dispose(bs, NULL, t); 551 } 552 ret = 0; 553 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) 554 ret = EAGAIN; 555 else { 556 ret = chn_sleep(c, timeout); 557 if (ret == EAGAIN) { 558 ret = EINVAL; 559 c->flags |= CHN_F_DEAD; 560 printf("%s: record interrupt timeout, " 561 "channel dead\n", c->name); 562 } else if (ret == ERESTART || ret == EINTR) 563 c->flags |= CHN_F_ABORTING; 564 } 565 } 566 567 return (ret); 568 } 569 570 void 571 chn_intr(struct pcm_channel *c) 572 { 573 CHN_LOCK(c); 574 c->interrupts++; 575 if (c->direction == PCMDIR_PLAY) 576 chn_wrintr(c); 577 else 578 chn_rdintr(c); 579 CHN_UNLOCK(c); 580 } 581 582 u_int32_t 583 chn_start(struct pcm_channel *c, int force) 584 { 585 u_int32_t i, j; 586 struct snd_dbuf *b = c->bufhard; 587 struct snd_dbuf *bs = c->bufsoft; 588 int err; 589 590 CHN_LOCKASSERT(c); 591 /* if we're running, or if we're prevented from triggering, bail */ 592 if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force)) 593 return (EINVAL); 594 595 err = 0; 596 597 if (force) { 598 i = 1; 599 j = 0; 600 } else { 601 if (c->direction == PCMDIR_REC) { 602 i = sndbuf_getfree(bs); 603 j = (i > 0) ? 1 : sndbuf_getready(b); 604 } else { 605 if (sndbuf_getfree(bs) == 0) { 606 i = 1; 607 j = 0; 608 } else { 609 struct snd_dbuf *pb; 610 611 pb = CHN_BUF_PARENT(c, b); 612 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb); 613 j = sndbuf_getbps(pb); 614 } 615 } 616 if (snd_verbose > 3 && CHN_EMPTY(c, children)) 617 printf("%s: %s (%s) threshold i=%d j=%d\n", 618 __func__, CHN_DIRSTR(c), 619 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", 620 i, j); 621 } 622 623 if (i >= j) { 624 c->flags |= CHN_F_TRIGGERED; 625 sndbuf_setrun(b, 1); 626 c->feedcount = (c->flags & CHN_F_CLOSING) ? 2 : 0; 627 c->interrupts = 0; 628 c->xruns = 0; 629 if (c->direction == PCMDIR_PLAY && c->parentchannel == NULL) { 630 sndbuf_fillsilence(b); 631 if (snd_verbose > 3) 632 printf("%s: %s starting! (%s) (ready=%d " 633 "force=%d i=%d j=%d intrtimeout=%u " 634 "latency=%dms)\n", 635 __func__, 636 (c->flags & CHN_F_HAS_VCHAN) ? 637 "VCHAN" : "HW", 638 (c->flags & CHN_F_CLOSING) ? "closing" : 639 "running", 640 sndbuf_getready(b), 641 force, i, j, c->timeout, 642 (sndbuf_getsize(b) * 1000) / 643 (sndbuf_getbps(b) * sndbuf_getspd(b))); 644 } 645 err = chn_trigger(c, PCMTRIG_START); 646 } 647 648 return (err); 649 } 650 651 void 652 chn_resetbuf(struct pcm_channel *c) 653 { 654 struct snd_dbuf *b = c->bufhard; 655 struct snd_dbuf *bs = c->bufsoft; 656 657 c->blocks = 0; 658 sndbuf_reset(b); 659 sndbuf_reset(bs); 660 } 661 662 /* 663 * chn_sync waits until the space in the given channel goes above 664 * a threshold. The threshold is checked against fl or rl respectively. 665 * Assume that the condition can become true, do not check here... 666 */ 667 int 668 chn_sync(struct pcm_channel *c, int threshold) 669 { 670 struct snd_dbuf *b, *bs; 671 int ret, count, hcount, minflush, resid, residp, syncdelay, blksz; 672 u_int32_t cflag; 673 674 CHN_LOCKASSERT(c); 675 676 if (c->direction != PCMDIR_PLAY) 677 return (EINVAL); 678 679 bs = c->bufsoft; 680 681 if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) || 682 (threshold < 1 && sndbuf_getready(bs) < 1)) 683 return (0); 684 685 /* if we haven't yet started and nothing is buffered, else start*/ 686 if (CHN_STOPPED(c)) { 687 if (threshold > 0 || sndbuf_getready(bs) > 0) { 688 ret = chn_start(c, 1); 689 if (ret != 0) 690 return (ret); 691 } else 692 return (0); 693 } 694 695 b = CHN_BUF_PARENT(c, c->bufhard); 696 697 minflush = threshold + sndbuf_xbytes(sndbuf_getready(b), b, bs); 698 699 syncdelay = chn_syncdelay; 700 701 if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0)) 702 minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs); 703 704 /* 705 * Append (0-1000) millisecond trailing buffer (if needed) 706 * for slower / high latency hardwares (notably USB audio) 707 * to avoid audible truncation. 708 */ 709 if (syncdelay > 0) 710 minflush += (sndbuf_getbps(bs) * sndbuf_getspd(bs) * 711 ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000; 712 713 minflush -= minflush % sndbuf_getbps(bs); 714 715 if (minflush > 0) { 716 threshold = min(minflush, sndbuf_getfree(bs)); 717 sndbuf_clear(bs, threshold); 718 sndbuf_acquire(bs, NULL, threshold); 719 minflush -= threshold; 720 } 721 722 resid = sndbuf_getready(bs); 723 residp = resid; 724 blksz = sndbuf_getblksz(b); 725 if (blksz < 1) { 726 printf("%s: WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n", 727 __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b), 728 sndbuf_getblksz(b), sndbuf_getblkcnt(b)); 729 if (sndbuf_getblkcnt(b) > 0) 730 blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b); 731 if (blksz < 1) 732 blksz = 1; 733 } 734 count = sndbuf_xbytes(minflush + resid, bs, b) / blksz; 735 hcount = count; 736 ret = 0; 737 738 if (snd_verbose > 3) 739 printf("%s: [begin] timeout=%d count=%d " 740 "minflush=%d resid=%d\n", __func__, c->timeout, count, 741 minflush, resid); 742 743 cflag = c->flags & CHN_F_CLOSING; 744 c->flags |= CHN_F_CLOSING; 745 while (count > 0 && (resid > 0 || minflush > 0)) { 746 ret = chn_sleep(c, c->timeout); 747 if (ret == ERESTART || ret == EINTR) { 748 c->flags |= CHN_F_ABORTING; 749 break; 750 } else if (ret == 0 || ret == EAGAIN) { 751 resid = sndbuf_getready(bs); 752 if (resid == residp) { 753 --count; 754 if (snd_verbose > 3) 755 printf("%s: [stalled] timeout=%d " 756 "count=%d hcount=%d " 757 "resid=%d minflush=%d\n", 758 __func__, c->timeout, count, 759 hcount, resid, minflush); 760 } else if (resid < residp && count < hcount) { 761 ++count; 762 if (snd_verbose > 3) 763 printf("%s: [resume] timeout=%d " 764 "count=%d hcount=%d " 765 "resid=%d minflush=%d\n", 766 __func__, c->timeout, count, 767 hcount, resid, minflush); 768 } 769 if (minflush > 0 && sndbuf_getfree(bs) > 0) { 770 threshold = min(minflush, 771 sndbuf_getfree(bs)); 772 sndbuf_clear(bs, threshold); 773 sndbuf_acquire(bs, NULL, threshold); 774 resid = sndbuf_getready(bs); 775 minflush -= threshold; 776 } 777 residp = resid; 778 } else 779 break; 780 } 781 c->flags &= ~CHN_F_CLOSING; 782 c->flags |= cflag; 783 784 if (snd_verbose > 3) 785 printf("%s: timeout=%d count=%d hcount=%d resid=%d residp=%d " 786 "minflush=%d ret=%d\n", 787 __func__, c->timeout, count, hcount, resid, residp, 788 minflush, ret); 789 790 return (0); 791 } 792 793 /* called externally, handle locking */ 794 int 795 chn_poll(struct pcm_channel *c, int ev, struct thread *td) 796 { 797 struct snd_dbuf *bs = c->bufsoft; 798 int ret; 799 800 CHN_LOCKASSERT(c); 801 if (!(c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED))) { 802 ret = chn_start(c, 1); 803 if (ret != 0) 804 return (0); 805 } 806 ret = 0; 807 if (chn_polltrigger(c) && chn_pollreset(c)) 808 ret = ev; 809 else 810 selrecord(td, sndbuf_getsel(bs)); 811 return (ret); 812 } 813 814 /* 815 * chn_abort terminates a running dma transfer. it may sleep up to 200ms. 816 * it returns the number of bytes that have not been transferred. 817 * 818 * called from: dsp_close, dsp_ioctl, with channel locked 819 */ 820 int 821 chn_abort(struct pcm_channel *c) 822 { 823 int missing = 0; 824 struct snd_dbuf *b = c->bufhard; 825 struct snd_dbuf *bs = c->bufsoft; 826 827 CHN_LOCKASSERT(c); 828 if (CHN_STOPPED(c)) 829 return 0; 830 c->flags |= CHN_F_ABORTING; 831 832 c->flags &= ~CHN_F_TRIGGERED; 833 /* kill the channel */ 834 chn_trigger(c, PCMTRIG_ABORT); 835 sndbuf_setrun(b, 0); 836 if (!(c->flags & CHN_F_VIRTUAL)) 837 chn_dmaupdate(c); 838 missing = sndbuf_getready(bs); 839 840 c->flags &= ~CHN_F_ABORTING; 841 return missing; 842 } 843 844 /* 845 * this routine tries to flush the dma transfer. It is called 846 * on a close of a playback channel. 847 * first, if there is data in the buffer, but the dma has not yet 848 * begun, we need to start it. 849 * next, we wait for the play buffer to drain 850 * finally, we stop the dma. 851 * 852 * called from: dsp_close, not valid for record channels. 853 */ 854 855 int 856 chn_flush(struct pcm_channel *c) 857 { 858 struct snd_dbuf *b = c->bufhard; 859 860 CHN_LOCKASSERT(c); 861 KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel")); 862 DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags)); 863 864 c->flags |= CHN_F_CLOSING; 865 chn_sync(c, 0); 866 c->flags &= ~CHN_F_TRIGGERED; 867 /* kill the channel */ 868 chn_trigger(c, PCMTRIG_ABORT); 869 sndbuf_setrun(b, 0); 870 871 c->flags &= ~CHN_F_CLOSING; 872 return 0; 873 } 874 875 int 876 fmtvalid(u_int32_t fmt, u_int32_t *fmtlist) 877 { 878 int i; 879 880 for (i = 0; fmtlist[i]; i++) 881 if (fmt == fmtlist[i]) 882 return 1; 883 return 0; 884 } 885 886 static struct afmtstr_table default_afmtstr_table[] = { 887 { "alaw", AFMT_A_LAW }, { "mulaw", AFMT_MU_LAW }, 888 { "u8", AFMT_U8 }, { "s8", AFMT_S8 }, 889 { "s16le", AFMT_S16_LE }, { "s16be", AFMT_S16_BE }, 890 { "u16le", AFMT_U16_LE }, { "u16be", AFMT_U16_BE }, 891 { "s24le", AFMT_S24_LE }, { "s24be", AFMT_S24_BE }, 892 { "u24le", AFMT_U24_LE }, { "u24be", AFMT_U24_BE }, 893 { "s32le", AFMT_S32_LE }, { "s32be", AFMT_S32_BE }, 894 { "u32le", AFMT_U32_LE }, { "u32be", AFMT_U32_BE }, 895 { NULL, 0 }, 896 }; 897 898 int 899 afmtstr_swap_sign(char *s) 900 { 901 if (s == NULL || strlen(s) < 2) /* full length of "s8" */ 902 return 0; 903 if (*s == 's') 904 *s = 'u'; 905 else if (*s == 'u') 906 *s = 's'; 907 else 908 return 0; 909 return 1; 910 } 911 912 int 913 afmtstr_swap_endian(char *s) 914 { 915 if (s == NULL || strlen(s) < 5) /* full length of "s16le" */ 916 return 0; 917 if (s[3] == 'l') 918 s[3] = 'b'; 919 else if (s[3] == 'b') 920 s[3] = 'l'; 921 else 922 return 0; 923 return 1; 924 } 925 926 u_int32_t 927 afmtstr2afmt(struct afmtstr_table *tbl, const char *s, int stereo) 928 { 929 size_t fsz, sz; 930 931 sz = (s == NULL) ? 0 : strlen(s); 932 933 if (sz > 1) { 934 935 if (tbl == NULL) 936 tbl = default_afmtstr_table; 937 938 for (; tbl->fmtstr != NULL; tbl++) { 939 fsz = strlen(tbl->fmtstr); 940 if (sz < fsz) 941 continue; 942 if (strncmp(s, tbl->fmtstr, fsz) != 0) 943 continue; 944 if (fsz == sz) 945 return tbl->format | 946 ((stereo) ? AFMT_STEREO : 0); 947 if ((sz - fsz) < 2 || s[fsz] != ':') 948 break; 949 /* 950 * For now, just handle mono/stereo. 951 */ 952 if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 'm' || 953 s[fsz + 1] == '1')) || 954 strcmp(s + fsz + 1, "mono") == 0) 955 return tbl->format; 956 if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 's' || 957 s[fsz + 1] == '2')) || 958 strcmp(s + fsz + 1, "stereo") == 0) 959 return tbl->format | AFMT_STEREO; 960 break; 961 } 962 } 963 964 return 0; 965 } 966 967 u_int32_t 968 afmt2afmtstr(struct afmtstr_table *tbl, u_int32_t afmt, char *dst, 969 size_t len, int type, int stereo) 970 { 971 u_int32_t fmt = 0; 972 char *fmtstr = NULL, *tag = ""; 973 974 if (tbl == NULL) 975 tbl = default_afmtstr_table; 976 977 for (; tbl->format != 0; tbl++) { 978 if (tbl->format == 0) 979 break; 980 if ((afmt & ~AFMT_STEREO) != tbl->format) 981 continue; 982 fmt = afmt; 983 fmtstr = tbl->fmtstr; 984 break; 985 } 986 987 if (fmt != 0 && fmtstr != NULL && dst != NULL && len > 0) { 988 strlcpy(dst, fmtstr, len); 989 switch (type) { 990 case AFMTSTR_SIMPLE: 991 tag = (fmt & AFMT_STEREO) ? ":s" : ":m"; 992 break; 993 case AFMTSTR_NUM: 994 tag = (fmt & AFMT_STEREO) ? ":2" : ":1"; 995 break; 996 case AFMTSTR_FULL: 997 tag = (fmt & AFMT_STEREO) ? ":stereo" : ":mono"; 998 break; 999 case AFMTSTR_NONE: 1000 default: 1001 break; 1002 } 1003 if (strlen(tag) > 0 && ((stereo && !(fmt & AFMT_STEREO)) || \ 1004 (!stereo && (fmt & AFMT_STEREO)))) 1005 strlcat(dst, tag, len); 1006 } 1007 1008 return fmt; 1009 } 1010 1011 int 1012 chn_reset(struct pcm_channel *c, u_int32_t fmt) 1013 { 1014 int hwspd, r; 1015 1016 CHN_LOCKASSERT(c); 1017 c->feedcount = 0; 1018 c->flags &= CHN_F_RESET; 1019 c->interrupts = 0; 1020 c->timeout = 1; 1021 c->xruns = 0; 1022 1023 r = CHANNEL_RESET(c->methods, c->devinfo); 1024 if (fmt != 0) { 1025 #if 0 1026 hwspd = DSP_DEFAULT_SPEED; 1027 /* only do this on a record channel until feederbuilder works */ 1028 if (c->direction == PCMDIR_REC) 1029 RANGE(hwspd, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed); 1030 c->speed = hwspd; 1031 #endif 1032 hwspd = chn_getcaps(c)->minspeed; 1033 c->speed = hwspd; 1034 1035 if (r == 0) 1036 r = chn_setformat(c, fmt); 1037 if (r == 0) 1038 r = chn_setspeed(c, hwspd); 1039 #if 0 1040 if (r == 0) 1041 r = chn_setvolume(c, 100, 100); 1042 #endif 1043 } 1044 if (r == 0) 1045 r = chn_setlatency(c, chn_latency); 1046 if (r == 0) { 1047 chn_resetbuf(c); 1048 r = CHANNEL_RESETDONE(c->methods, c->devinfo); 1049 } 1050 return r; 1051 } 1052 1053 int 1054 chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) 1055 { 1056 struct feeder_class *fc; 1057 struct snd_dbuf *b, *bs; 1058 int ret; 1059 1060 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX) 1061 chn_timeout = CHN_TIMEOUT; 1062 1063 chn_lockinit(c, dir); 1064 1065 b = NULL; 1066 bs = NULL; 1067 CHN_INIT(c, children); 1068 CHN_INIT(c, children.busy); 1069 c->devinfo = NULL; 1070 c->feeder = NULL; 1071 c->latency = -1; 1072 c->timeout = 1; 1073 1074 ret = ENOMEM; 1075 b = sndbuf_create(c->dev, c->name, "primary", c); 1076 if (b == NULL) 1077 goto out; 1078 bs = sndbuf_create(c->dev, c->name, "secondary", c); 1079 if (bs == NULL) 1080 goto out; 1081 1082 CHN_LOCK(c); 1083 1084 ret = EINVAL; 1085 fc = feeder_getclass(NULL); 1086 if (fc == NULL) 1087 goto out; 1088 if (chn_addfeeder(c, fc, NULL)) 1089 goto out; 1090 1091 /* 1092 * XXX - sndbuf_setup() & sndbuf_resize() expect to be called 1093 * with the channel unlocked because they are also called 1094 * from driver methods that don't know about locking 1095 */ 1096 CHN_UNLOCK(c); 1097 sndbuf_setup(bs, NULL, 0); 1098 CHN_LOCK(c); 1099 c->bufhard = b; 1100 c->bufsoft = bs; 1101 c->flags = 0; 1102 c->feederflags = 0; 1103 c->sm = NULL; 1104 1105 ret = ENODEV; 1106 CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */ 1107 c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); 1108 CHN_LOCK(c); 1109 if (c->devinfo == NULL) 1110 goto out; 1111 1112 ret = ENOMEM; 1113 if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) 1114 goto out; 1115 1116 ret = chn_setdir(c, direction); 1117 if (ret) 1118 goto out; 1119 1120 ret = sndbuf_setfmt(b, AFMT_U8); 1121 if (ret) 1122 goto out; 1123 1124 ret = sndbuf_setfmt(bs, AFMT_U8); 1125 if (ret) 1126 goto out; 1127 1128 /** 1129 * @todo Should this be moved somewhere else? The primary buffer 1130 * is allocated by the driver or via DMA map setup, and tmpbuf 1131 * seems to only come into existence in sndbuf_resize(). 1132 */ 1133 if (c->direction == PCMDIR_PLAY) { 1134 bs->sl = sndbuf_getmaxsize(bs); 1135 bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT); 1136 if (bs->shadbuf == NULL) { 1137 ret = ENOMEM; 1138 goto out; 1139 } 1140 } 1141 1142 out: 1143 CHN_UNLOCK(c); 1144 if (ret) { 1145 if (c->devinfo) { 1146 if (CHANNEL_FREE(c->methods, c->devinfo)) 1147 sndbuf_free(b); 1148 } 1149 if (bs) 1150 sndbuf_destroy(bs); 1151 if (b) 1152 sndbuf_destroy(b); 1153 CHN_LOCK(c); 1154 c->flags |= CHN_F_DEAD; 1155 chn_lockdestroy(c); 1156 1157 return ret; 1158 } 1159 1160 return 0; 1161 } 1162 1163 int 1164 chn_kill(struct pcm_channel *c) 1165 { 1166 struct snd_dbuf *b = c->bufhard; 1167 struct snd_dbuf *bs = c->bufsoft; 1168 1169 if (CHN_STARTED(c)) { 1170 CHN_LOCK(c); 1171 chn_trigger(c, PCMTRIG_ABORT); 1172 CHN_UNLOCK(c); 1173 } 1174 while (chn_removefeeder(c) == 0) 1175 ; 1176 if (CHANNEL_FREE(c->methods, c->devinfo)) 1177 sndbuf_free(b); 1178 sndbuf_destroy(bs); 1179 sndbuf_destroy(b); 1180 CHN_LOCK(c); 1181 c->flags |= CHN_F_DEAD; 1182 chn_lockdestroy(c); 1183 1184 return (0); 1185 } 1186 1187 int 1188 chn_setdir(struct pcm_channel *c, int dir) 1189 { 1190 #ifdef DEV_ISA 1191 struct snd_dbuf *b = c->bufhard; 1192 #endif 1193 int r; 1194 1195 CHN_LOCKASSERT(c); 1196 c->direction = dir; 1197 r = CHANNEL_SETDIR(c->methods, c->devinfo, c->direction); 1198 #ifdef DEV_ISA 1199 if (!r && SND_DMA(b)) 1200 sndbuf_dmasetdir(b, c->direction); 1201 #endif 1202 return r; 1203 } 1204 1205 int 1206 chn_setvolume(struct pcm_channel *c, int left, int right) 1207 { 1208 CHN_LOCKASSERT(c); 1209 /* should add a feeder for volume changing if channel returns -1 */ 1210 if (left > 100) 1211 left = 100; 1212 if (left < 0) 1213 left = 0; 1214 if (right > 100) 1215 right = 100; 1216 if (right < 0) 1217 right = 0; 1218 c->volume = left | (right << 8); 1219 return 0; 1220 } 1221 1222 static u_int32_t 1223 round_pow2(u_int32_t v) 1224 { 1225 u_int32_t ret; 1226 1227 if (v < 2) 1228 v = 2; 1229 ret = 0; 1230 while (v >> ret) 1231 ret++; 1232 ret = 1 << (ret - 1); 1233 while (ret < v) 1234 ret <<= 1; 1235 return ret; 1236 } 1237 1238 static u_int32_t 1239 round_blksz(u_int32_t v, int round) 1240 { 1241 u_int32_t ret, tmp; 1242 1243 if (round < 1) 1244 round = 1; 1245 1246 ret = min(round_pow2(v), CHN_2NDBUFMAXSIZE >> 1); 1247 1248 if (ret > v && (ret >> 1) > 0 && (ret >> 1) >= ((v * 3) >> 2)) 1249 ret >>= 1; 1250 1251 tmp = ret - (ret % round); 1252 while (tmp < 16 || tmp < round) { 1253 ret <<= 1; 1254 tmp = ret - (ret % round); 1255 } 1256 1257 return ret; 1258 } 1259 1260 /* 1261 * 4Front call it DSP Policy, while we call it "Latency Profile". The idea 1262 * is to keep 2nd buffer short so that it doesn't cause long queue during 1263 * buffer transfer. 1264 * 1265 * Latency reference table for 48khz stereo 16bit: (PLAY) 1266 * 1267 * +---------+------------+-----------+------------+ 1268 * | Latency | Blockcount | Blocksize | Buffersize | 1269 * +---------+------------+-----------+------------+ 1270 * | 0 | 2 | 64 | 128 | 1271 * +---------+------------+-----------+------------+ 1272 * | 1 | 4 | 128 | 512 | 1273 * +---------+------------+-----------+------------+ 1274 * | 2 | 8 | 512 | 4096 | 1275 * +---------+------------+-----------+------------+ 1276 * | 3 | 16 | 512 | 8192 | 1277 * +---------+------------+-----------+------------+ 1278 * | 4 | 32 | 512 | 16384 | 1279 * +---------+------------+-----------+------------+ 1280 * | 5 | 32 | 1024 | 32768 | 1281 * +---------+------------+-----------+------------+ 1282 * | 6 | 16 | 2048 | 32768 | 1283 * +---------+------------+-----------+------------+ 1284 * | 7 | 8 | 4096 | 32768 | 1285 * +---------+------------+-----------+------------+ 1286 * | 8 | 4 | 8192 | 32768 | 1287 * +---------+------------+-----------+------------+ 1288 * | 9 | 2 | 16384 | 32768 | 1289 * +---------+------------+-----------+------------+ 1290 * | 10 | 2 | 32768 | 65536 | 1291 * +---------+------------+-----------+------------+ 1292 * 1293 * Recording need a different reference table. All we care is 1294 * gobbling up everything within reasonable buffering threshold. 1295 * 1296 * Latency reference table for 48khz stereo 16bit: (REC) 1297 * 1298 * +---------+------------+-----------+------------+ 1299 * | Latency | Blockcount | Blocksize | Buffersize | 1300 * +---------+------------+-----------+------------+ 1301 * | 0 | 512 | 32 | 16384 | 1302 * +---------+------------+-----------+------------+ 1303 * | 1 | 256 | 64 | 16384 | 1304 * +---------+------------+-----------+------------+ 1305 * | 2 | 128 | 128 | 16384 | 1306 * +---------+------------+-----------+------------+ 1307 * | 3 | 64 | 256 | 16384 | 1308 * +---------+------------+-----------+------------+ 1309 * | 4 | 32 | 512 | 16384 | 1310 * +---------+------------+-----------+------------+ 1311 * | 5 | 32 | 1024 | 32768 | 1312 * +---------+------------+-----------+------------+ 1313 * | 6 | 16 | 2048 | 32768 | 1314 * +---------+------------+-----------+------------+ 1315 * | 7 | 8 | 4096 | 32768 | 1316 * +---------+------------+-----------+------------+ 1317 * | 8 | 4 | 8192 | 32768 | 1318 * +---------+------------+-----------+------------+ 1319 * | 9 | 2 | 16384 | 32768 | 1320 * +---------+------------+-----------+------------+ 1321 * | 10 | 2 | 32768 | 65536 | 1322 * +---------+------------+-----------+------------+ 1323 * 1324 * Calculations for other data rate are entirely based on these reference 1325 * tables. For normal operation, Latency 5 seems give the best, well 1326 * balanced performance for typical workload. Anything below 5 will 1327 * eat up CPU to keep up with increasing context switches because of 1328 * shorter buffer space and usually require the application to handle it 1329 * aggresively through possibly real time programming technique. 1330 * 1331 */ 1332 #define CHN_LATENCY_PBLKCNT_REF \ 1333 {{1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}, \ 1334 {1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}} 1335 #define CHN_LATENCY_PBUFSZ_REF \ 1336 {{7, 9, 12, 13, 14, 15, 15, 15, 15, 15, 16}, \ 1337 {11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 17}} 1338 1339 #define CHN_LATENCY_RBLKCNT_REF \ 1340 {{9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}, \ 1341 {9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}} 1342 #define CHN_LATENCY_RBUFSZ_REF \ 1343 {{14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, \ 1344 {15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17}} 1345 1346 #define CHN_LATENCY_DATA_REF 192000 /* 48khz stereo 16bit ~ 48000 x 2 x 2 */ 1347 1348 static int 1349 chn_calclatency(int dir, int latency, int bps, u_int32_t datarate, 1350 u_int32_t max, int *rblksz, int *rblkcnt) 1351 { 1352 static int pblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1353 CHN_LATENCY_PBLKCNT_REF; 1354 static int pbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1355 CHN_LATENCY_PBUFSZ_REF; 1356 static int rblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1357 CHN_LATENCY_RBLKCNT_REF; 1358 static int rbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1359 CHN_LATENCY_RBUFSZ_REF; 1360 u_int32_t bufsz; 1361 int lprofile, blksz, blkcnt; 1362 1363 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX || 1364 bps < 1 || datarate < 1 || 1365 !(dir == PCMDIR_PLAY || dir == PCMDIR_REC)) { 1366 if (rblksz != NULL) 1367 *rblksz = CHN_2NDBUFMAXSIZE >> 1; 1368 if (rblkcnt != NULL) 1369 *rblkcnt = 2; 1370 printf("%s: FAILED dir=%d latency=%d bps=%d " 1371 "datarate=%u max=%u\n", 1372 __func__, dir, latency, bps, datarate, max); 1373 return CHN_2NDBUFMAXSIZE; 1374 } 1375 1376 lprofile = chn_latency_profile; 1377 1378 if (dir == PCMDIR_PLAY) { 1379 blkcnt = pblkcnts[lprofile][latency]; 1380 bufsz = pbufszs[lprofile][latency]; 1381 } else { 1382 blkcnt = rblkcnts[lprofile][latency]; 1383 bufsz = rbufszs[lprofile][latency]; 1384 } 1385 1386 bufsz = round_pow2(snd_xbytes(1 << bufsz, CHN_LATENCY_DATA_REF, 1387 datarate)); 1388 if (bufsz > max) 1389 bufsz = max; 1390 blksz = round_blksz(bufsz >> blkcnt, bps); 1391 1392 if (rblksz != NULL) 1393 *rblksz = blksz; 1394 if (rblkcnt != NULL) 1395 *rblkcnt = 1 << blkcnt; 1396 1397 return blksz << blkcnt; 1398 } 1399 1400 static int 1401 chn_resizebuf(struct pcm_channel *c, int latency, 1402 int blkcnt, int blksz) 1403 { 1404 struct snd_dbuf *b, *bs, *pb; 1405 int sblksz, sblkcnt, hblksz, hblkcnt, limit = 1; 1406 int ret; 1407 1408 CHN_LOCKASSERT(c); 1409 1410 if ((c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)) || 1411 !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC)) 1412 return EINVAL; 1413 1414 if (latency == -1) { 1415 c->latency = -1; 1416 latency = chn_latency; 1417 } else if (latency == -2) { 1418 latency = c->latency; 1419 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX) 1420 latency = chn_latency; 1421 } else if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX) 1422 return EINVAL; 1423 else { 1424 c->latency = latency; 1425 limit = 0; 1426 } 1427 1428 bs = c->bufsoft; 1429 b = c->bufhard; 1430 1431 if (!(blksz == 0 || blkcnt == -1) && 1432 (blksz < 16 || blksz < sndbuf_getbps(bs) || blkcnt < 2 || 1433 (blksz * blkcnt) > CHN_2NDBUFMAXSIZE)) 1434 return EINVAL; 1435 1436 chn_calclatency(c->direction, latency, sndbuf_getbps(bs), 1437 sndbuf_getbps(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE, 1438 &sblksz, &sblkcnt); 1439 1440 if (blksz == 0 || blkcnt == -1) { 1441 if (blkcnt == -1) 1442 c->flags &= ~CHN_F_HAS_SIZE; 1443 if (c->flags & CHN_F_HAS_SIZE) { 1444 blksz = sndbuf_getblksz(bs); 1445 blkcnt = sndbuf_getblkcnt(bs); 1446 } 1447 } else 1448 c->flags |= CHN_F_HAS_SIZE; 1449 1450 if (c->flags & CHN_F_HAS_SIZE) { 1451 /* 1452 * The application has requested their own blksz/blkcnt. 1453 * Just obey with it, and let them toast alone. We can 1454 * clamp it to the nearest latency profile, but that would 1455 * defeat the purpose of having custom control. The least 1456 * we can do is round it to the nearest ^2 and align it. 1457 */ 1458 sblksz = round_blksz(blksz, sndbuf_getbps(bs)); 1459 sblkcnt = round_pow2(blkcnt); 1460 limit = 0; 1461 } 1462 1463 if (c->parentchannel != NULL) { 1464 pb = CHN_BUF_PARENT(c, NULL); 1465 CHN_UNLOCK(c); 1466 CHN_LOCK(c->parentchannel); 1467 chn_notify(c->parentchannel, CHN_N_BLOCKSIZE); 1468 CHN_UNLOCK(c->parentchannel); 1469 CHN_LOCK(c); 1470 limit = (limit != 0 && pb != NULL) ? 1471 sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0; 1472 c->timeout = c->parentchannel->timeout; 1473 } else { 1474 hblkcnt = 2; 1475 if (c->flags & CHN_F_HAS_SIZE) { 1476 hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b), 1477 sndbuf_getbps(b)); 1478 hblkcnt = round_pow2(sndbuf_getblkcnt(bs)); 1479 } else 1480 chn_calclatency(c->direction, latency, 1481 sndbuf_getbps(b), 1482 sndbuf_getbps(b) * sndbuf_getspd(b), 1483 CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt); 1484 1485 if ((hblksz << 1) > sndbuf_getmaxsize(b)) 1486 hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1, 1487 sndbuf_getbps(b)); 1488 1489 while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) { 1490 if (hblkcnt < 4) 1491 hblksz >>= 1; 1492 else 1493 hblkcnt >>= 1; 1494 } 1495 1496 hblksz -= hblksz % sndbuf_getbps(b); 1497 1498 #if 0 1499 hblksz = sndbuf_getmaxsize(b) >> 1; 1500 hblksz -= hblksz % sndbuf_getbps(b); 1501 hblkcnt = 2; 1502 #endif 1503 1504 CHN_UNLOCK(c); 1505 if (chn_usefrags == 0 || 1506 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, 1507 hblksz, hblkcnt) < 1) 1508 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods, 1509 c->devinfo, hblksz)); 1510 CHN_LOCK(c); 1511 1512 if (!CHN_EMPTY(c, children)) { 1513 sblksz = round_blksz( 1514 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs), 1515 sndbuf_getbps(bs)); 1516 sblkcnt = 2; 1517 limit = 0; 1518 } else if (limit != 0) 1519 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs); 1520 1521 /* 1522 * Interrupt timeout 1523 */ 1524 c->timeout = ((u_int64_t)hz * sndbuf_getsize(b)) / 1525 ((u_int64_t)sndbuf_getspd(b) * sndbuf_getbps(b)); 1526 if (c->timeout < 1) 1527 c->timeout = 1; 1528 } 1529 1530 if (limit > CHN_2NDBUFMAXSIZE) 1531 limit = CHN_2NDBUFMAXSIZE; 1532 1533 #if 0 1534 while (limit > 0 && (sblksz * sblkcnt) > limit) { 1535 if (sblkcnt < 4) 1536 break; 1537 sblkcnt >>= 1; 1538 } 1539 #endif 1540 1541 while ((sblksz * sblkcnt) < limit) 1542 sblkcnt <<= 1; 1543 1544 while ((sblksz * sblkcnt) > CHN_2NDBUFMAXSIZE) { 1545 if (sblkcnt < 4) 1546 sblksz >>= 1; 1547 else 1548 sblkcnt >>= 1; 1549 } 1550 1551 sblksz -= sblksz % sndbuf_getbps(bs); 1552 1553 if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz || 1554 sndbuf_getsize(bs) != (sblkcnt * sblksz)) { 1555 ret = sndbuf_remalloc(bs, sblkcnt, sblksz); 1556 if (ret != 0) { 1557 printf("%s: Failed: %d %d\n", __func__, 1558 sblkcnt, sblksz); 1559 return ret; 1560 } 1561 } 1562 1563 /* 1564 * OSSv4 docs: "By default OSS will set the low water level equal 1565 * to the fragment size which is optimal in most cases." 1566 */ 1567 c->lw = sndbuf_getblksz(bs); 1568 chn_resetbuf(c); 1569 1570 if (snd_verbose > 3) 1571 printf("%s: %s (%s) timeout=%u " 1572 "b[%d/%d/%d] bs[%d/%d/%d] limit=%d\n", 1573 __func__, CHN_DIRSTR(c), 1574 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", 1575 c->timeout, 1576 sndbuf_getsize(b), sndbuf_getblksz(b), 1577 sndbuf_getblkcnt(b), 1578 sndbuf_getsize(bs), sndbuf_getblksz(bs), 1579 sndbuf_getblkcnt(bs), limit); 1580 1581 return 0; 1582 } 1583 1584 int 1585 chn_setlatency(struct pcm_channel *c, int latency) 1586 { 1587 CHN_LOCKASSERT(c); 1588 /* Destroy blksz/blkcnt, enforce latency profile. */ 1589 return chn_resizebuf(c, latency, -1, 0); 1590 } 1591 1592 int 1593 chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz) 1594 { 1595 CHN_LOCKASSERT(c); 1596 /* Destroy latency profile, enforce blksz/blkcnt */ 1597 return chn_resizebuf(c, -1, blkcnt, blksz); 1598 } 1599 1600 static int 1601 chn_tryspeed(struct pcm_channel *c, int speed) 1602 { 1603 struct pcm_feeder *f; 1604 struct snd_dbuf *b = c->bufhard; 1605 struct snd_dbuf *bs = c->bufsoft; 1606 struct snd_dbuf *x; 1607 int r, delta; 1608 1609 CHN_LOCKASSERT(c); 1610 DEB(printf("setspeed, channel %s\n", c->name)); 1611 DEB(printf("want speed %d, ", speed)); 1612 if (speed <= 0) 1613 return EINVAL; 1614 if (CHN_STOPPED(c)) { 1615 r = 0; 1616 c->speed = speed; 1617 sndbuf_setspd(bs, speed); 1618 RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed); 1619 DEB(printf("try speed %d, ", speed)); 1620 sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, speed)); 1621 DEB(printf("got speed %d\n", sndbuf_getspd(b))); 1622 1623 delta = sndbuf_getspd(b) - sndbuf_getspd(bs); 1624 if (delta < 0) 1625 delta = -delta; 1626 1627 c->feederflags &= ~(1 << FEEDER_RATE); 1628 /* 1629 * Used to be 500. It was too big! 1630 */ 1631 if (delta > feeder_rate_round) 1632 c->feederflags |= 1 << FEEDER_RATE; 1633 else 1634 sndbuf_setspd(bs, sndbuf_getspd(b)); 1635 1636 r = chn_buildfeeder(c); 1637 DEB(printf("r = %d\n", r)); 1638 if (r) 1639 goto out; 1640 1641 if (!(c->feederflags & (1 << FEEDER_RATE))) 1642 goto out; 1643 1644 r = EINVAL; 1645 f = chn_findfeeder(c, FEEDER_RATE); 1646 DEB(printf("feedrate = %p\n", f)); 1647 if (f == NULL) 1648 goto out; 1649 1650 x = (c->direction == PCMDIR_REC)? b : bs; 1651 r = FEEDER_SET(f, FEEDRATE_SRC, sndbuf_getspd(x)); 1652 DEB(printf("feeder_set(FEEDRATE_SRC, %d) = %d\n", sndbuf_getspd(x), r)); 1653 if (r) 1654 goto out; 1655 1656 x = (c->direction == PCMDIR_REC)? bs : b; 1657 r = FEEDER_SET(f, FEEDRATE_DST, sndbuf_getspd(x)); 1658 DEB(printf("feeder_set(FEEDRATE_DST, %d) = %d\n", sndbuf_getspd(x), r)); 1659 out: 1660 if (!r) 1661 r = CHANNEL_SETFORMAT(c->methods, c->devinfo, 1662 sndbuf_getfmt(b)); 1663 if (!r) 1664 sndbuf_setfmt(bs, c->format); 1665 if (!r) 1666 r = chn_resizebuf(c, -2, 0, 0); 1667 DEB(printf("setspeed done, r = %d\n", r)); 1668 return r; 1669 } else 1670 return EINVAL; 1671 } 1672 1673 int 1674 chn_setspeed(struct pcm_channel *c, int speed) 1675 { 1676 int r, oldspeed = c->speed; 1677 1678 r = chn_tryspeed(c, speed); 1679 if (r) { 1680 if (snd_verbose > 3) 1681 printf("Failed to set speed %d falling back to %d\n", 1682 speed, oldspeed); 1683 r = chn_tryspeed(c, oldspeed); 1684 } 1685 return r; 1686 } 1687 1688 static int 1689 chn_tryformat(struct pcm_channel *c, u_int32_t fmt) 1690 { 1691 struct snd_dbuf *b = c->bufhard; 1692 struct snd_dbuf *bs = c->bufsoft; 1693 int r; 1694 1695 CHN_LOCKASSERT(c); 1696 if (CHN_STOPPED(c)) { 1697 DEB(printf("want format %d\n", fmt)); 1698 c->format = fmt; 1699 r = chn_buildfeeder(c); 1700 if (r == 0) { 1701 sndbuf_setfmt(bs, c->format); 1702 chn_resetbuf(c); 1703 r = CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b)); 1704 if (r == 0) 1705 r = chn_tryspeed(c, c->speed); 1706 } 1707 return r; 1708 } else 1709 return EINVAL; 1710 } 1711 1712 int 1713 chn_setformat(struct pcm_channel *c, u_int32_t fmt) 1714 { 1715 u_int32_t oldfmt = c->format; 1716 int r; 1717 1718 r = chn_tryformat(c, fmt); 1719 if (r) { 1720 if (snd_verbose > 3) 1721 printf("Format change 0x%08x failed, reverting to 0x%08x\n", 1722 fmt, oldfmt); 1723 chn_tryformat(c, oldfmt); 1724 } 1725 return r; 1726 } 1727 1728 int 1729 chn_trigger(struct pcm_channel *c, int go) 1730 { 1731 #ifdef DEV_ISA 1732 struct snd_dbuf *b = c->bufhard; 1733 #endif 1734 struct snddev_info *d = c->parentsnddev; 1735 int ret; 1736 1737 CHN_LOCKASSERT(c); 1738 #ifdef DEV_ISA 1739 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)) 1740 sndbuf_dmabounce(b); 1741 #endif 1742 if (!PCMTRIG_COMMON(go)) 1743 return (CHANNEL_TRIGGER(c->methods, c->devinfo, go)); 1744 1745 if (go == c->trigger) 1746 return (0); 1747 1748 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); 1749 if (ret != 0) 1750 return (ret); 1751 1752 switch (go) { 1753 case PCMTRIG_START: 1754 if (snd_verbose > 3) 1755 device_printf(c->dev, 1756 "%s() %s: calling go=0x%08x , " 1757 "prev=0x%08x\n", __func__, c->name, go, 1758 c->trigger); 1759 if (c->trigger != PCMTRIG_START) { 1760 c->trigger = go; 1761 CHN_UNLOCK(c); 1762 pcm_lock(d); 1763 CHN_INSERT_HEAD(d, c, channels.pcm.busy); 1764 pcm_unlock(d); 1765 CHN_LOCK(c); 1766 } 1767 break; 1768 case PCMTRIG_STOP: 1769 case PCMTRIG_ABORT: 1770 if (snd_verbose > 3) 1771 device_printf(c->dev, 1772 "%s() %s: calling go=0x%08x , " 1773 "prev=0x%08x\n", __func__, c->name, go, 1774 c->trigger); 1775 if (c->trigger == PCMTRIG_START) { 1776 c->trigger = go; 1777 CHN_UNLOCK(c); 1778 pcm_lock(d); 1779 CHN_REMOVE(d, c, channels.pcm.busy); 1780 pcm_unlock(d); 1781 CHN_LOCK(c); 1782 } 1783 break; 1784 default: 1785 break; 1786 } 1787 1788 return (0); 1789 } 1790 1791 /** 1792 * @brief Queries sound driver for sample-aligned hardware buffer pointer index 1793 * 1794 * This function obtains the hardware pointer location, then aligns it to 1795 * the current bytes-per-sample value before returning. (E.g., a channel 1796 * running in 16 bit stereo mode would require 4 bytes per sample, so a 1797 * hwptr value ranging from 32-35 would be returned as 32.) 1798 * 1799 * @param c PCM channel context 1800 * @returns sample-aligned hardware buffer pointer index 1801 */ 1802 int 1803 chn_getptr(struct pcm_channel *c) 1804 { 1805 int hwptr; 1806 1807 CHN_LOCKASSERT(c); 1808 hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0; 1809 return (hwptr - (hwptr % sndbuf_getbps(c->bufhard))); 1810 } 1811 1812 struct pcmchan_caps * 1813 chn_getcaps(struct pcm_channel *c) 1814 { 1815 CHN_LOCKASSERT(c); 1816 return CHANNEL_GETCAPS(c->methods, c->devinfo); 1817 } 1818 1819 u_int32_t 1820 chn_getformats(struct pcm_channel *c) 1821 { 1822 u_int32_t *fmtlist, fmts; 1823 int i; 1824 1825 fmtlist = chn_getcaps(c)->fmtlist; 1826 fmts = 0; 1827 for (i = 0; fmtlist[i]; i++) 1828 fmts |= fmtlist[i]; 1829 1830 /* report software-supported formats */ 1831 if (report_soft_formats) 1832 fmts |= AFMT_MU_LAW|AFMT_A_LAW|AFMT_U32_LE|AFMT_U32_BE| 1833 AFMT_S32_LE|AFMT_S32_BE|AFMT_U24_LE|AFMT_U24_BE| 1834 AFMT_S24_LE|AFMT_S24_BE|AFMT_U16_LE|AFMT_U16_BE| 1835 AFMT_S16_LE|AFMT_S16_BE|AFMT_U8|AFMT_S8; 1836 1837 return fmts; 1838 } 1839 1840 static int 1841 chn_buildfeeder(struct pcm_channel *c) 1842 { 1843 struct feeder_class *fc; 1844 struct pcm_feederdesc desc; 1845 struct snd_mixer *m; 1846 u_int32_t tmp[2], type, flags, hwfmt, *fmtlist; 1847 int err; 1848 char fmtstr[AFMTSTR_MAXSZ]; 1849 1850 CHN_LOCKASSERT(c); 1851 while (chn_removefeeder(c) == 0) 1852 ; 1853 KASSERT((c->feeder == NULL), ("feeder chain not empty")); 1854 1855 c->align = sndbuf_getalign(c->bufsoft); 1856 1857 if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) { 1858 /* 1859 * Virtual rec need this. 1860 */ 1861 fc = feeder_getclass(NULL); 1862 KASSERT(fc != NULL, ("can't find root feeder")); 1863 1864 err = chn_addfeeder(c, fc, NULL); 1865 if (err) { 1866 DEB(printf("can't add root feeder, err %d\n", err)); 1867 1868 return err; 1869 } 1870 c->feeder->desc->out = c->format; 1871 } else if (c->direction == PCMDIR_PLAY) { 1872 if (c->flags & CHN_F_HAS_VCHAN) { 1873 desc.type = FEEDER_MIXER; 1874 desc.in = c->format; 1875 } else { 1876 DEB(printf("can't decide which feeder type to use!\n")); 1877 return EOPNOTSUPP; 1878 } 1879 desc.out = c->format; 1880 desc.flags = 0; 1881 fc = feeder_getclass(&desc); 1882 if (fc == NULL) { 1883 DEB(printf("can't find vchan feeder\n")); 1884 1885 return EOPNOTSUPP; 1886 } 1887 1888 err = chn_addfeeder(c, fc, &desc); 1889 if (err) { 1890 DEB(printf("can't add vchan feeder, err %d\n", err)); 1891 1892 return err; 1893 } 1894 } else 1895 return EOPNOTSUPP; 1896 1897 /* XXX These are too much.. */ 1898 if (c->parentsnddev != NULL && c->parentsnddev->mixer_dev != NULL && 1899 c->parentsnddev->mixer_dev->si_drv1 != NULL) 1900 m = c->parentsnddev->mixer_dev->si_drv1; 1901 else 1902 m = NULL; 1903 1904 c->feederflags &= ~(1 << FEEDER_VOLUME); 1905 if (c->direction == PCMDIR_PLAY && !(c->flags & CHN_F_VIRTUAL) && m && 1906 (c->parentsnddev->flags & SD_F_SOFTPCMVOL)) 1907 c->feederflags |= 1 << FEEDER_VOLUME; 1908 1909 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev && 1910 ((c->direction == PCMDIR_PLAY && 1911 (c->parentsnddev->flags & SD_F_PSWAPLR)) || 1912 (c->direction == PCMDIR_REC && 1913 (c->parentsnddev->flags & SD_F_RSWAPLR)))) 1914 c->feederflags |= 1 << FEEDER_SWAPLR; 1915 1916 flags = c->feederflags; 1917 fmtlist = chn_getcaps(c)->fmtlist; 1918 1919 DEB(printf("feederflags %x\n", flags)); 1920 1921 for (type = FEEDER_RATE; type < FEEDER_LAST; type++) { 1922 if (flags & (1 << type)) { 1923 desc.type = type; 1924 desc.in = 0; 1925 desc.out = 0; 1926 desc.flags = 0; 1927 DEB(printf("find feeder type %d, ", type)); 1928 if (type == FEEDER_VOLUME || type == FEEDER_RATE) { 1929 if (c->feeder->desc->out & AFMT_32BIT) 1930 strlcpy(fmtstr,"s32le", sizeof(fmtstr)); 1931 else if (c->feeder->desc->out & AFMT_24BIT) 1932 strlcpy(fmtstr, "s24le", sizeof(fmtstr)); 1933 else { 1934 /* 1935 * 8bit doesn't provide enough headroom 1936 * for proper processing without 1937 * creating too much noises. Force to 1938 * 16bit instead. 1939 */ 1940 strlcpy(fmtstr, "s16le", sizeof(fmtstr)); 1941 } 1942 if (!(c->feeder->desc->out & AFMT_8BIT) && 1943 c->feeder->desc->out & AFMT_BIGENDIAN) 1944 afmtstr_swap_endian(fmtstr); 1945 if (!(c->feeder->desc->out & (AFMT_A_LAW | AFMT_MU_LAW)) && 1946 !(c->feeder->desc->out & AFMT_SIGNED)) 1947 afmtstr_swap_sign(fmtstr); 1948 desc.in = afmtstr2afmt(NULL, fmtstr, AFMTSTR_MONO_RETURN); 1949 if (desc.in == 0) 1950 desc.in = AFMT_S16_LE; 1951 /* feeder_volume need stereo processing */ 1952 if (type == FEEDER_VOLUME || 1953 c->feeder->desc->out & AFMT_STEREO) 1954 desc.in |= AFMT_STEREO; 1955 desc.out = desc.in; 1956 } else if (type == FEEDER_SWAPLR) { 1957 desc.in = c->feeder->desc->out; 1958 desc.in |= AFMT_STEREO; 1959 desc.out = desc.in; 1960 } 1961 1962 fc = feeder_getclass(&desc); 1963 DEB(printf("got %p\n", fc)); 1964 if (fc == NULL) { 1965 DEB(printf("can't find required feeder type %d\n", type)); 1966 1967 return EOPNOTSUPP; 1968 } 1969 1970 if (desc.in == 0 || desc.out == 0) 1971 desc = *fc->desc; 1972 1973 DEB(printf("build fmtchain from 0x%08x to 0x%08x: ", c->feeder->desc->out, fc->desc->in)); 1974 tmp[0] = desc.in; 1975 tmp[1] = 0; 1976 if (chn_fmtchain(c, tmp) == 0) { 1977 DEB(printf("failed\n")); 1978 1979 return ENODEV; 1980 } 1981 DEB(printf("ok\n")); 1982 1983 err = chn_addfeeder(c, fc, &desc); 1984 if (err) { 1985 DEB(printf("can't add feeder %p, output 0x%x, err %d\n", fc, fc->desc->out, err)); 1986 1987 return err; 1988 } 1989 DEB(printf("added feeder %p, output 0x%x\n", fc, c->feeder->desc->out)); 1990 } 1991 } 1992 1993 if (c->direction == PCMDIR_REC) { 1994 tmp[0] = c->format; 1995 tmp[1] = 0; 1996 hwfmt = chn_fmtchain(c, tmp); 1997 } else 1998 hwfmt = chn_fmtchain(c, fmtlist); 1999 2000 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) { 2001 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt)); 2002 return ENODEV; 2003 } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) { 2004 /* 2005 * Kind of awkward. This whole "MIXER" concept need a 2006 * rethinking, I guess :) . Recording is the inverse 2007 * of Playback, which is why we push mixer vchan down here. 2008 */ 2009 if (c->flags & CHN_F_HAS_VCHAN) { 2010 desc.type = FEEDER_MIXER; 2011 desc.in = c->format; 2012 } else 2013 return EOPNOTSUPP; 2014 desc.out = c->format; 2015 desc.flags = 0; 2016 fc = feeder_getclass(&desc); 2017 if (fc == NULL) 2018 return EOPNOTSUPP; 2019 2020 err = chn_addfeeder(c, fc, &desc); 2021 if (err != 0) 2022 return err; 2023 } 2024 2025 sndbuf_setfmt(c->bufhard, hwfmt); 2026 2027 if ((flags & (1 << FEEDER_VOLUME))) { 2028 u_int32_t parent; 2029 int vol, left, right; 2030 2031 CHN_UNLOCK(c); 2032 vol = mix_get(m, SOUND_MIXER_PCM); 2033 if (vol == -1) { 2034 device_printf(c->dev, 2035 "Soft PCM Volume: Failed to read default value\n"); 2036 vol = 100 | (100 << 8); 2037 } 2038 left = vol & 0x7f; 2039 right = (vol >> 8) & 0x7f; 2040 parent = mix_getparent(m, SOUND_MIXER_PCM); 2041 if (parent != SOUND_MIXER_NONE) { 2042 vol = mix_get(m, parent); 2043 if (vol == -1) { 2044 device_printf(c->dev, 2045 "Soft Volume: Failed to read parent " 2046 "default value\n"); 2047 vol = 100 | (100 << 8); 2048 } 2049 left = (left * (vol & 0x7f)) / 100; 2050 right = (right * ((vol >> 8) & 0x7f)) / 100; 2051 } 2052 CHN_LOCK(c); 2053 chn_setvolume(c, left, right); 2054 } 2055 2056 return 0; 2057 } 2058 2059 int 2060 chn_notify(struct pcm_channel *c, u_int32_t flags) 2061 { 2062 int err, run, nrun; 2063 2064 CHN_LOCKASSERT(c); 2065 2066 if (CHN_EMPTY(c, children)) 2067 return (ENODEV); 2068 2069 err = 0; 2070 2071 /* 2072 * If the hwchan is running, we can't change its rate, format or 2073 * blocksize 2074 */ 2075 run = (CHN_STARTED(c)) ? 1 : 0; 2076 if (run) 2077 flags &= CHN_N_VOLUME | CHN_N_TRIGGER; 2078 2079 if (flags & CHN_N_RATE) { 2080 /* XXX I'll make good use of this someday. */ 2081 } 2082 if (flags & CHN_N_FORMAT) { 2083 /* XXX I'll make good use of this someday. */ 2084 } 2085 if (flags & CHN_N_VOLUME) { 2086 /* XXX I'll make good use of this someday. */ 2087 } 2088 if (flags & CHN_N_BLOCKSIZE) { 2089 /* 2090 * Set to default latency profile 2091 */ 2092 chn_setlatency(c, chn_latency); 2093 } 2094 if (flags & CHN_N_TRIGGER) { 2095 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1; 2096 if (nrun && !run) 2097 err = chn_start(c, 1); 2098 if (!nrun && run) 2099 chn_abort(c); 2100 } 2101 2102 return (err); 2103 } 2104 2105 /** 2106 * @brief Fetch array of supported discrete sample rates 2107 * 2108 * Wrapper for CHANNEL_GETRATES. Please see channel_if.m:getrates() for 2109 * detailed information. 2110 * 2111 * @note If the operation isn't supported, this function will just return 0 2112 * (no rates in the array), and *rates will be set to NULL. Callers 2113 * should examine rates @b only if this function returns non-zero. 2114 * 2115 * @param c pcm channel to examine 2116 * @param rates pointer to array of integers; rate table will be recorded here 2117 * 2118 * @return number of rates in the array pointed to be @c rates 2119 */ 2120 int 2121 chn_getrates(struct pcm_channel *c, int **rates) 2122 { 2123 KASSERT(rates != NULL, ("rates is null")); 2124 CHN_LOCKASSERT(c); 2125 return CHANNEL_GETRATES(c->methods, c->devinfo, rates); 2126 } 2127 2128 /** 2129 * @brief Remove channel from a sync group, if there is one. 2130 * 2131 * This function is initially intended for the following conditions: 2132 * - Starting a syncgroup (@c SNDCTL_DSP_SYNCSTART ioctl) 2133 * - Closing a device. (A channel can't be destroyed if it's still in use.) 2134 * 2135 * @note Before calling this function, the syncgroup list mutex must be 2136 * held. (Consider pcm_channel::sm protected by the SG list mutex 2137 * whether @c c is locked or not.) 2138 * 2139 * @param c channel device to be started or closed 2140 * @returns If this channel was the only member of a group, the group ID 2141 * is returned to the caller so that the caller can release it 2142 * via free_unr() after giving up the syncgroup lock. Else it 2143 * returns 0. 2144 */ 2145 int 2146 chn_syncdestroy(struct pcm_channel *c) 2147 { 2148 struct pcmchan_syncmember *sm; 2149 struct pcmchan_syncgroup *sg; 2150 int sg_id; 2151 2152 sg_id = 0; 2153 2154 PCM_SG_LOCKASSERT(MA_OWNED); 2155 2156 if (c->sm != NULL) { 2157 sm = c->sm; 2158 sg = sm->parent; 2159 c->sm = NULL; 2160 2161 KASSERT(sg != NULL, ("syncmember has null parent")); 2162 2163 SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link); 2164 free(sm, M_DEVBUF); 2165 2166 if (SLIST_EMPTY(&sg->members)) { 2167 SLIST_REMOVE(&snd_pcm_syncgroups, sg, pcmchan_syncgroup, link); 2168 sg_id = sg->id; 2169 free(sg, M_DEVBUF); 2170 } 2171 } 2172 2173 return sg_id; 2174 } 2175 2176 void 2177 chn_lock(struct pcm_channel *c) 2178 { 2179 CHN_LOCK(c); 2180 } 2181 2182 void 2183 chn_unlock(struct pcm_channel *c) 2184 { 2185 CHN_UNLOCK(c); 2186 } 2187 2188 #ifdef OSSV4_EXPERIMENT 2189 int 2190 chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak) 2191 { 2192 CHN_LOCKASSERT(c); 2193 return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak); 2194 } 2195 #endif 2196