DirectX音频播放工具类

据说DirectX只能播放8位WAV文件,然而我使用格式工厂转码的WAV文件一直都可以正常加载。。。
项目设置:
项目属性 > VC++目录:
设置包含目录: ${DIRECTXPATH}\Include
设置库目录: ${DIRECTXPATH}\Lib\x86或者 ${DIRECTXPATH}\Lib\x64
链接器->输入->附加依赖项:
dxguid.lib
winmm.lib
dsound.lib

.h文件和 .cpp文件:

/**
*DirectXSound.h
*/
#pragma once
#include <mmsystem.h>
#include <dsound.h>

#define PLAYONCE 0
#define PLAYLOOP 1

class DirectXSound
{
private:
	LPDIRECTSOUND pDS;
	HRESULT result;
	LPDIRECTSOUNDBUFFER pSBuf;
	DSBUFFERDESC desc;
	BOOL playing;
	int loadStatus;

public:
	DirectXSound();
	~DirectXSound();
	
	// 加载音频文件,hwnd是窗口句柄,fileName是WAV文件名,播放前必须已经加载过,否则不会播放
	void LoadSound(HWND hwnd,LPWSTR fileName);
	// 重载
	void LoadSound(HWND hwnd, CString fileName);
	// 播放,playType是播放类型,可以是PLAYONCE播放一次和PLAYLOOP循环播放
	void StartSound(DWORD playType);
	// 停止播放
	void StopSound();
	//设置音量,单位db,取值-100 - 0
	void SetVolumeDb(DWORD db);
	// 设置频率(似乎没有用)
	void SetSoundFrequency(DWORD frequency);
	// 获取音频文件加载状态,返回1表示已经正确加载,其他返回值参看LoadSound实现
	int GetLoadStatus();

};

 /**
*DirectXSound.cpp
*/
#include "stdafx.h"
#include "DirectXSound.h"

DirectXSound::DirectXSound()
{
	playing = FALSE;
	loadStatus = 0;
}


DirectXSound::~DirectXSound()
{
	StopSound();
}

void DirectXSound::LoadSound(HWND hwnd, LPWSTR fileName)
{
	HMMIO hmmio;
	MMRESULT mmResult;
	MMCKINFO ckRiff, ckInfo;
	WAVEFORMATEX swfmt;
	DWORD size;
	HRESULT result;
	LPVOID pAudio;
	DWORD bytesAudio;

	if (playing == TRUE)
	{
		loadStatus = -12; // 音频正在播放
		return;
	}

	result = DirectSoundCreate(NULL, &pDS, NULL);
	if (result != DS_OK)
	{
		loadStatus = -10; // 创建DirectSound失败
		return;
	}
	result = pDS->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
	if (result != DS_OK)
	{
		loadStatus = -11;// 设定设备协调等级失败
		return;
	}
	//打开wav文件
	hmmio = mmioOpen(fileName, NULL, MMIO_ALLOCBUF | MMIO_READ);
	if (hmmio == NULL)
	{
		loadStatus = - 1;// 文件打开失败
		return;
	}
	//进入WAVE区块
	ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E');
	mmResult = mmioDescend(hmmio, &ckRiff, NULL, MMIO_FINDRIFF);
	if (mmResult != MMSYSERR_NOERROR)
	{
		loadStatus = -2;// 文件格式错误
		return;
	}
	//进入fmt区块
	ckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
	mmResult = mmioDescend(hmmio, &ckInfo, &ckRiff, MMIO_FINDCHUNK);
	if (mmResult != MMSYSERR_NOERROR)
	{
		loadStatus = -3;// fmt区块错误
		return;
	}
	//获取播放格式,用于创建次缓冲区
	if (mmioRead(hmmio, (HPSTR)&swfmt, sizeof(WAVEFORMATEX)) == -1)
	{
		loadStatus = -4;// 格式读取出错
		return;
	}
	//退出子区块
	mmResult = mmioAscend(hmmio, &ckInfo, 0);
	ckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
	mmResult = mmioDescend(hmmio, &ckInfo, &ckRiff, MMIO_FINDCHUNK);
	if (mmResult != MMSYSERR_NOERROR)
	{
		loadStatus = -5;// 文件格式错误
		return;
	}
	size = ckInfo.cksize;
	//创建次缓冲区
	memset(&desc, 0, sizeof(DSBUFFERDESC));
	desc.dwSize = sizeof(DSBUFFERDESC);
	desc.dwBufferBytes = size;
	desc.lpwfxFormat = &swfmt;
	desc.dwFlags = DSBCAPS_STATIC | DSBCAPS_GLOBALFOCUS;
	result = pDS->CreateSoundBuffer(&desc, &pSBuf, NULL);
	if (result != DS_OK)
	{
		loadStatus = -6;// 创建第二音频缓冲区失败
		return;
	}
	//载入音频
	result = pSBuf->Lock(0, size, &pAudio, &bytesAudio, NULL, NULL, NULL);
	if (result != DS_OK)
	{
		loadStatus = -7;// 锁定音频缓冲区失败
		return;
	}
	mmResult = mmioRead(hmmio, (HPSTR)pAudio, bytesAudio);
	if (mmResult == -1)
	{
		loadStatus = -8;// 文件读取失败
		return;
	}
	result = pSBuf->Unlock(pAudio, bytesAudio, NULL, NULL);
	if (result != DS_OK)
	{
		loadStatus = -9;// 解锁音频缓冲区失败
		return;
	}
	mmioClose(hmmio, MMIO_FHOPEN);
	loadStatus = 1;
	//pSBuf->SetVolume(DSBVOLUME_MAX);
}

void DirectXSound::LoadSound(HWND hwnd, CString fileName)
{
	LoadSound(hwnd, (LPWSTR)(LPCTSTR)fileName);
}

void DirectXSound::StartSound(DWORD playType)//PLAYONCE PLAYLOOP
{
	if (loadStatus > 0)
	{
		pSBuf->Play(0, 0, playType);
		playing = TRUE;
	}
}

void DirectXSound::StopSound()
{
	if (playing == TRUE)
	{
		pSBuf->Stop();
		playing = FALSE;
	}
}

int DirectXSound::GetLoadStatus()
{
	return loadStatus;
}

void DirectXSound::SetVolumeDb(DWORD db)
{
	if (db <= 0 && db >= -100)
	{
		pSBuf->SetVolume(db*100);
	}
}
void DirectXSound::SetSoundFrequency(DWORD frequency)
{
	pSBuf->SetFrequency(frequency);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值