DSBuffer.cpp
上传用户:sdpcwz
上传日期:2009-12-14
资源大小:1237k
文件大小:7k
- // 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);
- }
- }