Date: Sun, 28 Oct 2001 19:30:01 -0800 (PST) From: Ted Faber <faber@lunabase.org> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/31445: cat sound.au > /dev/audio fails for sounds < 4KB Message-ID: <200110290330.f9T3U1I58861@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/31445; it has been noted by GNATS.
From: Ted Faber <faber@lunabase.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc: faber@lunabase.org
Subject: Re: kern/31445: cat sound.au > /dev/audio fails for sounds < 4KB
Date: Sun, 28 Oct 2001 19:23:32 -0800
--ew6BAiZeqk4r7MaW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I've got a fix for this. It may not be ideal, but I think it
characterizes the problem well enough that someone who cares can fine
tune it.
The problem is that if a sound is small enough, it never apsses the low
water mark in chn_start to start the playout process. This patch looks
for small sounds in chn_flush. If it detects such a sound (a partially
filled soft output buffer when the channel is not triggered), it pads
the output buffer with silence and starts it playing.
A patch follows, relative to /sys/dev/sound/pcm
--- buffer.c.orig Sun Oct 28 18:31:14 2001
+++ buffer.c Sun Oct 28 18:33:09 2001
@@ -218,6 +218,28 @@
}
void
+sndbuf_padsilence(struct snd_dbuf *b, unsigned int length)
+{
+ int i;
+ u_char data, *p;
+ unsigned int len = length;
+
+ if (b->fmt & AFMT_SIGNED)
+ data = 0x00;
+ else
+ data = 0x80;
+
+ i = sndbuf_getfreeptr(b);
+ p = sndbuf_getbuf(b);
+ while (len) {
+ p[i++] = data;
+ len--;
+ if ( i >= b->bufsize ) i = 0;
+ }
+ b->rl += length;
+}
+
+void
sndbuf_reset(struct snd_dbuf *b)
{
b->hp = 0;
--- buffer.h.orig Sun Oct 28 18:31:19 2001
+++ buffer.h Sun Oct 28 18:32:15 2001
@@ -45,6 +45,7 @@
int sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz);
void sndbuf_reset(struct snd_dbuf *b);
void sndbuf_clear(struct snd_dbuf *b, unsigned int length);
+void sndbuf_padsilence(struct snd_dbuf *b, unsigned int length);
void sndbuf_fillsilence(struct snd_dbuf *b);
u_int32_t sndbuf_getfmt(struct snd_dbuf *b);
--- channel.c.orig Sun Oct 28 18:31:05 2001
+++ channel.c Sun Oct 28 18:41:40 2001
@@ -555,8 +555,17 @@
CHN_LOCKASSERT(c);
KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel"));
DEB(printf("chn_flush c->flags 0x%08x\n", c->flags));
- if (!(c->flags & CHN_F_TRIGGERED))
- return 0;
+ if (!(c->flags & CHN_F_TRIGGERED))
+ if ( sndbuf_getready(bs) > 0 &&
+ sndbuf_getready(bs) < sndbuf_getfree(b) ) {
+ /* this is probably a short sound, pad it out with
+ silence and start the driver playing it. */
+ sndbuf_padsilence(bs, sndbuf_getfree(b));
+ chn_start(c, 1);
+ chn_sleep(c, "pcmflu", hz / 10);
+ }
+ else
+ return 0;
c->flags |= CHN_F_CLOSING;
resid = sndbuf_getready(bs) + sndbuf_getready(b);
--ew6BAiZeqk4r7MaW
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org
iD8DBQE73Mu0aUz3f+Zf+XsRAvBRAKCbKhnrJDasVQwAkfD0uzg+EHm+8QCfVO0w
+ept2DHJR9t0vvkSScHpiv8=
=83nc
-----END PGP SIGNATURE-----
--ew6BAiZeqk4r7MaW--
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110290330.f9T3U1I58861>
