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

📄 dsbuffer.cpp

📁 此书包含了大量的VC程序源代码,对于学习者来说是非常重要的,看后大家对VC将会有质的提高.非常经典.
💻 CPP
字号:
// DSBuffer.cpp : Implementation of CDSBuffer class
//

#include "stdafx.h"
#include "DSBuffer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//设置如下两个全局变量控制音量:
//用于控制背景音乐音量大小
int   m_nBkGrdVolume = DSBVOLUME_MAX; 
//用于控制音效音量大小
int   m_nYinXiaoVolume= DSBVOLUME_MAX-DSBVOLUME_MIN ;  

/////////////////////////////////////////////////////////////////////////////
// CDSBuffer

CDSBuffer::CDSBuffer()
{
	// 复位声音缓冲区
	m_lpDSBuffer = NULL;
}

CDSBuffer::CDSBuffer(const char *FileName,BOOL m_bBackGroundMusic,LPDIRECTSOUND lpDS, DWORD dwFlags)
{
    //判断是否用于背景音乐
	//若m_bBackGroundMusic为TRUE,则该音乐用于背景音乐
	//若m_bBackGroundMusic为FALSE,则该音乐用于音效
	m_bBkGrdMusic=m_bBackGroundMusic;

	// 复位声音缓冲区
	m_lpDSBuffer = NULL;

    // 打开wave文件       
	FILE* pFile = fopen(FileName, "rb");
	if(!pFile)
		return;

	// 把相关信息读入Wave header          
	WaveHeader wavHdr;
	if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1) 
	{
		fclose(pFile);
		return;
	}

	// 所需的数据区的大小
	DWORD dwSize = wavHdr.dwDSize;

	// 是否是一个立体声声音文件?
	BOOL bStereo = wavHdr.wChnls > 1 ? true : false;

	// 为这个wave文件创建声音缓冲区
	if(CreateSoundBuffer(lpDS, dwFlags, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
	{
		// 从wave文件中读入声音数据
		if (!ReadData(pFile, dwSize, sizeof(wavHdr)))
			MessageBox(NULL,"读入声音数据出错",NULL,MB_OK);
	}

	fclose(pFile);
}


CDSBuffer::~CDSBuffer()
{
	StopSound();
	if(m_lpDSBuffer)
	{       
		m_lpDSBuffer->Release();
	}
}


BOOL CDSBuffer::CreateSoundBuffer(LPDIRECTSOUND lpDS, DWORD dwFlags, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
{
	PCMWAVEFORMAT pcmwf;
	DSBUFFERDESC dsbdesc;

	// 设置wave format结构.
	memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
	pcmwf.wf.wFormatTag         = WAVE_FORMAT_PCM;      
	pcmwf.wf.nChannels          = bStereo ? 2 : 1;
	pcmwf.wf.nSamplesPerSec     = dwFreq;
	pcmwf.wf.nBlockAlign        = (WORD)dwBlkAlign;
	pcmwf.wf.nAvgBytesPerSec    = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
	pcmwf.wBitsPerSample        = (WORD)dwBitsPerSample;

	// 设置DSBUFFERDESC结构
	memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));  // Zero it out. 
	dsbdesc.dwSize              = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags             = dwFlags;
	dsbdesc.dwBufferBytes       = dwBufSize; 
	dsbdesc.lpwfxFormat         = (LPWAVEFORMATEX)&pcmwf;

	if (DS_OK != lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSBuffer, NULL))
	{
		MessageBox(NULL,"创建声音缓冲区失败",NULL,MB_OK);
		return FALSE;
	}

	return TRUE;
}


BOOL CDSBuffer::ReadData(FILE* pFile, DWORD dwSize, DWORD dwPos) 
{
	// 定位到文件中的正确位置
	if (dwPos != 0xffffffff) 
	{
		if (fseek(pFile, dwPos, SEEK_SET) != 0) 
		{
			return FALSE;
		}
	}

	// 锁定缓冲区数据
	LPVOID pData1;
	DWORD  dwData1Size;
	LPVOID pData2;
	DWORD  dwData2Size;
	HRESULT rval;

	rval = m_lpDSBuffer->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
	if (rval != DS_OK)
	{
		return FALSE;
	}

	// 读取数据
	if (dwData1Size > 0) 
	{
		if (fread(pData1, dwData1Size, 1, pFile) != 1) 
		{               
			return FALSE;
		}
	}

	if (dwData2Size > 0) 
	{
		if (fread(pData2, dwData2Size, 1, pFile) != 1) 
		{
			return FALSE;
		}
	}

	// 解除锁定
	rval = m_lpDSBuffer->Unlock(pData1, dwData1Size, pData2, dwData2Size);
	if (rval != DS_OK)
	{
		return FALSE;
	}

	return TRUE;
}

//入口参数:bContinue,控制调用StopSound后是否接着原来的播放点播放
//                    bContinue为TRUE时接着原来点播放,为FALSE时从头播放
//                    默认bContinue为FALSE
BOOL CDSBuffer::PlaySound(BOOL bContinue)
{
	if(m_lpDSBuffer)	// 确认声音缓冲区有效
	{
		DWORD dwStatus;
		if (DS_OK != m_lpDSBuffer->GetStatus(&dwStatus))
		{
			MessageBox(NULL,"获取DirectSound缓冲区状态失败!",NULL,MB_OK);
			return FALSE;
		}

		if((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
		{
			if (m_bBkGrdMusic)  //是背景音乐则循环播放
			{
				//设置播放位置
				if (!bContinue)
					m_lpDSBuffer->SetCurrentPosition(0);

				if (DS_OK != m_lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING))		// Play the sound
				{
					return FALSE;
				}
			}
			else    //是音效则播放一次停止
			{
				//设置播放位置
				if (!bContinue)
					m_lpDSBuffer->SetCurrentPosition(0);

				if (DS_OK != m_lpDSBuffer->Play(0, 0, 0))		// Play the sound
				{
					MessageBox(NULL,"不能播放声音缓冲区对象",NULL,MB_OK);
					return FALSE;
				}
			}
		}
	}

	return TRUE;
}

BOOL CDSBuffer::StopSound()
{
	if(m_lpDSBuffer)	// 确认声音缓冲区有效
	{
		DWORD dwStatus;
		if (DS_OK != m_lpDSBuffer->GetStatus(&dwStatus))
		{
			return FALSE;
		}

		if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
		{  
			if (DS_OK != m_lpDSBuffer->Stop())		// Stop the sound
			{
				return FALSE;
			}

		}
	}
	return TRUE;
}


BOOL CDSBuffer::IsValid()
{
	if (m_lpDSBuffer)
		return TRUE;
	else
		return FALSE;
}

//------------音量控制部分---------------
//SetVolume:设置音量
//入口参数为百分数(0~100)
void CDSBuffer::SetVolume(int percent)
{
	int nVolume;
	if (percent<=0)
		nVolume=DSBVOLUME_MIN;
	else if (percent>=100)
		nVolume=DSBVOLUME_MAX;
	else
		nVolume=DSBVOLUME_MIN+(DSBVOLUME_MAX-DSBVOLUME_MIN)*percent/100;
    GetBuffer()->SetVolume(nVolume);
}

//以下两个函数用于控制音量大小
//入口参数为百分数(0~100)
void CDSBuffer::VolumeDown(int percent)
{
	if (percent<=0 )
		percent=1;
	if (percent>=100)
		percent=100;
	if(m_bBkGrdMusic)    //如果是背景音乐,则设置背景音乐音量
	{
		if (m_nBkGrdVolume<=DSBVOLUME_MIN)
		{
			m_nBkGrdVolume=DSBVOLUME_MIN;	
			GetBuffer()->SetVolume(m_nBkGrdVolume);
			return;
		}
		m_nBkGrdVolume-=(DSBVOLUME_MAX-DSBVOLUME_MIN)/percent;
		if (m_nBkGrdVolume<=DSBVOLUME_MIN)
			m_nBkGrdVolume=DSBVOLUME_MIN;
		GetBuffer()->SetVolume(m_nBkGrdVolume);
	}
	else                //是音效,则设置音效音量
	{
		if (m_nYinXiaoVolume<=DSBVOLUME_MIN)
		{
			m_nYinXiaoVolume=DSBVOLUME_MIN;	
			GetBuffer()->SetVolume(m_nYinXiaoVolume);
			return;
		}
		m_nYinXiaoVolume-=(DSBVOLUME_MAX-DSBVOLUME_MIN)/percent;
		if (m_nYinXiaoVolume<=DSBVOLUME_MIN)
			m_nYinXiaoVolume=DSBVOLUME_MIN;
		GetBuffer()->SetVolume(m_nYinXiaoVolume);
	}

}

void CDSBuffer::VolumeUp(int percent)
{
	if (percent<=0 )
		percent=1;
	if (percent>=100)
		percent=100;
    if (m_bBkGrdMusic)    //如果是背景音乐,则设置背景音乐音量
	{
		if (m_nBkGrdVolume>=DSBVOLUME_MAX)
		{
			m_nBkGrdVolume=DSBVOLUME_MAX;
			GetBuffer()->SetVolume(m_nBkGrdVolume);
			return;
		}
		m_nBkGrdVolume+=(DSBVOLUME_MAX-DSBVOLUME_MIN)/10;
		if (m_nBkGrdVolume>=DSBVOLUME_MAX)
			m_nBkGrdVolume=DSBVOLUME_MAX;
		GetBuffer()->SetVolume(m_nBkGrdVolume);
	}
	else                //是音效,则设置音效音量
	{
		if (m_nYinXiaoVolume>=DSBVOLUME_MAX)
		{
			m_nYinXiaoVolume=DSBVOLUME_MAX;
			GetBuffer()->SetVolume(m_nYinXiaoVolume);
			return;
		}
		m_nYinXiaoVolume+=(DSBVOLUME_MAX-DSBVOLUME_MIN)/10;
		if (m_nYinXiaoVolume>=DSBVOLUME_MAX)
			m_nYinXiaoVolume=DSBVOLUME_MAX;
		GetBuffer()->SetVolume(m_nYinXiaoVolume);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -