【VC开源代码栏目提醒】:以下是网学会员为您推荐的VC开源代码-DSBuffer.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
上一篇:
DrvSrlNmbrDlg.cpp
下一篇:
为定制而来 欧马可快递物流一体化解决方案抢滩苏浙沪