写入波形数据的示例
[与此页面关联的功能 波形音频是一项旧功能。 它已被 WASAPI 和 Audio Graphs 取代。 WASAPI 和 Audio Graphs 已针对Windows 10和Windows 11进行了优化。 如果可能,Microsoft 强烈建议新代码使用 WASAPI 和 音频图 ,而不是 波形音频。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
以下示例演示了分配和设置 WAVEHDR 结构并将数据块写入波形输出设备所需的步骤。
// 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;
}
}