Lines Matching +full:out +full:- +full:volume +full:- +full:limit

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org>
5 * Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006
7 * Portions Copyright (c) Luigi Rizzo <luigi@FreeBSD.org> - 1997-99
9 * Copyright (c) 2024-2025 The FreeBSD Foundation
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 &report_soft_formats, 0, "report software-emulated formats");
51 &report_soft_matrix, 0, "report software-emulated channel matrixing");
62 if (err != 0 || req->newptr == NULL) in sysctl_hw_snd_latency()
85 if (err != 0 || req->newptr == NULL) in sysctl_hw_snd_latency_profile()
108 if (err != 0 || req->newptr == NULL) in sysctl_hw_snd_timeout()
120 "interrupt timeout (1 - 10) seconds");
124 &chn_vpc_autoreset, 0, "automatically reset channels volume to 0db");
164 if (err != 0 || req->newptr == NULL) in sysctl_hw_snd_vpc_0db()
186 if (err != 0 || req->newptr == NULL || val == 0) in sysctl_hw_snd_vpc_reset()
197 "reset volume on all channels");
200 static int chn_syncdelay = -1;
206 "append (0-1000) millisecond trailing buffer delay on each sync");
231 c->lock = snd_mtxcreate(c->name, "pcm play channel"); in chn_lockinit()
232 cv_init(&c->intr_cv, "pcmwr"); in chn_lockinit()
235 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); in chn_lockinit()
236 cv_init(&c->intr_cv, "pcmwrv"); in chn_lockinit()
239 c->lock = snd_mtxcreate(c->name, "pcm record channel"); in chn_lockinit()
240 cv_init(&c->intr_cv, "pcmrd"); in chn_lockinit()
243 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel"); in chn_lockinit()
244 cv_init(&c->intr_cv, "pcmrdv"); in chn_lockinit()
251 cv_init(&c->cv, "pcmchn"); in chn_lockinit()
259 CHN_BROADCAST(&c->cv); in chn_lockdestroy()
260 CHN_BROADCAST(&c->intr_cv); in chn_lockdestroy()
262 cv_destroy(&c->cv); in chn_lockdestroy()
263 cv_destroy(&c->intr_cv); in chn_lockdestroy()
265 snd_mtxfree(c->lock); in chn_lockdestroy()
277 struct snd_dbuf *bs = c->bufsoft; in chn_polltrigger()
282 if (c->flags & CHN_F_MMAP) { in chn_polltrigger()
283 if (bs->prev_total < c->lw) in chn_polltrigger()
284 delta = c->lw; in chn_polltrigger()
286 delta = bs->total - bs->prev_total; in chn_polltrigger()
288 if (c->direction == PCMDIR_PLAY) in chn_polltrigger()
294 return ((delta < c->lw) ? 0 : 1); in chn_polltrigger()
302 c->bufsoft->prev_total = c->bufsoft->total; in chn_pollreset()
313 bs = c->bufsoft; in chn_wakeup()
316 KNOTE_LOCKED(&bs->sel.si_note, 0); in chn_wakeup()
317 if (SEL_WAITING(&bs->sel) && chn_polltrigger(c)) in chn_wakeup()
318 selwakeuppri(&bs->sel, PRIBIO); in chn_wakeup()
319 CHN_BROADCAST(&c->intr_cv); in chn_wakeup()
336 if (c->flags & CHN_F_DEAD) in chn_sleep()
339 c->sleeping++; in chn_sleep()
340 ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout); in chn_sleep()
341 c->sleeping--; in chn_sleep()
343 return ((c->flags & CHN_F_DEAD) ? EINVAL : ret); in chn_sleep()
354 struct snd_dbuf *b = c->bufhard; in chn_dmaupdate()
357 KASSERT(b->bufsize > 0, ("bufsize == 0")); in chn_dmaupdate()
360 old = b->hp; in chn_dmaupdate()
362 delta = (b->bufsize + hwptr - old) % b->bufsize; in chn_dmaupdate()
363 b->hp = hwptr; in chn_dmaupdate()
365 if (c->direction == PCMDIR_PLAY) { in chn_dmaupdate()
367 amt -= amt % b->align; in chn_dmaupdate()
372 amt -= amt % b->align; in chn_dmaupdate()
377 device_printf(c->dev, "WARNING: %s DMA completion " in chn_dmaupdate()
390 struct snd_dbuf *b = c->bufhard; in chn_wrfeed()
391 struct snd_dbuf *bs = c->bufsoft; in chn_wrfeed()
396 if ((c->flags & CHN_F_MMAP) && !(c->flags & CHN_F_CLOSING)) in chn_wrfeed()
400 want = min(b->bufsize, imax(0, sndbuf_xbytes(bs->bufsize, bs, b) - in chn_wrfeed()
404 sndbuf_feed(bs, b, c, c->feeder, amt); in chn_wrfeed()
410 c->xruns++; in chn_wrfeed()
430 * user write routine - uiomove data into secondary buffer, trigger if necessary
439 struct snd_dbuf *bs = c->bufsoft; in chn_write()
448 while (ret == 0 && buf->uio_resid > 0) { in chn_write()
449 sz = min(buf->uio_resid, sndbuf_getfree(bs)); in chn_write()
454 * unlock-uiomove-lock sequence. in chn_write()
458 t = min(sz, bs->bufsize - p); in chn_write()
463 sz -= t; in chn_write()
467 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { in chn_write()
470 c->flags |= CHN_F_DEAD; in chn_write()
472 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) { in chn_write()
488 c->flags |= CHN_F_DEAD; in chn_write()
489 device_printf(c->dev, "%s(): %s: " in chn_write()
491 __func__, c->name); in chn_write()
493 c->flags |= CHN_F_ABORTING; in chn_write()
506 struct snd_dbuf *b = c->bufhard; in chn_rdfeed()
507 struct snd_dbuf *bs = c->bufsoft; in chn_rdfeed()
512 if (c->flags & CHN_F_MMAP) in chn_rdfeed()
517 sndbuf_feed(b, bs, c, c->feeder, amt); in chn_rdfeed()
521 c->xruns++; in chn_rdfeed()
535 /* tell the driver to update the primary buffer if non-dma */ in chn_rdintr()
544 * user read routine - trigger if necessary, uiomove data from secondary buffer
553 struct snd_dbuf *bs = c->bufsoft; in chn_read()
559 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { in chn_read()
562 c->flags |= CHN_F_DEAD; in chn_read()
570 while (ret == 0 && buf->uio_resid > 0) { in chn_read()
571 sz = min(buf->uio_resid, sndbuf_getready(bs)); in chn_read()
576 * unlock-uiomove-lock sequence. in chn_read()
580 t = min(sz, bs->bufsize - p); in chn_read()
585 sz -= t; in chn_read()
589 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) in chn_read()
595 c->flags |= CHN_F_DEAD; in chn_read()
596 device_printf(c->dev, "%s(): %s: " in chn_read()
598 __func__, c->name); in chn_read()
600 c->flags |= CHN_F_ABORTING; in chn_read()
613 c->interrupts++; in chn_intr_locked()
615 if (c->direction == PCMDIR_PLAY) in chn_intr_locked()
639 struct snd_dbuf *b = c->bufhard; in chn_start()
640 struct snd_dbuf *bs = c->bufsoft; in chn_start()
645 if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force)) in chn_start()
654 if (c->direction == PCMDIR_REC) { in chn_start()
666 j = pb->align; in chn_start()
670 device_printf(c->dev, "%s(): %s (%s) threshold " in chn_start()
672 (c->flags & CHN_F_VIRTUAL) ? "virtual" : in chn_start()
677 c->flags |= CHN_F_TRIGGERED; in chn_start()
679 if (c->flags & CHN_F_CLOSING) in chn_start()
680 c->feedcount = 2; in chn_start()
682 c->feedcount = 0; in chn_start()
683 c->interrupts = 0; in chn_start()
684 c->xruns = 0; in chn_start()
686 if (c->parentchannel == NULL) { in chn_start()
687 if (c->direction == PCMDIR_PLAY) in chn_start()
689 sndbuf_xbytes(bs->bufsize, bs, b)); in chn_start()
691 device_printf(c->dev, in chn_start()
696 (c->flags & CHN_F_HAS_VCHAN) ? in chn_start()
698 (c->flags & CHN_F_CLOSING) ? "closing" : in chn_start()
701 force, i, j, c->timeout, in chn_start()
702 (b->bufsize * 1000) / in chn_start()
703 (b->align * b->spd)); in chn_start()
714 struct snd_dbuf *b = c->bufhard; in chn_resetbuf()
715 struct snd_dbuf *bs = c->bufsoft; in chn_resetbuf()
717 c->blocks = 0; in chn_resetbuf()
736 if (c->direction != PCMDIR_PLAY) in chn_sync()
739 bs = c->bufsoft; in chn_sync()
741 if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) || in chn_sync()
755 b = CHN_BUF_PARENT(c, c->bufhard); in chn_sync()
762 minflush += sndbuf_xbytes(b->bufsize, b, bs); in chn_sync()
765 * Append (0-1000) millisecond trailing buffer (if needed) in chn_sync()
770 minflush += (bs->align * bs->spd * in chn_sync()
773 minflush -= minflush % bs->align; in chn_sync()
779 minflush -= threshold; in chn_sync()
784 blksz = b->blksz; in chn_sync()
786 device_printf(c->dev, in chn_sync()
788 __func__, b->maxsize, b->bufsize, in chn_sync()
789 b->blksz, b->blkcnt); in chn_sync()
790 if (b->blkcnt > 0) in chn_sync()
791 blksz = b->bufsize / b->blkcnt; in chn_sync()
800 device_printf(c->dev, "%s(): [begin] timeout=%d count=%d " in chn_sync()
801 "minflush=%d resid=%d\n", __func__, c->timeout, count, in chn_sync()
804 cflag = c->flags & CHN_F_CLOSING; in chn_sync()
805 c->flags |= CHN_F_CLOSING; in chn_sync()
807 ret = chn_sleep(c, c->timeout); in chn_sync()
809 c->flags |= CHN_F_ABORTING; in chn_sync()
814 --count; in chn_sync()
816 device_printf(c->dev, in chn_sync()
820 __func__, c->timeout, count, in chn_sync()
825 device_printf(c->dev, in chn_sync()
829 __func__, c->timeout, count, in chn_sync()
838 minflush -= threshold; in chn_sync()
844 c->flags &= ~CHN_F_CLOSING; in chn_sync()
845 c->flags |= cflag; in chn_sync()
848 device_printf(c->dev, in chn_sync()
851 __func__, c->timeout, count, hcount, resid, residp, in chn_sync()
861 struct snd_dbuf *bs = c->bufsoft; in chn_poll()
866 if (!(c->flags & (CHN_F_MMAP | CHN_F_TRIGGERED))) { in chn_poll()
877 selrecord(td, &bs->sel); in chn_poll()
892 struct snd_dbuf *b = c->bufhard; in chn_abort()
893 struct snd_dbuf *bs = c->bufsoft; in chn_abort()
898 c->flags |= CHN_F_ABORTING; in chn_abort()
900 c->flags &= ~CHN_F_TRIGGERED; in chn_abort()
904 if (!(c->flags & CHN_F_VIRTUAL)) in chn_abort()
908 c->flags &= ~CHN_F_ABORTING; in chn_abort()
926 struct snd_dbuf *b = c->bufhard; in chn_flush()
929 KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel")); in chn_flush()
930 DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags)); in chn_flush()
932 c->flags |= CHN_F_CLOSING; in chn_flush()
934 c->flags &= ~CHN_F_TRIGGERED; in chn_flush()
939 c->flags &= ~CHN_F_CLOSING; in chn_flush()
1093 afmt_tab[i].name, ch - ext, ext); in snd_afmt2str()
1105 c->feedcount = 0; in chn_reset()
1106 c->flags &= CHN_F_RESET; in chn_reset()
1107 c->interrupts = 0; in chn_reset()
1108 c->timeout = 1; in chn_reset()
1109 c->xruns = 0; in chn_reset()
1111 c->flags |= (pcm_getflags(c->dev) & SD_F_BITPERFECT) ? in chn_reset()
1114 r = CHANNEL_RESET(c->methods, c->devinfo); in chn_reset()
1128 r = CHANNEL_RESETDONE(c->methods, c->devinfo); in chn_reset()
1138 return (d->p_unr); in chn_getunr()
1140 return (d->vp_unr); in chn_getunr()
1142 return (d->r_unr); in chn_getunr()
1144 return (d->vr_unr); in chn_getunr()
1159 switch (c->type) { in chn_mkname()
1177 device_get_unit(c->dev), str, c->unit); in chn_mkname()
1197 d->playcount++; in chn_init()
1201 d->pvchancount++; in chn_init()
1203 vchanrate = &d->pvchanrate; in chn_init()
1204 vchanformat = &d->pvchanformat; in chn_init()
1207 d->reccount++; in chn_init()
1211 d->rvchancount++; in chn_init()
1213 vchanrate = &d->rvchanrate; in chn_init()
1214 vchanformat = &d->rvchanformat; in chn_init()
1217 device_printf(d->dev, in chn_init()
1228 c->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO); in chn_init()
1232 c->direction = direction; in chn_init()
1233 c->type = dir; in chn_init()
1234 c->unit = alloc_unr(chn_getunr(d, c->type)); in chn_init()
1235 c->format = SND_FORMAT(AFMT_S16_LE, 2, 0); in chn_init()
1236 c->speed = 48000; in chn_init()
1237 c->pid = -1; in chn_init()
1238 c->latency = -1; in chn_init()
1239 c->timeout = 1; in chn_init()
1240 strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); in chn_init()
1241 c->parentsnddev = d; in chn_init()
1242 c->parentchannel = parent; in chn_init()
1243 c->dev = d->dev; in chn_init()
1244 c->trigger = PCMTRIG_STOP; in chn_init()
1245 strlcpy(c->name, chn_mkname(buf, sizeof(buf), c), sizeof(c->name)); in chn_init()
1247 c->matrix = *feeder_matrix_id_map(SND_CHN_MATRIX_1_0); in chn_init()
1248 c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; in chn_init()
1251 c->volume[SND_VOL_C_MASTER][i] = SND_VOL_0DB_MASTER; in chn_init()
1253 c->volume[SND_VOL_C_MASTER][SND_CHN_T_VOL_0DB] = SND_VOL_0DB_MASTER; in chn_init()
1254 c->volume[SND_VOL_C_PCM][SND_CHN_T_VOL_0DB] = chn_vol_0db_pcm; in chn_init()
1262 device_printf(d->dev, "%s(): failed to get feeder class\n", in chn_init()
1267 device_printf(d->dev, "%s(): failed to add feeder\n", __func__); in chn_init()
1274 device_printf(d->dev, "%s(): failed to create %s buffer\n", in chn_init()
1278 c->bufhard = b; in chn_init()
1279 c->bufsoft = bs; in chn_init()
1280 knlist_init_mtx(&bs->sel.si_note, c->lock); in chn_init()
1282 c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); in chn_init()
1283 if (c->devinfo == NULL) { in chn_init()
1284 device_printf(d->dev, "%s(): CHANNEL_INIT() failed\n", __func__); in chn_init()
1288 if (b->bufsize == 0 && ((c->flags & CHN_F_VIRTUAL) == 0)) { in chn_init()
1289 device_printf(d->dev, "%s(): hardware buffer's size is 0\n", in chn_init()
1294 sndbuf_setfmt(b, c->format); in chn_init()
1295 sndbuf_setspd(b, c->speed); in chn_init()
1296 sndbuf_setfmt(bs, c->format); in chn_init()
1297 sndbuf_setspd(bs, c->speed); in chn_init()
1305 if (c->direction == PCMDIR_PLAY) { in chn_init()
1306 bs->sl = bs->maxsize; in chn_init()
1307 bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_WAITOK); in chn_init()
1310 if ((c->flags & CHN_F_VIRTUAL) == 0) { in chn_init()
1312 err = chn_reset(c, c->format, c->speed); in chn_init()
1320 if ((c->flags & CHN_F_VIRTUAL) == 0) { in chn_init()
1323 *vchanrate = c->bufsoft->spd; in chn_init()
1324 *vchanformat = c->bufsoft->fmt; in chn_init()
1339 struct snddev_info *d = c->parentsnddev; in chn_kill()
1340 struct snd_dbuf *b = c->bufhard; in chn_kill()
1341 struct snd_dbuf *bs = c->bufsoft; in chn_kill()
1343 PCM_BUSYASSERT(c->parentsnddev); in chn_kill()
1347 if ((c->flags & CHN_F_VIRTUAL) == 0) in chn_kill()
1350 switch (c->type) { in chn_kill()
1352 d->playcount--; in chn_kill()
1355 d->pvchancount--; in chn_kill()
1358 d->reccount--; in chn_kill()
1361 d->rvchancount--; in chn_kill()
1373 free_unr(chn_getunr(d, c->type), c->unit); in chn_kill()
1375 if (c->devinfo) in chn_kill()
1376 CHANNEL_FREE(c->methods, c->devinfo); in chn_kill()
1378 knlist_clear(&bs->sel.si_note, 0); in chn_kill()
1379 knlist_destroy(&bs->sel.si_note); in chn_kill()
1385 c->flags |= CHN_F_DEAD; in chn_kill()
1387 kobj_delete(c->methods, M_DEVBUF); in chn_kill()
1397 c->flags |= CHN_F_DEAD; in chn_shutdown()
1404 PCM_BUSYASSERT(c->parentsnddev); in chn_release()
1407 c->flags &= ~CHN_F_BUSY; in chn_release()
1408 c->pid = -1; in chn_release()
1409 strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); in chn_release()
1445 ("%s(): invalid volume matrix c=%p vc=%d vt=%d val=%d", in chn_setvolume_matrix()
1454 c->volume[vc][vt] = val; in chn_setvolume_matrix()
1463 c->volume[SND_VOL_C_VAL(vc)][vt] = in chn_setvolume_matrix()
1464 SND_VOL_CALC_VAL(c->volume, vc, vt); in chn_setvolume_matrix()
1469 c->volume[SND_VOL_C_VAL(vc)][i] = in chn_setvolume_matrix()
1470 SND_VOL_CALC_VAL(c->volume, vc, i); in chn_setvolume_matrix()
1473 c->volume[SND_VOL_C_VAL(vc)][vt] = in chn_setvolume_matrix()
1474 SND_VOL_CALC_VAL(c->volume, vc, vt); in chn_setvolume_matrix()
1486 ("%s(): invalid volume matrix c=%p vc=%d vt=%d", in chn_getvolume_matrix()
1490 return (c->volume[vc][vt]); in chn_getvolume_matrix()
1526 c->muted[vc][vt] = mute; in chn_setmute_matrix()
1535 c->muted[SND_VOL_C_VAL(vc)][vt] = mute; in chn_setmute_matrix()
1540 c->muted[SND_VOL_C_VAL(vc)][i] = mute; in chn_setmute_matrix()
1543 c->muted[SND_VOL_C_VAL(vc)][vt] = mute; in chn_setmute_matrix()
1559 return (c->muted[vc][vt]); in chn_getmute_matrix()
1569 if (!(c->format & AFMT_CONVERTIBLE)) in chn_getmatrix()
1572 return (&c->matrix); in chn_getmatrix()
1583 if (!(c->format & AFMT_CONVERTIBLE)) in chn_setmatrix()
1586 c->matrix = *m; in chn_setmatrix()
1587 c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; in chn_setmatrix()
1589 return (chn_setformat(c, SND_FORMAT(c->format, m->channels, m->ext))); in chn_setmatrix()
1603 if (!(c->format & AFMT_CONVERTIBLE)) in chn_oss_getorder()
1606 return (feeder_matrix_oss_get_channel_order(&c->matrix, map)); in chn_oss_getorder()
1619 if (!(c->format & AFMT_CONVERTIBLE)) in chn_oss_setorder()
1622 m = c->matrix; in chn_oss_setorder()
1647 if (caps == NULL || caps->fmtlist == NULL) in chn_oss_getmask()
1650 for (i = 0; caps->fmtlist[i] != 0; i++) { in chn_oss_getmask()
1651 format = caps->fmtlist[i]; in chn_oss_getmask()
1656 m = CHANNEL_GETMATRIX(c->methods, c->devinfo, format); in chn_oss_getmask()
1659 if (m->mask & SND_CHN_OSS_FRONT) in chn_oss_getmask()
1661 if (m->mask & SND_CHN_OSS_SURR) in chn_oss_getmask()
1663 if (m->mask & SND_CHN_OSS_CENTER_LFE) in chn_oss_getmask()
1665 if (m->mask & SND_CHN_OSS_REAR) in chn_oss_getmask()
1669 /* report software-supported binding mask */ in chn_oss_getmask()
1690 CHN_SETVOLUME(c, vc, i, c->volume[vc][SND_CHN_T_VOL_0DB]); in chn_vpc_reset()
1703 ret = 1 << (ret - 1); in round_pow2()
1722 tmp = ret - (ret % round); in round_blksz()
1725 tmp = ret - (ret % round); in round_blksz()
1738 * +---------+------------+-----------+------------+
1740 * +---------+------------+-----------+------------+
1742 * +---------+------------+-----------+------------+
1744 * +---------+------------+-----------+------------+
1746 * +---------+------------+-----------+------------+
1748 * +---------+------------+-----------+------------+
1750 * +---------+------------+-----------+------------+
1752 * +---------+------------+-----------+------------+
1754 * +---------+------------+-----------+------------+
1756 * +---------+------------+-----------+------------+
1758 * +---------+------------+-----------+------------+
1760 * +---------+------------+-----------+------------+
1762 * +---------+------------+-----------+------------+
1769 * +---------+------------+-----------+------------+
1771 * +---------+------------+-----------+------------+
1773 * +---------+------------+-----------+------------+
1775 * +---------+------------+-----------+------------+
1777 * +---------+------------+-----------+------------+
1779 * +---------+------------+-----------+------------+
1781 * +---------+------------+-----------+------------+
1783 * +---------+------------+-----------+------------+
1785 * +---------+------------+-----------+------------+
1787 * +---------+------------+-----------+------------+
1789 * +---------+------------+-----------+------------+
1791 * +---------+------------+-----------+------------+
1793 * +---------+------------+-----------+------------+
1876 int sblksz, sblkcnt, hblksz, hblkcnt, limit = 0, nsblksz, nsblkcnt; in chn_resizebuf() local
1881 if ((c->flags & (CHN_F_MMAP | CHN_F_TRIGGERED)) || in chn_resizebuf()
1882 !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC)) in chn_resizebuf()
1885 if (latency == -1) { in chn_resizebuf()
1886 c->latency = -1; in chn_resizebuf()
1888 } else if (latency == -2) { in chn_resizebuf()
1889 latency = c->latency; in chn_resizebuf()
1895 c->latency = latency; in chn_resizebuf()
1898 bs = c->bufsoft; in chn_resizebuf()
1899 b = c->bufhard; in chn_resizebuf()
1901 if (!(blksz == 0 || blkcnt == -1) && in chn_resizebuf()
1902 (blksz < 16 || blksz < bs->align || blkcnt < 2 || in chn_resizebuf()
1906 chn_calclatency(c->direction, latency, bs->align, in chn_resizebuf()
1907 bs->align * bs->spd, CHN_2NDBUFMAXSIZE, in chn_resizebuf()
1910 if (blksz == 0 || blkcnt == -1) { in chn_resizebuf()
1911 if (blkcnt == -1) in chn_resizebuf()
1912 c->flags &= ~CHN_F_HAS_SIZE; in chn_resizebuf()
1913 if (c->flags & CHN_F_HAS_SIZE) { in chn_resizebuf()
1914 blksz = bs->blksz; in chn_resizebuf()
1915 blkcnt = bs->blkcnt; in chn_resizebuf()
1918 c->flags |= CHN_F_HAS_SIZE; in chn_resizebuf()
1920 if (c->flags & CHN_F_HAS_SIZE) { in chn_resizebuf()
1928 sblksz = round_blksz(blksz, bs->align); in chn_resizebuf()
1932 if (c->parentchannel != NULL) { in chn_resizebuf()
1933 pb = c->parentchannel->bufsoft; in chn_resizebuf()
1935 CHN_LOCK(c->parentchannel); in chn_resizebuf()
1936 chn_notify(c->parentchannel, CHN_N_BLOCKSIZE); in chn_resizebuf()
1937 CHN_UNLOCK(c->parentchannel); in chn_resizebuf()
1939 if (c->direction == PCMDIR_PLAY) { in chn_resizebuf()
1940 limit = (pb != NULL) ? in chn_resizebuf()
1941 sndbuf_xbytes(pb->bufsize, pb, bs) : 0; in chn_resizebuf()
1943 limit = (pb != NULL) ? in chn_resizebuf()
1944 sndbuf_xbytes(pb->blksz, pb, bs) * 2 : 0; in chn_resizebuf()
1948 if (c->flags & CHN_F_HAS_SIZE) { in chn_resizebuf()
1950 b->align); in chn_resizebuf()
1951 hblkcnt = round_pow2(bs->blkcnt); in chn_resizebuf()
1953 chn_calclatency(c->direction, latency, in chn_resizebuf()
1954 b->align, b->align * b->spd, in chn_resizebuf()
1957 if ((hblksz << 1) > b->maxsize) in chn_resizebuf()
1958 hblksz = round_blksz(b->maxsize >> 1, b->align); in chn_resizebuf()
1960 while ((hblksz * hblkcnt) > b->maxsize) { in chn_resizebuf()
1967 hblksz -= hblksz % b->align; in chn_resizebuf()
1971 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, in chn_resizebuf()
1973 b->blksz = CHANNEL_SETBLOCKSIZE(c->methods, in chn_resizebuf()
1974 c->devinfo, hblksz); in chn_resizebuf()
1979 sndbuf_xbytes(b->blksz, b, bs), bs->align); in chn_resizebuf()
1980 nsblkcnt = b->blkcnt; in chn_resizebuf()
1981 if (c->direction == PCMDIR_PLAY) { in chn_resizebuf()
1983 nsblkcnt--; in chn_resizebuf()
1990 limit = 0; in chn_resizebuf()
1992 limit = sndbuf_xbytes(b->blksz, b, bs) * 2; in chn_resizebuf()
1995 if (limit > CHN_2NDBUFMAXSIZE) in chn_resizebuf()
1996 limit = CHN_2NDBUFMAXSIZE; in chn_resizebuf()
1998 while ((sblksz * sblkcnt) < limit) in chn_resizebuf()
2008 sblksz -= sblksz % bs->align; in chn_resizebuf()
2010 if (bs->blkcnt != sblkcnt || bs->blksz != sblksz || in chn_resizebuf()
2011 bs->bufsize != (sblkcnt * sblksz)) { in chn_resizebuf()
2014 device_printf(c->dev, "%s(): Failed: %d %d\n", in chn_resizebuf()
2023 c->timeout = ((u_int64_t)hz * bs->bufsize) / in chn_resizebuf()
2024 ((u_int64_t)bs->spd * bs->align); in chn_resizebuf()
2025 if (c->parentchannel != NULL) in chn_resizebuf()
2026 c->timeout = min(c->timeout, c->parentchannel->timeout); in chn_resizebuf()
2027 if (c->timeout < 1) in chn_resizebuf()
2028 c->timeout = 1; in chn_resizebuf()
2034 c->lw = bs->blksz; in chn_resizebuf()
2038 device_printf(c->dev, "%s(): %s (%s) timeout=%u " in chn_resizebuf()
2039 "b[%d/%d/%d] bs[%d/%d/%d] limit=%d\n", in chn_resizebuf()
2041 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", in chn_resizebuf()
2042 c->timeout, in chn_resizebuf()
2043 b->bufsize, b->blksz, in chn_resizebuf()
2044 b->blkcnt, in chn_resizebuf()
2045 bs->bufsize, bs->blksz, in chn_resizebuf()
2046 bs->blkcnt, limit); in chn_resizebuf()
2056 return chn_resizebuf(c, latency, -1, 0); in chn_setlatency()
2064 return chn_resizebuf(c, -1, blkcnt, blksz); in chn_setblocksize()
2079 c->format = format; in chn_setparam()
2080 c->speed = speed; in chn_setparam()
2085 RANGE(hwspeed, caps->minspeed, caps->maxspeed); in chn_setparam()
2087 sndbuf_setspd(c->bufhard, CHANNEL_SETSPEED(c->methods, c->devinfo, in chn_setparam()
2089 hwspeed = c->bufhard->spd; in chn_setparam()
2091 delta = (hwspeed > speed) ? (hwspeed - speed) : (speed - hwspeed); in chn_setparam()
2094 c->speed = hwspeed; in chn_setparam()
2099 ret = CHANNEL_SETFORMAT(c->methods, c->devinfo, c->bufhard->fmt); in chn_setparam()
2102 ret = chn_resizebuf(c, -2, 0, 0); in chn_setparam()
2113 oldformat = c->format; in chn_setspeed()
2114 oldspeed = c->speed; in chn_setspeed()
2116 if (c->speed == speed) in chn_setspeed()
2119 ret = chn_setparam(c, c->format, speed); in chn_setspeed()
2122 device_printf(c->dev, in chn_setspeed()
2144 oldformat = c->format; in chn_setformat()
2145 oldspeed = c->speed; in chn_setformat()
2147 if (c->format == format) in chn_setformat()
2150 ret = chn_setparam(c, format, c->speed); in chn_setformat()
2153 device_printf(c->dev, in chn_setformat()
2169 d = (c != NULL) ? c->parentsnddev : NULL; in chn_syncstate()
2170 m = (d != NULL && d->mixer_dev != NULL) ? d->mixer_dev->si_drv1 : in chn_syncstate()
2178 if (c->feederflags & (1 << FEEDER_VOLUME)) { in chn_syncstate()
2182 if (c->direction == PCMDIR_PLAY && in chn_syncstate()
2183 (d->flags & SD_F_SOFTPCMVOL)) { in chn_syncstate()
2197 if (vol == -1) { in chn_syncstate()
2198 device_printf(c->dev, in chn_syncstate()
2199 "Soft PCM Volume: Failed to read pcm " in chn_syncstate()
2204 if (pvol == -1) { in chn_syncstate()
2205 device_printf(c->dev, in chn_syncstate()
2206 "Soft PCM Volume: Failed to read parent " in chn_syncstate()
2218 if (c->feederflags & (1 << FEEDER_EQ)) { in chn_syncstate()
2227 if (treble == -1) in chn_syncstate()
2233 if (bass == -1) in chn_syncstate()
2241 device_printf(c->dev, in chn_syncstate()
2242 "EQ: Failed to set treble -- %d\n", in chn_syncstate()
2245 device_printf(c->dev, in chn_syncstate()
2246 "EQ: Failed to set bass -- %d\n", in chn_syncstate()
2248 if (FEEDER_SET(f, FEEDEQ_PREAMP, d->eqpreamp) != 0) in chn_syncstate()
2249 device_printf(c->dev, in chn_syncstate()
2250 "EQ: Failed to set preamp -- %d\n", in chn_syncstate()
2251 d->eqpreamp); in chn_syncstate()
2252 if (d->flags & SD_F_EQ_BYPASSED) in chn_syncstate()
2254 else if (d->flags & SD_F_EQ_ENABLED) in chn_syncstate()
2259 device_printf(c->dev, in chn_syncstate()
2260 "EQ: Failed to set state -- %d\n", state); in chn_syncstate()
2268 struct snddev_info *d = c->parentsnddev; in chn_trigger()
2273 return (CHANNEL_TRIGGER(c->methods, c->devinfo, go)); in chn_trigger()
2275 if (go == c->trigger) in chn_trigger()
2279 device_printf(c->dev, "%s() %s: calling go=0x%08x , " in chn_trigger()
2280 "prev=0x%08x\n", __func__, c->name, go, c->trigger); in chn_trigger()
2283 c->trigger = go; in chn_trigger()
2284 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); in chn_trigger()
2296 if (go != c->trigger) { in chn_trigger()
2325 * @brief Queries sound driver for sample-aligned hardware buffer pointer index
2328 * the current bytes-per-sample value before returning. (E.g., a channel
2330 * hwptr value ranging from 32-35 would be returned as 32.)
2333 * @returns sample-aligned hardware buffer pointer index
2341 hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0; in chn_getptr()
2342 return (hwptr - (hwptr % c->bufhard->align)); in chn_getptr()
2349 return CHANNEL_GETCAPS(c->methods, c->devinfo); in chn_getcaps()
2358 fmtlist = chn_getcaps(c)->fmtlist; in chn_getformats()
2363 /* report software-supported formats */ in chn_getformats()
2413 * soft volume control is currently pretty much in chn_notify()
2425 if ((flags & CHN_N_TRIGGER) && !(c->flags & CHN_F_VCHAN_DYNAMIC)) { in chn_notify()
2435 if (c->direction == PCMDIR_PLAY) { in chn_notify()
2436 vchanformat = &c->parentsnddev->pvchanformat; in chn_notify()
2437 vchanrate = &c->parentsnddev->pvchanrate; in chn_notify()
2439 vchanformat = &c->parentsnddev->rvchanformat; in chn_notify()
2440 vchanrate = &c->parentsnddev->rvchanrate; in chn_notify()
2444 if (!(c->flags & CHN_F_VCHAN_ADAPTIVE)) { in chn_notify()
2460 if ((ch->format & AFMT_PASSTHROUGH) && in chn_notify()
2461 snd_fmtvalid(ch->format, caps->fmtlist)) { in chn_notify()
2462 bestformat = ch->format; in chn_notify()
2463 bestspeed = ch->speed; in chn_notify()
2469 if ((ch->flags & CHN_F_EXCLUSIVE) && vpflags == 0) { in chn_notify()
2470 if (c->flags & CHN_F_VCHAN_ADAPTIVE) { in chn_notify()
2471 bestspeed = ch->speed; in chn_notify()
2472 RANGE(bestspeed, caps->minspeed, in chn_notify()
2473 caps->maxspeed); in chn_notify()
2474 besthwformat = snd_fmtbest(ch->format, in chn_notify()
2475 caps->fmtlist); in chn_notify()
2484 if (!(c->flags & CHN_F_VCHAN_ADAPTIVE) || in chn_notify()
2490 if (ch->speed > bestspeed) { in chn_notify()
2491 bestspeed = ch->speed; in chn_notify()
2492 RANGE(bestspeed, caps->minspeed, in chn_notify()
2493 caps->maxspeed); in chn_notify()
2495 besthwformat = snd_fmtbest(ch->format, caps->fmtlist); in chn_notify()
2513 bestformat = c->format; in chn_notify()
2515 bestspeed = c->speed; in chn_notify()
2517 if (bestformat != c->format || bestspeed != c->speed) in chn_notify()
2520 c->flags &= ~(CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE); in chn_notify()
2521 c->flags |= vpflags; in chn_notify()
2525 bestspeed = CHANNEL_SETSPEED(c->methods, in chn_notify()
2526 c->devinfo, bestspeed); in chn_notify()
2539 c->flags |= CHN_F_DIRTY; in chn_notify()
2546 bestspeed = CHANNEL_SETSPEED(c->methods, c->devinfo, in chn_notify()
2558 c->flags |= CHN_F_DIRTY; in chn_notify()
2570 c->flags &= ~(CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE); in chn_notify()
2574 if (c->format != bestformat || c->speed != bestspeed) in chn_notify()
2590 * should examine rates @b only if this function returns non-zero.
2602 return CHANNEL_GETRATES(c->methods, c->devinfo, rates); in chn_getrates()
2609 * - Starting a syncgroup (@c SNDCTL_DSP_SYNCSTART ioctl)
2610 * - Closing a device. (A channel can't be destroyed if it's still in use.)
2633 if (c->sm != NULL) { in chn_syncdestroy()
2634 sm = c->sm; in chn_syncdestroy()
2635 sg = sm->parent; in chn_syncdestroy()
2636 c->sm = NULL; in chn_syncdestroy()
2640 SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link); in chn_syncdestroy()
2643 if (SLIST_EMPTY(&sg->members)) { in chn_syncdestroy()
2645 sg_id = sg->id; in chn_syncdestroy()
2658 return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak); in chn_getpeaks()