windows API播放wav

wav是未压缩的音频格式文件。

使用Windows API播放WAV的代码如下所示:


#include <windows.h>
#include <mmsystem.h>		//不需要加,加上错误
#include <stdio.h>
#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;
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值