wav是未压缩的音频格式文件。
使用Windows API播放WAV的代码如下所示:
#include
#include //不需要加,加上错误
#include
#pragma comment (lib,"winmm.lib")
#define QUITMESSAGE 0x1000
typedef struct
{
unsigned char RIFF[4];
unsigned int WaveSize;
unsigned char WAVE[4];
unsigned char FMT[4];
unsigned int FormatInfoSize;
unsigned short PCM;
unsigned short ChannelCnt;
unsigned int SamplesPerSec;
unsigned int AvgBytesPerSec;
unsigned short BlockAlign;
unsigned short BitsPerSample;
}WAVEHEADER, * LPWAVEHEADER;
typedef struct
{
unsigned char DATA[4];
unsigned int DataSize;
}WAVEDATA, * LPWAVEDATA;
int __stdcall ProcWOMOPEN();
int main()
{
HANDLE hWavFile = CreateFileA("start.wav", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hWavFile == INVALID_HANDLE_VALUE)
{
printf("Open file error!\n");
return false;
}
DWORD FileSizeHigh;
DWORD FileSizeLow = GetFileSize(hWavFile, &FileSizeHigh);
if (FileSizeHigh || !FileSizeLow)
{
printf("File too big to load!\n");
return false;
}
char* FileBuf = (char*)VirtualAlloc(0, FileSizeLow+1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!FileBuf)
{
printf("VirtualAlloc error!\n");
return false;
}
DWORD Counter;
unsigned long Result = ReadFile(hWavFile, FileBuf, FileSizeLow, &Counter, 0);
if (Counter != FileSizeLow)
{
printf("ReadFile error!\n");
return false;
}
else
{
printf("ReadFile OK!\n");
FileBuf[FileSizeLow] = 0;
}
unsigned long ThreadID;
HANDLE ThreadMain = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ProcWOMOPEN, 0, 0, &ThreadID);
LPWAVEHEADER WavHeader = (LPWAVEHEADER)FileBuf;
WAVEFORMATEX WavFmtEx;
WavFmtEx.cbSize = 0;
WavFmtEx.nAvgBytesPerSec = WavHeader->AvgBytesPerSec;
WavFmtEx.nBlockAlign = WavHeader->BlockAlign;
WavFmtEx.nChannels = WavHeader->ChannelCnt;
WavFmtEx.nSamplesPerSec = WavHeader->SamplesPerSec;
WavFmtEx.wBitsPerSample = WavHeader->BitsPerSample;
WavFmtEx.wFormatTag = WAVE_FORMAT_PCM;
HWAVEOUT hWavOut;
Result = waveOutOpen(&hWavOut, WAVE_MAPPER, &WavFmtEx, 0, 0, CALLBACK_FUNCTION);
if (Result != MMSYSERR_NOERROR)
{
printf("WaveOutOpen error!\n");
return false;
}
else
{
printf("waveOutOpen success!\n");
}
LPWAVEDATA WaveData = (LPWAVEDATA)((unsigned int)WavHeader + WavHeader->FormatInfoSize + 20);
if (strstr((char*)WaveData, "fact"))
{
WaveData = (LPWAVEDATA)((unsigned int)WaveData + WaveData->DataSize + 8);
}
if (!strstr((char*)WaveData, "data"))
{
printf("Not valid wave format file!\n");
return false;
}
else
{
printf("data Init OK!\n");
}
LPWAVEHDR WavHdr = (LPWAVEHDR)VirtualAlloc(0, sizeof(WAVEHEADER), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WavHdr->dwBufferLength = WaveData->DataSize;
WavHdr->dwBytesRecorded = 0;
WavHdr->dwFlags = 0;
WavHdr->dwLoops = 1;
WavHdr->dwUser = 0;
WavHdr->lpData = (char*)((unsigned int)WaveData + sizeof(WAVEDATA));
WavHdr->lpNext = 0;
WavHdr->reserved = 0;
waveOutPrepareHeader(hWavOut, WavHdr, sizeof(WAVEHDR));
waveOutWrite(hWavOut, WavHdr, sizeof(WAVEHDR));
getchar();
waveOutReset(hWavOut);
// waveOutStop(hWavOut);
waveOutUnprepareHeader(hWavOut, WavHdr, sizeof(WAVEHDR));
waveOutClose(hWavOut);
PostThreadMessage(ThreadID, QUITMESSAGE, 0, 0);
CloseHandle(ThreadMain);
return true;
}
int __stdcall ProcWOMOPEN()
{
int Result;
MSG Msg;
while (true)
{
Result = PeekMessage(&Msg, 0, 0, 0, PM_NOREMOVE);
if (Result == QUITMESSAGE)
{
printf("Quit!\n");
getchar();
return true;
}
else if (Result == MM_WOM_OPEN)
{
printf("Start to play!\n");
}
else if (Result == MM_WOM_DONE)
{
printf("Play complete!\n");
}
else if (Result == MM_WOM_CLOSE)
{
printf("Play over!\n");
}
}
return true;
}