waveOutPrepareHeader

本文详细介绍了在Windows系统中使用波形音频输出设备进行音频播放的方法,包括如何准备WAVEHDR结构并使用waveOutPrepareHeader函数进行设备初始化。
http://msdn.microsoft.com/en-us/library/ms713756(v=VS.85).aspx

waveOutPrepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);


MMRESULT waveOutPrepareHeader(
HWAVEOUT hwo, /* 波形音频输出设备的句柄 */
LPWAVEHDR pwh, /* 一个WAVEHDR结构的指针 */
UINT cbwh /* WAVEHDR结构的大小,以字节 */

);


返回值:

如果成功,返回MMSYSERR_NOERROR.否则,返回错误,可能的错误值为:

ValueDescription
MMSYSERR_INVALHANDLESpecified device handle is invalid.
MMSYSERR_NODRIVERNo device driver is present.
MMSYSERR_NOMEMUnable to allocate or lock memory.

备注:

调用此函数之前必须设置WAVEHDR结构的lpData,dwBufferLength,dwFlags中成员。 dwFlags成员必须设置为WHDR_PREPAREDWHDR_BEGINLOOP,或WHDR_ENDLOOP

/* flags for dwFlags field of WAVEHDR */
#define WHDR_DONE 0x00000001 /* done bit */
#define WHDR_PREPARED 0x00000002 /* set if this header has been prepared */
#define WHDR_BEGINLOOP 0x00000004 /* loop start block */
#define WHDR_ENDLOOP 0x00000008 /* loop end block */
#define WHDR_INQUEUE 0x00000010 /* reserved for driver */ 0001 0000 :16


依次是:1,2,4,8,16

0000 0001

0000 0010

0000 0100

0000 1000

0001 0000


The dwFlags , dwBufferLength , and dwLoops members of the WAVEHDR structure can change between calls to this function and the waveOutWrite function. (The only flags that can change in this interval for the dwFlags member are WHDR_BEGINLOOP and WHDR_ENDLOOP.) If you change the size specified by dwBufferLength before the call to waveOutWrite , the new value must be less than the prepared value.

Preparing a header that has already been prepared has no effect, and the function returns zero.

Requirements

Windows NT/2000/XP: Included in Windows NT 3.1 and later. 
Windows 95/98/Me: Included in Windows 95 and later. 
Header: Declared in Mmsystem.h; include Windows.h. 
Library: Use Winmm.lib.


提示有多个操作符"-"与这些操作匹配 #include <windows.h> #include <mmsystem.h> #include <fstream> #include <NXOpen/UI.hxx> // 全局变量 HWAVEOUT hWaveOut; WAVEHDR waveHeader; bool isPlaying = false; // 回调函数(播放完成通知) void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { if (uMsg == WOM_DONE) { waveOutUnprepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)); delete[] waveHeader.lpData; isPlaying = false; } } // 播放WAV文件 void PlayWavFile(const char* filePath) { if (isPlaying) return; std::ifstream wavFile(filePath, std::ios::binary); if (!wavFile.is_open()) { UF_UI_set_status("无法打开音频文件"); return; } // 读取WAV文件头 char header[44]; wavFile.read(header, 44); // 解析音频参数 WAVEFORMATEX waveFormat; waveFormat.wFormatTag = *(WORD*)(header + 20); waveFormat.nChannels = *(WORD*)(header + 22); waveFormat.nSamplesPerSec = *(DWORD*)(header + 24); waveFormat.nAvgBytesPerSec = *(DWORD*)(header + 28); waveFormat.nBlockAlign = *(WORD*)(header + 32); waveFormat.wBitsPerSample = *(WORD*)(header + 34); waveFormat.cbSize = 0; DWORD dataSize = *(DWORD*)(header + 40); // 读取音频数据 char* audioData = new char[dataSize]; wavFile.read(audioData, dataSize); wavFile.close(); // 打开音频设备 if (waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormat, (DWORD_PTR)waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { delete[] audioData; UF_UI_set_status("音频设备初始化失败"); return; } // 准备播放头 ZeroMemory(&waveHeader, sizeof(WAVEHDR)); waveHeader.lpData = audioData; waveHeader.dwBufferLength = dataSize; if (waveOutPrepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)) { delete[] audioData; waveOutClose(hWaveOut); UF_UI_set_status("音频数据准备失败"); return; } // 开始播放 if (waveOutWrite(hWaveOut, &waveHeader, sizeof(WAVEHDR))) { waveOutUnprepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)); delete[] audioData; waveOutClose(hWaveOut); UF_UI_set_status("播放失败"); return; } isPlaying = true; UF_UI_set_status("音频播放中..."); } // 停止播放 void StopPlayback() { if (!isPlaying) return; waveOutReset(hWaveOut); // 立即停止播放 waveOutUnprepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)); waveOutClose(hWaveOut); isPlaying = false; UF_UI_set_status("播放已停止"); }
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值