From owner-freebsd-bugs Sun Oct 28 19:30: 6 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 40A6937B403 for ; Sun, 28 Oct 2001 19:30:01 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id f9T3U1I58861; Sun, 28 Oct 2001 19:30:01 -0800 (PST) (envelope-from gnats) Date: Sun, 28 Oct 2001 19:30:01 -0800 (PST) Message-Id: <200110290330.f9T3U1I58861@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Ted Faber Subject: Re: kern/31445: cat sound.au > /dev/audio fails for sounds < 4KB Reply-To: Ted Faber Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR kern/31445; it has been noted by GNATS. From: Ted Faber 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