I finally tracked down the regression in the MSVC 4.0 installer to one patch:
http://www.winehq.com/hypermail/wine-cvs/2002/08/0166.html ------ Modified files: dlls/winmm/wineoss: audio.c
Log message: Ove Kaaven ovek@transgaming.com Tweaks to improve playback performance and reduce sound glitches: - wodGetPosition does not send an update message to the player thread; this reduces the accuracy of the readout from byte-accuracy to near fragment-accuracy, but we save 2-4 context switches and kernel scheduling penalties. - if FeedDSP runs out of data, do not flush output buffers before notifications are sent and given the chance to provide more sound data. Do not flush before we're down to the last fragment. - messages to the player thread are signaled using Unix pipes instead of Win32 synchronization primitives, to avoid having the player thread wait for the wineserver (and context switches from/to it) before the it can feed more data to the sound card. - ring buffer size is increased from 30 to 192 to support some games that fires 128 messages at once to determine DMA buffer size. ------
Before this patch, clicking on "Exit" in MSVC 4.0 installer worked. After this patch, it hangs.
Baseline: inserting disc 1 of MSVC4.0 into drive and mounting it cvs update -D "2002-08-26 17:49 EDT" ./configure make depend && make ./wine d:setup.exe click on exit it terminates normally
Error case:
cvs update -D "2002-08-26 17:50 EDT" ./configure comment out #ifdef HAVE_SYS_POLL in dlls/winmm/wineoss/audio.c so it compiles comment out #define USE_PIPE_SYNC in dlls/winmm/wineoss/audio.c to get closer to old behavior make depend && make ./wine --debugmsg +event,+relay,+wave d:setup.exe > /tmp/bad.log 2>&1 click on exit it hangs, must kill with SIGINT
Log in http://www.kegel.com/msvc4-setup-wine-20020826-17:50.bad.log.bz2
Problem occurred whether or not I commented out #define USE_PIPE_SYNC
I'd be happy to provide more info. FWIW I'm running Red Hat 8.0. - Dan
Dan Kegel wrote:
I finally tracked down the regression in the MSVC 4.0 installer to one patch:
http://www.winehq.com/hypermail/wine-cvs/2002/08/0166.html
Modified files: dlls/winmm/wineoss: audio.c
Log message: Ove Kaaven ovek@transgaming.com Tweaks to improve playback performance and reduce sound glitches:
I've tracked it down further. Attached find a trace+wave and a patch that reverts half of Ove's patch from August, thereby "fixing" the problem.
Chris Morgan seems interested in looking into the problem, and I imagine he and I will iterate a bit on it, but I wanted to post this patch and log in case anyone was curious about this bug. (In case it isn't clear, I'm a total newbie when it comes to wine internals, so I'd never have gotten this far if I were doing anything more than tracking down a regression.) - Dan
======= patch that "fixes" the problem by reverting half of Ove's patch ======== ======= this is overkill, but I haven't tracked it down precisely yet ==========
--- wine-20021125/dlls/winmm/wineoss/audio.c.old 2002-12-10 21:59:45.000000000 -0800 +++ wine-20021125/dlls/winmm/wineoss/audio.c 2002-12-10 21:57:48.000000000 -0800 @@ -31,10 +31,6 @@ /* unless someone makes a wineserver kernel module, Unix pipes are faster than win32 events */ #define USE_PIPE_SYNC
-/* an exact wodGetPosition is usually not worth the extra context switches, - * as we're going to have near fragment accuracy anyway */ -/* #define EXACT_WODPOSITION */ - #include "config.h"
#include <stdlib.h> @@ -130,8 +126,7 @@ */ typedef struct { /* FIXME: this could be made a dynamically growing array (if needed) */ - /* maybe it's needed, a Humongous game manages to transmit 128 messages at once at startup */ -#define OSS_RING_BUFFER_SIZE 192 +#define OSS_RING_BUFFER_SIZE 30 OSS_MSG messages[OSS_RING_BUFFER_SIZE]; int msg_tosave; int msg_toget; @@ -181,7 +176,6 @@
DWORD dwPlayedTotal; /* number of bytes actually played since opening */ DWORD dwWrittenTotal; /* number of bytes written to OSS buffer since opening */ - BOOL bNeedPost; /* whether audio still needs to be physically started */
/* synchronization stuff */ HANDLE hStartUpEvent; @@ -1145,11 +1139,13 @@ wodUpdatePlayedTotal(wwo, &dspspace); availInQ = dspspace.bytes; TRACE("fragments=%d/%d, fragsize=%d, bytes=%d\n", - dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes); + dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
/* input queue empty and output buffer with less than one fragment to play */ - if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) { - TRACE("Run out of wavehdr:s...\n"); + if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize) { + TRACE("Run out of wavehdr:s... flushing (%lu => %lu)\n", + wwo->dwPlayedTotal, wwo->dwWrittenTotal); + wwo->dwPlayedTotal = wwo->dwWrittenTotal; return INFINITE; }
@@ -1169,14 +1165,6 @@ wwo->lpPlayPtr->reserved = wwo->dwWrittenTotal + wwo->lpPlayPtr->dwBufferLength; } while (wodPlayer_WriteMaxFrags(wwo, &availInQ) && wwo->lpPlayPtr && availInQ > 0); } - - if (wwo->bNeedPost) { - /* OSS doesn't start before it gets either 2 fragments or a SNDCTL_DSP_POST; - * if it didn't get one, we give it the other */ - if (wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize) - ioctl(wwo->ossdev->fd, SNDCTL_DSP_POST, 0); - wwo->bNeedPost = FALSE; - } }
return wodPlayer_DSPWait(wwo); @@ -1208,20 +1196,6 @@ if (wwo->state == WINE_WS_PLAYING) { dwNextFeedTime = wodPlayer_FeedDSP(wwo); dwNextNotifyTime = wodPlayer_NotifyCompletions(wwo, FALSE); - if (dwNextFeedTime == INFINITE) { - /* FeedDSP ran out of data, but before flushing, */ - /* check that a notification didn't give us more */ - wodPlayer_ProcessMessages(wwo); - if (!wwo->lpPlayPtr) { - TRACE("flushing\n"); - ioctl(wwo->ossdev->fd, SNDCTL_DSP_SYNC, 0); - wwo->dwPlayedTotal = wwo->dwWrittenTotal; - } - else { - TRACE("recovering\n"); - dwNextFeedTime = wodPlayer_FeedDSP(wwo); - } - } } else { dwNextFeedTime = dwNextNotifyTime = INFINITE; } @@ -1351,7 +1325,6 @@ wwo->dwBufferSize = info.fragstotal * info.fragsize; wwo->dwPlayedTotal = 0; wwo->dwWrittenTotal = 0; - wwo->bNeedPost = TRUE;
OSS_InitRingMessage(&wwo->msgRing);
@@ -1568,9 +1541,7 @@ if (lpTime == NULL) return MMSYSERR_INVALPARAM;
wwo = &WOutDev[wDevID]; -#ifdef EXACT_WODPOSITION OSS_AddRingMessage(&wwo->msgRing, WINE_WM_UPDATE, 0, TRUE); -#endif val = wwo->dwPlayedTotal;
TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%lu nChannels=%u nAvgBytesPerSec=%lu\n",
============ trace+wave showing the problem ================
trace:wave:OSS_WaveOutInit OSS dsp out mask=00000018 trace:wave:OSS_WaveOutInit OSS dsp out caps=00000000 trace:wave:OSS_WaveOutInit out dwFormats = 00000FFF, dwSupport = 0000000C trace:wave:OSS_WaveInInit OSS dsp in caps=00000000 trace:wave:OSS_WaveInInit OSS in dsp mask=00000018 trace:wave:OSS_WaveInInit in dwFormats = 00000FFF trace:wave:OSS_widMessage (0, 0064, 00000000, 00000000, 00000000); trace:wave:OSS_widMessage (0, 0032, 00000000, 00000000, 00000000); trace:wave:OSS_wodMessage (0, 0064, 00000000, 00000000, 00000000); trace:wave:OSS_wodMessage (0, 0003, 00000000, 00000000, 00000000); trace:wave:OSS_wodMessage (0, 0005, 417B2C18, 417B2C48, 00030008); trace:wave:wodOpen (0, 0x417b2c48, 00030008); trace:wave:wodPlayer waiting 4294967295ms (4294967295,4294967295) trace:wave:wodOpen fd=12 fragmentSize=1024 trace:wave:wodOpen wBitsPerSample=16, nAvgBytesPerSec=88200, nSamplesPerSec=44100, nChannels=1 nBlockAlign=2! trace:wave:wodNotifyClient wMsg = 0x03bb dwParm1 = 0000 dwParam2 = 0000 trace:wave:OSS_wodMessage (0, 0007, 00000001, 40296160, 00000020); trace:wave:wodPrepare (0, 0x40296160, 00000020); trace:wave:OSS_wodMessage (0, 0007, 00000001, 40296180, 00000020); trace:wave:wodPrepare (0, 0x40296180, 00000020); trace:wave:OSS_wodMessage (0, 0009, 00000001, 40296160, 00000020); trace:wave:wodWrite (0, 0x40296160, 00000020); trace:wave:OSS_wodMessage (0, 0009, 00000001, 40296180, 00000020); trace:wave:wodWrite (0, 0x40296180, 00000020); trace:wave:wodPlayer_ProcessMessages Received WINE_WM_HEADER 40296160 trace:wave:wodPlayer_ProcessMessages Received WINE_WM_HEADER 40296180 trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15998 trace:wave:wodPlayer_FeedDSP Setting time to elapse for 0x40296160 to 29400 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.0[29400]/15998 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=470 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=1/17, fragsize=1024, bytes=1880 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.15998[29400]/1880 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=942 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.17878[29400]/2352 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=1/17, fragsize=1024, bytes=1412 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.20230[29400]/1412 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=940 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.21642[29400]/2352 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=940 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.23994[29400]/2352 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=940 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.26346[29400]/2352 trace:wave:wodPlayer waiting 11ms (11,4294967295) trace:wave:wodPlayer_FeedDSP fragments=1/17, fragsize=1024, bytes=1410 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296160.28698[29400]/702 trace:wave:wodPlayer_FeedDSP Setting time to elapse for 0x40296180 to 34972 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296180.0[5572]/708 trace:wave:wodPlayer waiting 11ms (11,189) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=942 trace:wave:wodPlayer waiting 11ms (11,178) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296180.708[5572]/2352 trace:wave:wodPlayer waiting 11ms (11,162) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=942 trace:wave:wodPlayer waiting 11ms (11,151) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296180.3060[5572]/2352 trace:wave:wodPlayer waiting 11ms (11,136) trace:wave:wodPlayer_FeedDSP fragments=0/17, fragsize=1024, bytes=942 trace:wave:wodPlayer waiting 11ms (11,125) trace:wave:wodPlayer_FeedDSP fragments=2/17, fragsize=1024, bytes=2352 trace:wave:wodPlayer_WriteMaxFrags Writing wavehdr 0x40296180.5412[5572]/160 trace:wave:wodPlayer waiting 11ms (11,109) trace:wave:wodPlayer_FeedDSP fragments=3/17, fragsize=1024, bytes=3134 trace:wave:wodPlayer waiting 11ms (11,98) trace:wave:wodPlayer_FeedDSP fragments=4/17, fragsize=1024, bytes=4544 trace:wave:wodPlayer waiting 11ms (11,82) trace:wave:wodPlayer_FeedDSP fragments=5/17, fragsize=1024, bytes=5956 trace:wave:wodPlayer waiting 11ms (11,66) trace:wave:wodPlayer_FeedDSP fragments=6/17, fragsize=1024, bytes=6896 trace:wave:wodPlayer waiting 11ms (11,56) trace:wave:wodPlayer_FeedDSP fragments=8/17, fragsize=1024, bytes=8308 trace:wave:wodPlayer waiting 11ms (11,40) trace:wave:wodPlayer_FeedDSP fragments=9/17, fragsize=1024, bytes=9248 trace:wave:wodPlayer waiting 11ms (11,29) trace:wave:wodPlayer_FeedDSP fragments=10/17, fragsize=1024, bytes=10660 trace:wave:wodPlayer waiting 11ms (11,13) trace:wave:wodPlayer_FeedDSP fragments=11/17, fragsize=1024, bytes=11600 trace:wave:wodPlayer waiting 2ms (11,2) trace:wave:wodPlayer_FeedDSP fragments=11/17, fragsize=1024, bytes=12072 trace:wave:wodNotifyClient wMsg = 0x03bd dwParm1 = 40296160 dwParam2 = 0000 trace:wave:wodPlayer waiting 11ms (11,60) trace:wave:wodPlayer_FeedDSP fragments=13/17, fragsize=1024, bytes=13482 trace:wave:wodPlayer waiting 11ms (11,44) trace:wave:wodPlayer_FeedDSP fragments=14/17, fragsize=1024, bytes=14894 trace:wave:wodPlayer waiting 11ms (11,28) trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15834 trace:wave:wodPlayer waiting 11ms (11,17) trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15998 trace:wave:wodPlayer waiting 11ms (11,15) trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15998 trace:wave:wodPlayer waiting 11ms (11,15) trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15998 trace:wave:wodPlayer waiting 11ms (11,15) trace:wave:wodPlayer_FeedDSP fragments=15/17, fragsize=1024, bytes=15998 trace:wave:wodPlayer waiting 11ms (11,15) ============ (repeats forever, doesn't exit) =======================
On December 11, 2002 01:48 am, Dan Kegel wrote:
I've tracked it down further. Attached find a trace+wave and a patch that reverts half of Ove's patch from August, thereby "fixing" the problem.
I suggest leaving the noops in, so you minimize the size of the patch, and thus narrow down the bug even further.
For example:
-/* an exact wodGetPosition is usually not worth the extra context switches, - * as we're going to have near fragment accuracy anyway */ -/* #define EXACT_WODPOSITION */
These are comments, can stay.
#include "config.h"
#include <stdlib.h> @@ -130,8 +126,7 @@ */ typedef struct { /* FIXME: this could be made a dynamically growing array (if needed) */ - /* maybe it's needed, a Humongous game manages to transmit 128 messages at once at startup */ -#define OSS_RING_BUFFER_SIZE 192 +#define OSS_RING_BUFFER_SIZE 30
Maybe (?) this one can stay.
opening */ DWORD dwWrittenTotal; /* number of bytes written to OSS buffer since opening */
- BOOL bNeedPost; /* whether audio
This one can stay.
TRACE("fragments=%d/%d, fragsize=%d, bytes=%d\n",
dspspace.fragments, dspspace.fragstotal, dspspace.fragsize,
dspspace.bytes); + dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
This one seems to be just white space change, so it can stay.
wwo->dwPlayedTotal = 0; wwo->dwWrittenTotal = 0;
- wwo->bNeedPost = TRUE;
Can stay.
OSS_InitRingMessage(&wwo->msgRing);
@@ -1568,9 +1541,7 @@ if (lpTime == NULL) return MMSYSERR_INVALPARAM;
wwo = &WOutDev[wDevID];
-#ifdef EXACT_WODPOSITION OSS_AddRingMessage(&wwo->msgRing, WINE_WM_UPDATE, 0, TRUE); -#endif val = wwo->dwPlayedTotal;
Ditto.
Dimitrie O. Paun wrote:
On December 11, 2002 01:48 am, Dan Kegel wrote:
I've tracked it down further. Attached find a trace+wave and a patch that reverts half of Ove's patch from August, thereby "fixing" the problem.
I suggest leaving the noops in, so you minimize the size of the patch, and thus narrow down the bug even further.
Thanks for the encouragement. I think I have it. Here's the smallest reversion that fixes the problem for me:
--- wine-20021125/dlls/winmm/wineoss/audio.c 2002-11-04 14:39:19.000000000 -0800 +++ wine-20021125/dlls/winmm/wineoss/audio.c.spam 2002-12-10 22:57:27.000000000 -0800 @@ -1148,8 +1147,10 @@ dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
/* input queue empty and output buffer with less than one fragment to play */ - if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) { - TRACE("Run out of wavehdr:s...\n"); + if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize) { + TRACE("Run out of wavehdr:s... flushing (%lu => %lu)\n", + wwo->dwPlayedTotal, wwo->dwWrittenTotal); + wwo->dwPlayedTotal = wwo->dwWrittenTotal; return INFINITE; }
Can someone who understands the code comment?
Thanks, Dan
On December 11, 2002 02:20 am, Dan Kegel wrote:
/* input queue empty and output buffer with less than one fragment to play */
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) {
TRACE("Run out of wavehdr:s...\n");
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize) {
TRACE("Run out of wavehdr:s... flushing (%lu => %lu)\n",
wwo->dwPlayedTotal, wwo->dwWrittenTotal);
wwo->dwPlayedTotal = wwo->dwWrittenTotal; return INFINITE; }
Can someone who understands the code comment?
I don't, never looked at audio code before, but the above has two changes:
The condition has the '2 *' bit in it, and the body of the if has + wwo->dwPlayedTotal = wwo->dwWrittenTotal; The TRACEs are noops, can be ignored.
So I suggest trying them out individually, to see which one causes the problem (or maybe they can not be separated). Experimentation will tell. :)
Dimitrie O. Paun wrote:
On December 11, 2002 02:20 am, Dan Kegel wrote:
/* input queue empty and output buffer with less than one fragment to play */
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) {
TRACE("Run out of wavehdr:s...\n");
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize) {
TRACE("Run out of wavehdr:s... flushing (%lu => %lu)\n",
wwo->dwPlayedTotal, wwo->dwWrittenTotal);
}wwo->dwPlayedTotal = wwo->dwWrittenTotal; return INFINITE;
Can someone who understands the code comment?
I don't, never looked at audio code before, but the above has two changes:
The condition has the '2 *' bit in it, and the body of the if has
wwo->dwPlayedTotal = wwo->dwWrittenTotal;
The TRACEs are noops, can be ignored.
So I suggest trying them out individually, to see which one causes the problem (or maybe they can not be separated). Experimentation will tell. :)
I tried each individually, and neither helped. Only the two changes together yielded a wine that properly terminated when I clicked on the "Exit" button in msvc4++'s installer. - Dan
Can someone who understands the code comment?
I don't, never looked at audio code before, but the above has two changes:
The condition has the '2 *' bit in it, and the body of the if has
wwo->dwPlayedTotal = wwo->dwWrittenTotal;
The TRACEs are noops, can be ignored.
So I suggest trying them out individually, to see which one causes the problem (or maybe they can not be separated). Experimentation will tell. :)
I tried each individually, and neither helped. Only the two changes together yielded a wine that properly terminated when I clicked on the "Exit" button in msvc4++'s installer.
- Dan
a more complete fix should be included could you try if it works fine ?
A+
Index: dlls/winmm/wineoss/audio.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/wineoss/audio.c,v retrieving revision 1.65 diff -u -r1.65 audio.c --- dlls/winmm/wineoss/audio.c 4 Nov 2002 22:39:19 -0000 1.65 +++ dlls/winmm/wineoss/audio.c 11 Dec 2002 20:21:45 -0000 @@ -1147,8 +1171,12 @@ TRACE("fragments=%d/%d, fragsize=%d, bytes=%d\n", dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
- /* input queue empty and output buffer with less than one fragment to play */ - if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) { + /* input queue empty and output buffer with less than one fragment to play + * actually some cards do not play the fragment before the last if this one is partially feed + * so we need to test for full the availability of 2 fragments + */ + if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize && + !wwo->bNeedPost) { TRACE("Run out of wavehdr:s...\n"); return INFINITE; } @@ -1216,8 +1244,8 @@ TRACE("flushing\n"); ioctl(wwo->ossdev->fd, SNDCTL_DSP_SYNC, 0); wwo->dwPlayedTotal = wwo->dwWrittenTotal; - } - else { + dwNextNotifyTime = wodPlayer_NotifyCompletions(wwo, FALSE); + } else { TRACE("recovering\n"); dwNextFeedTime = wodPlayer_FeedDSP(wwo); }
Eric Pouech wrote:
I tried each individually, and neither helped. Only the two changes together yielded a wine that properly terminated when I clicked on the "Exit" button in msvc4++'s installer.
- Dan
a more complete fix should be included could you try if it works fine ?
It does, thanks!
Now on to figuring out why none of the *other* buttons in the installer do anything :-( - Dan
Index: dlls/winmm/wineoss/audio.c
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/wineoss/audio.c,v retrieving revision 1.65 diff -u -r1.65 audio.c --- dlls/winmm/wineoss/audio.c 4 Nov 2002 22:39:19 -0000 1.65 +++ dlls/winmm/wineoss/audio.c 11 Dec 2002 20:21:45 -0000 @@ -1147,8 +1171,12 @@ TRACE("fragments=%d/%d, fragsize=%d, bytes=%d\n", dspspace.fragments, dspspace.fragstotal, dspspace.fragsize, dspspace.bytes);
- /* input queue empty and output buffer with less than one fragment to play */
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + wwo->dwFragmentSize) {
- /* input queue empty and output buffer with less than one fragment to play
* actually some cards do not play the fragment before the last if this one is partially feed
* so we need to test for full the availability of 2 fragments
*/
- if (!wwo->lpPlayPtr && wwo->dwBufferSize < availInQ + 2 * wwo->dwFragmentSize &&
TRACE("Run out of wavehdr:s...\n"); return INFINITE; }!wwo->bNeedPost) {
@@ -1216,8 +1244,8 @@ TRACE("flushing\n"); ioctl(wwo->ossdev->fd, SNDCTL_DSP_SYNC, 0); wwo->dwPlayedTotal = wwo->dwWrittenTotal;
}
else {
dwNextNotifyTime = wodPlayer_NotifyCompletions(wwo, FALSE);
TRACE("recovering\n"); dwNextFeedTime = wodPlayer_FeedDSP(wwo); }} else {