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 #define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
38 #define DMA_ALIGN_THRESHOLD 4
39 #define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
42 #define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED)
43 #define CHN_STOPPED(c) (!CHN_STARTED(c))
44 #define CHN_DIRSTR(c) (((c)->direction == PCMDIR_PLAY) ? \
45 "PCMDIR_PLAY" : "PCMDIR_REC")
47 #define BUF_PARENT(c, b) \
48 (((c) != NULL && (c)->parentchannel != NULL && \
49 (c)->parentchannel->bufhard != NULL) ? \
50 (c)->parentchannel->bufhard : (b))
53 #define CHN_TIMEOUT_MIN 1
54 #define CHN_TIMEOUT_MAX 10
60 int report_soft_formats = 1;
61 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_formats, CTLFLAG_RW,
62 &report_soft_formats, 1, "report software-emulated formats");
64 int chn_latency = CHN_LATENCY_DEFAULT;
65 TUNABLE_INT("hw.snd.latency", &chn_latency);
68 sysctl_hw_snd_latency(SYSCTL_HANDLER_ARGS)
73 err = sysctl_handle_int(oidp, &val, sizeof(val), req);
74 if (err != 0 || req->newptr == NULL)
76 if (val < CHN_LATENCY_MIN || val > CHN_LATENCY_MAX)
83 SYSCTL_PROC(_hw_snd, OID_AUTO, latency, CTLTYPE_INT | CTLFLAG_RW,
84 0, sizeof(int), sysctl_hw_snd_latency, "I",
85 "buffering latency (0=low ... 10=high)");
87 int chn_latency_profile = CHN_LATENCY_PROFILE_DEFAULT;
88 TUNABLE_INT("hw.snd.latency_profile", &chn_latency_profile);
91 sysctl_hw_snd_latency_profile(SYSCTL_HANDLER_ARGS)
95 val = chn_latency_profile;
96 err = sysctl_handle_int(oidp, &val, sizeof(val), req);
97 if (err != 0 || req->newptr == NULL)
99 if (val < CHN_LATENCY_PROFILE_MIN || val > CHN_LATENCY_PROFILE_MAX)
102 chn_latency_profile = val;
106 SYSCTL_PROC(_hw_snd, OID_AUTO, latency_profile, CTLTYPE_INT | CTLFLAG_RW,
107 0, sizeof(int), sysctl_hw_snd_latency_profile, "I",
108 "buffering latency profile (0=aggresive 1=safe)");
110 static int chn_timeout = CHN_TIMEOUT;
111 TUNABLE_INT("hw.snd.timeout", &chn_timeout);
114 sysctl_hw_snd_timeout(SYSCTL_HANDLER_ARGS)
119 err = sysctl_handle_int(oidp, &val, sizeof(val), req);
120 if (err != 0 || req->newptr == NULL)
122 if (val < CHN_TIMEOUT_MIN || val > CHN_TIMEOUT_MAX)
129 SYSCTL_PROC(_hw_snd, OID_AUTO, timeout, CTLTYPE_INT | CTLFLAG_RW,
130 0, sizeof(int), sysctl_hw_snd_timeout, "I",
131 "interrupt timeout (1 - 10) seconds");
134 static int chn_usefrags = 0;
135 TUNABLE_INT("hw.snd.usefrags", &chn_usefrags);
136 static int chn_syncdelay = -1;
137 TUNABLE_INT("hw.snd.syncdelay", &chn_syncdelay);
139 SYSCTL_INT(_hw_snd, OID_AUTO, usefrags, CTLFLAG_RW,
140 &chn_usefrags, 1, "prefer setfragments() over setblocksize()");
141 SYSCTL_INT(_hw_snd, OID_AUTO, syncdelay, CTLFLAG_RW,
143 "append (0-1000) millisecond trailing buffer delay on each sync");
147 * @brief Channel sync group lock
149 * Clients should acquire this lock @b without holding any channel locks
150 * before touching syncgroups or the main syncgroup list.
152 struct mtx snd_pcm_syncgroups_mtx;
153 MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock", MTX_DEF);
155 * @brief syncgroups' master list
157 * Each time a channel syncgroup is created, it's added to this list. This
158 * list should only be accessed with @sa snd_pcm_syncgroups_mtx held.
160 * See SNDCTL_DSP_SYNCGROUP for more information.
162 struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(head);
164 static int chn_buildfeeder(struct pcm_channel *c);
167 chn_lockinit(struct pcm_channel *c, int dir)
171 c->lock = snd_mtxcreate(c->name, "pcm play channel");
173 case PCMDIR_PLAY_VIRTUAL:
174 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
177 c->lock = snd_mtxcreate(c->name, "pcm record channel");
179 case PCMDIR_REC_VIRTUAL:
180 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel");
183 c->lock = snd_mtxcreate(c->name, "pcm fake channel");
187 cv_init(&c->cv, c->name);
191 chn_lockdestroy(struct pcm_channel *c)
193 snd_mtxfree(c->lock);
198 * @brief Determine channel is ready for I/O
200 * @retval 1 = ready for I/O
201 * @retval 0 = not ready for I/O
204 chn_polltrigger(struct pcm_channel *c)
206 struct snd_dbuf *bs = c->bufsoft;
210 if (c->flags & CHN_F_MAPPED) {
211 if (sndbuf_getprevblocks(bs) == 0)
214 return (sndbuf_getblocks(bs) > sndbuf_getprevblocks(bs))? 1 : 0;
216 amt = (c->direction == PCMDIR_PLAY)? sndbuf_getfree(bs) : sndbuf_getready(bs);
218 lim = (c->flags & CHN_F_HAS_SIZE)? sndbuf_getblksz(bs) : 1;
221 return (amt >= lim) ? 1 : 0;
227 chn_pollreset(struct pcm_channel *c)
229 struct snd_dbuf *bs = c->bufsoft;
232 sndbuf_updateprevtotal(bs);
237 chn_wakeup(struct pcm_channel *c)
239 struct snd_dbuf *bs = c->bufsoft;
240 struct pcm_channel *ch;
243 if (CHN_EMPTY(c, children)) {
244 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
245 selwakeuppri(sndbuf_getsel(bs), PRIBIO);
246 } else if (CHN_EMPTY(c, children.busy)) {
247 CHN_FOREACH(ch, c, children) {
253 CHN_FOREACH(ch, c, children.busy) {
259 if (c->flags & CHN_F_SLEEPING)
264 chn_sleep(struct pcm_channel *c, char *str, int timeout)
266 struct snd_dbuf *bs = c->bufsoft;
271 c->flags |= CHN_F_SLEEPING;
273 ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout);
275 ret = tsleep(bs, PRIBIO | PCATCH, str, timeout);
277 c->flags &= ~CHN_F_SLEEPING;
283 * chn_dmaupdate() tracks the status of a dma transfer,
288 chn_dmaupdate(struct pcm_channel *c)
290 struct snd_dbuf *b = c->bufhard;
291 unsigned int delta, old, hwptr, amt;
293 KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0"));
296 old = sndbuf_gethwptr(b);
297 hwptr = chn_getptr(c);
298 delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b);
299 sndbuf_sethwptr(b, hwptr);
302 if (delta >= ((sndbuf_getsize(b) * 15) / 16)) {
303 if (!(c->flags & (CHN_F_CLOSING | CHN_F_ABORTING)))
304 device_printf(c->dev, "hwptr went backwards %d -> %d\n", old, hwptr);
308 if (c->direction == PCMDIR_PLAY) {
309 amt = min(delta, sndbuf_getready(b));
310 amt -= amt % sndbuf_getbps(b);
312 sndbuf_dispose(b, NULL, amt);
314 amt = min(delta, sndbuf_getfree(b));
315 amt -= amt % sndbuf_getbps(b);
317 sndbuf_acquire(b, NULL, amt);
319 if (snd_verbose > 3 && CHN_STARTED(c) && delta == 0) {
320 device_printf(c->dev, "WARNING: %s DMA completion "
321 "too fast/slow ! hwptr=%u, old=%u "
322 "delta=%u amt=%u ready=%u free=%u\n",
323 CHN_DIRSTR(c), hwptr, old, delta, amt,
324 sndbuf_getready(b), sndbuf_getfree(b));
331 chn_wrupdate(struct pcm_channel *c)
336 KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel"));
338 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
342 /* tell the driver we've updated the primary buffer */
343 chn_trigger(c, PCMTRIG_EMLDMAWR);
345 printf("chn_wrupdate: chn_wrfeed returned %d\n", ret);)
350 chn_wrfeed(struct pcm_channel *c)
352 struct snd_dbuf *b = c->bufhard;
353 struct snd_dbuf *bs = c->bufsoft;
354 unsigned int ret, amt;
359 if (c->flags & CHN_F_CLOSING) {
360 sndbuf_dump(b, "b", 0x02);
361 sndbuf_dump(bs, "bs", 0x02);
365 if ((c->flags & CHN_F_MAPPED) && !(c->flags & CHN_F_CLOSING))
366 sndbuf_acquire(bs, NULL, sndbuf_getfree(bs));
368 amt = sndbuf_getfree(b);
369 DEB(if (amt > sndbuf_getsize(bs) &&
370 sndbuf_getbps(bs) >= sndbuf_getbps(b)) {
371 printf("%s(%s): amt %d > source size %d, flags 0x%x", __func__, c->name,
372 amt, sndbuf_getsize(bs), c->flags);
375 ret = (amt > 0) ? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
377 * Possible xruns. There should be no empty space left in buffer.
379 if (sndbuf_getfree(b) > 0)
382 if (sndbuf_getfree(b) < amt)
389 chn_wrintr(struct pcm_channel *c)
394 /* update pointers in primary buffer */
396 /* ...and feed from secondary to primary */
398 /* tell the driver we've updated the primary buffer */
399 chn_trigger(c, PCMTRIG_EMLDMAWR);
401 printf("chn_wrintr: chn_wrfeed returned %d\n", ret);)
405 * user write routine - uiomove data into secondary buffer, trigger if necessary
406 * if blocking, sleep, rinse and repeat.
408 * called externally, so must handle locking
412 chn_write(struct pcm_channel *c, struct uio *buf)
414 struct snd_dbuf *bs = c->bufsoft;
416 int ret, timeout, sz, t, p;
421 timeout = chn_timeout * hz;
423 while (ret == 0 && buf->uio_resid > 0) {
424 sz = min(buf->uio_resid, sndbuf_getfree(bs));
427 * The following assumes that the free space in
428 * the buffer can never be less around the
429 * unlock-uiomove-lock sequence.
431 while (ret == 0 && sz > 0) {
432 p = sndbuf_getfreeptr(bs);
433 t = min(sz, sndbuf_getsize(bs) - p);
434 off = sndbuf_getbufofs(bs, p);
436 ret = uiomove(off, t, buf);
439 sndbuf_acquire(bs, NULL, t);
444 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) {
446 * @todo Evaluate whether EAGAIN is truly desirable.
447 * 4Front drivers behave like this, but I'm
448 * not sure if it at all violates the "write
449 * should be allowed to block" model.
451 * The idea is that, while set with CHN_F_NOTRIGGER,
452 * a channel isn't playing, *but* without this we
453 * end up with "interrupt timeout / channel dead".
457 ret = chn_sleep(c, "pcmwr", timeout);
460 c->flags |= CHN_F_DEAD;
461 printf("%s: play interrupt timeout, "
462 "channel dead\n", c->name);
463 } else if (ret == ERESTART || ret == EINTR)
464 c->flags |= CHN_F_ABORTING;
473 chn_rddump(struct pcm_channel *c, unsigned int cnt)
475 struct snd_dbuf *b = c->bufhard;
479 static u_int32_t kk = 0;
480 printf("%u: dumping %d bytes\n", ++kk, cnt);
483 sndbuf_setxrun(b, sndbuf_getxrun(b) + cnt);
484 return sndbuf_dispose(b, NULL, cnt);
489 * Feed new data from the read buffer. Can be called in the bottom half.
492 chn_rdfeed(struct pcm_channel *c)
494 struct snd_dbuf *b = c->bufhard;
495 struct snd_dbuf *bs = c->bufsoft;
496 unsigned int ret, amt;
500 if (c->flags & CHN_F_CLOSING) {
501 sndbuf_dump(b, "b", 0x02);
502 sndbuf_dump(bs, "bs", 0x02);
506 amt = sndbuf_getready(b);
507 if (sndbuf_getfree(bs) < amt) {
509 amt = sndbuf_getfree(bs);
512 amt = sndbuf_getfree(bs);
513 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC;
515 amt = sndbuf_getready(b);
518 sndbuf_dispose(b, NULL, amt);
521 if (sndbuf_getready(bs) > 0)
528 chn_rdupdate(struct pcm_channel *c)
533 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel"));
535 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
537 chn_trigger(c, PCMTRIG_EMLDMARD);
541 printf("chn_rdfeed: %d\n", ret);)
545 /* read interrupt routine. Must be called with interrupts blocked. */
547 chn_rdintr(struct pcm_channel *c)
552 /* tell the driver to update the primary buffer if non-dma */
553 chn_trigger(c, PCMTRIG_EMLDMARD);
554 /* update pointers in primary buffer */
556 /* ...and feed from primary to secondary */
561 * user read routine - trigger if necessary, uiomove data from secondary buffer
562 * if blocking, sleep, rinse and repeat.
564 * called externally, so must handle locking
568 chn_read(struct pcm_channel *c, struct uio *buf)
570 struct snd_dbuf *bs = c->bufsoft;
572 int ret, timeout, sz, t, p;
580 timeout = chn_timeout * hz;
582 while (ret == 0 && buf->uio_resid > 0) {
583 sz = min(buf->uio_resid, sndbuf_getready(bs));
586 * The following assumes that the free space in
587 * the buffer can never be less around the
588 * unlock-uiomove-lock sequence.
590 while (ret == 0 && sz > 0) {
591 p = sndbuf_getreadyptr(bs);
592 t = min(sz, sndbuf_getsize(bs) - p);
593 off = sndbuf_getbufofs(bs, p);
595 ret = uiomove(off, t, buf);
598 sndbuf_dispose(bs, NULL, t);
601 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER))
604 ret = chn_sleep(c, "pcmrd", timeout);
607 c->flags |= CHN_F_DEAD;
608 printf("%s: record interrupt timeout, "
609 "channel dead\n", c->name);
610 } else if (ret == ERESTART || ret == EINTR)
611 c->flags |= CHN_F_ABORTING;
619 chn_intr(struct pcm_channel *c)
623 if (c->direction == PCMDIR_PLAY)
631 chn_start(struct pcm_channel *c, int force)
634 struct snd_dbuf *b = c->bufhard;
635 struct snd_dbuf *bs = c->bufsoft;
638 /* if we're running, or if we're prevented from triggering, bail */
639 if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force))
646 if (c->direction == PCMDIR_REC) {
647 i = sndbuf_getfree(bs);
648 j = (i > 0) ? 1 : sndbuf_getready(b);
650 if (sndbuf_getfree(bs) == 0) {
656 pb = BUF_PARENT(c, b);
657 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
658 j = sndbuf_getbps(pb);
661 if (snd_verbose > 3 && CHN_EMPTY(c, children))
662 printf("%s: %s (%s) threshold i=%d j=%d\n",
663 __func__, CHN_DIRSTR(c),
664 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
669 c->flags |= CHN_F_TRIGGERED;
671 c->feedcount = (c->flags & CHN_F_CLOSING) ? 2 : 0;
674 if (c->direction == PCMDIR_PLAY && c->parentchannel == NULL) {
675 sndbuf_fillsilence(b);
677 printf("%s: %s starting! (%s) (ready=%d "
678 "force=%d i=%d j=%d intrtimeout=%u "
681 (c->flags & CHN_F_HAS_VCHAN) ?
683 (c->flags & CHN_F_CLOSING) ? "closing" :
686 force, i, j, c->timeout,
687 (sndbuf_getsize(b) * 1000) /
688 (sndbuf_getbps(b) * sndbuf_getspd(b)));
690 chn_trigger(c, PCMTRIG_START);
698 chn_resetbuf(struct pcm_channel *c)
700 struct snd_dbuf *b = c->bufhard;
701 struct snd_dbuf *bs = c->bufsoft;
709 * chn_sync waits until the space in the given channel goes above
710 * a threshold. The threshold is checked against fl or rl respectively.
711 * Assume that the condition can become true, do not check here...
714 chn_sync(struct pcm_channel *c, int threshold)
716 struct snd_dbuf *b, *bs;
717 int ret, count, hcount, minflush, resid, residp, syncdelay, blksz;
724 if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) ||
725 (threshold < 1 && sndbuf_getready(bs) < 1))
728 if (c->direction != PCMDIR_PLAY)
731 /* if we haven't yet started and nothing is buffered, else start*/
732 if (CHN_STOPPED(c)) {
733 if (threshold > 0 || sndbuf_getready(bs) > 0) {
734 ret = chn_start(c, 1);
741 b = BUF_PARENT(c, c->bufhard);
743 minflush = threshold + sndbuf_xbytes(sndbuf_getready(b), b, bs);
745 syncdelay = chn_syncdelay;
747 if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0))
748 minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs);
751 * Append (0-1000) millisecond trailing buffer (if needed)
752 * for slower / high latency hardwares (notably USB audio)
753 * to avoid audible truncation.
756 minflush += (sndbuf_getbps(bs) * sndbuf_getspd(bs) *
757 ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000;
759 minflush -= minflush % sndbuf_getbps(bs);
762 threshold = min(minflush, sndbuf_getfree(bs));
763 sndbuf_clear(bs, threshold);
764 sndbuf_acquire(bs, NULL, threshold);
765 minflush -= threshold;
768 resid = sndbuf_getready(bs);
770 blksz = sndbuf_getblksz(b);
772 printf("%s: WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n",
773 __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b),
774 sndbuf_getblksz(b), sndbuf_getblkcnt(b));
775 if (sndbuf_getblkcnt(b) > 0)
776 blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b);
780 count = sndbuf_xbytes(minflush + resid, bs, b) / blksz;
785 printf("%s: [begin] timeout=%d count=%d "
786 "minflush=%d resid=%d\n", __func__, c->timeout, count,
789 cflag = c->flags & CHN_F_CLOSING;
790 c->flags |= CHN_F_CLOSING;
791 while (count > 0 && (resid > 0 || minflush > 0)) {
792 ret = chn_sleep(c, "pcmsyn", c->timeout);
793 if (ret == ERESTART || ret == EINTR) {
794 c->flags |= CHN_F_ABORTING;
797 if (ret == 0 || ret == EAGAIN) {
798 resid = sndbuf_getready(bs);
799 if (resid == residp) {
802 printf("%s: [stalled] timeout=%d "
803 "count=%d hcount=%d "
804 "resid=%d minflush=%d\n",
805 __func__, c->timeout, count,
806 hcount, resid, minflush);
807 } else if (resid < residp && count < hcount) {
810 printf("%s: [resume] timeout=%d "
811 "count=%d hcount=%d "
812 "resid=%d minflush=%d\n",
813 __func__, c->timeout, count,
814 hcount, resid, minflush);
816 if (minflush > 0 && sndbuf_getfree(bs) > 0) {
817 threshold = min(minflush,
819 sndbuf_clear(bs, threshold);
820 sndbuf_acquire(bs, NULL, threshold);
821 resid = sndbuf_getready(bs);
822 minflush -= threshold;
827 c->flags &= ~CHN_F_CLOSING;
831 printf("%s: timeout=%d count=%d hcount=%d resid=%d residp=%d "
832 "minflush=%d ret=%d\n",
833 __func__, c->timeout, count, hcount, resid, residp,
839 /* called externally, handle locking */
841 chn_poll(struct pcm_channel *c, int ev, struct thread *td)
843 struct snd_dbuf *bs = c->bufsoft;
847 if (!(c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)))
850 if (chn_polltrigger(c) && chn_pollreset(c))
853 selrecord(td, sndbuf_getsel(bs));
858 * chn_abort terminates a running dma transfer. it may sleep up to 200ms.
859 * it returns the number of bytes that have not been transferred.
861 * called from: dsp_close, dsp_ioctl, with channel locked
864 chn_abort(struct pcm_channel *c)
867 struct snd_dbuf *b = c->bufhard;
868 struct snd_dbuf *bs = c->bufsoft;
873 c->flags |= CHN_F_ABORTING;
875 c->flags &= ~CHN_F_TRIGGERED;
876 /* kill the channel */
877 chn_trigger(c, PCMTRIG_ABORT);
879 if (!(c->flags & CHN_F_VIRTUAL))
881 missing = sndbuf_getready(bs);
883 c->flags &= ~CHN_F_ABORTING;
888 * this routine tries to flush the dma transfer. It is called
889 * on a close of a playback channel.
890 * first, if there is data in the buffer, but the dma has not yet
891 * begun, we need to start it.
892 * next, we wait for the play buffer to drain
893 * finally, we stop the dma.
895 * called from: dsp_close, not valid for record channels.
899 chn_flush(struct pcm_channel *c)
901 struct snd_dbuf *b = c->bufhard;
904 KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel"));
905 DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags));
907 c->flags |= CHN_F_CLOSING;
909 c->flags &= ~CHN_F_TRIGGERED;
910 /* kill the channel */
911 chn_trigger(c, PCMTRIG_ABORT);
914 c->flags &= ~CHN_F_CLOSING;
919 fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
923 for (i = 0; fmtlist[i]; i++)
924 if (fmt == fmtlist[i])
929 static struct afmtstr_table default_afmtstr_table[] = {
930 { "alaw", AFMT_A_LAW }, { "mulaw", AFMT_MU_LAW },
931 { "u8", AFMT_U8 }, { "s8", AFMT_S8 },
932 { "s16le", AFMT_S16_LE }, { "s16be", AFMT_S16_BE },
933 { "u16le", AFMT_U16_LE }, { "u16be", AFMT_U16_BE },
934 { "s24le", AFMT_S24_LE }, { "s24be", AFMT_S24_BE },
935 { "u24le", AFMT_U24_LE }, { "u24be", AFMT_U24_BE },
936 { "s32le", AFMT_S32_LE }, { "s32be", AFMT_S32_BE },
937 { "u32le", AFMT_U32_LE }, { "u32be", AFMT_U32_BE },
942 afmtstr_swap_sign(char *s)
944 if (s == NULL || strlen(s) < 2) /* full length of "s8" */
956 afmtstr_swap_endian(char *s)
958 if (s == NULL || strlen(s) < 5) /* full length of "s16le" */
962 else if (s[3] == 'b')
970 afmtstr2afmt(struct afmtstr_table *tbl, const char *s, int stereo)
974 sz = (s == NULL) ? 0 : strlen(s);
979 tbl = default_afmtstr_table;
981 for (; tbl->fmtstr != NULL; tbl++) {
982 fsz = strlen(tbl->fmtstr);
985 if (strncmp(s, tbl->fmtstr, fsz) != 0)
989 ((stereo) ? AFMT_STEREO : 0);
990 if ((sz - fsz) < 2 || s[fsz] != ':')
993 * For now, just handle mono/stereo.
995 if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 'm' ||
996 s[fsz + 1] == '1')) ||
997 strcmp(s + fsz + 1, "mono") == 0)
999 if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 's' ||
1000 s[fsz + 1] == '2')) ||
1001 strcmp(s + fsz + 1, "stereo") == 0)
1002 return tbl->format | AFMT_STEREO;
1011 afmt2afmtstr(struct afmtstr_table *tbl, u_int32_t afmt, char *dst,
1012 size_t len, int type, int stereo)
1015 char *fmtstr = NULL, *tag = "";
1018 tbl = default_afmtstr_table;
1020 for (; tbl->format != 0; tbl++) {
1021 if (tbl->format == 0)
1023 if ((afmt & ~AFMT_STEREO) != tbl->format)
1026 fmtstr = tbl->fmtstr;
1030 if (fmt != 0 && fmtstr != NULL && dst != NULL && len > 0) {
1031 strlcpy(dst, fmtstr, len);
1033 case AFMTSTR_SIMPLE:
1034 tag = (fmt & AFMT_STEREO) ? ":s" : ":m";
1037 tag = (fmt & AFMT_STEREO) ? ":2" : ":1";
1040 tag = (fmt & AFMT_STEREO) ? ":stereo" : ":mono";
1046 if (strlen(tag) > 0 && ((stereo && !(fmt & AFMT_STEREO)) || \
1047 (!stereo && (fmt & AFMT_STEREO))))
1048 strlcat(dst, tag, len);
1055 chn_reset(struct pcm_channel *c, u_int32_t fmt)
1061 c->flags &= CHN_F_RESET;
1066 r = CHANNEL_RESET(c->methods, c->devinfo);
1069 hwspd = DSP_DEFAULT_SPEED;
1070 /* only do this on a record channel until feederbuilder works */
1071 if (c->direction == PCMDIR_REC)
1072 RANGE(hwspd, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
1075 hwspd = chn_getcaps(c)->minspeed;
1079 r = chn_setformat(c, fmt);
1081 r = chn_setspeed(c, hwspd);
1084 r = chn_setvolume(c, 100, 100);
1088 r = chn_setlatency(c, chn_latency);
1091 r = CHANNEL_RESETDONE(c->methods, c->devinfo);
1097 chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
1099 struct feeder_class *fc;
1100 struct snd_dbuf *b, *bs;
1103 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
1104 chn_timeout = CHN_TIMEOUT;
1106 chn_lockinit(c, dir);
1110 CHN_INIT(c, children);
1111 CHN_INIT(c, children.busy);
1118 b = sndbuf_create(c->dev, c->name, "primary", c);
1121 bs = sndbuf_create(c->dev, c->name, "secondary", c);
1128 fc = feeder_getclass(NULL);
1131 if (chn_addfeeder(c, fc, NULL))
1135 * XXX - sndbuf_setup() & sndbuf_resize() expect to be called
1136 * with the channel unlocked because they are also called
1137 * from driver methods that don't know about locking
1140 sndbuf_setup(bs, NULL, 0);
1149 CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */
1150 c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction);
1152 if (c->devinfo == NULL)
1156 if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0))
1159 ret = chn_setdir(c, direction);
1163 ret = sndbuf_setfmt(b, AFMT_U8);
1167 ret = sndbuf_setfmt(bs, AFMT_U8);
1172 * @todo Should this be moved somewhere else? The primary buffer
1173 * is allocated by the driver or via DMA map setup, and tmpbuf
1174 * seems to only come into existence in sndbuf_resize().
1176 if (c->direction == PCMDIR_PLAY) {
1177 bs->sl = sndbuf_getmaxsize(bs);
1178 bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT);
1179 if (bs->shadbuf == NULL) {
1189 if (CHANNEL_FREE(c->methods, c->devinfo))
1196 c->flags |= CHN_F_DEAD;
1206 chn_kill(struct pcm_channel *c)
1208 struct snd_dbuf *b = c->bufhard;
1209 struct snd_dbuf *bs = c->bufsoft;
1211 if (CHN_STARTED(c)) {
1213 chn_trigger(c, PCMTRIG_ABORT);
1216 while (chn_removefeeder(c) == 0)
1218 if (CHANNEL_FREE(c->methods, c->devinfo))
1220 c->flags |= CHN_F_DEAD;
1228 chn_setdir(struct pcm_channel *c, int dir)
1231 struct snd_dbuf *b = c->bufhard;
1237 r = CHANNEL_SETDIR(c->methods, c->devinfo, c->direction);
1239 if (!r && SND_DMA(b))
1240 sndbuf_dmasetdir(b, c->direction);
1246 chn_setvolume(struct pcm_channel *c, int left, int right)
1249 /* should add a feeder for volume changing if channel returns -1 */
1258 c->volume = left | (right << 8);
1263 round_pow2(u_int32_t v)
1272 ret = 1 << (ret - 1);
1279 round_blksz(u_int32_t v, int round)
1286 ret = min(round_pow2(v), CHN_2NDBUFMAXSIZE >> 1);
1288 if (ret > v && (ret >> 1) > 0 && (ret >> 1) >= ((v * 3) >> 2))
1291 tmp = ret - (ret % round);
1292 while (tmp < 16 || tmp < round) {
1294 tmp = ret - (ret % round);
1301 * 4Front call it DSP Policy, while we call it "Latency Profile". The idea
1302 * is to keep 2nd buffer short so that it doesn't cause long queue during
1305 * Latency reference table for 48khz stereo 16bit: (PLAY)
1307 * +---------+------------+-----------+------------+
1308 * | Latency | Blockcount | Blocksize | Buffersize |
1309 * +---------+------------+-----------+------------+
1310 * | 0 | 2 | 64 | 128 |
1311 * +---------+------------+-----------+------------+
1312 * | 1 | 4 | 128 | 512 |
1313 * +---------+------------+-----------+------------+
1314 * | 2 | 8 | 512 | 4096 |
1315 * +---------+------------+-----------+------------+
1316 * | 3 | 16 | 512 | 8192 |
1317 * +---------+------------+-----------+------------+
1318 * | 4 | 32 | 512 | 16384 |
1319 * +---------+------------+-----------+------------+
1320 * | 5 | 32 | 1024 | 32768 |
1321 * +---------+------------+-----------+------------+
1322 * | 6 | 16 | 2048 | 32768 |
1323 * +---------+------------+-----------+------------+
1324 * | 7 | 8 | 4096 | 32768 |
1325 * +---------+------------+-----------+------------+
1326 * | 8 | 4 | 8192 | 32768 |
1327 * +---------+------------+-----------+------------+
1328 * | 9 | 2 | 16384 | 32768 |
1329 * +---------+------------+-----------+------------+
1330 * | 10 | 2 | 32768 | 65536 |
1331 * +---------+------------+-----------+------------+
1333 * Recording need a different reference table. All we care is
1334 * gobbling up everything within reasonable buffering threshold.
1336 * Latency reference table for 48khz stereo 16bit: (REC)
1338 * +---------+------------+-----------+------------+
1339 * | Latency | Blockcount | Blocksize | Buffersize |
1340 * +---------+------------+-----------+------------+
1341 * | 0 | 512 | 32 | 16384 |
1342 * +---------+------------+-----------+------------+
1343 * | 1 | 256 | 64 | 16384 |
1344 * +---------+------------+-----------+------------+
1345 * | 2 | 128 | 128 | 16384 |
1346 * +---------+------------+-----------+------------+
1347 * | 3 | 64 | 256 | 16384 |
1348 * +---------+------------+-----------+------------+
1349 * | 4 | 32 | 512 | 16384 |
1350 * +---------+------------+-----------+------------+
1351 * | 5 | 32 | 1024 | 32768 |
1352 * +---------+------------+-----------+------------+
1353 * | 6 | 16 | 2048 | 32768 |
1354 * +---------+------------+-----------+------------+
1355 * | 7 | 8 | 4096 | 32768 |
1356 * +---------+------------+-----------+------------+
1357 * | 8 | 4 | 8192 | 32768 |
1358 * +---------+------------+-----------+------------+
1359 * | 9 | 2 | 16384 | 32768 |
1360 * +---------+------------+-----------+------------+
1361 * | 10 | 2 | 32768 | 65536 |
1362 * +---------+------------+-----------+------------+
1364 * Calculations for other data rate are entirely based on these reference
1365 * tables. For normal operation, Latency 5 seems give the best, well
1366 * balanced performance for typical workload. Anything below 5 will
1367 * eat up CPU to keep up with increasing context switches because of
1368 * shorter buffer space and usually require the application to handle it
1369 * aggresively through possibly real time programming technique.
1372 #define CHN_LATENCY_PBLKCNT_REF \
1373 {{1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}, \
1374 {1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}}
1375 #define CHN_LATENCY_PBUFSZ_REF \
1376 {{7, 9, 12, 13, 14, 15, 15, 15, 15, 15, 16}, \
1377 {11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 17}}
1379 #define CHN_LATENCY_RBLKCNT_REF \
1380 {{9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}, \
1381 {9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}}
1382 #define CHN_LATENCY_RBUFSZ_REF \
1383 {{14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, \
1384 {15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17}}
1386 #define CHN_LATENCY_DATA_REF 192000 /* 48khz stereo 16bit ~ 48000 x 2 x 2 */
1389 chn_calclatency(int dir, int latency, int bps, u_int32_t datarate,
1390 u_int32_t max, int *rblksz, int *rblkcnt)
1392 static int pblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1393 CHN_LATENCY_PBLKCNT_REF;
1394 static int pbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1395 CHN_LATENCY_PBUFSZ_REF;
1396 static int rblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1397 CHN_LATENCY_RBLKCNT_REF;
1398 static int rbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1399 CHN_LATENCY_RBUFSZ_REF;
1401 int lprofile, blksz, blkcnt;
1403 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX ||
1404 bps < 1 || datarate < 1 ||
1405 !(dir == PCMDIR_PLAY || dir == PCMDIR_REC)) {
1407 *rblksz = CHN_2NDBUFMAXSIZE >> 1;
1408 if (rblkcnt != NULL)
1410 printf("%s: FAILED dir=%d latency=%d bps=%d "
1411 "datarate=%u max=%u\n",
1412 __func__, dir, latency, bps, datarate, max);
1413 return CHN_2NDBUFMAXSIZE;
1416 lprofile = chn_latency_profile;
1418 if (dir == PCMDIR_PLAY) {
1419 blkcnt = pblkcnts[lprofile][latency];
1420 bufsz = pbufszs[lprofile][latency];
1422 blkcnt = rblkcnts[lprofile][latency];
1423 bufsz = rbufszs[lprofile][latency];
1426 bufsz = round_pow2(snd_xbytes(1 << bufsz, CHN_LATENCY_DATA_REF,
1430 blksz = round_blksz(bufsz >> blkcnt, bps);
1434 if (rblkcnt != NULL)
1435 *rblkcnt = 1 << blkcnt;
1437 return blksz << blkcnt;
1441 chn_resizebuf(struct pcm_channel *c, int latency,
1442 int blkcnt, int blksz)
1444 struct snd_dbuf *b, *bs, *pb;
1445 int sblksz, sblkcnt, hblksz, hblkcnt, limit = 1;
1450 if ((c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)) ||
1451 !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC))
1454 if (latency == -1) {
1456 latency = chn_latency;
1457 } else if (latency == -2) {
1458 latency = c->latency;
1459 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX)
1460 latency = chn_latency;
1461 } else if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX)
1464 c->latency = latency;
1471 if (!(blksz == 0 || blkcnt == -1) &&
1472 (blksz < 16 || blksz < sndbuf_getbps(bs) || blkcnt < 2 ||
1473 (blksz * blkcnt) > CHN_2NDBUFMAXSIZE))
1476 chn_calclatency(c->direction, latency, sndbuf_getbps(bs),
1477 sndbuf_getbps(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE,
1480 if (blksz == 0 || blkcnt == -1) {
1482 c->flags &= ~CHN_F_HAS_SIZE;
1483 if (c->flags & CHN_F_HAS_SIZE) {
1484 blksz = sndbuf_getblksz(bs);
1485 blkcnt = sndbuf_getblkcnt(bs);
1488 c->flags |= CHN_F_HAS_SIZE;
1490 if (c->flags & CHN_F_HAS_SIZE) {
1492 * The application has requested their own blksz/blkcnt.
1493 * Just obey with it, and let them toast alone. We can
1494 * clamp it to the nearest latency profile, but that would
1495 * defeat the purpose of having custom control. The least
1496 * we can do is round it to the nearest ^2 and align it.
1498 sblksz = round_blksz(blksz, sndbuf_getbps(bs));
1499 sblkcnt = round_pow2(blkcnt);
1503 if (c->parentchannel != NULL) {
1504 pb = BUF_PARENT(c, NULL);
1506 chn_notify(c->parentchannel, CHN_N_BLOCKSIZE);
1508 limit = (limit != 0 && pb != NULL) ?
1509 sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0;
1510 c->timeout = c->parentchannel->timeout;
1513 if (c->flags & CHN_F_HAS_SIZE) {
1514 hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b),
1516 hblkcnt = round_pow2(sndbuf_getblkcnt(bs));
1518 chn_calclatency(c->direction, latency,
1520 sndbuf_getbps(b) * sndbuf_getspd(b),
1521 CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt);
1523 if ((hblksz << 1) > sndbuf_getmaxsize(b))
1524 hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1,
1527 while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) {
1534 hblksz -= hblksz % sndbuf_getbps(b);
1537 hblksz = sndbuf_getmaxsize(b) >> 1;
1538 hblksz -= hblksz % sndbuf_getbps(b);
1543 if (chn_usefrags == 0 ||
1544 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo,
1545 hblksz, hblkcnt) < 1)
1546 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods,
1547 c->devinfo, hblksz));
1550 if (!CHN_EMPTY(c, children)) {
1551 sblksz = round_blksz(
1552 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs),
1556 } else if (limit != 0)
1557 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs);
1562 c->timeout = ((u_int64_t)hz * sndbuf_getsize(b)) /
1563 ((u_int64_t)sndbuf_getspd(b) * sndbuf_getbps(b));
1568 if (limit > CHN_2NDBUFMAXSIZE)
1569 limit = CHN_2NDBUFMAXSIZE;
1572 while (limit > 0 && (sblksz * sblkcnt) > limit) {
1579 while ((sblksz * sblkcnt) < limit)
1582 while ((sblksz * sblkcnt) > CHN_2NDBUFMAXSIZE) {
1589 sblksz -= sblksz % sndbuf_getbps(bs);
1591 if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz ||
1592 sndbuf_getsize(bs) != (sblkcnt * sblksz)) {
1593 ret = sndbuf_remalloc(bs, sblkcnt, sblksz);
1595 printf("%s: Failed: %d %d\n", __func__,
1602 * OSSv4 docs: "By default OSS will set the low water level equal
1603 * to the fragment size which is optimal in most cases."
1605 c->lw = sndbuf_getblksz(bs);
1608 if (snd_verbose > 3)
1609 printf("%s: %s (%s) timeout=%u "
1610 "b[%d/%d/%d] bs[%d/%d/%d] limit=%d\n",
1611 __func__, CHN_DIRSTR(c),
1612 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
1614 sndbuf_getsize(b), sndbuf_getblksz(b),
1615 sndbuf_getblkcnt(b),
1616 sndbuf_getsize(bs), sndbuf_getblksz(bs),
1617 sndbuf_getblkcnt(bs), limit);
1623 chn_setlatency(struct pcm_channel *c, int latency)
1626 /* Destroy blksz/blkcnt, enforce latency profile. */
1627 return chn_resizebuf(c, latency, -1, 0);
1631 chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
1634 /* Destroy latency profile, enforce blksz/blkcnt */
1635 return chn_resizebuf(c, -1, blkcnt, blksz);
1639 chn_tryspeed(struct pcm_channel *c, int speed)
1641 struct pcm_feeder *f;
1642 struct snd_dbuf *b = c->bufhard;
1643 struct snd_dbuf *bs = c->bufsoft;
1648 DEB(printf("setspeed, channel %s\n", c->name));
1649 DEB(printf("want speed %d, ", speed));
1652 if (CHN_STOPPED(c)) {
1655 sndbuf_setspd(bs, speed);
1656 RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
1657 DEB(printf("try speed %d, ", speed));
1658 sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, speed));
1659 DEB(printf("got speed %d\n", sndbuf_getspd(b)));
1661 delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
1665 c->feederflags &= ~(1 << FEEDER_RATE);
1667 * Used to be 500. It was too big!
1669 if (delta > feeder_rate_round)
1670 c->feederflags |= 1 << FEEDER_RATE;
1672 sndbuf_setspd(bs, sndbuf_getspd(b));
1674 r = chn_buildfeeder(c);
1675 DEB(printf("r = %d\n", r));
1679 if (!(c->feederflags & (1 << FEEDER_RATE)))
1683 f = chn_findfeeder(c, FEEDER_RATE);
1684 DEB(printf("feedrate = %p\n", f));
1688 x = (c->direction == PCMDIR_REC)? b : bs;
1689 r = FEEDER_SET(f, FEEDRATE_SRC, sndbuf_getspd(x));
1690 DEB(printf("feeder_set(FEEDRATE_SRC, %d) = %d\n", sndbuf_getspd(x), r));
1694 x = (c->direction == PCMDIR_REC)? bs : b;
1695 r = FEEDER_SET(f, FEEDRATE_DST, sndbuf_getspd(x));
1696 DEB(printf("feeder_set(FEEDRATE_DST, %d) = %d\n", sndbuf_getspd(x), r));
1699 r = CHANNEL_SETFORMAT(c->methods, c->devinfo,
1702 sndbuf_setfmt(bs, c->format);
1704 r = chn_resizebuf(c, -2, 0, 0);
1705 DEB(printf("setspeed done, r = %d\n", r));
1712 chn_setspeed(struct pcm_channel *c, int speed)
1714 int r, oldspeed = c->speed;
1716 r = chn_tryspeed(c, speed);
1718 if (snd_verbose > 3)
1719 printf("Failed to set speed %d falling back to %d\n",
1721 r = chn_tryspeed(c, oldspeed);
1727 chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
1729 struct snd_dbuf *b = c->bufhard;
1730 struct snd_dbuf *bs = c->bufsoft;
1734 if (CHN_STOPPED(c)) {
1735 DEB(printf("want format %d\n", fmt));
1737 r = chn_buildfeeder(c);
1739 sndbuf_setfmt(bs, c->format);
1741 r = CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b));
1743 r = chn_tryspeed(c, c->speed);
1751 chn_setformat(struct pcm_channel *c, u_int32_t fmt)
1753 u_int32_t oldfmt = c->format;
1756 r = chn_tryformat(c, fmt);
1758 if (snd_verbose > 3)
1759 printf("Format change 0x%08x failed, reverting to 0x%08x\n",
1761 chn_tryformat(c, oldfmt);
1767 chn_trigger(struct pcm_channel *c, int go)
1770 struct snd_dbuf *b = c->bufhard;
1772 struct snddev_info *d = c->parentsnddev;
1777 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD))
1778 sndbuf_dmabounce(b);
1780 if ((go == PCMTRIG_START || go == PCMTRIG_STOP ||
1781 go == PCMTRIG_ABORT) && go == c->trigger)
1784 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
1789 if (snd_verbose > 3)
1790 device_printf(c->dev,
1791 "%s() %s: calling go=0x%08x , "
1792 "prev=0x%08x\n", __func__, c->name, go,
1794 if (c->trigger != PCMTRIG_START) {
1798 CHN_INSERT_HEAD(d, c, channels.pcm.busy);
1805 if (snd_verbose > 3)
1806 device_printf(c->dev,
1807 "%s() %s: calling go=0x%08x , "
1808 "prev=0x%08x\n", __func__, c->name, go,
1810 if (c->trigger == PCMTRIG_START) {
1814 CHN_REMOVE(d, c, channels.pcm.busy);
1828 * @brief Queries sound driver for sample-aligned hardware buffer pointer index
1830 * This function obtains the hardware pointer location, then aligns it to
1831 * the current bytes-per-sample value before returning. (E.g., a channel
1832 * running in 16 bit stereo mode would require 4 bytes per sample, so a
1833 * hwptr value ranging from 32-35 would be returned as 32.)
1835 * @param c PCM channel context
1836 * @returns sample-aligned hardware buffer pointer index
1839 chn_getptr(struct pcm_channel *c)
1843 int a = (1 << c->align) - 1;
1846 hwptr = (c->flags & CHN_F_TRIGGERED)? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
1847 /* don't allow unaligned values in the hwa ptr */
1849 hwptr &= ~a ; /* Apply channel align mask */
1851 hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
1857 hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
1858 return (hwptr - (hwptr % sndbuf_getbps(c->bufhard)));
1861 struct pcmchan_caps *
1862 chn_getcaps(struct pcm_channel *c)
1865 return CHANNEL_GETCAPS(c->methods, c->devinfo);
1869 chn_getformats(struct pcm_channel *c)
1871 u_int32_t *fmtlist, fmts;
1874 fmtlist = chn_getcaps(c)->fmtlist;
1876 for (i = 0; fmtlist[i]; i++)
1879 /* report software-supported formats */
1880 if (report_soft_formats)
1881 fmts |= AFMT_MU_LAW|AFMT_A_LAW|AFMT_U32_LE|AFMT_U32_BE|
1882 AFMT_S32_LE|AFMT_S32_BE|AFMT_U24_LE|AFMT_U24_BE|
1883 AFMT_S24_LE|AFMT_S24_BE|AFMT_U16_LE|AFMT_U16_BE|
1884 AFMT_S16_LE|AFMT_S16_BE|AFMT_U8|AFMT_S8;
1890 chn_buildfeeder(struct pcm_channel *c)
1892 struct feeder_class *fc;
1893 struct pcm_feederdesc desc;
1894 u_int32_t tmp[2], type, flags, hwfmt, *fmtlist;
1896 char fmtstr[AFMTSTR_MAXSZ];
1899 while (chn_removefeeder(c) == 0)
1901 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1903 c->align = sndbuf_getalign(c->bufsoft);
1905 if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) {
1907 * Virtual rec need this.
1909 fc = feeder_getclass(NULL);
1910 KASSERT(fc != NULL, ("can't find root feeder"));
1912 err = chn_addfeeder(c, fc, NULL);
1914 DEB(printf("can't add root feeder, err %d\n", err));
1918 c->feeder->desc->out = c->format;
1919 } else if (c->direction == PCMDIR_PLAY) {
1920 if (c->flags & CHN_F_HAS_VCHAN) {
1921 desc.type = FEEDER_MIXER;
1922 desc.in = c->format;
1924 DEB(printf("can't decide which feeder type to use!\n"));
1927 desc.out = c->format;
1929 fc = feeder_getclass(&desc);
1931 DEB(printf("can't find vchan feeder\n"));
1936 err = chn_addfeeder(c, fc, &desc);
1938 DEB(printf("can't add vchan feeder, err %d\n", err));
1945 c->feederflags &= ~(1 << FEEDER_VOLUME);
1946 if (c->direction == PCMDIR_PLAY &&
1947 !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1948 (c->parentsnddev->flags & SD_F_SOFTPCMVOL) &&
1949 c->parentsnddev->mixer_dev)
1950 c->feederflags |= 1 << FEEDER_VOLUME;
1951 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1952 ((c->direction == PCMDIR_PLAY &&
1953 (c->parentsnddev->flags & SD_F_PSWAPLR)) ||
1954 (c->direction == PCMDIR_REC &&
1955 (c->parentsnddev->flags & SD_F_RSWAPLR))))
1956 c->feederflags |= 1 << FEEDER_SWAPLR;
1957 flags = c->feederflags;
1958 fmtlist = chn_getcaps(c)->fmtlist;
1960 DEB(printf("feederflags %x\n", flags));
1962 for (type = FEEDER_RATE; type < FEEDER_LAST; type++) {
1963 if (flags & (1 << type)) {
1968 DEB(printf("find feeder type %d, ", type));
1969 if (type == FEEDER_VOLUME || type == FEEDER_RATE) {
1970 if (c->feeder->desc->out & AFMT_32BIT)
1971 strlcpy(fmtstr,"s32le", sizeof(fmtstr));
1972 else if (c->feeder->desc->out & AFMT_24BIT)
1973 strlcpy(fmtstr, "s24le", sizeof(fmtstr));
1976 * 8bit doesn't provide enough headroom
1977 * for proper processing without
1978 * creating too much noises. Force to
1981 strlcpy(fmtstr, "s16le", sizeof(fmtstr));
1983 if (!(c->feeder->desc->out & AFMT_8BIT) &&
1984 c->feeder->desc->out & AFMT_BIGENDIAN)
1985 afmtstr_swap_endian(fmtstr);
1986 if (!(c->feeder->desc->out & (AFMT_A_LAW | AFMT_MU_LAW)) &&
1987 !(c->feeder->desc->out & AFMT_SIGNED))
1988 afmtstr_swap_sign(fmtstr);
1989 desc.in = afmtstr2afmt(NULL, fmtstr, AFMTSTR_MONO_RETURN);
1991 desc.in = AFMT_S16_LE;
1992 /* feeder_volume need stereo processing */
1993 if (type == FEEDER_VOLUME ||
1994 c->feeder->desc->out & AFMT_STEREO)
1995 desc.in |= AFMT_STEREO;
1997 } else if (type == FEEDER_SWAPLR) {
1998 desc.in = c->feeder->desc->out;
1999 desc.in |= AFMT_STEREO;
2003 fc = feeder_getclass(&desc);
2004 DEB(printf("got %p\n", fc));
2006 DEB(printf("can't find required feeder type %d\n", type));
2011 if (desc.in == 0 || desc.out == 0)
2014 DEB(printf("build fmtchain from 0x%08x to 0x%08x: ", c->feeder->desc->out, fc->desc->in));
2017 if (chn_fmtchain(c, tmp) == 0) {
2018 DEB(printf("failed\n"));
2022 DEB(printf("ok\n"));
2024 err = chn_addfeeder(c, fc, &desc);
2026 DEB(printf("can't add feeder %p, output 0x%x, err %d\n", fc, fc->desc->out, err));
2030 DEB(printf("added feeder %p, output 0x%x\n", fc, c->feeder->desc->out));
2034 if (c->direction == PCMDIR_REC) {
2037 hwfmt = chn_fmtchain(c, tmp);
2039 hwfmt = chn_fmtchain(c, fmtlist);
2041 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
2042 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt));
2044 } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) {
2046 * Kind of awkward. This whole "MIXER" concept need a
2047 * rethinking, I guess :) . Recording is the inverse
2048 * of Playback, which is why we push mixer vchan down here.
2050 if (c->flags & CHN_F_HAS_VCHAN) {
2051 desc.type = FEEDER_MIXER;
2052 desc.in = c->format;
2055 desc.out = c->format;
2057 fc = feeder_getclass(&desc);
2061 err = chn_addfeeder(c, fc, &desc);
2066 sndbuf_setfmt(c->bufhard, hwfmt);
2068 if ((flags & (1 << FEEDER_VOLUME))) {
2069 u_int32_t parent = SOUND_MIXER_NONE;
2070 int vol, left, right;
2072 vol = 100 | (100 << 8);
2076 * XXX This is ugly! The way mixer subs being so secretive
2077 * about its own internals force us to use this silly
2080 if (mixer_ioctl(c->parentsnddev->mixer_dev,
2081 MIXER_READ(SOUND_MIXER_PCM), (caddr_t)&vol, -1, NULL) != 0)
2082 device_printf(c->dev, "Soft PCM Volume: Failed to read default value\n");
2084 right = (vol >> 8) & 0x7f;
2085 if (c->parentsnddev != NULL &&
2086 c->parentsnddev->mixer_dev != NULL &&
2087 c->parentsnddev->mixer_dev->si_drv1 != NULL)
2088 parent = mix_getparent(
2089 c->parentsnddev->mixer_dev->si_drv1,
2091 if (parent != SOUND_MIXER_NONE) {
2092 vol = 100 | (100 << 8);
2093 if (mixer_ioctl(c->parentsnddev->mixer_dev,
2095 (caddr_t)&vol, -1, NULL) != 0)
2096 device_printf(c->dev, "Soft Volume: Failed to read parent default value\n");
2097 left = (left * (vol & 0x7f)) / 100;
2098 right = (right * ((vol >> 8) & 0x7f)) / 100;
2101 chn_setvolume(c, left, right);
2108 chn_notify(struct pcm_channel *c, u_int32_t flags)
2114 if (CHN_EMPTY(c, children)) {
2119 run = (CHN_STARTED(c)) ? 1 : 0;
2121 * if the hwchan is running, we can't change its rate, format or
2125 flags &= CHN_N_VOLUME | CHN_N_TRIGGER;
2127 if (flags & CHN_N_RATE) {
2129 * we could do something here, like scan children and decide on
2130 * the most appropriate rate to mix at, but we don't for now
2133 if (flags & CHN_N_FORMAT) {
2135 * we could do something here, like scan children and decide on
2136 * the most appropriate mixer feeder to use, but we don't for now
2139 if (flags & CHN_N_VOLUME) {
2141 * we could do something here but we don't for now
2144 if (flags & CHN_N_BLOCKSIZE) {
2146 * Set to default latency profile
2148 chn_setlatency(c, chn_latency);
2150 if (flags & CHN_N_TRIGGER) {
2153 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1;
2164 * @brief Fetch array of supported discrete sample rates
2166 * Wrapper for CHANNEL_GETRATES. Please see channel_if.m:getrates() for
2167 * detailed information.
2169 * @note If the operation isn't supported, this function will just return 0
2170 * (no rates in the array), and *rates will be set to NULL. Callers
2171 * should examine rates @b only if this function returns non-zero.
2173 * @param c pcm channel to examine
2174 * @param rates pointer to array of integers; rate table will be recorded here
2176 * @return number of rates in the array pointed to be @c rates
2179 chn_getrates(struct pcm_channel *c, int **rates)
2181 KASSERT(rates != NULL, ("rates is null"));
2183 return CHANNEL_GETRATES(c->methods, c->devinfo, rates);
2187 * @brief Remove channel from a sync group, if there is one.
2189 * This function is initially intended for the following conditions:
2190 * - Starting a syncgroup (@c SNDCTL_DSP_SYNCSTART ioctl)
2191 * - Closing a device. (A channel can't be destroyed if it's still in use.)
2193 * @note Before calling this function, the syncgroup list mutex must be
2194 * held. (Consider pcm_channel::sm protected by the SG list mutex
2195 * whether @c c is locked or not.)
2197 * @param c channel device to be started or closed
2198 * @returns If this channel was the only member of a group, the group ID
2199 * is returned to the caller so that the caller can release it
2200 * via free_unr() after giving up the syncgroup lock. Else it
2204 chn_syncdestroy(struct pcm_channel *c)
2206 struct pcmchan_syncmember *sm;
2207 struct pcmchan_syncgroup *sg;
2212 PCM_SG_LOCKASSERT(MA_OWNED);
2214 if (c->sm != NULL) {
2219 KASSERT(sg != NULL, ("syncmember has null parent"));
2221 SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link);
2224 if (SLIST_EMPTY(&sg->members)) {
2225 SLIST_REMOVE(&snd_pcm_syncgroups, sg, pcmchan_syncgroup, link);
2235 chn_lock(struct pcm_channel *c)
2241 chn_unlock(struct pcm_channel *c)
2246 #ifdef OSSV4_EXPERIMENT
2248 chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak)
2251 return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak);