📄 cdsound.cpp
字号:
/*DirectSound的应用函数
*
*编辑: jzZ 2000,05
*
*/
#include "CDSound.h"
// CDSound()
//默认构造函数,初始化成员变量
CDSound::CDSound()
{
lpDS = NULL;
for (int i = 0; i < 50; i++)
{
DSBufStack[i].lpDSBuffer = NULL;
DSBufStack[i].dwWaveSize = 0;
DSBufStack[i].szFileName = NULL;
DSBufStack[i].lpWFmtEX = NULL;
DSBufStack[i].lpWaveData = NULL;
}
size = 0;
}
// ~CDSound()
//默认销毁函数,调用销毁已经分配的资源
CDSound::~CDSound()
{
Terminate();
}
// Init()
// 建立DirectSound目标,设置合作级别
// 输入参数: HWND 应用程序得window目标
BOOL CDSound::Init(HWND hwnd)
{
HRESULT hr;
//确定我们没有再次初始化
lpDS = NULL;
for (int i = 0; i < 50; i++)
{
DSBufStack[i].lpDSBuffer = NULL;
DSBufStack[i].szFileName = NULL;
DSBufStack[i].dwWaveSize = 0;
DSBufStack[i].lpWFmtEX = NULL;
DSBufStack[i].lpWaveData = NULL;
}
size = 0;
// 第一次构造DirectSound目标
hr = DirectSoundCreate(NULL, &lpDS, NULL);
if (hr != DS_OK)
{
MessageBox(hwnd, "ERROR: Can't construct directsound object!",
"DirectSound initialization:", MB_OK);
Terminate();
return FALSE;
}
// 设置合作级别为 通常 模式
hr = lpDS->SetCooperativeLevel(hwnd, DSSCL_NORMAL);
if (hr != DS_OK)
{
MessageBox(hwnd, "ERROR: Can't set cooperative level!",
"DirectSound initialization:", MB_OK);
Terminate();
return FALSE;
}
return TRUE;
}
// Terminate()
// 销毁DirectSound目标并且释放资源
void CDSound::Terminate()
{
if (lpDS != NULL)
{
for (int i = 0; i < 50; i++)
{
DestroySoundBuffer(i);
}
lpDS->Release();
lpDS = NULL;
}
size = 0;
}
// DestroySoundBuffer()
// 根据索引销毁声音缓冲
// 输入参数: num - 声音缓冲队列索引
void CDSound::DestroySoundBuffer(int num)
{
if (DSBufStack[num].lpDSBuffer != NULL)
{
DSBufStack[num].lpDSBuffer->Release();
DSBufStack[num].lpDSBuffer = NULL;
}
if(DSBufStack[num].dwWaveSize != 0)
DSBufStack[num].dwWaveSize = 0;
if(DSBufStack[num].szFileName != NULL)
DSBufStack[num].szFileName = NULL;
if(DSBufStack[num].lpWFmtEX != NULL)
{
delete DSBufStack[num].lpWFmtEX;
DSBufStack[num].lpWFmtEX = NULL;
}
if(DSBufStack[num].lpWaveData != NULL)
{
GlobalFree(DSBufStack[num].lpWaveData);
DSBufStack[num].lpWaveData = NULL;
}
if (size != 0)
size -= 1;
}
// GetSoundDataFromFile
// 从文件中得到声音数据
// 输入参数: 1. fn - 文件名
// 2. num - 需要建立的索引序号
// 返回值: 成功为TRUE否则FALSE
BOOL CDSound::GetSoundDataFromFile(LPSTR fn, int num)
{
BOOL success;
WAVEFORMATEX * lpTempWFmtEX;
char * lpWaveDataTemp;
CWave * lpTempWave = new CWave;
success = lpTempWave->LoadWaveFile(fn);
if(!success)
return FALSE;
if(IsBufferExisting(num))
DestroySoundBuffer(num);
lpTempWFmtEX = lpTempWave->GetWaveFormatEXPtr();
lpWaveDataTemp = lpTempWave->GetWaveData();
DSBufStack[num].dwWaveSize = lpTempWave->GetWaveSize();
DSBufStack[num].szFileName = fn;
DSBufStack[num].lpWFmtEX = new WAVEFORMATEX;
DSBufStack[num].lpWaveData = (char *)GlobalAlloc(GMEM_FIXED, DSBufStack[num].dwWaveSize);
memcpy(DSBufStack[num].lpWFmtEX, lpTempWFmtEX, sizeof(WAVEFORMATEX));
memcpy(DSBufStack[num].lpWaveData, lpWaveDataTemp, DSBufStack[num].dwWaveSize);
delete lpTempWave;
lpTempWFmtEX = NULL;
lpWaveDataTemp = NULL;
size += 1;
return TRUE;
}
// CreateBuffer
// 为具体的索引建立缓冲
// *注意: 必须先调用GetSoundDataFrom()
// 输入参数: num - 索引值
// 返回值: 成功TRUE否则FALSE
BOOL CDSound::CreateBuffer(int num)
{
DSBUFFERDESC dsbc;
HRESULT hr;
if (IsStackFull())
return FALSE;
if(!IsIndexValid(num))
return FALSE;
memset(&dsbc, 0, sizeof(DSBUFFERDESC));
dsbc.dwSize = sizeof(DSBUFFERDESC);
dsbc.dwFlags = DSBCAPS_STATIC;
if(DSBufStack[num].dwWaveSize == 0)
return FALSE;
dsbc.dwBufferBytes = DSBufStack[num].dwWaveSize;
if(DSBufStack[num].lpWFmtEX == NULL)
return FALSE;
dsbc.lpwfxFormat = DSBufStack[num].lpWFmtEX;
// 建立缓冲
hr = lpDS->CreateSoundBuffer(&dsbc, &DSBufStack[num].lpDSBuffer, NULL);
if (hr != DS_OK)
{
DSBufStack[num].lpDSBuffer = NULL;
return FALSE;
}
return TRUE;
}
// LoadDataToBuffer
// 建立缓冲后,将数据存入缓冲
// *注意: 必须先调用CreateBuffer()
// 输入参数: num - 索引值
// 返回值: 成功TRUE否则FALSE
BOOL CDSound::LoadDataToBuffer(int num)
{
LPVOID pSoundBlock1;
LPVOID pSoundBlock2;
DWORD bytes1;
DWORD bytes2;
HRESULT hr;
if(DSBufStack[num].lpWaveData == NULL && DSBufStack[num].dwWaveSize == 0)
return FALSE;
hr = DSBufStack[num].lpDSBuffer->Lock(0, DSBufStack[num].dwWaveSize,
&pSoundBlock1, &bytes1, &pSoundBlock2, &bytes2,0);
if(hr != DS_OK)
return FALSE;
// 存入数据
memcpy((void *)pSoundBlock1, DSBufStack[num].lpWaveData, DSBufStack[num].dwWaveSize);
// 取消内存缓冲锁定
DSBufStack[num].lpDSBuffer->Unlock(pSoundBlock1, bytes1, pSoundBlock2, bytes2);
if (hr != DS_OK)
return FALSE;
return TRUE;
}
// SetTrack()
// 将一个有效的文件调入具体的Dsound缓冲
// * 包含如下步骤:
// 1. 调用GetSoundDataFromFile()
// 2. 调用CreateBuffer()
// 3. 调用LoadSoundDataToBuffer().
// 输入参数: 1. fn - 文件名
// 2. num - 索引值
// 返回值: 成功TRUE否则FALSE
BOOL CDSound::SetTrack(LPSTR fn, int num)
{
if(!GetSoundDataFromFile(fn, num))
return FALSE;
if(!CreateBuffer(num))
return FALSE;
if(!LoadDataToBuffer(num))
return FALSE;
return TRUE;
}
// Play()
// 播放选择的索引对应的具体缓冲
// 输入参数: 1. loop - 循环标志
// 2. num - 索引值
// 返回值: 成功TRUE否则FALSE
BOOL CDSound::Play(BOOL loop, int num)
{
HRESULT hr;
if(!IsIndexValid(num))
return FALSE;
if (!IsBufferExisting(num))
return FALSE;
hr = DSBufStack[num].lpDSBuffer->SetCurrentPosition(0);
if (hr != DS_OK)
return FALSE;
if (loop)
{
hr = DSBufStack[num].lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING);
if(hr != DS_OK)
return FALSE;
}
else
{
hr = DSBufStack[num].lpDSBuffer->Play(0, 0, 0);
if(hr != DS_OK)
return FALSE;
}
return TRUE;
}
// Stop()
// 停止播放所选择索引的缓冲
// 输入参数: num - 索引值
void CDSound::Stop(int num)
{
if(!IsIndexValid(num))
return;
if (!IsBufferExisting(num))
return;
DSBufStack[num].lpDSBuffer->Stop();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -