Date: Sun, 21 Dec 1997 13:56:29 -0800 (PST) From: Matthew Dillon <dillon@backplane.com> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: i386/5359: Soundblaster16 / general audio fixes Message-ID: <199712212156.NAA00699@apollo.backplane.com> Resent-Message-ID: <199712212200.OAA00832@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 5359
>Category: i386
>Synopsis: diffs to fix problems, add flexibility to i386/isa/sound/*
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Dec 21 14:00:01 PST 1997
>Last-Modified:
>Originator: Matthew Dillon
>Organization:
>Release: FreeBSD 3.0-CURRENT i386
>Environment:
FreeBSD-current running on ASUS PPro 200 motherboard, soundblaster 16
>Description:
The default write timeout of 2 seconds is too low, I've upped it
from 2 to 5 seconds. I'm not sure why, but I was getting timeouts
trying to start realaudio's sound player... there would be a little
smidgen of sound and then nothing. Upping the timeout parameter
fixed the problem. The problem occured prior to my other hacks.
Enhancements: I've added (partially tested) support for large
DMA buffers. The default maximum of 64K is just not big enough
for 44Khz output, especially in stereo.
I have made DSP_BUFFSIZE programmable and overrideable in the kernel
config, e.g.:
options "DSP_BUFFSIZE=131072"
And added code to ensure that individual DMA's are not over 64K
each. This has significantly improved the ability of my system
to play mpeg3 audio off a hard disk even while the system is heavily
loaded doing other things. e.g. one second of 44.1kHz @ 16 bits stereo
requires 88KB of buffer space. The standard 32K/64K is just not
enough to deal with disk latency if the disk is doing other things
at the same time.
I've only tested the buffering with sound output and the quake II
demo (linux binary running on FreeBSD).
>How-To-Repeat:
>Fix:
diff included below:
Index: sound/dmabuf.c
===================================================================
RCS file: /src/FreeBSD-CVS/ncvs/src/sys/i386/isa/sound/dmabuf.c,v
retrieving revision 1.30
diff -r1.30 dmabuf.c
101a102,108
> *
> * In high-datarate applications, buffsize may not be large enough
> * to give enough of a margin, even with double buffering, but
> * buffsize is also limited to the dma count. What we do is allow
> * buffsize (DSP_DMABUFFSIZE) to be overriden with a kernel
> * config option and to be made much, much larger, but still limit
> * the DMA transaction to something the isa dma can handle.
105c112
< while (bsz > sz)
---
> while (bsz > sz && bsz > DSP_MAXDMABUFFSIZE)
490c497
< timeout = 2 * hz;
---
> timeout = 5 * hz;
993c1000
< timeout = 2 * hz;
---
> timeout = 5 * hz;
1066a1074
> u_long flags = splhigh();
1076a1085
> splx(flags);
1163a1173
> u_long flags = splhigh();
1170a1181
> splx(flags);
1196a1208
> u_long flags = splhigh();
1203a1216
> splx(flags);
Index: sound/local.h
===================================================================
RCS file: /src/FreeBSD-CVS/ncvs/src/sys/i386/isa/sound/local.h,v
retrieving revision 1.28
diff -r1.28 local.h
122a123
> #ifndef DSP_BUFFSIZE /* allow config option to override */
123a125,126
> #endif
> #define DSP_MAXDMABUFFSIZE 32768
Index: sound/sb16_dsp.c
===================================================================
RCS file: /src/FreeBSD-CVS/ncvs/src/sys/i386/isa/sound/sb16_dsp.c,v
retrieving revision 1.27
diff -r1.27 sb16_dsp.c
252c252
< if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt==dsp_count) {
---
> if ((audio_devs[dev]->flags & DMA_AUTOMODE) && intrflag && cnt==dsp_count) {
Index: sound/sb_dsp.c
===================================================================
RCS file: /src/FreeBSD-CVS/ncvs/src/sys/i386/isa/sound/sb_dsp.c,v
retrieving revision 1.34
diff -r1.34 sb_dsp.c
994a995
> sb_reset_dsp(); /* clear prior garbage (e.g. soft reset) */
1008,1009c1009,1010
< } else
< DELAY(20);
---
> }
> DELAY(20);
Index: sound/soundcard.c
===================================================================
RCS file: /src/FreeBSD-CVS/ncvs/src/sys/i386/isa/sound/soundcard.c,v
retrieving revision 1.59
diff -r1.59 soundcard.c
470a471
> int boundary = audio_devs[dev]->buffsize;
471a473,485
> /*
> * boundary must be at least 65536, and >= buffsize. Buffers
> * > 65536 will be cut up in powers of two into chunks no larger
> * then 65536 and so each individual buffer is still guarenteed
> * to be <= 65536 and on a 65536 boundary.
> */
>
> boundary = 65536;
>
> while (boundary < audio_devs[dev]->buffsize)
> boundary <<= 1;
>
> #ifdef NOTDEF
473a488,490
> #endif
> tmpbuf = contigmalloc(audio_devs[dev]->buffsize, M_DEVBUF, M_NOWAIT,
> 0ul, 0xfffffful, 1ul, boundary);
479c496
< 2 * (int) audio_devs[dev]->buffsize);
---
> (int) audio_devs[dev]->buffsize);
>Audit-Trail:
>Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199712212156.NAA00699>
