Workaround a SoundBlaster 16 OSS bug

Francois Gouget fgouget at codeweavers.com
Thu Apr 8 19:27:19 CDT 2004


Some SoundBlaster 16 drivers return an incorrect (odd) fragment size for 
16 bit sound. Currently our wineoss driver will curse bout this but 
faithfully send an odd number of bytes to the OSS driver. Unfortunately 
this will cause said driver to enter an infinite loop which causes the 
whole kernel to freeze.

So this patch checks if the fragment size is wrong for the current sound 
format, curse about it, *and adjust it* to the closest smaller value. I 
don't have a test system but it seems to fix the kernel freeze.

For additional information see:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0206.2/0033.html

Note: AFAIK Andreas' kernel patch has never been applied :-(
(now you know how to mount a DOS on these systems!)


Changelog:

  * dlls/winmm/wineoss/audio.c

    Francois Gouget <fgouget at codeweavers.com>

    Patch the fragment size if it does not match the current sound 
format. This saves us from trigerring a kernel freeze on some OSS 2.4 + 
SounBlaster 16 systems.

-- 
Francois Gouget
fgouget at codeweavers.com

-------------- next part --------------
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /var/cvs/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.122
diff -u -r1.122 audio.c
--- a/dlls/winmm/wineoss/audio.c	31 Mar 2004 19:57:53 -0000	1.122
+++ b/dlls/winmm/wineoss/audio.c	8 Apr 2004 11:19:36 -0000
@@ -1780,6 +1780,18 @@
     wwo->dwWrittenTotal = 0;
     wwo->bNeedPost = TRUE;
 
+    TRACE("fd=%d fragstotal=%d fragsize=%d BufferSize=%ld\n",
+          wwo->ossdev->fd, info.fragstotal, info.fragsize, wwo->dwBufferSize);
+    if (wwo->dwFragmentSize % wwo->format.wf.nBlockAlign) {
+        ERR("Fragment doesn't contain an integral number of data blocks fragsize=%ld BlockAlign=%d\n",wwo->dwFragmentSize,wwo->format.wf.nBlockAlign);
+        /* Some SoundBlaster 16 cards return an incorrect (odd) fragment
+         * size for 16 bit sound. This will cause a system crash when we try
+         * to write just the specified odd number of bytes. So if we
+         * detect something is wrong we'd better fix it.
+         */
+        wwo->dwFragmentSize-=wwo->dwFragmentSize % wwo->format.wf.nBlockAlign;
+    }
+
     OSS_InitRingMessage(&wwo->msgRing);
 
     wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
@@ -1788,11 +1800,6 @@
     CloseHandle(wwo->hStartUpEvent);
     wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
 
-    TRACE("fd=%d fragmentSize=%ld\n",
-	  wwo->ossdev->fd, wwo->dwFragmentSize);
-    if (wwo->dwFragmentSize % wwo->format.wf.nBlockAlign)
-	ERR("Fragment doesn't contain an integral number of data blocks\n");
-
     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
 	  wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
 	  wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,


More information about the wine-patches mailing list