我需要根据用户输入依次播放一个或多个
.wav
文件。是否有回调函数可用于确定文件是否已播放完毕?
我在这里找到了一个例子:How to know if a music file has finished playing, but that is for some coco2dx, whatever that is.
有人能指出我正确的方向吗?
PlaySound(MAKEINTRESOURCE(IDR_WAVE1), GetModuleHandle(NULL), SND_RESOURCE);
编辑:为我的目的使用带有估计播放时间的计时器不是最合适的解决方案,我已经尝试过,它有效但不能依赖这样做的可靠性。
我在dsp_user的链接建议中找到了这个
MMRESULT waveOutGetPosition(
HWAVEOUT hwo,
LPMMTIME pmmt,
UINT cbmmt`
现在只需要知道它如何或是否对我有用,也许是一个线程来监视播放声音文件的组件中的播放功能。
这样的事情会有帮助吗?
// Global variables.
HANDLE hData = NULL; // handle of waveform data memory
HPSTR lpData = NULL; // pointer to waveform data memory
void WriteWaveData(void)
{
HWAVEOUT hWaveOut;
HGLOBAL hWaveHdr;
LPWAVEHDR lpWaveHdr;
HMMIO hmmio;
UINT wResult;
HANDLE hFormat;
WAVEFORMAT *pFormat;
DWORD dwDataSize;
// Open a waveform device for output using window callback.
if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
(LPWAVEFORMAT)pFormat,
(LONG)hwndApp, 0L, CALLBACK_WINDOW))
{
MessageBox(hwndApp,
"Failed to open waveform output device.",
NULL, MB_OK | MB_ICONEXCLAMATION);
LocalUnlock(hFormat);
LocalFree(hFormat);
mmioClose(hmmio, 0);
return;
}
// Allocate and lock memory for the waveform data.
hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwDataSize );
if (!hData)
{
MessageBox(hwndApp, "Out of memory.",
NULL, MB_OK | MB_ICONEXCLAMATION);
mmioClose(hmmio, 0);
return;
}
if ((lpData = GlobalLock(hData)) == NULL)
{
MessageBox(hwndApp, "Failed to lock memory for data chunk.",
NULL, MB_OK | MB_ICONEXCLAMATION);
GlobalFree(hData);
mmioClose(hmmio, 0);
return;
}
// Read the waveform data subchunk.
if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LRESULT)dwDataSize)
{
MessageBox(hwndApp, "Failed to read data chunk.",
NULL, MB_OK | MB_ICONEXCLAMATION);
GlobalUnlock(hData);
GlobalFree(hData);
mmioClose(hmmio, 0);
return;
}
// Allocate and lock memory for the header.
hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
(DWORD) sizeof(WAVEHDR));
if (hWaveHdr == NULL)
{
GlobalUnlock(hData);
GlobalFree(hData);
MessageBox(hwndApp, "Not enough memory for header.",
NULL, MB_OK | MB_ICONEXCLAMATION);
return;
}
lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);
if (lpWaveHdr == NULL)
{
GlobalUnlock(hData);
GlobalFree(hData);
MessageBox(hwndApp,
"Failed to lock memory for header.",
NULL, MB_OK | MB_ICONEXCLAMATION);
return;
}
// After allocation, set up and prepare header.
lpWaveHdr->lpData = lpData;
lpWaveHdr->dwBufferLength = dwDataSize;
lpWaveHdr->dwFlags = 0L;
lpWaveHdr->dwLoops = 0L;
waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
// Now the data block can be sent to the output device. The
// waveOutWrite function returns immediately and waveform
// data is sent to the output device in the background.
wResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
if (wResult != 0)
{
waveOutUnprepareHeader(hWaveOut, lpWaveHdr,
sizeof(WAVEHDR));
GlobalUnlock( hData);
GlobalFree(hData);
MessageBox(hwndApp, "Failed to write block to device",
NULL, MB_OK | MB_ICONEXCLAMATION);
return;
}
}