Commit 6036ad7f authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Fixed PlaySound proc for non PCM content.

parent dfd13e2f
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* 98/9 added Win32 MCI support * 98/9 added Win32 MCI support
* 99/4 added mmTask and mmThread functions support * 99/4 added mmTask and mmThread functions support
* added midiStream support * added midiStream support
* 99/9 added support for loadable low level drivers
*/ */
/* FIXME: I think there are some segmented vs. linear pointer weirdnesses /* FIXME: I think there are some segmented vs. linear pointer weirdnesses
...@@ -253,8 +254,13 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCSTR lpszName) ...@@ -253,8 +254,13 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCSTR lpszName)
static BOOL WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT uFlags) static BOOL WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT uFlags)
{ {
BOOL bRet = FALSE; BOOL bRet = FALSE;
HMMIO hmmio; HMMIO hmmio = 0;
MMCKINFO ckMainRIFF; MMCKINFO ckMainRIFF;
MMCKINFO mmckInfo;
LPWAVEFORMATEX lpWaveFormat = NULL;
HWAVE hWave = 0;
WAVEHDR waveHdr;
INT count, bufsize, left;
TRACE("SoundName='%s' uFlags=%04X !\n", lpszSoundName, uFlags); TRACE("SoundName='%s' uFlags=%04X !\n", lpszSoundName, uFlags);
if (lpszSoundName == NULL) { if (lpszSoundName == NULL) {
...@@ -280,115 +286,103 @@ static BOOL WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT uFlags) ...@@ -280,115 +286,103 @@ static BOOL WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT uFlags)
if (PlaySound_SearchMode == 1) { if (PlaySound_SearchMode == 1) {
PlaySound_SearchMode = 0; PlaySound_SearchMode = 0;
if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0) if ((hmmio = get_mmioFromFile(lpszSoundName)) == 0)
if ((hmmio=get_mmioFromProfile(uFlags, lpszSoundName)) == 0) hmmio = get_mmioFromProfile(uFlags, lpszSoundName);
return FALSE;
} }
if (PlaySound_SearchMode == 2) { if (PlaySound_SearchMode == 2) {
PlaySound_SearchMode = 0; PlaySound_SearchMode = 0;
if ((hmmio=get_mmioFromProfile(uFlags | SND_NODEFAULT, lpszSoundName)) == 0) if ((hmmio = get_mmioFromProfile(uFlags | SND_NODEFAULT, lpszSoundName)) == 0)
if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0) if ((hmmio = get_mmioFromFile(lpszSoundName)) == 0)
if ((hmmio=get_mmioFromProfile(uFlags, lpszSoundName)) == 0) return FALSE; hmmio = get_mmioFromProfile(uFlags, lpszSoundName);
} }
} }
if (hmmio == 0) return FALSE;
if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) == 0) {
DWORD dwPos = mmioSeek(hmmio, 0, SEEK_CUR); if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
do { goto errCleanUp;
TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
ckMainRIFF.cksize); (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
mmioSeek(hmmio, dwPos, SEEK_SET); if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
(ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
if ((ckMainRIFF.ckid == FOURCC_RIFF) && goto errCleanUp;
(ckMainRIFF.fccType == mmioFOURCC('W', 'A', 'V', 'E'))) {
MMCKINFO mmckInfo; mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' '); goto errCleanUp;
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0) { TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
PCMWAVEFORMAT pcmWaveFormat; (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n", lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize); if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(WAVEFORMAT))
goto errCleanUp;
if (mmioRead(hmmio, (HPSTR)&pcmWaveFormat,
(long) sizeof(PCMWAVEFORMAT)) == (long) sizeof(PCMWAVEFORMAT)) { TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
TRACE("wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag); TRACE("nChannels=%d \n", lpWaveFormat->nChannels);
TRACE("nChannels=%d \n", pcmWaveFormat.wf.nChannels); TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec);
TRACE("nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec); TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec);
TRACE("nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec); TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign);
TRACE("nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign); TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
TRACE("wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
/* move to end of 'fmt ' chunk */
mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmioAscend(hmmio, &mmckInfo, 0);
/* move to end of 'fmt ' chunk */
mmioSeek(hmmio, mmckInfo.dwDataOffset + ((mmckInfo.cksize + 1) & ~1), SEEK_SET); mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0) { goto errCleanUp;
DWORD dwRet;
HWAVE hWave; TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize); if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, 0L, 0L, CALLBACK_NULL) != MMSYSERR_NOERROR)
goto errCleanUp;
pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec *
pcmWaveFormat.wf.nBlockAlign; /* make it so that 3 buffers per second are needed */
bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
dwRet = waveOutOpen(&hWave, WAVE_MAPPER, (LPWAVEFORMATEX)&pcmWaveFormat, 0L, 0L, CALLBACK_NULL); lpWaveFormat->nBlockAlign;
if (dwRet == MMSYSERR_NOERROR) { waveHdr.lpData = HeapAlloc(GetProcessHeap(), 0, bufsize);
WAVEHDR waveHdr;
HGLOBAL16 hData; do {
INT count, bufsize, left = mmckInfo.cksize; waveHdr.dwUser = 0L;
waveHdr.dwFlags = 0L;
bufsize = 64000; waveHdr.dwLoops = 0L;
hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
waveHdr.lpData = (LPSTR)GlobalLock16(hData); left = mmckInfo.cksize;
waveHdr.dwBufferLength = bufsize; mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
waveHdr.dwUser = 0L; while (left) {
waveHdr.dwFlags = 0L; waveHdr.dwBufferLength = bufsize;
waveHdr.dwLoops = 0L; if (waveOutPrepareHeader(hWave, &waveHdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
if (PlaySound_Stop) {
dwRet = waveOutPrepareHeader(hWave, &waveHdr, sizeof(WAVEHDR)); PlaySound_Stop = FALSE;
if (dwRet == MMSYSERR_NOERROR) { PlaySound_Loop = FALSE;
while (left) { break;
if (PlaySound_Stop) {
PlaySound_Stop = FALSE;
PlaySound_Loop = FALSE;
break;
}
if (bufsize > left) bufsize = left;
count = mmioRead(hmmio, waveHdr.lpData, bufsize);
if (count < 1) break;
left -= count;
waveHdr.dwBufferLength = count;
/* waveHdr.dwBytesRecorded = count; */
/* FIXME: doesn't expect async ops */
waveOutWrite(hWave, &waveHdr, sizeof(WAVEHDR));
while (!(waveHdr.dwFlags & WHDR_DONE))
Sleep(10);
}
waveOutUnprepareHeader(hWave, &waveHdr, sizeof(WAVEHDR));
while (waveOutClose(hWave) == WAVERR_STILLPLAYING)
Sleep(100);
bRet = TRUE;
} else
WARN("can't prepare WaveOut device !\n");
GlobalUnlock16(hData);
GlobalFree16(hData);
}
}
}
} }
} if (bufsize > left) bufsize = left;
} while (PlaySound_Loop); count = mmioRead(hmmio, waveHdr.lpData, bufsize);
} if (count < 1) break;
left -= count;
waveHdr.dwBufferLength = count;
/* waveHdr.dwBytesRecorded = count; */
/* FIXME: doesn't expect async ops */
waveOutWrite(hWave, &waveHdr, sizeof(WAVEHDR));
while (!(waveHdr.dwFlags & WHDR_DONE))
Sleep(10);
waveOutUnprepareHeader(hWave, &waveHdr, sizeof(WAVEHDR));
bRet = TRUE;
} else
WARN("can't prepare WaveOut device !\n");
}
} while (PlaySound_Loop);
errCleanUp:
HeapFree(GetProcessHeap(), 0, waveHdr.lpData);
HeapFree(GetProcessHeap(), 0, lpWaveFormat);
if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100);
if (hmmio) mmioClose(hmmio, 0);
if (hmmio != 0) mmioClose(hmmio, 0);
return bRet; return bRet;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment