头文件
#if !defined(AFX_DIRECTSOUND_H__A20FE86F_118F_11D2_9AB3_0060B0CDC13E__INCLUDED_)
#define AFX_DIRECTSOUND_H__A20FE86F_118F_11D2_9AB3_0060B0CDC13E__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include
#include
#pragma message("linking with Microsoft's DirectSound library ...")
#pragma comment(lib, "dsound.lib")
class CDirectSound
{
public:
// 构造、析构函数
CDirectSound();
virtual ~CDirectSound();
//创建DirectSound对象
BOOL Create(LPCTSTR pszResource, CWnd * pWnd = 0);
BOOL Create(UINT uResourceID, CWnd * pWnd = 0) {
return Create(MAKEINTRESOURCE(uResourceID), pWnd);
}
BOOL Create(LPVOID pSoundData, CWnd * pWnd = 0);
public:
//操作函数
BOOL IsValid() const;
void Play(DWORD dwStartPosition = 0, BOOL bLoop = FALSE);
void Stop();
void Pause();
void Continue();
CDirectSound & EnableSound(BOOL bEnable = TRUE) {
m_bEnabled = bEnable;
if( ! bEnable )
Stop();
return * this;
}
BOOL IsEnabled() const { return m_bEnabled; }
protected:
//设置声音数据缓冲区
BOOL SetSoundData(LPVOID pSoundData, DWORD dwSoundSize);
//创建DirectSoundBuffer
BOOL CreateSoundBuffer(WAVEFORMATEX * pcmwf);
//获取Wave数据
BOOL GetWaveData(void * pRes, WAVEFORMATEX * & pWaveHeader, void * & pbWaveData, DWORD & cbWaveSize);
private:
//声音数据
LPVOID m_pTheSound;
//数据大小
DWORD m_dwTheSound;
//DirectSoundBuffer指针
LPDIRECTSOUNDBUFFER m_pDsb;
BOOL m_bEnabled;
//DirectSound对象
static LPDIRECTSOUND m_lpDirectSound;
static DWORD m_dwInstances;
};
#endif // !defined(AFX_DIRECTSOUND_H__A20FE86F_118F_11D2_9AB3_0060B0CDC13E__INCLUDED_)
类的主体
- #include"stdafx.h"
- #include"DirectSound.h"
- //ThefollowingmacroisdefinedsinceDirectX5,butwillworkwith
- //olderversionstoo.
- #ifndefDSBLOCK_ENTIREBUFFER
- #defineDSBLOCK_ENTIREBUFFER0x00000002
- #endif
- #ifdef_DEBUG
- #undefTHIS_FILE
- staticcharTHIS_FILE[]=__FILE__;
- #definenewDEBUG_NEW
- #endif
- staticvoidDSError(HRESULThRes){
- switch(hRes){
- caseDS_OK:TRACE0("NOERROR\n");break;
- caseDSERR_ALLOCATED:TRACE0("ALLOCATED\n");break;
- caseDSERR_INVALIDPARAM:TRACE0("INVALIDPARAM\n");break;
- caseDSERR_OUTOFMEMORY:TRACE0("OUTOFMEMORY\n");break;
- caseDSERR_UNSUPPORTED:TRACE0("UNSUPPORTED\n");break;
- caseDSERR_NOAGGREGATION:TRACE0("NOAGGREGATION\n");break;
- caseDSERR_UNINITIALIZED:TRACE0("UNINITIALIZED\n");break;
- caseDSERR_BADFORMAT:TRACE0("BADFORMAT\n");break;
- caseDSERR_ALREADYINITIALIZED:TRACE0("ALREADYINITIALIZED\n");break;
- caseDSERR_BUFFERLOST:TRACE0("BUFFERLOST\n");break;
- caseDSERR_CONTROLUNAVAIL:TRACE0("CONTROLUNAVAIL\n");break;
- caseDSERR_GENERIC:TRACE0("GENERIC\n");break;
- caseDSERR_INVALIDCALL:TRACE0("INVALIDCALL\n");break;
- caseDSERR_OTHERAPPHASPRIO:TRACE0("OTHERAPPHASPRIO\n");break;
- caseDSERR_PRIOLEVELNEEDED:TRACE0("PRIOLEVELNEEDED\n");break;
- default:TRACE1("%lu\n",hRes);break;
- }
- }
- //
- //Construction/Destruction
- //
- LPDIRECTSOUNDCDirectSound::m_lpDirectSound;
- DWORDCDirectSound::m_dwInstances;
- CDirectSound::CDirectSound()
- {
- m_lpDirectSound=0;
- m_pDsb=0;
- m_pTheSound=0;
- m_dwTheSound=0;
- m_bEnabled=TRUE;
- ++m_dwInstances;
- }
- CDirectSound::~CDirectSound()
- {
- if(m_pDsb)
- m_pDsb->Release();
- if(!--m_dwInstances&&m_lpDirectSound){
- m_lpDirectSound->Release();
- m_lpDirectSound=0;
- }
- }
- BOOLCDirectSound::Create(LPCTSTRpszResource,CWnd*pWnd)
- {
- //
- //loadresource
- HINSTANCEhApp=::GetModuleHandle(0);
- ASSERT(hApp);
- HRSRChResInfo=::FindResource(hApp,pszResource,TEXT("WAVE"));
- if(hResInfo==0)
- returnFALSE;
- HGLOBALhRes=::LoadResource(hApp,hResInfo);
- if(hRes==0)
- returnFALSE;
- LPVOIDpTheSound=::LockResource(hRes);
- if(pTheSound==0)
- returnFALSE;
- returnCreate(pTheSound,pWnd);
- }
- BOOLCDirectSound::Create(LPVOIDpSoundData,CWnd*pWnd){
- //获取窗口句柄
- if(pWnd==0)
- pWnd=AfxGetApp()->GetMainWnd();
- ASSERT(pWnd!=0);
- ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
- ASSERT(pSoundData!=0);
- //创建DirectSound对象
- if(m_lpDirectSound==0)
- {
- HRESULThRes=DS_OK;
- shortnRes=0;
- do{
- if(nRes)
- ::Sleep(500);
- hRes=::DirectSoundCreate(0,&m_lpDirectSound,0);
- ++nRes;
- }while(nRes<10&&(hRes==DSERR_ALLOCATED||hRes==DSERR_NODRIVER));
- if(hRes!=DS_OK)
- returnFALSE;
- //设置协调模式
- m_lpDirectSound->SetCooperativeLevel(pWnd->GetSafeHwnd(),DSSCL_NORMAL);
- }
- ASSERT(m_lpDirectSound!=0);
- //准备数据
- WAVEFORMATEX*pcmwf;
- if(!GetWaveData(pSoundData,pcmwf,m_pTheSound,m_dwTheSound)||
- !CreateSoundBuffer(pcmwf)||
- !SetSoundData(m_pTheSound,m_dwTheSound))
- returnFALSE;
- returnTRUE;
- }
- BOOLCDirectSound::GetWaveData(void*pRes,WAVEFORMATEX*&pWaveHeader,void*&pbWaveData,DWORD&cbWaveSize){
- pWaveHeader=0;
- pbWaveData=0;
- cbWaveSize=0;
- DWORD*pdw=(DWORD*)pRes;
- DWORDdwRiff=*pdw++;
- DWORDdwLength=*pdw++;
- DWORDdwType=*pdw++;
- //检验“RIFF”标志
- if(dwRiff!=mmioFOURCC('R','I','F','F'))
- returnFALSE;
- //检验“WAVE”标志
- if(dwType!=mmioFOURCC('W','A','V','E'))
- returnFALSE;
- //指向声音数据
- DWORD*pdwEnd=(DWORD*)((BYTE*)pdw+dwLength-4);
- //查找声音数据
- while(pdw<pdwEnd)
- {
- dwType=*pdw++;
- dwLength=*pdw++;
- switch(dwType){
- casemmioFOURCC('f','m','t',''):
- if(!pWaveHeader)
- {
- if(dwLength<sizeof(WAVEFORMAT))
- returnFALSE;
- pWaveHeader=(WAVEFORMATEX*)pdw;
- if(pbWaveData&&cbWaveSize)
- returnTRUE;
- }
- break;
- casemmioFOURCC('d','a','t','a'):
- pbWaveData=LPVOID(pdw);
- cbWaveSize=dwLength;
- if(pWaveHeader)
- returnTRUE;
- break;
- }
- pdw=(DWORD*)((BYTE*)pdw+((dwLength+1)&~1));
- }
- returnFALSE;
- }
- BOOLCDirectSound::CreateSoundBuffer(WAVEFORMATEX*pcmwf)
- {
- DSBUFFERDESCdsbdesc;
- //初始化DSBUFFERDESCstructure.
- memset(&dsbdesc,0,sizeof(DSBUFFERDESC));
- dsbdesc.dwSize=sizeof(DSBUFFERDESC);
- //不需要控制pan,volume,frequency
- dsbdesc.dwFlags=DSBCAPS_STATIC;
- dsbdesc.dwBufferBytes=m_dwTheSound;
- dsbdesc.lpwfxFormat=pcmwf;
- HRESULThRes;
- if(DS_OK!=(hRes=m_lpDirectSound->CreateSoundBuffer(&dsbdesc,&m_pDsb,0)))
- {
- //Failed.
- DSError(hRes);
- m_pDsb=0;
- returnFALSE;
- }
- returnTRUE;
- }
- BOOLCDirectSound::SetSoundData(void*pSoundData,DWORDdwSoundSize){
- LPVOIDlpvPtr1;
- DWORDdwBytes1;
- //获取一块内存
- HRESULThr=m_pDsb->Lock(0,0,&lpvPtr1,&dwBytes1,0,0,DSBLOCK_ENTIREBUFFER);
- //如果失败,重新分配
- if(DSERR_BUFFERLOST==hr)
- {
- m_pDsb->Restore();
- hr=m_pDsb->Lock(0,0,&lpvPtr1,&dwBytes1,0,0,DSBLOCK_ENTIREBUFFER);
- }
- if(DS_OK==hr){
- //复制声音数据
- ::CopyMemory(lpvPtr1,pSoundData,dwBytes1);
- //释放锁定的内存块
- hr=m_pDsb->Unlock(lpvPtr1,dwBytes1,0,0);
- if(DS_OK==hr)
- returnTRUE;
- }
- returnFALSE;
- }
- voidCDirectSound::Play(DWORDdwStartPosition,BOOLbLoop)
- {
- if(!IsValid()||!IsEnabled())
- return;
- //播放位置边界检验
- if(dwStartPosition>m_dwTheSound)
- dwStartPosition=m_dwTheSound;
- //重新设置播放位置
- m_pDsb->SetCurrentPosition(dwStartPosition);
- //开始播放
- if(DSERR_BUFFERLOST==m_pDsb->Play(0,0,bLoop?DSBPLAY_LOOPING:0)){
- SetSoundData(m_pTheSound,m_dwTheSound);
- m_pDsb->Play(0,0,bLoop?DSBPLAY_LOOPING:0);
- }
- }
- voidCDirectSound::Stop()
- {
- if(IsValid())
- m_pDsb->Stop();
- }
- voidCDirectSound::Pause()
- {
- Stop();
- }
- voidCDirectSound::Continue()
- {
- if(IsValid())
- {
- DWORDdwPlayCursor,dwWriteCursor;
- m_pDsb->GetCurrentPosition(&dwPlayCursor,&dwWriteCursor);
- Play(dwPlayCursor);
- }
- }
- BOOLCDirectSound::IsValid()const
- {
- return(m_lpDirectSound&&m_pDsb&&m_pTheSound&&m_dwTheSound)?TRUE:FALSE;
- }