Hello All,
        Could people experiencing pops and crackles try the attached
patch and set hw.snd.fragps=128.   This patch also fixes select on
vchans.

more details in

http://www.freebsd.org/cgi/query-pr.cgi?pr=59208

        Thanks,
        --Mat

-- 
        I don't even know what street Canada is on.
                        - Al Capone
--- channel.c.old       Wed Nov 12 02:42:43 2003
+++ channel.c   Wed Nov 12 03:59:31 2003
@@ -41,6 +41,10 @@
 #define DEB(x) x
 */
 
+static int chn_fragsps = 0;
+SYSCTL_INT(_hw_snd, OID_AUTO, fragsps, CTLFLAG_RW,
+       &chn_fragsps, 1, "max fragments per second, 0 to disable");
+
 static int chn_targetirqrate = 32;
 TUNABLE_INT("hw.snd.targetirqrate", &chn_targetirqrate);
 
@@ -59,7 +63,7 @@
        return err;
 }
 SYSCTL_PROC(_hw_snd, OID_AUTO, targetirqrate, CTLTYPE_INT | CTLFLAG_RW,
-       0, sizeof(int), sysctl_hw_snd_targetirqrate, "I", "");
+       0, sizeof(int), sysctl_hw_snd_targetirqrate, "I", "default fragment targets 
this IRQ rate");
 static int report_soft_formats = 1;
 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_formats, CTLFLAG_RW,
        &report_soft_formats, 1, "report software-emulated formats");
@@ -113,10 +117,17 @@
 chn_wakeup(struct pcm_channel *c)
 {
        struct snd_dbuf *bs = c->bufsoft;
+        struct pcmchan_children *pce;
 
-       CHN_LOCKASSERT(c);
-       if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
-               selwakeup(sndbuf_getsel(bs));
+//     CHN_LOCKASSERT(c);
+       if (SLIST_EMPTY(&c->children)) {
+               if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
+                       selwakeup(sndbuf_getsel(bs));
+       } else {
+               SLIST_FOREACH(pce, &c->children, link) {
+                       chn_wakeup(pce->channel);
+               }
+       }
        wakeup(bs);
 }
 
@@ -931,7 +942,7 @@
 {
        struct snd_dbuf *b = c->bufhard;
        struct snd_dbuf *bs = c->bufsoft;
-       int bufsz, irqhz, tmp, ret;
+       int irqhz, tmp, ret;
 
        CHN_LOCKASSERT(c);
        if (!CANCHANGE(c) || (c->flags & CHN_F_MAPPED))
@@ -960,14 +971,23 @@
                        DEB(printf("%s: updating (%d, %d)\n", __func__, blkcnt, 
blksz));
                }
        } else {
+               if ( chn_fragsps != 0 && 
+                       sndbuf_getbps(bs) * sndbuf_getspd(bs) / blksz > chn_fragsps) 
+               {
+                       blksz = sndbuf_getbps(bs) * sndbuf_getspd(bs) / chn_fragsps;
+                       tmp = 32;
+                       while (tmp < blksz)
+                               tmp <<= 1;
+                       blksz = tmp;
+                       if (blksz * blkcnt > CHN_2NDBUFMAXSIZE)
+                               blkcnt = CHN_2NDBUFMAXSIZE / blksz;
+               }
                ret = EINVAL;
                if ((blksz < 16) || (blkcnt < 2) || (blkcnt * blksz > 
CHN_2NDBUFMAXSIZE))
                        goto out;
                ret = 0;
                c->flags |= CHN_F_HAS_SIZE;
        }
-
-       bufsz = blkcnt * blksz;
 
        ret = sndbuf_remalloc(bs, blkcnt, blksz);
        if (ret)
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to