파형 데이터 쓰기 예제
[이 페이지와 연결된 기능인 Waveform Audio레거시 기능입니다. WASAPI 오디오 그래프 대체되었습니다. WASAPI 및 오디오 그래프 Windows 10 및 Windows 11에 최적화되었습니다. 가능한 경우 새 코드에서 Waveform Audio대신 WASAPI 및 Audio Graphs 사용하는 것이 좋습니다. 가능한 경우 레거시 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;
}
}