2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3 * Portions Copyright by Luigi Rizzo - 1997-99
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
30 #include <dev/sound/pcm/sound.h>
32 #include "feeder_if.h"
34 SND_DECLARE_FILE("$FreeBSD$");
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");
40 int chn_latency = CHN_LATENCY_DEFAULT;
41 TUNABLE_INT("hw.snd.latency", &chn_latency);
44 sysctl_hw_snd_latency(SYSCTL_HANDLER_ARGS)
49 err = sysctl_handle_int(oidp, &val, 0, req);
50 if (err != 0 || req->newptr == NULL)
52 if (val < CHN_LATENCY_MIN || val > CHN_LATENCY_MAX)
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)");
63 int chn_latency_profile = CHN_LATENCY_PROFILE_DEFAULT;
64 TUNABLE_INT("hw.snd.latency_profile", &chn_latency_profile);
67 sysctl_hw_snd_latency_profile(SYSCTL_HANDLER_ARGS)
71 val = chn_latency_profile;
72 err = sysctl_handle_int(oidp, &val, 0, req);
73 if (err != 0 || req->newptr == NULL)
75 if (val < CHN_LATENCY_PROFILE_MIN || val > CHN_LATENCY_PROFILE_MAX)
78 chn_latency_profile = val;
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)");
86 static int chn_timeout = CHN_TIMEOUT;
87 TUNABLE_INT("hw.snd.timeout", &chn_timeout);
90 sysctl_hw_snd_timeout(SYSCTL_HANDLER_ARGS)
95 err = sysctl_handle_int(oidp, &val, 0, req);
96 if (err != 0 || req->newptr == NULL)
98 if (val < CHN_TIMEOUT_MIN || val > CHN_TIMEOUT_MAX)
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");
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);
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,
119 "append (0-1000) millisecond trailing buffer delay on each sync");
123 * @brief Channel sync group lock
125 * Clients should acquire this lock @b without holding any channel locks
126 * before touching syncgroups or the main syncgroup list.
128 struct mtx snd_pcm_syncgroups_mtx;
129 MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock", MTX_DEF);
131 * @brief syncgroups' master list
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.
136 * See SNDCTL_DSP_SYNCGROUP for more information.
138 struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(head);
140 static int chn_buildfeeder(struct pcm_channel *c);
143 chn_lockinit(struct pcm_channel *c, int dir)
147 c->lock = snd_mtxcreate(c->name, "pcm play channel");
148 cv_init(&c->intr_cv, "pcmwr");
150 case PCMDIR_PLAY_VIRTUAL:
151 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
152 cv_init(&c->intr_cv, "pcmwrv");
155 c->lock = snd_mtxcreate(c->name, "pcm record channel");
156 cv_init(&c->intr_cv, "pcmrd");
158 case PCMDIR_REC_VIRTUAL:
159 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel");
160 cv_init(&c->intr_cv, "pcmrdv");
163 c->lock = snd_mtxcreate(c->name, "pcm fake channel");
164 cv_init(&c->intr_cv, "pcmfk");
168 cv_init(&c->cv, "pcmchn");
172 chn_lockdestroy(struct pcm_channel *c)
176 CHN_BROADCAST(&c->cv);
177 CHN_BROADCAST(&c->intr_cv);
180 cv_destroy(&c->intr_cv);
182 snd_mtxfree(c->lock);
186 * @brief Determine channel is ready for I/O
188 * @retval 1 = ready for I/O
189 * @retval 0 = not ready for I/O
192 chn_polltrigger(struct pcm_channel *c)
194 struct snd_dbuf *bs = c->bufsoft;
198 if (c->flags & CHN_F_MAPPED) {
199 if (sndbuf_getprevblocks(bs) == 0)
202 return (sndbuf_getblocks(bs) > sndbuf_getprevblocks(bs))? 1 : 0;
204 amt = (c->direction == PCMDIR_PLAY)? sndbuf_getfree(bs) : sndbuf_getready(bs);
206 lim = (c->flags & CHN_F_HAS_SIZE)? sndbuf_getblksz(bs) : 1;
209 return (amt >= lim) ? 1 : 0;
215 chn_pollreset(struct pcm_channel *c)
217 struct snd_dbuf *bs = c->bufsoft;
220 sndbuf_updateprevtotal(bs);
225 chn_wakeup(struct pcm_channel *c)
228 struct pcm_channel *ch;
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) {
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...
243 CHN_BROADCAST(&c->intr_cv);
246 CHN_FOREACH(ch, c, children.busy) {
255 chn_sleep(struct pcm_channel *c, int timeout)
261 if (c->flags & CHN_F_DEAD)
264 c->flags |= CHN_F_SLEEPING;
265 ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout);
266 c->flags &= ~CHN_F_SLEEPING;
268 return ((c->flags & CHN_F_DEAD) ? EINVAL : ret);
272 * chn_dmaupdate() tracks the status of a dma transfer,
277 chn_dmaupdate(struct pcm_channel *c)
279 struct snd_dbuf *b = c->bufhard;
280 unsigned int delta, old, hwptr, amt;
282 KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0"));
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);
290 if (c->direction == PCMDIR_PLAY) {
291 amt = min(delta, sndbuf_getready(b));
292 amt -= amt % sndbuf_getbps(b);
294 sndbuf_dispose(b, NULL, amt);
296 amt = min(delta, sndbuf_getfree(b));
297 amt -= amt % sndbuf_getbps(b);
299 sndbuf_acquire(b, NULL, amt);
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));
313 chn_wrupdate(struct pcm_channel *c)
318 KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel"));
320 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
324 /* tell the driver we've updated the primary buffer */
325 chn_trigger(c, PCMTRIG_EMLDMAWR);
327 printf("chn_wrupdate: chn_wrfeed returned %d\n", ret);)
332 chn_wrfeed(struct pcm_channel *c)
334 struct snd_dbuf *b = c->bufhard;
335 struct snd_dbuf *bs = c->bufsoft;
336 unsigned int ret, amt;
340 if ((c->flags & CHN_F_MAPPED) && !(c->flags & CHN_F_CLOSING))
341 sndbuf_acquire(bs, NULL, sndbuf_getfree(bs));
343 amt = sndbuf_getfree(b);
345 ret = (amt > 0) ? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
347 * Possible xruns. There should be no empty space left in buffer.
349 if (sndbuf_getfree(b) > 0)
352 if (sndbuf_getfree(b) < amt)
359 chn_wrintr(struct pcm_channel *c)
364 /* update pointers in primary buffer */
366 /* ...and feed from secondary to primary */
368 /* tell the driver we've updated the primary buffer */
369 chn_trigger(c, PCMTRIG_EMLDMAWR);
371 printf("chn_wrintr: chn_wrfeed returned %d\n", ret);)
375 * user write routine - uiomove data into secondary buffer, trigger if necessary
376 * if blocking, sleep, rinse and repeat.
378 * called externally, so must handle locking
382 chn_write(struct pcm_channel *c, struct uio *buf)
384 struct snd_dbuf *bs = c->bufsoft;
386 int ret, timeout, sz, t, p;
391 timeout = chn_timeout * hz;
393 while (ret == 0 && buf->uio_resid > 0) {
394 sz = min(buf->uio_resid, sndbuf_getfree(bs));
397 * The following assumes that the free space in
398 * the buffer can never be less around the
399 * unlock-uiomove-lock sequence.
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);
406 ret = uiomove(off, t, buf);
409 sndbuf_acquire(bs, NULL, t);
412 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) {
413 ret = chn_start(c, 0);
415 c->flags |= CHN_F_DEAD;
417 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) {
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.
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".
430 ret = chn_sleep(c, timeout);
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;
445 * Feed new data from the read buffer. Can be called in the bottom half.
448 chn_rdfeed(struct pcm_channel *c)
450 struct snd_dbuf *b = c->bufhard;
451 struct snd_dbuf *bs = c->bufsoft;
452 unsigned int ret, amt;
456 if (c->flags & CHN_F_MAPPED)
457 sndbuf_dispose(bs, NULL, sndbuf_getready(bs));
459 amt = sndbuf_getfree(bs);
460 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC;
462 amt = sndbuf_getready(b);
465 sndbuf_dispose(b, NULL, amt);
468 if (sndbuf_getready(bs) > 0)
475 chn_rdupdate(struct pcm_channel *c)
480 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel"));
482 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
484 chn_trigger(c, PCMTRIG_EMLDMARD);
488 printf("chn_rdfeed: %d\n", ret);)
492 /* read interrupt routine. Must be called with interrupts blocked. */
494 chn_rdintr(struct pcm_channel *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 */
503 /* ...and feed from primary to secondary */
508 * user read routine - trigger if necessary, uiomove data from secondary buffer
509 * if blocking, sleep, rinse and repeat.
511 * called externally, so must handle locking
515 chn_read(struct pcm_channel *c, struct uio *buf)
517 struct snd_dbuf *bs = c->bufsoft;
519 int ret, timeout, sz, t, p;
523 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) {
524 ret = chn_start(c, 0);
526 c->flags |= CHN_F_DEAD;
532 timeout = chn_timeout * hz;
534 while (ret == 0 && buf->uio_resid > 0) {
535 sz = min(buf->uio_resid, sndbuf_getready(bs));
538 * The following assumes that the free space in
539 * the buffer can never be less around the
540 * unlock-uiomove-lock sequence.
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);
547 ret = uiomove(off, t, buf);
550 sndbuf_dispose(bs, NULL, t);
553 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER))
556 ret = chn_sleep(c, timeout);
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;
571 chn_intr(struct pcm_channel *c)
575 if (c->direction == PCMDIR_PLAY)
583 chn_start(struct pcm_channel *c, int force)
586 struct snd_dbuf *b = c->bufhard;
587 struct snd_dbuf *bs = c->bufsoft;
591 /* if we're running, or if we're prevented from triggering, bail */
592 if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force))
601 if (c->direction == PCMDIR_REC) {
602 i = sndbuf_getfree(bs);
603 j = (i > 0) ? 1 : sndbuf_getready(b);
605 if (sndbuf_getfree(bs) == 0) {
611 pb = CHN_BUF_PARENT(c, b);
612 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
613 j = sndbuf_getbps(pb);
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",
624 c->flags |= CHN_F_TRIGGERED;
626 c->feedcount = (c->flags & CHN_F_CLOSING) ? 2 : 0;
629 if (c->direction == PCMDIR_PLAY && c->parentchannel == NULL) {
630 sndbuf_fillsilence(b);
632 printf("%s: %s starting! (%s) (ready=%d "
633 "force=%d i=%d j=%d intrtimeout=%u "
636 (c->flags & CHN_F_HAS_VCHAN) ?
638 (c->flags & CHN_F_CLOSING) ? "closing" :
641 force, i, j, c->timeout,
642 (sndbuf_getsize(b) * 1000) /
643 (sndbuf_getbps(b) * sndbuf_getspd(b)));
645 err = chn_trigger(c, PCMTRIG_START);
652 chn_resetbuf(struct pcm_channel *c)
654 struct snd_dbuf *b = c->bufhard;
655 struct snd_dbuf *bs = c->bufsoft;
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...
668 chn_sync(struct pcm_channel *c, int threshold)
670 struct snd_dbuf *b, *bs;
671 int ret, count, hcount, minflush, resid, residp, syncdelay, blksz;
676 if (c->direction != PCMDIR_PLAY)
681 if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) ||
682 (threshold < 1 && sndbuf_getready(bs) < 1))
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);
695 b = CHN_BUF_PARENT(c, c->bufhard);
697 minflush = threshold + sndbuf_xbytes(sndbuf_getready(b), b, bs);
699 syncdelay = chn_syncdelay;
701 if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0))
702 minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs);
705 * Append (0-1000) millisecond trailing buffer (if needed)
706 * for slower / high latency hardwares (notably USB audio)
707 * to avoid audible truncation.
710 minflush += (sndbuf_getbps(bs) * sndbuf_getspd(bs) *
711 ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000;
713 minflush -= minflush % sndbuf_getbps(bs);
716 threshold = min(minflush, sndbuf_getfree(bs));
717 sndbuf_clear(bs, threshold);
718 sndbuf_acquire(bs, NULL, threshold);
719 minflush -= threshold;
722 resid = sndbuf_getready(bs);
724 blksz = sndbuf_getblksz(b);
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);
734 count = sndbuf_xbytes(minflush + resid, bs, b) / blksz;
739 printf("%s: [begin] timeout=%d count=%d "
740 "minflush=%d resid=%d\n", __func__, c->timeout, count,
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;
750 } else if (ret == 0 || ret == EAGAIN) {
751 resid = sndbuf_getready(bs);
752 if (resid == residp) {
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) {
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);
769 if (minflush > 0 && sndbuf_getfree(bs) > 0) {
770 threshold = min(minflush,
772 sndbuf_clear(bs, threshold);
773 sndbuf_acquire(bs, NULL, threshold);
774 resid = sndbuf_getready(bs);
775 minflush -= threshold;
781 c->flags &= ~CHN_F_CLOSING;
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,
793 /* called externally, handle locking */
795 chn_poll(struct pcm_channel *c, int ev, struct thread *td)
797 struct snd_dbuf *bs = c->bufsoft;
801 if (!(c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED))) {
802 ret = chn_start(c, 1);
807 if (chn_polltrigger(c) && chn_pollreset(c))
810 selrecord(td, sndbuf_getsel(bs));
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.
818 * called from: dsp_close, dsp_ioctl, with channel locked
821 chn_abort(struct pcm_channel *c)
824 struct snd_dbuf *b = c->bufhard;
825 struct snd_dbuf *bs = c->bufsoft;
830 c->flags |= CHN_F_ABORTING;
832 c->flags &= ~CHN_F_TRIGGERED;
833 /* kill the channel */
834 chn_trigger(c, PCMTRIG_ABORT);
836 if (!(c->flags & CHN_F_VIRTUAL))
838 missing = sndbuf_getready(bs);
840 c->flags &= ~CHN_F_ABORTING;
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.
852 * called from: dsp_close, not valid for record channels.
856 chn_flush(struct pcm_channel *c)
858 struct snd_dbuf *b = c->bufhard;
861 KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel"));
862 DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags));
864 c->flags |= CHN_F_CLOSING;
866 c->flags &= ~CHN_F_TRIGGERED;
867 /* kill the channel */
868 chn_trigger(c, PCMTRIG_ABORT);
871 c->flags &= ~CHN_F_CLOSING;
876 fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
880 for (i = 0; fmtlist[i]; i++)
881 if (fmt == fmtlist[i])
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 },
899 afmtstr_swap_sign(char *s)
901 if (s == NULL || strlen(s) < 2) /* full length of "s8" */
913 afmtstr_swap_endian(char *s)
915 if (s == NULL || strlen(s) < 5) /* full length of "s16le" */
919 else if (s[3] == 'b')
927 afmtstr2afmt(struct afmtstr_table *tbl, const char *s, int stereo)
931 sz = (s == NULL) ? 0 : strlen(s);
936 tbl = default_afmtstr_table;
938 for (; tbl->fmtstr != NULL; tbl++) {
939 fsz = strlen(tbl->fmtstr);
942 if (strncmp(s, tbl->fmtstr, fsz) != 0)
946 ((stereo) ? AFMT_STEREO : 0);
947 if ((sz - fsz) < 2 || s[fsz] != ':')
950 * For now, just handle mono/stereo.
952 if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 'm' ||
953 s[fsz + 1] == '1')) ||
954 strcmp(s + fsz + 1, "mono") == 0)
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;
968 afmt2afmtstr(struct afmtstr_table *tbl, u_int32_t afmt, char *dst,
969 size_t len, int type, int stereo)
972 char *fmtstr = NULL, *tag = "";
975 tbl = default_afmtstr_table;
977 for (; tbl->format != 0; tbl++) {
978 if (tbl->format == 0)
980 if ((afmt & ~AFMT_STEREO) != tbl->format)
983 fmtstr = tbl->fmtstr;
987 if (fmt != 0 && fmtstr != NULL && dst != NULL && len > 0) {
988 strlcpy(dst, fmtstr, len);
991 tag = (fmt & AFMT_STEREO) ? ":s" : ":m";
994 tag = (fmt & AFMT_STEREO) ? ":2" : ":1";
997 tag = (fmt & AFMT_STEREO) ? ":stereo" : ":mono";
1003 if (strlen(tag) > 0 && ((stereo && !(fmt & AFMT_STEREO)) || \
1004 (!stereo && (fmt & AFMT_STEREO))))
1005 strlcat(dst, tag, len);
1012 chn_reset(struct pcm_channel *c, u_int32_t fmt)
1018 c->flags &= CHN_F_RESET;
1023 r = CHANNEL_RESET(c->methods, c->devinfo);
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);
1032 hwspd = chn_getcaps(c)->minspeed;
1036 r = chn_setformat(c, fmt);
1038 r = chn_setspeed(c, hwspd);
1041 r = chn_setvolume(c, 100, 100);
1045 r = chn_setlatency(c, chn_latency);
1048 r = CHANNEL_RESETDONE(c->methods, c->devinfo);
1054 chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
1056 struct feeder_class *fc;
1057 struct snd_dbuf *b, *bs;
1060 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
1061 chn_timeout = CHN_TIMEOUT;
1063 chn_lockinit(c, dir);
1067 CHN_INIT(c, children);
1068 CHN_INIT(c, children.busy);
1075 b = sndbuf_create(c->dev, c->name, "primary", c);
1078 bs = sndbuf_create(c->dev, c->name, "secondary", c);
1085 fc = feeder_getclass(NULL);
1088 if (chn_addfeeder(c, fc, NULL))
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
1097 sndbuf_setup(bs, NULL, 0);
1106 CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */
1107 c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction);
1109 if (c->devinfo == NULL)
1113 if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0))
1116 ret = chn_setdir(c, direction);
1120 ret = sndbuf_setfmt(b, AFMT_U8);
1124 ret = sndbuf_setfmt(bs, AFMT_U8);
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().
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) {
1146 if (CHANNEL_FREE(c->methods, c->devinfo))
1154 c->flags |= CHN_F_DEAD;
1164 chn_kill(struct pcm_channel *c)
1166 struct snd_dbuf *b = c->bufhard;
1167 struct snd_dbuf *bs = c->bufsoft;
1169 if (CHN_STARTED(c)) {
1171 chn_trigger(c, PCMTRIG_ABORT);
1174 while (chn_removefeeder(c) == 0)
1176 if (CHANNEL_FREE(c->methods, c->devinfo))
1181 c->flags |= CHN_F_DEAD;
1188 chn_setdir(struct pcm_channel *c, int dir)
1191 struct snd_dbuf *b = c->bufhard;
1197 r = CHANNEL_SETDIR(c->methods, c->devinfo, c->direction);
1199 if (!r && SND_DMA(b))
1200 sndbuf_dmasetdir(b, c->direction);
1206 chn_setvolume(struct pcm_channel *c, int left, int right)
1209 /* should add a feeder for volume changing if channel returns -1 */
1218 c->volume = left | (right << 8);
1223 round_pow2(u_int32_t v)
1232 ret = 1 << (ret - 1);
1239 round_blksz(u_int32_t v, int round)
1246 ret = min(round_pow2(v), CHN_2NDBUFMAXSIZE >> 1);
1248 if (ret > v && (ret >> 1) > 0 && (ret >> 1) >= ((v * 3) >> 2))
1251 tmp = ret - (ret % round);
1252 while (tmp < 16 || tmp < round) {
1254 tmp = ret - (ret % round);
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
1265 * Latency reference table for 48khz stereo 16bit: (PLAY)
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 * +---------+------------+-----------+------------+
1293 * Recording need a different reference table. All we care is
1294 * gobbling up everything within reasonable buffering threshold.
1296 * Latency reference table for 48khz stereo 16bit: (REC)
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 * +---------+------------+-----------+------------+
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.
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}}
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}}
1346 #define CHN_LATENCY_DATA_REF 192000 /* 48khz stereo 16bit ~ 48000 x 2 x 2 */
1349 chn_calclatency(int dir, int latency, int bps, u_int32_t datarate,
1350 u_int32_t max, int *rblksz, int *rblkcnt)
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;
1361 int lprofile, blksz, blkcnt;
1363 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX ||
1364 bps < 1 || datarate < 1 ||
1365 !(dir == PCMDIR_PLAY || dir == PCMDIR_REC)) {
1367 *rblksz = CHN_2NDBUFMAXSIZE >> 1;
1368 if (rblkcnt != NULL)
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;
1376 lprofile = chn_latency_profile;
1378 if (dir == PCMDIR_PLAY) {
1379 blkcnt = pblkcnts[lprofile][latency];
1380 bufsz = pbufszs[lprofile][latency];
1382 blkcnt = rblkcnts[lprofile][latency];
1383 bufsz = rbufszs[lprofile][latency];
1386 bufsz = round_pow2(snd_xbytes(1 << bufsz, CHN_LATENCY_DATA_REF,
1390 blksz = round_blksz(bufsz >> blkcnt, bps);
1394 if (rblkcnt != NULL)
1395 *rblkcnt = 1 << blkcnt;
1397 return blksz << blkcnt;
1401 chn_resizebuf(struct pcm_channel *c, int latency,
1402 int blkcnt, int blksz)
1404 struct snd_dbuf *b, *bs, *pb;
1405 int sblksz, sblkcnt, hblksz, hblkcnt, limit = 1;
1410 if ((c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)) ||
1411 !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC))
1414 if (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)
1424 c->latency = latency;
1431 if (!(blksz == 0 || blkcnt == -1) &&
1432 (blksz < 16 || blksz < sndbuf_getbps(bs) || blkcnt < 2 ||
1433 (blksz * blkcnt) > CHN_2NDBUFMAXSIZE))
1436 chn_calclatency(c->direction, latency, sndbuf_getbps(bs),
1437 sndbuf_getbps(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE,
1440 if (blksz == 0 || 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);
1448 c->flags |= CHN_F_HAS_SIZE;
1450 if (c->flags & CHN_F_HAS_SIZE) {
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.
1458 sblksz = round_blksz(blksz, sndbuf_getbps(bs));
1459 sblkcnt = round_pow2(blkcnt);
1463 if (c->parentchannel != NULL) {
1464 pb = CHN_BUF_PARENT(c, NULL);
1466 CHN_LOCK(c->parentchannel);
1467 chn_notify(c->parentchannel, CHN_N_BLOCKSIZE);
1468 CHN_UNLOCK(c->parentchannel);
1470 limit = (limit != 0 && pb != NULL) ?
1471 sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0;
1472 c->timeout = c->parentchannel->timeout;
1475 if (c->flags & CHN_F_HAS_SIZE) {
1476 hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b),
1478 hblkcnt = round_pow2(sndbuf_getblkcnt(bs));
1480 chn_calclatency(c->direction, latency,
1482 sndbuf_getbps(b) * sndbuf_getspd(b),
1483 CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt);
1485 if ((hblksz << 1) > sndbuf_getmaxsize(b))
1486 hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1,
1489 while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) {
1496 hblksz -= hblksz % sndbuf_getbps(b);
1499 hblksz = sndbuf_getmaxsize(b) >> 1;
1500 hblksz -= hblksz % sndbuf_getbps(b);
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));
1512 if (!CHN_EMPTY(c, children)) {
1513 sblksz = round_blksz(
1514 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs),
1518 } else if (limit != 0)
1519 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs);
1524 c->timeout = ((u_int64_t)hz * sndbuf_getsize(b)) /
1525 ((u_int64_t)sndbuf_getspd(b) * sndbuf_getbps(b));
1530 if (limit > CHN_2NDBUFMAXSIZE)
1531 limit = CHN_2NDBUFMAXSIZE;
1534 while (limit > 0 && (sblksz * sblkcnt) > limit) {
1541 while ((sblksz * sblkcnt) < limit)
1544 while ((sblksz * sblkcnt) > CHN_2NDBUFMAXSIZE) {
1551 sblksz -= sblksz % sndbuf_getbps(bs);
1553 if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz ||
1554 sndbuf_getsize(bs) != (sblkcnt * sblksz)) {
1555 ret = sndbuf_remalloc(bs, sblkcnt, sblksz);
1557 printf("%s: Failed: %d %d\n", __func__,
1564 * OSSv4 docs: "By default OSS will set the low water level equal
1565 * to the fragment size which is optimal in most cases."
1567 c->lw = sndbuf_getblksz(bs);
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",
1576 sndbuf_getsize(b), sndbuf_getblksz(b),
1577 sndbuf_getblkcnt(b),
1578 sndbuf_getsize(bs), sndbuf_getblksz(bs),
1579 sndbuf_getblkcnt(bs), limit);
1585 chn_setlatency(struct pcm_channel *c, int latency)
1588 /* Destroy blksz/blkcnt, enforce latency profile. */
1589 return chn_resizebuf(c, latency, -1, 0);
1593 chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
1596 /* Destroy latency profile, enforce blksz/blkcnt */
1597 return chn_resizebuf(c, -1, blkcnt, blksz);
1601 chn_tryspeed(struct pcm_channel *c, int speed)
1603 struct pcm_feeder *f;
1604 struct snd_dbuf *b = c->bufhard;
1605 struct snd_dbuf *bs = c->bufsoft;
1610 DEB(printf("setspeed, channel %s\n", c->name));
1611 DEB(printf("want speed %d, ", speed));
1614 if (CHN_STOPPED(c)) {
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)));
1623 delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
1627 c->feederflags &= ~(1 << FEEDER_RATE);
1629 * Used to be 500. It was too big!
1631 if (delta > feeder_rate_round)
1632 c->feederflags |= 1 << FEEDER_RATE;
1634 sndbuf_setspd(bs, sndbuf_getspd(b));
1636 r = chn_buildfeeder(c);
1637 DEB(printf("r = %d\n", r));
1641 if (!(c->feederflags & (1 << FEEDER_RATE)))
1645 f = chn_findfeeder(c, FEEDER_RATE);
1646 DEB(printf("feedrate = %p\n", f));
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));
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));
1661 r = CHANNEL_SETFORMAT(c->methods, c->devinfo,
1664 sndbuf_setfmt(bs, c->format);
1666 r = chn_resizebuf(c, -2, 0, 0);
1667 DEB(printf("setspeed done, r = %d\n", r));
1674 chn_setspeed(struct pcm_channel *c, int speed)
1676 int r, oldspeed = c->speed;
1678 r = chn_tryspeed(c, speed);
1680 if (snd_verbose > 3)
1681 printf("Failed to set speed %d falling back to %d\n",
1683 r = chn_tryspeed(c, oldspeed);
1689 chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
1691 struct snd_dbuf *b = c->bufhard;
1692 struct snd_dbuf *bs = c->bufsoft;
1696 if (CHN_STOPPED(c)) {
1697 DEB(printf("want format %d\n", fmt));
1699 r = chn_buildfeeder(c);
1701 sndbuf_setfmt(bs, c->format);
1703 r = CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b));
1705 r = chn_tryspeed(c, c->speed);
1713 chn_setformat(struct pcm_channel *c, u_int32_t fmt)
1715 u_int32_t oldfmt = c->format;
1718 r = chn_tryformat(c, fmt);
1720 if (snd_verbose > 3)
1721 printf("Format change 0x%08x failed, reverting to 0x%08x\n",
1723 chn_tryformat(c, oldfmt);
1729 chn_trigger(struct pcm_channel *c, int go)
1732 struct snd_dbuf *b = c->bufhard;
1734 struct snddev_info *d = c->parentsnddev;
1739 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD))
1740 sndbuf_dmabounce(b);
1742 if (!PCMTRIG_COMMON(go))
1743 return (CHANNEL_TRIGGER(c->methods, c->devinfo, go));
1745 if (go == c->trigger)
1748 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
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,
1759 if (c->trigger != PCMTRIG_START) {
1763 CHN_INSERT_HEAD(d, c, channels.pcm.busy);
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,
1775 if (c->trigger == PCMTRIG_START) {
1779 CHN_REMOVE(d, c, channels.pcm.busy);
1792 * @brief Queries sound driver for sample-aligned hardware buffer pointer index
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.)
1799 * @param c PCM channel context
1800 * @returns sample-aligned hardware buffer pointer index
1803 chn_getptr(struct pcm_channel *c)
1808 hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
1809 return (hwptr - (hwptr % sndbuf_getbps(c->bufhard)));
1812 struct pcmchan_caps *
1813 chn_getcaps(struct pcm_channel *c)
1816 return CHANNEL_GETCAPS(c->methods, c->devinfo);
1820 chn_getformats(struct pcm_channel *c)
1822 u_int32_t *fmtlist, fmts;
1825 fmtlist = chn_getcaps(c)->fmtlist;
1827 for (i = 0; fmtlist[i]; i++)
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;
1841 chn_buildfeeder(struct pcm_channel *c)
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;
1848 char fmtstr[AFMTSTR_MAXSZ];
1851 while (chn_removefeeder(c) == 0)
1853 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1855 c->align = sndbuf_getalign(c->bufsoft);
1857 if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) {
1859 * Virtual rec need this.
1861 fc = feeder_getclass(NULL);
1862 KASSERT(fc != NULL, ("can't find root feeder"));
1864 err = chn_addfeeder(c, fc, NULL);
1866 DEB(printf("can't add root feeder, err %d\n", err));
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;
1876 DEB(printf("can't decide which feeder type to use!\n"));
1879 desc.out = c->format;
1881 fc = feeder_getclass(&desc);
1883 DEB(printf("can't find vchan feeder\n"));
1888 err = chn_addfeeder(c, fc, &desc);
1890 DEB(printf("can't add vchan feeder, err %d\n", err));
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;
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;
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;
1916 flags = c->feederflags;
1917 fmtlist = chn_getcaps(c)->fmtlist;
1919 DEB(printf("feederflags %x\n", flags));
1921 for (type = FEEDER_RATE; type < FEEDER_LAST; type++) {
1922 if (flags & (1 << type)) {
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));
1935 * 8bit doesn't provide enough headroom
1936 * for proper processing without
1937 * creating too much noises. Force to
1940 strlcpy(fmtstr, "s16le", sizeof(fmtstr));
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);
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;
1956 } else if (type == FEEDER_SWAPLR) {
1957 desc.in = c->feeder->desc->out;
1958 desc.in |= AFMT_STEREO;
1962 fc = feeder_getclass(&desc);
1963 DEB(printf("got %p\n", fc));
1965 DEB(printf("can't find required feeder type %d\n", type));
1970 if (desc.in == 0 || desc.out == 0)
1973 DEB(printf("build fmtchain from 0x%08x to 0x%08x: ", c->feeder->desc->out, fc->desc->in));
1976 if (chn_fmtchain(c, tmp) == 0) {
1977 DEB(printf("failed\n"));
1981 DEB(printf("ok\n"));
1983 err = chn_addfeeder(c, fc, &desc);
1985 DEB(printf("can't add feeder %p, output 0x%x, err %d\n", fc, fc->desc->out, err));
1989 DEB(printf("added feeder %p, output 0x%x\n", fc, c->feeder->desc->out));
1993 if (c->direction == PCMDIR_REC) {
1996 hwfmt = chn_fmtchain(c, tmp);
1998 hwfmt = chn_fmtchain(c, fmtlist);
2000 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
2001 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt));
2003 } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) {
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.
2009 if (c->flags & CHN_F_HAS_VCHAN) {
2010 desc.type = FEEDER_MIXER;
2011 desc.in = c->format;
2014 desc.out = c->format;
2016 fc = feeder_getclass(&desc);
2020 err = chn_addfeeder(c, fc, &desc);
2025 sndbuf_setfmt(c->bufhard, hwfmt);
2027 if ((flags & (1 << FEEDER_VOLUME))) {
2029 int vol, left, right;
2032 vol = mix_get(m, SOUND_MIXER_PCM);
2034 device_printf(c->dev,
2035 "Soft PCM Volume: Failed to read default value\n");
2036 vol = 100 | (100 << 8);
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);
2044 device_printf(c->dev,
2045 "Soft Volume: Failed to read parent "
2047 vol = 100 | (100 << 8);
2049 left = (left * (vol & 0x7f)) / 100;
2050 right = (right * ((vol >> 8) & 0x7f)) / 100;
2053 chn_setvolume(c, left, right);
2060 chn_notify(struct pcm_channel *c, u_int32_t flags)
2066 if (CHN_EMPTY(c, children))
2072 * If the hwchan is running, we can't change its rate, format or
2075 run = (CHN_STARTED(c)) ? 1 : 0;
2077 flags &= CHN_N_VOLUME | CHN_N_TRIGGER;
2079 if (flags & CHN_N_RATE) {
2080 /* XXX I'll make good use of this someday. */
2082 if (flags & CHN_N_FORMAT) {
2083 /* XXX I'll make good use of this someday. */
2085 if (flags & CHN_N_VOLUME) {
2086 /* XXX I'll make good use of this someday. */
2088 if (flags & CHN_N_BLOCKSIZE) {
2090 * Set to default latency profile
2092 chn_setlatency(c, chn_latency);
2094 if (flags & CHN_N_TRIGGER) {
2095 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1;
2097 err = chn_start(c, 1);
2106 * @brief Fetch array of supported discrete sample rates
2108 * Wrapper for CHANNEL_GETRATES. Please see channel_if.m:getrates() for
2109 * detailed information.
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.
2115 * @param c pcm channel to examine
2116 * @param rates pointer to array of integers; rate table will be recorded here
2118 * @return number of rates in the array pointed to be @c rates
2121 chn_getrates(struct pcm_channel *c, int **rates)
2123 KASSERT(rates != NULL, ("rates is null"));
2125 return CHANNEL_GETRATES(c->methods, c->devinfo, rates);
2129 * @brief Remove channel from a sync group, if there is one.
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.)
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.)
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
2146 chn_syncdestroy(struct pcm_channel *c)
2148 struct pcmchan_syncmember *sm;
2149 struct pcmchan_syncgroup *sg;
2154 PCM_SG_LOCKASSERT(MA_OWNED);
2156 if (c->sm != NULL) {
2161 KASSERT(sg != NULL, ("syncmember has null parent"));
2163 SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link);
2166 if (SLIST_EMPTY(&sg->members)) {
2167 SLIST_REMOVE(&snd_pcm_syncgroups, sg, pcmchan_syncgroup, link);
2177 chn_lock(struct pcm_channel *c)
2183 chn_unlock(struct pcm_channel *c)
2188 #ifdef OSSV4_EXPERIMENT
2190 chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak)
2193 return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak);