[PATCH] Horrid wineoss hack

Gerard Patel gerard.patel at nerim.net
Mon Dec 3 09:43:24 CST 2001


I have found that since a few weeks my Eudora was hanging 
with current Cvs when I tried to get a new message off the server.
This occurred exactly when it was trying to play a sound to
warn about the new message.

I have found that playing any sound using PlaySound is
triggering the new problem. On my older computer, the problem
just does not exist. After investigation, the older computer has a
true sound card (a sound blaster) while the new has just a Via
chip on the mother board (via82cxx_audio)

This is the reason : the Via wineoss driver seems to be buggy,
when a sound is finished, the available space never goes back
to the total available. 

This problem did not happen with versions of audio.c < 1.45,
where the Wine code has been made to rely on this feature.

ChangeLog:

	* dlls/winmm/wineoss/audio.c
               Works around a bug in Via wineoss driver

-------------- next part --------------
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.47
diff -u -r1.47 audio.c
--- dlls/winmm/wineoss/audio.c	2001/11/19 02:10:50	1.47
+++ dlls/winmm/wineoss/audio.c	2001/12/03 12:48:35
@@ -131,6 +131,8 @@
     
     DWORD			dwPlayedTotal;		/* number of bytes played since opening */
     DWORD                       dwWrittenTotal;         /* number of bytes written since opening */
+    DWORD                       dwPreviousTotal;
+    int                         cntTotalChange;
 
     /* synchronization stuff */
     HANDLE			hStartUpEvent;
@@ -646,6 +648,23 @@
 }
 
 
+/* works around buggy wineoss driver never finishing
+   update of played data :-//, that is, info.bytes
+   stays at a few hundred of bytes and never goes to 0
+   when the end of sound data is hit. This hack avoids an
+   infinite notification loop and Wine hangging.
+*/
+void workAroundBuggyWineOSSDriver( WINE_WAVEOUT* wwo)
+{
+    if (wwo->dwPlayedTotal == wwo->dwPreviousTotal)
+       wwo->cntTotalChange++;
+    else
+       wwo->cntTotalChange = 0;
+    wwo->dwPreviousTotal = wwo->dwPlayedTotal;
+    if ((!wwo->lpPlayPtr) && (wwo->cntTotalChange > 2) && (wwo->lpQueuePtr))
+       wwo->lpQueuePtr->reserved = wwo->dwPlayedTotal; /* force exit */
+}
+
 /**************************************************************************
  * 				wodPlayer_NotifyCompletions	[internal]
  *
@@ -659,6 +678,8 @@
     LPWAVEHDR		lpWaveHdr;
 
     updatePlayedTotal(wwo);
+    workAroundBuggyWineOSSDriver(wwo);
+
     /* Start from lpQueuePtr and keep notifying until:
      * - we hit an unwritten wavehdr
      * - we hit the beginning of a running loop
@@ -717,7 +738,10 @@
 	wwo->state = WINE_WS_STOPPED;
 	wwo->dwPlayedTotal = 0;
 	wwo->dwWrittenTotal = 0;
-    } else {
+        wwo->dwPreviousTotal = 0;
+        wwo->cntTotalChange = 0;
+     }
+     else {
 	/* FIXME: this is not accurate when looping, but can be do better ? */
 	wwo->lpPlayPtr = (wwo->lpLoopPtr) ? wwo->lpLoopPtr : wwo->lpQueuePtr;
 	wwo->state = WINE_WS_PAUSED;
-------------- next part --------------



More information about the wine-patches mailing list