据说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
#include
#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);
}