[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    winmm: PlaySound SND_ASYNC fix
From:       "Vedran Rodic" <vrodic () gmail ! com>
Date:       2007-05-28 14:38:29
Message-ID: 8ccf2e9c0705280738i2054e748u1314a95272a1f38 () mail ! gmail ! com
[Download RAW message or body]

Hi, this patch is still not applied though I've submitted it last
Wednesday. I guess it's not obviously clear that it is correct, so I'm
asking for a review here. I've peronally tested it with alsa and oss
sound backends. It specifically fixes one series of Croatian child
educational games named "Suncica".

Detailed info:

Applications expect PlaySound() not to block when called with
SND_ASYNC flag. However, if a sound is currently playing, there is a
real chance of PlaySound() blocking for up to 1/3 of a second (size of
the playsound buffer), because of a sound buffer waiting to be played.
This patch adds a hWave field in the WINE_PLAYSOUND internal struct in
winemm.h so that MULTIMEDIA_PlaySound() function can call waveOutReset
when a sound is already playing to quickly remove it from the sound
system. Another scenario is when application wants to quickly  stop a
currently playing sound at a specific time. Blocking behaviour isn't
necessarily a problem for such applications, but playing the sound for
additional 300 miliseconds could be.

ChangeLog entry:
Vedran Rodic <vrodic@gmail.com>
- fix PlaySound so it doesn't block when another sound is already playing.

Thanks

["playsound.diff" (text/x-diff)]

diff --git a/dlls/winmm/playsound.c b/dlls/winmm/playsound.c
index 3a5dc1f..1601ecb 100644
--- a/dlls/winmm/playsound.c
+++ b/dlls/winmm/playsound.c
@@ -357,6 +357,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
     if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback,
 		    (DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
 	goto errCleanUp;
+    wps->hWave = hWave;
 
     /* make it so that 3 buffers per second are needed */
     bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
@@ -451,6 +452,7 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
          * NULL... as of today, we stop all playing instances */
         SetEvent(WINMM_IData.psStopEvent);
 
+        waveOutReset(WINMM_IData.lpPlaySound->hWave);
         LeaveCriticalSection(&WINMM_IData.cs);
         WaitForSingleObject(WINMM_IData.psLastEvent, INFINITE);
         EnterCriticalSection(&WINMM_IData.cs);
diff --git a/dlls/winmm/winemm.h b/dlls/winmm/winemm.h
index ef90d32..004714b 100644
--- a/dlls/winmm/winemm.h
+++ b/dlls/winmm/winemm.h
@@ -192,6 +192,7 @@ typedef struct tagWINE_PLAYSOUND {
     HMODULE		        hMod;
     DWORD		        fdwSound;
     HANDLE                      hThread;
+    HWAVEOUT                    hWave;
     struct tagWINE_PLAYSOUND*   lpNext;
 } WINE_PLAYSOUND, *LPWINE_PLAYSOUND;
 




[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic