⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdsound.cpp

📁 打飞机的游戏
💻 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 + -