sound patch for pop & crackles
Mathew Kanner
mat at cnd.mcgill.ca
Wed Nov 12 10:38:53 PST 2003
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
-------------- next part --------------
--- 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)
More information about the freebsd-current
mailing list