- Timestamp:
- Mar 24, 2001, 2:23:48 PM (24 years ago)
- Location:
- trunk/src/winmm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/winmm/playsound.cpp
r3473 r5364 1 /* $Id: playsound.cpp,v 1. 6 2000-05-02 13:29:59 birdExp $ */1 /* $Id: playsound.cpp,v 1.7 2001-03-24 13:23:48 sandervl Exp $ */ 2 2 3 3 /* 4 * Playsound stubs 5 * 6 * Copyright 1998 Joel Troster 7 * 4 * Playsound implementation 5 * 6 * Wine port (winmm\mmsystem.c) 7 * 8 * Copyright 1993 Martin Ayotte 9 * Eric POUECH 8 10 * 9 11 * Project Odin Software License can be found in LICENSE.TXT … … 16 18 ****************************************************************************/ 17 19 18 #define INCL_BASE 19 #define INCL_OS2MM 20 #include <os2wrap.h> //Odin32 OS/2 api wrappers 20 #include <os2win.h> 21 21 #include <odinwrap.h> 22 #include < win32type.h>23 #include < winconst.h>22 #include <mmsystem.h> 23 #include <heapstring.h> 24 24 #include <misc.h> 25 #include <string.h> 26 #include <win\debugtools.h> 25 27 26 28 #define DBG_LOCALLOG DBG_playsound 27 29 #include "dbglocal.h" 28 30 29 //kso: dirty fix to make this compile! not permanent!30 BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *);31 #define LowPart u.LowPart32 33 34 31 ODINDEBUGCHANNEL(WINMM-PLAYSOUND) 32 33 34 static HANDLE PlaySound_hThread = 0; 35 static HANDLE PlaySound_hPlayEvent = 0; 36 static HANDLE PlaySound_hReadyEvent = 0; 37 static HANDLE PlaySound_hMiddleEvent = 0; 38 static BOOL PlaySound_Result = FALSE; 39 static int PlaySound_Stop = FALSE; 40 static int PlaySound_Playing = FALSE; 41 42 static LPCSTR PlaySound_pszSound = NULL; 43 static HMODULE PlaySound_hmod = 0; 44 static DWORD PlaySound_fdwSound = 0; 45 static int PlaySound_Loop = FALSE; 46 static int PlaySound_SearchMode = 0; /* 1 - sndPlaySound search order 47 2 - PlaySound order */ 48 49 static HMMIO get_mmioFromFile(LPCSTR lpszName) 50 { 51 return mmioOpenA((LPSTR)lpszName, NULL, 52 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 53 } 54 55 static HMMIO get_mmioFromProfile(UINT uFlags, LPCSTR lpszName) 56 { 57 char str[128]; 58 LPSTR ptr; 59 HMMIO hmmio; 60 61 TRACE("searching in SystemSound List !\n"); 62 GetProfileStringA("Sounds", (LPSTR)lpszName, "", str, sizeof(str)); 63 if (strlen(str) == 0) { 64 if (uFlags & SND_NODEFAULT) return 0; 65 GetProfileStringA("Sounds", "Default", "", str, sizeof(str)); 66 if (strlen(str) == 0) return 0; 67 } 68 if ((ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0'; 69 hmmio = get_mmioFromFile(str); 70 if (hmmio == 0) { 71 WARN("can't find SystemSound='%s' !\n", str); 72 return 0; 73 } 74 return hmmio; 75 } 76 77 struct playsound_data { 78 HANDLE hEvent; 79 DWORD dwEventCount; 80 }; 81 82 static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg, 83 DWORD dwInstance, 84 DWORD dwParam1, DWORD dwParam2) 85 { 86 struct playsound_data* s = (struct playsound_data*)dwInstance; 87 88 switch (uMsg) { 89 case WOM_OPEN: 90 case WOM_CLOSE: 91 break; 92 case WOM_DONE: 93 InterlockedIncrement((LPLONG)&s->dwEventCount); 94 TRACE("Returning waveHdr=%lx\n", dwParam1); 95 SetEvent(s->hEvent); 96 break; 97 default: 98 ERR("Unknown uMsg=%d\n", uMsg); 99 } 100 } 101 102 static void PlaySound_WaitDone(struct playsound_data* s) 103 { 104 for (;;) { 105 ResetEvent(s->hEvent); 106 if (InterlockedDecrement((LPLONG)&s->dwEventCount) >= 0) { 107 break; 108 } 109 InterlockedIncrement((LPLONG)&s->dwEventCount); 110 111 WaitForSingleObject(s->hEvent, INFINITE); 112 } 113 } 114 115 static BOOL WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT uFlags) 116 { 117 BOOL bRet = FALSE; 118 HMMIO hmmio = 0; 119 MMCKINFO ckMainRIFF; 120 MMCKINFO mmckInfo; 121 LPWAVEFORMATEX lpWaveFormat = NULL; 122 HWAVE hWave = 0; 123 LPWAVEHDR waveHdr = NULL; 124 INT count, bufsize, left, index; 125 struct playsound_data s; 126 127 s.hEvent = 0; 128 129 TRACE("SoundName='%s' uFlags=%04X !\n", lpszSoundName, uFlags); 130 if (lpszSoundName == NULL) { 131 TRACE("Stop !\n"); 132 return FALSE; 133 } 134 if (uFlags & SND_MEMORY) { 135 MMIOINFO mminfo; 136 memset(&mminfo, 0, sizeof(mminfo)); 137 mminfo.fccIOProc = FOURCC_MEM; 138 mminfo.pchBuffer = (LPSTR)lpszSoundName; 139 mminfo.cchBuffer = -1; 140 TRACE("Memory sound %p\n", lpszSoundName); 141 hmmio = mmioOpenA(NULL, &mminfo, MMIO_READ); 142 } else { 143 hmmio = 0; 144 if (uFlags & SND_ALIAS) 145 if ((hmmio = get_mmioFromProfile(uFlags, lpszSoundName)) == 0) 146 return FALSE; 147 148 if (uFlags & SND_FILENAME) 149 if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0) return FALSE; 150 151 if (PlaySound_SearchMode == 1) { 152 PlaySound_SearchMode = 0; 153 if ((hmmio = get_mmioFromFile(lpszSoundName)) == 0) 154 hmmio = get_mmioFromProfile(uFlags, lpszSoundName); 155 } 156 157 if (PlaySound_SearchMode == 2) { 158 PlaySound_SearchMode = 0; 159 if ((hmmio = get_mmioFromProfile(uFlags | SND_NODEFAULT, lpszSoundName)) == 0) 160 if ((hmmio = get_mmioFromFile(lpszSoundName)) == 0) 161 hmmio = get_mmioFromProfile(uFlags, lpszSoundName); 162 } 163 } 164 if (hmmio == 0) return FALSE; 165 166 if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0)) 167 goto errCleanUp; 168 169 TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n", 170 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize); 171 172 if ((ckMainRIFF.ckid != FOURCC_RIFF) || 173 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) 174 goto errCleanUp; 175 176 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' '); 177 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK)) 178 goto errCleanUp; 179 180 TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n", 181 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize); 182 183 lpWaveFormat = (WAVEFORMATEX*)HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); 184 if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(WAVEFORMAT)) 185 goto errCleanUp; 186 187 TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag); 188 TRACE("nChannels=%d \n", lpWaveFormat->nChannels); 189 TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec); 190 TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec); 191 TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign); 192 TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample); 193 194 /* move to end of 'fmt ' chunk */ 195 mmioAscend(hmmio, &mmckInfo, 0); 196 197 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a'); 198 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK)) 199 goto errCleanUp; 200 201 TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n", 202 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize); 203 204 s.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); 205 206 if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback, 207 (DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) 208 goto errCleanUp; 209 210 /* make it so that 3 buffers per second are needed */ 211 bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) * 212 lpWaveFormat->nBlockAlign; 213 waveHdr = (LPWAVEHDR)HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize); 214 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR); 215 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize; 216 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L; 217 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L; 218 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L; 219 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize; 220 if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) || 221 waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) { 222 goto errCleanUp; 223 } 224 225 do { 226 index = 0; 227 left = mmckInfo.cksize; 228 s.dwEventCount = 1L; /* for first buffer */ 229 230 mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET); 231 while (left) { 232 if (PlaySound_Stop) { 233 PlaySound_Stop = PlaySound_Loop = FALSE; 234 break; 235 } 236 count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left)); 237 if (count < 1) break; 238 left -= count; 239 waveHdr[index].dwBufferLength = count; 240 waveHdr[index].dwFlags &= ~WHDR_DONE; 241 waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)); 242 index ^= 1; 243 PlaySound_WaitDone(&s); 244 } 245 bRet = TRUE; 246 } while (PlaySound_Loop); 247 248 PlaySound_WaitDone(&s); 249 waveOutReset(hWave); 250 251 waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)); 252 waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR)); 253 254 errCleanUp: 255 CloseHandle(s.hEvent); 256 HeapFree(GetProcessHeap(), 0, waveHdr); 257 HeapFree(GetProcessHeap(), 0, lpWaveFormat); 258 if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100); 259 if (hmmio) mmioClose(hmmio, 0); 260 261 return bRet; 262 } 263 264 static DWORD WINAPI PlaySound_Thread(LPVOID arg) 265 { 266 DWORD res; 267 268 for (;;) { 269 PlaySound_Playing = FALSE; 270 SetEvent(PlaySound_hReadyEvent); 271 res = WaitForSingleObject(PlaySound_hPlayEvent, INFINITE); 272 ResetEvent(PlaySound_hReadyEvent); 273 SetEvent(PlaySound_hMiddleEvent); 274 if (res == WAIT_FAILED) ExitThread(2); 275 if (res != WAIT_OBJECT_0) continue; 276 PlaySound_Playing = TRUE; 277 278 if ((PlaySound_fdwSound & SND_RESOURCE) == SND_RESOURCE) { 279 HRSRC hRES; 280 HGLOBAL hGLOB; 281 void* ptr; 282 283 if ((hRES = FindResourceA(PlaySound_hmod, PlaySound_pszSound, "WAVE")) == 0) { 284 PlaySound_Result = FALSE; 285 continue; 286 } 287 if ((hGLOB = LoadResource(PlaySound_hmod, hRES)) == 0) { 288 PlaySound_Result = FALSE; 289 continue; 290 } 291 if ((ptr = LockResource(hGLOB)) == NULL) { 292 FreeResource(hGLOB); 293 PlaySound_Result = FALSE; 294 continue; 295 } 296 PlaySound_Result = proc_PlaySound((LPCSTR)ptr, 297 ((UINT16)PlaySound_fdwSound ^ SND_RESOURCE) | SND_MEMORY); 298 FreeResource(hGLOB); 299 continue; 300 } 301 PlaySound_Result = proc_PlaySound(PlaySound_pszSound, (UINT16)PlaySound_fdwSound); 302 } 303 } 35 304 36 305 … … 54 323 DWORD, fdwSound) 55 324 { 56 dprintf(("WINMM:PlaySoundA not implemented\n")); 57 if((fdwSound & (SND_SYNC_W|SND_ASYNC_W)) == (SND_SYNC_W|SND_ASYNC_W)) { 58 // SetLastError(ERROR_INVALID_PARAMETER_W); 325 static LPSTR StrDup = NULL; 326 327 TRACE("pszSound='%p' hmod=%04X fdwSound=%08lX\n", 328 pszSound, hmod, fdwSound); 329 330 if (PlaySound_hThread == 0) { /* This is the first time they called us */ 331 DWORD id; 332 if ((PlaySound_hReadyEvent = CreateEventA(NULL, TRUE, FALSE, NULL)) == 0) 333 return FALSE; 334 if ((PlaySound_hMiddleEvent = CreateEventA(NULL, FALSE, FALSE, NULL)) == 0) 335 return FALSE; 336 if ((PlaySound_hPlayEvent = CreateEventA(NULL, FALSE, FALSE, NULL)) == 0) 337 return FALSE; 338 if ((PlaySound_hThread = CreateThread(NULL, 0, PlaySound_Thread, 0, 0, &id)) == 0) 339 return FALSE; 340 } 341 342 /* FIXME? I see no difference between SND_WAIT and SND_NOSTOP ! */ 343 if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySound_Playing) 59 344 return FALSE; 60 } 61 // if(fdwSound & (SND_MEMORY_W|SND_ALIAS_W|SND_FILENAME_W|SND_RESOURCE_W) == (SND_SYNC_W|SND_ASYNC_W)) { 62 // SetLastError(ERROR_INVALID_PARAMETER_W); 63 // return FALSE; 64 // } 65 return(FALSE); 345 346 /* Trying to stop if playing */ 347 if (PlaySound_Playing) PlaySound_Stop = TRUE; 348 349 /* Waiting playing thread to get ready. I think 10 secs is ok & if not then leave*/ 350 if (WaitForSingleObject(PlaySound_hReadyEvent, 1000*10) != WAIT_OBJECT_0) 351 return FALSE; 352 353 if (!pszSound || (fdwSound & SND_PURGE)) 354 return FALSE; /* We stoped playing so leaving */ 355 356 if (PlaySound_SearchMode != 1) PlaySound_SearchMode = 2; 357 if (!(fdwSound & SND_ASYNC)) { 358 if (fdwSound & SND_LOOP) 359 return FALSE; 360 PlaySound_pszSound = pszSound; 361 PlaySound_hmod = hmod; 362 PlaySound_fdwSound = fdwSound; 363 PlaySound_Result = FALSE; 364 SetEvent(PlaySound_hPlayEvent); 365 if (WaitForSingleObject(PlaySound_hMiddleEvent, INFINITE) != WAIT_OBJECT_0) 366 return FALSE; 367 if (WaitForSingleObject(PlaySound_hReadyEvent, INFINITE) != WAIT_OBJECT_0) 368 return FALSE; 369 return PlaySound_Result; 370 } else { 371 PlaySound_hmod = hmod; 372 PlaySound_fdwSound = fdwSound; 373 PlaySound_Result = FALSE; 374 if (StrDup) { 375 HeapFree(GetProcessHeap(), 0, StrDup); 376 StrDup = NULL; 377 } 378 if (!((fdwSound & SND_MEMORY) || ((fdwSound & SND_RESOURCE) && 379 !((DWORD)pszSound >> 16)) || !pszSound)) { 380 StrDup = HEAP_strdupA(GetProcessHeap(), 0,pszSound); 381 PlaySound_pszSound = StrDup; 382 } else PlaySound_pszSound = pszSound; 383 PlaySound_Loop = fdwSound & SND_LOOP; 384 SetEvent(PlaySound_hPlayEvent); 385 ResetEvent(PlaySound_hMiddleEvent); 386 return TRUE; 387 } 388 return FALSE; 66 389 } 67 390 … … 86 409 DWORD, fdwSound) 87 410 { 88 dprintf(("WINMM:PlaySoundW not implemented\n")); 89 return(FALSE); 411 LPSTR pszSoundA; 412 BOOL bSound; 413 414 if (!((fdwSound & SND_MEMORY) || ((fdwSound & SND_RESOURCE) && 415 !((DWORD)pszSound >> 16)) || !pszSound)) { 416 pszSoundA = HEAP_strdupWtoA(GetProcessHeap(), 0,pszSound); 417 bSound = PlaySoundA(pszSoundA, hmod, fdwSound); 418 HeapFree(GetProcessHeap(), 0, pszSoundA); 419 } else 420 bSound = PlaySoundA((LPCSTR)pszSound, hmod, fdwSound); 421 422 return bSound; 90 423 } 91 424 … … 104 437 105 438 ODINFUNCTION2(BOOL, sndPlaySoundA, 106 LPCSTR, pszSound,107 UINT, fuSound)108 { 109 dprintf(("WINMM:sndPlaySoundA not implemented\n"));110 return(FALSE);439 LPCSTR, lpszSoundName, 440 UINT, uFlags) 441 { 442 PlaySound_SearchMode = 1; 443 return PlaySoundA(lpszSoundName, 0, uFlags); 111 444 } 112 445 … … 126 459 127 460 ODINFUNCTION2(BOOL, sndPlaySoundW, 128 LPCWSTR, pszSound,129 UINT, fuSound)130 { 131 dprintf(("WINMM:sndPlaySoundW not implemented\n"));132 return(FALSE);133 } 134 461 LPCWSTR, lpszSoundName, 462 UINT, uFlags) 463 { 464 PlaySound_SearchMode = 1; 465 return PlaySoundW(lpszSoundName, 0, uFlags); 466 } 467 -
trunk/src/winmm/time.cpp
r5348 r5364 1 /* $Id: time.cpp,v 1.1 0 2001-03-21 12:33:22sandervl Exp $ */1 /* $Id: time.cpp,v 1.11 2001-03-24 13:23:48 sandervl Exp $ */ 2 2 3 3 /* … … 28 28 29 29 30 31 30 /***************************************************************************** 32 31 * Name : mmsystemGetVersion … … 44 43 ODINFUNCTION0(UINT, mmsystemGetVersion) 45 44 { 46 return 4;47 } 48 45 //Returned by winmm.dll from NT4, SP6 46 return 0x030A; 47 } 49 48 50 49 /*****************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.