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) =======================