[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