Date: Wed, 12 Nov 2003 13:36:31 -0500 From: Mathew Kanner <mat@cnd.mcgill.ca> To: freebsd-current@freebsd.org Cc: Cameron Grant <cg@ijcg.net> Subject: sound patch for pop & crackles Message-ID: <20031112183631.GD35191@cnd.mcgill.ca>
next in thread | raw e-mail | index | archive | help
--G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="channel_frag.patch" --- 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) --G4iJoqBmSsgzjUCe--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031112183631.GD35191>