`

一个vc++ direct sound播放wav文件的类

 
阅读更多

头文件

#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_)

类的主体

  1. #include"stdafx.h"
  2. #include"DirectSound.h"
  3. //ThefollowingmacroisdefinedsinceDirectX5,butwillworkwith
  4. //olderversionstoo.
  5. #ifndefDSBLOCK_ENTIREBUFFER
  6. #defineDSBLOCK_ENTIREBUFFER0x00000002
  7. #endif
  8. #ifdef_DEBUG
  9. #undefTHIS_FILE
  10. staticcharTHIS_FILE[]=__FILE__;
  11. #definenewDEBUG_NEW
  12. #endif
  13. staticvoidDSError(HRESULThRes){
  14. switch(hRes){
  15. caseDS_OK:TRACE0("NOERROR/n");break;
  16. caseDSERR_ALLOCATED:TRACE0("ALLOCATED/n");break;
  17. caseDSERR_INVALIDPARAM:TRACE0("INVALIDPARAM/n");break;
  18. caseDSERR_OUTOFMEMORY:TRACE0("OUTOFMEMORY/n");break;
  19. caseDSERR_UNSUPPORTED:TRACE0("UNSUPPORTED/n");break;
  20. caseDSERR_NOAGGREGATION:TRACE0("NOAGGREGATION/n");break;
  21. caseDSERR_UNINITIALIZED:TRACE0("UNINITIALIZED/n");break;
  22. caseDSERR_BADFORMAT:TRACE0("BADFORMAT/n");break;
  23. caseDSERR_ALREADYINITIALIZED:TRACE0("ALREADYINITIALIZED/n");break;
  24. caseDSERR_BUFFERLOST:TRACE0("BUFFERLOST/n");break;
  25. caseDSERR_CONTROLUNAVAIL:TRACE0("CONTROLUNAVAIL/n");break;
  26. caseDSERR_GENERIC:TRACE0("GENERIC/n");break;
  27. caseDSERR_INVALIDCALL:TRACE0("INVALIDCALL/n");break;
  28. caseDSERR_OTHERAPPHASPRIO:TRACE0("OTHERAPPHASPRIO/n");break;
  29. caseDSERR_PRIOLEVELNEEDED:TRACE0("PRIOLEVELNEEDED/n");break;
  30. default:TRACE1("%lu/n",hRes);break;
  31. }
  32. }
  33. //////////////////////////////////////////////////////////////////////
  34. //Construction/Destruction
  35. //////////////////////////////////////////////////////////////////////
  36. LPDIRECTSOUNDCDirectSound::m_lpDirectSound;
  37. DWORDCDirectSound::m_dwInstances;
  38. CDirectSound::CDirectSound()
  39. {
  40. m_lpDirectSound=0;
  41. m_pDsb=0;
  42. m_pTheSound=0;
  43. m_dwTheSound=0;
  44. m_bEnabled=TRUE;
  45. ++m_dwInstances;
  46. }
  47. CDirectSound::~CDirectSound()
  48. {
  49. if(m_pDsb)
  50. m_pDsb->Release();
  51. if(!--m_dwInstances&&m_lpDirectSound){
  52. m_lpDirectSound->Release();
  53. m_lpDirectSound=0;
  54. }
  55. }
  56. BOOLCDirectSound::Create(LPCTSTRpszResource,CWnd*pWnd)
  57. {
  58. //////////////////////////////////////////////////////////////////
  59. //loadresource
  60. HINSTANCEhApp=::GetModuleHandle(0);
  61. ASSERT(hApp);
  62. HRSRChResInfo=::FindResource(hApp,pszResource,TEXT("WAVE"));
  63. if(hResInfo==0)
  64. returnFALSE;
  65. HGLOBALhRes=::LoadResource(hApp,hResInfo);
  66. if(hRes==0)
  67. returnFALSE;
  68. LPVOIDpTheSound=::LockResource(hRes);
  69. if(pTheSound==0)
  70. returnFALSE;
  71. returnCreate(pTheSound,pWnd);
  72. }
  73. BOOLCDirectSound::Create(LPVOIDpSoundData,CWnd*pWnd){
  74. //获取窗口句柄
  75. if(pWnd==0)
  76. pWnd=AfxGetApp()->GetMainWnd();
  77. ASSERT(pWnd!=0);
  78. ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
  79. ASSERT(pSoundData!=0);
  80. //创建DirectSound对象
  81. if(m_lpDirectSound==0)
  82. {
  83. HRESULThRes=DS_OK;
  84. shortnRes=0;
  85. do{
  86. if(nRes)
  87. ::Sleep(500);
  88. hRes=::DirectSoundCreate(0,&m_lpDirectSound,0);
  89. ++nRes;
  90. }while(nRes<10&&(hRes==DSERR_ALLOCATED||hRes==DSERR_NODRIVER));
  91. if(hRes!=DS_OK)
  92. returnFALSE;
  93. //设置协调模式
  94. m_lpDirectSound->SetCooperativeLevel(pWnd->GetSafeHwnd(),DSSCL_NORMAL);
  95. }
  96. ASSERT(m_lpDirectSound!=0);
  97. //准备数据
  98. WAVEFORMATEX*pcmwf;
  99. if(!GetWaveData(pSoundData,pcmwf,m_pTheSound,m_dwTheSound)||
  100. !CreateSoundBuffer(pcmwf)||
  101. !SetSoundData(m_pTheSound,m_dwTheSound))
  102. returnFALSE;
  103. returnTRUE;
  104. }
  105. BOOLCDirectSound::GetWaveData(void*pRes,WAVEFORMATEX*&pWaveHeader,void*&pbWaveData,DWORD&cbWaveSize){
  106. pWaveHeader=0;
  107. pbWaveData=0;
  108. cbWaveSize=0;
  109. DWORD*pdw=(DWORD*)pRes;
  110. DWORDdwRiff=*pdw++;
  111. DWORDdwLength=*pdw++;
  112. DWORDdwType=*pdw++;
  113. //检验“RIFF”标志
  114. if(dwRiff!=mmioFOURCC('R','I','F','F'))
  115. returnFALSE;
  116. //检验“WAVE”标志
  117. if(dwType!=mmioFOURCC('W','A','V','E'))
  118. returnFALSE;
  119. //指向声音数据
  120. DWORD*pdwEnd=(DWORD*)((BYTE*)pdw+dwLength-4);
  121. //查找声音数据
  122. while(pdw<pdwEnd)
  123. {
  124. dwType=*pdw++;
  125. dwLength=*pdw++;
  126. switch(dwType){
  127. casemmioFOURCC('f','m','t',''):
  128. if(!pWaveHeader)
  129. {
  130. if(dwLength<sizeof(WAVEFORMAT))
  131. returnFALSE;
  132. pWaveHeader=(WAVEFORMATEX*)pdw;
  133. if(pbWaveData&&cbWaveSize)
  134. returnTRUE;
  135. }
  136. break;
  137. casemmioFOURCC('d','a','t','a'):
  138. pbWaveData=LPVOID(pdw);
  139. cbWaveSize=dwLength;
  140. if(pWaveHeader)
  141. returnTRUE;
  142. break;
  143. }
  144. pdw=(DWORD*)((BYTE*)pdw+((dwLength+1)&~1));
  145. }
  146. returnFALSE;
  147. }
  148. BOOLCDirectSound::CreateSoundBuffer(WAVEFORMATEX*pcmwf)
  149. {
  150. DSBUFFERDESCdsbdesc;
  151. //初始化DSBUFFERDESCstructure.
  152. memset(&dsbdesc,0,sizeof(DSBUFFERDESC));
  153. dsbdesc.dwSize=sizeof(DSBUFFERDESC);
  154. //不需要控制pan,volume,frequency
  155. dsbdesc.dwFlags=DSBCAPS_STATIC;
  156. dsbdesc.dwBufferBytes=m_dwTheSound;
  157. dsbdesc.lpwfxFormat=pcmwf;
  158. HRESULThRes;
  159. if(DS_OK!=(hRes=m_lpDirectSound->CreateSoundBuffer(&dsbdesc,&m_pDsb,0)))
  160. {
  161. //Failed.
  162. DSError(hRes);
  163. m_pDsb=0;
  164. returnFALSE;
  165. }
  166. returnTRUE;
  167. }
  168. BOOLCDirectSound::SetSoundData(void*pSoundData,DWORDdwSoundSize){
  169. LPVOIDlpvPtr1;
  170. DWORDdwBytes1;
  171. //获取一块内存
  172. HRESULThr=m_pDsb->Lock(0,0,&lpvPtr1,&dwBytes1,0,0,DSBLOCK_ENTIREBUFFER);
  173. //如果失败,重新分配
  174. if(DSERR_BUFFERLOST==hr)
  175. {
  176. m_pDsb->Restore();
  177. hr=m_pDsb->Lock(0,0,&lpvPtr1,&dwBytes1,0,0,DSBLOCK_ENTIREBUFFER);
  178. }
  179. if(DS_OK==hr){
  180. //复制声音数据
  181. ::CopyMemory(lpvPtr1,pSoundData,dwBytes1);
  182. //释放锁定的内存块
  183. hr=m_pDsb->Unlock(lpvPtr1,dwBytes1,0,0);
  184. if(DS_OK==hr)
  185. returnTRUE;
  186. }
  187. returnFALSE;
  188. }
  189. voidCDirectSound::Play(DWORDdwStartPosition,BOOLbLoop)
  190. {
  191. if(!IsValid()||!IsEnabled())
  192. return;
  193. //播放位置边界检验
  194. if(dwStartPosition>m_dwTheSound)
  195. dwStartPosition=m_dwTheSound;
  196. //重新设置播放位置
  197. m_pDsb->SetCurrentPosition(dwStartPosition);
  198. //开始播放
  199. if(DSERR_BUFFERLOST==m_pDsb->Play(0,0,bLoop?DSBPLAY_LOOPING:0)){
  200. SetSoundData(m_pTheSound,m_dwTheSound);
  201. m_pDsb->Play(0,0,bLoop?DSBPLAY_LOOPING:0);
  202. }
  203. }
  204. voidCDirectSound::Stop()
  205. {
  206. if(IsValid())
  207. m_pDsb->Stop();
  208. }
  209. voidCDirectSound::Pause()
  210. {
  211. Stop();
  212. }
  213. voidCDirectSound::Continue()
  214. {
  215. if(IsValid())
  216. {
  217. DWORDdwPlayCursor,dwWriteCursor;
  218. m_pDsb->GetCurrentPosition(&dwPlayCursor,&dwWriteCursor);
  219. Play(dwPlayCursor);
  220. }
  221. }
  222. BOOLCDirectSound::IsValid()const
  223. {
  224. return(m_lpDirectSound&&m_pDsb&&m_pTheSound&&m_dwTheSound)?TRUE:FALSE;
  225. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics