ReactOS 0.4.15-dev-5865-g640e228
playsound.c File Reference
#include "winemm.h"
#include <winternl.h>
Include dependency graph for playsound.c:

Go to the source code of this file.

Classes

struct  tagWINE_PLAYSOUND
 
struct  playsound_data
 

Typedefs

typedef struct tagWINE_PLAYSOUND WINE_PLAYSOUND
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (winmm)
 
static HMMIO get_mmioFromFile (LPCWSTR lpszName)
 
static HMMIO get_mmioFromProfile (UINT uFlags, LPCWSTR lpszName)
 
static void CALLBACK PlaySound_Callback (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 
static void PlaySound_WaitDone (struct playsound_data *s)
 
static BOOL PlaySound_IsString (DWORD fdwSound, const void *psz)
 
static void PlaySound_Free (WINE_PLAYSOUND *wps)
 
static WINE_PLAYSOUNDPlaySound_Alloc (const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
 
static DWORD WINAPI proc_PlaySound (LPVOID arg)
 
static BOOL MULTIMEDIA_PlaySound (const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
 
BOOL WINAPI PlaySoundA (LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound)
 
BOOL WINAPI PlaySoundW (LPCWSTR pszSoundW, HMODULE hmod, DWORD fdwSound)
 
BOOL WINAPI sndPlaySoundA (LPCSTR pszSoundA, UINT uFlags)
 
BOOL WINAPI sndPlaySoundW (LPCWSTR pszSound, UINT uFlags)
 
UINT WINAPI mmsystemGetVersion (void)
 

Variables

static WINE_PLAYSOUNDPlaySoundList
 

Typedef Documentation

◆ WINE_PLAYSOUND

Function Documentation

◆ get_mmioFromFile()

static HMMIO get_mmioFromFile ( LPCWSTR  lpszName)
static

Definition at line 44 of file playsound.c.

45{
46 HMMIO ret;
47 WCHAR buf[256];
49
50 ret = mmioOpenW((LPWSTR)lpszName, NULL,
52 if (ret != 0) return ret;
53 if (SearchPathW(NULL, lpszName, NULL, sizeof(buf)/sizeof(buf[0]), buf, &dummy))
54 {
55 return mmioOpenW(buf, NULL,
57 }
58 return 0;
59}
#define NULL
Definition: types.h:112
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:670
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
#define MMIO_READ
Definition: mmsystem.h:535
int ret
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by proc_PlaySound().

◆ get_mmioFromProfile()

static HMMIO get_mmioFromProfile ( UINT  uFlags,
LPCWSTR  lpszName 
)
static

Definition at line 61 of file playsound.c.

62{
63 WCHAR str[128];
64 LPWSTR ptr;
65 HMMIO hmmio;
66 HKEY hRegSnd, hRegApp, hScheme, hSnd;
68
69 static const WCHAR wszSounds[] = {'S','o','u','n','d','s',0};
70 static const WCHAR wszDefault[] = {'D','e','f','a','u','l','t',0};
71 static const WCHAR wszKey[] = {'A','p','p','E','v','e','n','t','s','\\',
72 'S','c','h','e','m','e','s','\\',
73 'A','p','p','s',0};
74 static const WCHAR wszDotDefault[] = {'.','D','e','f','a','u','l','t',0};
75 static const WCHAR wszDotCurrent[] = {'.','C','u','r','r','e','n','t',0};
76 static const WCHAR wszNull[] = {0};
77
78 TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName));
79 GetProfileStringW(wszSounds, lpszName, wszNull, str, sizeof(str)/sizeof(str[0]));
80 if (lstrlenW(str) == 0)
81 {
82 if (uFlags & SND_NODEFAULT) goto next;
83 GetProfileStringW(wszSounds, wszDefault, wszNull, str, sizeof(str)/sizeof(str[0]));
84 if (lstrlenW(str) == 0) goto next;
85 }
86 for (ptr = str; *ptr && *ptr != ','; ptr++);
87 if (*ptr) *ptr = 0;
89 if (hmmio != 0) return hmmio;
90 next:
91 /* we look up the registry under
92 * HKCU\AppEvents\Schemes\Apps\.Default
93 * HKCU\AppEvents\Schemes\Apps<AppName>
94 */
95 if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none;
97 {
98 DWORD len;
99
100 err = 1; /* error */
101 len = GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0]));
102 if (len > 0 && len < sizeof(str)/sizeof(str[0]))
103 {
104 for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
105 {
106 if (*ptr == '.') *ptr = 0;
107 if (*ptr == '\\')
108 {
109 err = RegOpenKeyW(hRegSnd, ptr+1, &hRegApp);
110 break;
111 }
112 }
113 }
114 }
115 else
116 {
117 err = RegOpenKeyW(hRegSnd, wszDotDefault, &hRegApp);
118 }
119 RegCloseKey(hRegSnd);
120 if (err != 0) goto none;
121 err = RegOpenKeyW(hRegApp, lpszName, &hScheme);
122 RegCloseKey(hRegApp);
123 if (err != 0) goto none;
124 /* what's the difference between .Current and .Default ? */
125 err = RegOpenKeyW(hScheme, wszDotDefault, &hSnd);
126 if (err != 0)
127 {
128 err = RegOpenKeyW(hScheme, wszDotCurrent, &hSnd);
129 RegCloseKey(hScheme);
130 if (err != 0)
131 goto none;
132 }
133 count = sizeof(str);
134 err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count);
135 RegCloseKey(hSnd);
136 if (err != 0 || !*str) goto none;
138 if (hmmio) return hmmio;
139 none:
140 WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName));
141 return 0;
142}
#define WARN(fmt,...)
Definition: debug.h:112
#define RegCloseKey(hKey)
Definition: registry.h:47
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3291
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4121
UINT uFlags
Definition: api.c:59
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
INT WINAPI GetProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len)
Definition: profile.c:1267
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_w
Definition: kernel32.h:32
#define SND_NODEFAULT
Definition: mmsystem.h:155
#define SND_APPLICATION
Definition: mmsystem.h:165
static PVOID ptr
Definition: dispmode.c:27
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
const WCHAR * str
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char * LPBYTE
Definition: typedefs.h:53
#define HKEY_CURRENT_USER
Definition: winreg.h:11

Referenced by proc_PlaySound().

◆ mmsystemGetVersion()

UINT WINAPI mmsystemGetVersion ( void  )

Definition at line 557 of file playsound.c.

558{
559 TRACE("3.10 (Win95?)\n");
560 return 0x030a;
561}

◆ MULTIMEDIA_PlaySound()

static BOOL MULTIMEDIA_PlaySound ( const void pszSound,
HMODULE  hmod,
DWORD  fdwSound,
BOOL  bUnicode 
)
static

Definition at line 457 of file playsound.c.

458{
459 WINE_PLAYSOUND* wps = NULL;
460
461 TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n",
462 pszSound, hmod, fdwSound);
463
464 /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
465 * there could be one if several sounds can be played at once...
466 */
467 if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySoundList != NULL)
468 return FALSE;
469
470 /* alloc internal structure, if we need to play something */
471 if (pszSound && !(fdwSound & SND_PURGE))
472 {
473 if (!(wps = PlaySound_Alloc(pszSound, hmod, fdwSound, bUnicode)))
474 return FALSE;
475 }
476
478 /* since several threads can enter PlaySound in parallel, we're not
479 * sure, at this point, that another thread didn't start a new playsound
480 */
481 while (PlaySoundList != NULL)
482 {
484 /* FIXME: doc says we have to stop all instances of pszSound if it's non
485 * NULL... as of today, we stop all playing instances */
487
492
494 }
495
496 if (wps) wps->lpNext = PlaySoundList;
497 PlaySoundList = wps;
499
500 if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
501
502 if (fdwSound & SND_ASYNC)
503 {
504 DWORD id;
506 wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
507 if ((handle = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0) {
508 wps->hThread = handle;
510 return TRUE;
511 }
512 }
513 else return proc_PlaySound(wps);
514
515 /* error cases */
516 PlaySound_Free(wps);
517 return FALSE;
518}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define INFINITE
Definition: serial.h:102
GLuint id
Definition: glext.h:5910
#define SND_NOWAIT
Definition: mmsystem.h:159
#define SND_PURGE
Definition: mmsystem.h:164
#define SND_LOOP
Definition: mmsystem.h:157
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_NOSTOP
Definition: mmsystem.h:158
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static WINE_PLAYSOUND * PlaySound_Alloc(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:212
static void PlaySound_Free(WINE_PLAYSOUND *wps)
Definition: playsound.c:198
static DWORD WINAPI proc_PlaySound(LPVOID arg)
Definition: playsound.c:255
static WINE_PLAYSOUND * PlaySoundList
Definition: playsound.c:42
struct tagWINE_PLAYSOUND * lpNext
Definition: playsound.c:39
unsigned bLoop
Definition: playsound.c:32
HWAVEOUT hWave
Definition: playsound.c:38
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:281
HANDLE psLastEvent
Definition: winmm.c:51
HANDLE psStopEvent
Definition: winmm.c:52
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:54
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388

Referenced by PlaySoundA(), PlaySoundW(), sndPlaySoundA(), and sndPlaySoundW().

◆ PlaySound_Alloc()

static WINE_PLAYSOUND * PlaySound_Alloc ( const void pszSound,
HMODULE  hmod,
DWORD  fdwSound,
BOOL  bUnicode 
)
static

Definition at line 212 of file playsound.c.

214{
215 WINE_PLAYSOUND* wps;
216
217 wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps));
218 if (!wps) return NULL;
219
220 wps->hMod = hmod;
221 wps->fdwSound = fdwSound;
222 if (PlaySound_IsString(fdwSound, pszSound))
223 {
224 if (bUnicode)
225 {
226 if (fdwSound & SND_ASYNC)
227 {
228 LPWSTR sound = HeapAlloc(GetProcessHeap(), 0,
229 (lstrlenW(pszSound)+1) * sizeof(WCHAR));
230 if (!sound) goto oom_error;
231 wps->pszSound = lstrcpyW(sound, pszSound);
232 wps->bAlloc = TRUE;
233 }
234 else
235 wps->pszSound = pszSound;
236 }
237 else
238 {
239 UNICODE_STRING usBuffer;
240 RtlCreateUnicodeStringFromAsciiz(&usBuffer, pszSound);
241 wps->pszSound = usBuffer.Buffer;
242 if (!wps->pszSound) goto oom_error;
243 wps->bAlloc = TRUE;
244 }
245 }
246 else
247 wps->pszSound = pszSound;
248
249 return wps;
250 oom_error:
251 PlaySound_Free(wps);
252 return NULL;
253}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define lstrcpyW
Definition: compat.h:749
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
static BOOL PlaySound_IsString(DWORD fdwSound, const void *psz)
Definition: playsound.c:181
unsigned bAlloc
Definition: playsound.c:33
LPCWSTR pszSound
Definition: playsound.c:34

Referenced by MULTIMEDIA_PlaySound().

◆ PlaySound_Callback()

static void CALLBACK PlaySound_Callback ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
DWORD_PTR  dwParam1,
DWORD_PTR  dwParam2 
)
static

Definition at line 150 of file playsound.c.

153{
154 struct playsound_data* s = (struct playsound_data*)dwInstance;
155
156 switch (uMsg) {
157 case WOM_OPEN:
158 case WOM_CLOSE:
159 break;
160 case WOM_DONE:
161 InterlockedIncrement(&s->dwEventCount);
162 TRACE("Returning waveHdr=%lx\n", dwParam1);
163 SetEvent(s->hEvent);
164 break;
165 default:
166 ERR("Unknown uMsg=%d\n", uMsg);
167 }
168}
#define InterlockedIncrement
Definition: armddk.h:53
#define ERR(fmt,...)
Definition: debug.h:110
GLdouble s
Definition: gl.h:2039
#define WOM_DONE
Definition: mmsystem.h:183
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182

Referenced by proc_PlaySound().

◆ PlaySound_Free()

static void PlaySound_Free ( WINE_PLAYSOUND wps)
static

Definition at line 198 of file playsound.c.

199{
201
203 for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext));
204 if (*p) *p = (*p)->lpNext;
207 if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
208 if (wps->hThread) CloseHandle(wps->hThread);
209 HeapFree(GetProcessHeap(), 0, wps);
210}
#define CloseHandle
Definition: compat.h:739
#define HeapFree(x, y, z)
Definition: compat.h:735
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by MULTIMEDIA_PlaySound(), PlaySound_Alloc(), and proc_PlaySound().

◆ PlaySound_IsString()

static BOOL PlaySound_IsString ( DWORD  fdwSound,
const void psz 
)
static

Definition at line 181 of file playsound.c.

182{
183 /* SND_RESOURCE is 0x40004 while
184 * SND_MEMORY is 0x00004
185 */
186 switch (fdwSound & (SND_RESOURCE|SND_ALIAS_ID|SND_FILENAME))
187 {
188 case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
189 case SND_ALIAS_ID:
190 case SND_MEMORY: return FALSE;
191 case SND_ALIAS:
192 case SND_FILENAME:
193 case 0: return TRUE;
194 default: FIXME("WTF\n"); return FALSE;
195 }
196}
#define FIXME(fmt,...)
Definition: debug.h:111
#define SND_RESOURCE
Definition: mmsystem.h:163
#define SND_FILENAME
Definition: mmsystem.h:162
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define SND_MEMORY
Definition: mmsystem.h:156
#define SND_ALIAS
Definition: mmsystem.h:160
#define HIWORD(l)
Definition: typedefs.h:247

Referenced by PlaySound_Alloc().

◆ PlaySound_WaitDone()

static void PlaySound_WaitDone ( struct playsound_data s)
static

Definition at line 170 of file playsound.c.

171{
172 for (;;) {
173 ResetEvent(s->hEvent);
174 if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
175 InterlockedIncrement(&s->dwEventCount);
176
178 }
179}
#define InterlockedDecrement
Definition: armddk.h:52

Referenced by proc_PlaySound().

◆ PlaySoundA()

BOOL WINAPI PlaySoundA ( LPCSTR  pszSoundA,
HMODULE  hmod,
DWORD  fdwSound 
)

Definition at line 523 of file playsound.c.

524{
525 return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE);
526}
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:457

Referenced by test_PlaySound().

◆ PlaySoundW()

BOOL WINAPI PlaySoundW ( LPCWSTR  pszSoundW,
HMODULE  hmod,
DWORD  fdwSound 
)

◆ proc_PlaySound()

static DWORD WINAPI proc_PlaySound ( LPVOID  arg)
static

Definition at line 255 of file playsound.c.

256{
257 WINE_PLAYSOUND* wps = arg;
258 BOOL bRet = FALSE;
259 HMMIO hmmio = 0;
260 MMCKINFO ckMainRIFF;
261 MMCKINFO mmckInfo;
262 LPWAVEFORMATEX lpWaveFormat = NULL;
263 LPWAVEHDR waveHdr = NULL;
265 struct playsound_data s;
266 void* data;
267
268 s.hEvent = 0;
269
270 TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound));
271
272 /* if resource, grab it */
273 if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
274 static const WCHAR wszWave[] = {'W','A','V','E',0};
275 HRSRC hRes;
276 HGLOBAL hGlob;
277
278 if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 ||
279 (hGlob = LoadResource(wps->hMod, hRes)) == 0)
280 goto errCleanUp;
281 if ((data = LockResource(hGlob)) == NULL) {
282 FreeResource(hGlob);
283 goto errCleanUp;
284 }
285 FreeResource(hGlob);
286 } else
287 data = (void*)wps->pszSound;
288
289 /* construct an MMIO stream (either in memory, or from a file */
290 if (wps->fdwSound & SND_MEMORY)
291 { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
292 MMIOINFO mminfo;
293
294 memset(&mminfo, 0, sizeof(mminfo));
295 mminfo.fccIOProc = FOURCC_MEM;
296 mminfo.pchBuffer = data;
297 mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
298 TRACE("Memory sound %p\n", data);
299 hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
300 }
301 else if (wps->fdwSound & SND_ALIAS)
302 {
303 if ((wps->fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID)
304 {
305 static const WCHAR wszSystemAsterisk[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0};
306 static const WCHAR wszSystemDefault[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t',0};
307 static const WCHAR wszSystemExclamation[] = {'S','y','s','t','e','m','E','x','c','l','a','m','a','t','i','o','n',0};
308 static const WCHAR wszSystemExit[] = {'S','y','s','t','e','m','E','x','i','t',0};
309 static const WCHAR wszSystemHand[] = {'S','y','s','t','e','m','H','a','n','d',0};
310 static const WCHAR wszSystemQuestion[] = {'S','y','s','t','e','m','Q','u','e','s','t','i','o','n',0};
311 static const WCHAR wszSystemStart[] = {'S','y','s','t','e','m','S','t','a','r','t',0};
312 static const WCHAR wszSystemWelcome[] = {'S','y','s','t','e','m','W','e','l','c','o','m','e',0};
313
314 wps->fdwSound &= ~(SND_ALIAS_ID ^ SND_ALIAS);
316 wps->pszSound = wszSystemAsterisk;
318 wps->pszSound = wszSystemDefault;
320 wps->pszSound = wszSystemExclamation;
322 wps->pszSound = wszSystemExit;
324 wps->pszSound = wszSystemHand;
326 wps->pszSound = wszSystemQuestion;
328 wps->pszSound = wszSystemStart;
330 wps->pszSound = wszSystemWelcome;
331 else goto errCleanUp;
332 }
333 hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
334 }
335 else if (wps->fdwSound & SND_FILENAME)
336 {
337 hmmio = get_mmioFromFile(wps->pszSound);
338 }
339 else
340 {
341 if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0)
342 {
343 if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0)
344 {
345 hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
346 }
347 }
348 }
349 if (hmmio == 0) goto errCleanUp;
350
351 if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
352 goto errCleanUp;
353
354 TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
355 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
356
357 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
358 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
359 goto errCleanUp;
360
361 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
362 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
363 goto errCleanUp;
364
365 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
366 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
367
368 lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
369 if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(PCMWAVEFORMAT))
370 goto errCleanUp;
371
372 TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
373 TRACE("nChannels=%d\n", lpWaveFormat->nChannels);
374 TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec);
375 TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec);
376 TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign);
377 TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
378
379 /* move to end of 'fmt ' chunk */
380 mmioAscend(hmmio, &mmckInfo, 0);
381
382 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
383 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
384 goto errCleanUp;
385
386 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
387 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
388
389 s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
390
391 if (waveOutOpen(&wps->hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
393 goto errCleanUp;
394
395 /* make it so that 3 buffers per second are needed */
396 bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
397 lpWaveFormat->nBlockAlign;
398 waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
399 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
400 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
401 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
402 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
403 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
404 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
405 if (waveOutPrepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
406 waveOutPrepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
407 goto errCleanUp;
408 }
409
410 s.dwEventCount = 1L; /* for first buffer */
411 index = 0;
412
413 do {
414 left = mmckInfo.cksize;
415
416 mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
417 while (left)
418 {
420 {
421 wps->bLoop = FALSE;
422 break;
423 }
424 count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left));
425 if (count < 1) break;
426 left -= count;
427 waveHdr[index].dwBufferLength = count;
428 waveHdr[index].dwFlags &= ~WHDR_DONE;
429 if (waveOutWrite(wps->hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
430 index ^= 1;
432 }
433 else FIXME("Couldn't play header\n");
434 }
435 bRet = TRUE;
436 } while (wps->bLoop);
437
438 PlaySound_WaitDone(&s); /* for last buffer */
439 waveOutReset(wps->hWave);
440
441 waveOutUnprepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR));
442 waveOutUnprepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR));
443
444errCleanUp:
445 TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
446 CloseHandle(s.hEvent);
447 HeapFree(GetProcessHeap(), 0, waveHdr);
448 HeapFree(GetProcessHeap(), 0, lpWaveFormat);
449 if (wps->hWave) while (waveOutClose(wps->hWave) == WAVERR_STILLPLAYING) Sleep(100);
450 if (hmmio) mmioClose(hmmio, 0);
451
452 PlaySound_Free(wps);
453
454 return bRet;
455}
#define index(s, c)
Definition: various.h:29
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:702
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint index
Definition: glext.h:6031
GLint left
Definition: glext.h:7726
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define SEEK_SET
Definition: jmemansi.c:26
if(dx< 0)
Definition: linetemp.h:194
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
struct wavehdr_tag WAVEHDR
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define SND_ALIAS_SYSTEMEXCLAMATION
Definition: mmsystem.h:174
#define SND_ALIAS_SYSTEMSTART
Definition: mmsystem.h:172
#define SND_ALIAS_SYSTEMDEFAULT
Definition: mmsystem.h:175
#define SND_ALIAS_SYSTEMHAND
Definition: mmsystem.h:170
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define SND_ALIAS_SYSTEMEXIT
Definition: mmsystem.h:171
#define SND_ALIAS_SYSTEMWELCOME
Definition: mmsystem.h:173
#define FOURCC_MEM
Definition: mmsystem.h:567
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define SND_ALIAS_SYSTEMQUESTION
Definition: mmsystem.h:169
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
char * HPSTR
Definition: mmsystem.h:1477
#define SND_ALIAS_SYSTEMASTERISK
Definition: mmsystem.h:168
#define min(a, b)
Definition: monoChain.cc:55
#define L(x)
Definition: ntvdm.h:50
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: playsound.c:150
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
Definition: playsound.c:44
static void PlaySound_WaitDone(struct playsound_data *s)
Definition: playsound.c:170
static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
Definition: playsound.c:61
#define memset(x, y, z)
Definition: compat.h:39
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
FOURCC fccType
Definition: mmsystem.h:1509
LONG cchBuffer
Definition: mmsystem.h:1491
HPSTR pchBuffer
Definition: mmsystem.h:1492
FOURCC fccIOProc
Definition: mmsystem.h:1487
DWORD dwBufferLength
Definition: mmsystem.h:1015
DWORD dwLoops
Definition: mmsystem.h:1019
DWORD dwFlags
Definition: mmsystem.h:1018
DWORD_PTR dwUser
Definition: mmsystem.h:1017
LPSTR lpData
Definition: mmsystem.h:1014
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define WAIT_OBJECT_0
Definition: winbase.h:406
void * arg
Definition: msvc.h:10
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
char * LPSTR
Definition: xmlstorage.h:182
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by MULTIMEDIA_PlaySound().

◆ sndPlaySoundA()

BOOL WINAPI sndPlaySoundA ( LPCSTR  pszSoundA,
UINT  uFlags 
)

Definition at line 539 of file playsound.c.

Referenced by test_sndPlaySound().

◆ sndPlaySoundW()

BOOL WINAPI sndPlaySoundW ( LPCWSTR  pszSound,
UINT  uFlags 
)

Definition at line 548 of file playsound.c.

Referenced by test_sndPlaySound().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( winmm  )

Variable Documentation

◆ PlaySoundList

WINE_PLAYSOUND* PlaySoundList
static

Definition at line 42 of file playsound.c.

Referenced by MULTIMEDIA_PlaySound(), and PlaySound_Free().