Dsutil.hpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:9k
源码类别:

游戏

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       dsutil.cpp
  6.  *  Content:    Routines for dealing with sounds from resources
  7.  *
  8.  *
  9.  ***************************************************************************/
  10. #ifndef WIN32_LEAN_AND_MEAN
  11. #define WIN32_LEAN_AND_MEAN
  12. #endif
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include <mmsystem.h>
  16. #include <dsound.h>
  17. typedef struct
  18. {
  19.     BYTE *pbWaveData;               // pointer into wave resource (for restore)
  20.     DWORD cbWaveSize;               // size of wave data (for restore)
  21.     int iAlloc;                     // number of buffers.
  22.     int iCurrent;                   // current buffer
  23.     IDirectSoundBuffer* Buffers[1]; // list of buffers
  24. } SNDOBJ, *HSNDOBJ;
  25. #define _HSNDOBJ_DEFINED
  26. #include "dsutil.h"
  27. static const char c_szWAV[] = "WAV";
  28. ///////////////////////////////////////////////////////////////////////////////
  29. //
  30. // DSLoadSoundBuffer
  31. //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. IDirectSoundBuffer *DSLoadSoundBuffer(IDirectSound *pDS, LPCTSTR lpName)
  34. {
  35.     IDirectSoundBuffer *pDSB = NULL;
  36.     DSBUFFERDESC dsBD = {0};
  37.     BYTE *pbWaveData;
  38.     if (DSGetWaveResource(NULL, lpName, &dsBD.lpwfxFormat, &pbWaveData, &dsBD.dwBufferBytes))
  39.     {
  40. dsBD.dwSize = sizeof(dsBD);
  41. dsBD.dwFlags = DSBCAPS_STATIC | DSBCAPS_GETCURRENTPOSITION2;
  42. if (SUCCEEDED(IDirectSound_CreateSoundBuffer(pDS, &dsBD, &pDSB, NULL)))
  43. {
  44.     if (!DSFillSoundBuffer(pDSB, pbWaveData, dsBD.dwBufferBytes))
  45.     {
  46. IDirectSoundBuffer_Release(pDSB);
  47. pDSB = NULL;
  48.     }
  49. }
  50. else
  51. {
  52.     pDSB = NULL;
  53. }
  54.     }
  55.     return pDSB;
  56. }
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //
  59. // DSReloadSoundBuffer
  60. //
  61. ///////////////////////////////////////////////////////////////////////////////
  62. BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName)
  63. {
  64.     BOOL result=FALSE;
  65.     BYTE *pbWaveData;
  66.     DWORD cbWaveSize;
  67.     if (DSGetWaveResource(NULL, lpName, NULL, &pbWaveData, &cbWaveSize))
  68.     {
  69. if (SUCCEEDED(IDirectSoundBuffer_Restore(pDSB)) &&
  70.     DSFillSoundBuffer(pDSB, pbWaveData, cbWaveSize))
  71. {
  72.     result = TRUE;
  73. }
  74.     }
  75.     return result;
  76. }
  77. ///////////////////////////////////////////////////////////////////////////////
  78. //
  79. // DSGetWaveResource
  80. //
  81. ///////////////////////////////////////////////////////////////////////////////
  82. BOOL DSGetWaveResource(HMODULE hModule, LPCTSTR lpName,
  83.     WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData, DWORD *pcbWaveSize)
  84. {
  85.     HRSRC hResInfo;
  86.     HGLOBAL hResData;
  87.     void *pvRes;
  88.     if ((hResInfo = FindResource(hModule, lpName, c_szWAV)) != NULL)
  89. {
  90. if ((hResData = LoadResource(hModule, hResInfo)) != NULL) 
  91. {
  92. if ((pvRes = LockResource(hResData)) != NULL) 
  93. {
  94. if (DSParseWaveResource(pvRes, ppWaveHeader, ppbWaveData, pcbWaveSize))
  95. {
  96. return TRUE;
  97. }
  98. else
  99. OutputDebugString("Erro no ParseWaveResource");
  100. }
  101. else
  102. OutputDebugString("Erro no LockResource");
  103. }
  104. else
  105. OutputDebugString("Erro no LoadResource");
  106. }
  107. else
  108. OutputDebugString("Erro no FindResource");
  109. return FALSE;
  110. }
  111. ///////////////////////////////////////////////////////////////////////////////
  112. // SndObj fns
  113. ///////////////////////////////////////////////////////////////////////////////
  114. SNDOBJ *SndObjCreate(IDirectSound *pDS, LPCTSTR lpName, int iConcurrent)
  115. {
  116.     SNDOBJ *pSO = NULL;
  117.     LPWAVEFORMATEX pWaveHeader;
  118.     BYTE *pbData;
  119.     DWORD cbData;
  120.     if (DSGetWaveResource(NULL, lpName, &pWaveHeader, &pbData, &cbData))
  121.     {
  122. if (iConcurrent < 1)
  123.     iConcurrent = 1;
  124. if ((pSO = (SNDOBJ *)LocalAlloc(LPTR, sizeof(SNDOBJ) +
  125.     (iConcurrent-1) * sizeof(IDirectSoundBuffer *))) != NULL)
  126. {
  127.     int i;
  128.     pSO->iAlloc = iConcurrent;
  129.     pSO->pbWaveData = pbData;
  130.     pSO->cbWaveSize = cbData;
  131.     pSO->Buffers[0] = DSLoadSoundBuffer(pDS, lpName);
  132.     for (i=1; i<pSO->iAlloc; i++)
  133.     {
  134. if (FAILED(IDirectSound_DuplicateSoundBuffer(pDS,
  135.     pSO->Buffers[0], &pSO->Buffers[i])))
  136. {
  137.     pSO->Buffers[i] = DSLoadSoundBuffer(pDS, lpName);
  138.     if (!pSO->Buffers[i]) {
  139. SndObjDestroy(pSO);
  140. pSO = NULL;
  141. break;
  142.     }
  143. }
  144.     }
  145. }
  146.     }
  147. else
  148. OutputDebugString("PROBLEMA COM O UNISGNEDn");
  149.     return pSO;
  150. }
  151. ///////////////////////////////////////////////////////////////////////////////
  152. ///////////////////////////////////////////////////////////////////////////////
  153. void SndObjDestroy(SNDOBJ *pSO)
  154. {
  155.     if (pSO)
  156.     {
  157. int i;
  158. for (i=0; i<pSO->iAlloc; i++)
  159. {
  160.     if (pSO->Buffers[i])
  161.     {
  162. IDirectSoundBuffer_Release(pSO->Buffers[i]);
  163. pSO->Buffers[i] = NULL;
  164.     }
  165. }
  166. LocalFree((HANDLE)pSO);
  167.     }
  168. }
  169. ///////////////////////////////////////////////////////////////////////////////
  170. ///////////////////////////////////////////////////////////////////////////////
  171. IDirectSoundBuffer *SndObjGetFreeBuffer(SNDOBJ *pSO)
  172. {
  173.     IDirectSoundBuffer *pDSB;
  174.     if (pSO == NULL)
  175. return NULL;
  176.     if (pDSB = pSO->Buffers[pSO->iCurrent])
  177.     {
  178. HRESULT hres;
  179. DWORD dwStatus;
  180. hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
  181. if (FAILED(hres))
  182.     dwStatus = 0;
  183. if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
  184. {
  185.     if (pSO->iAlloc > 1)
  186.     {
  187. if (++pSO->iCurrent >= pSO->iAlloc)
  188.     pSO->iCurrent = 0;
  189. pDSB = pSO->Buffers[pSO->iCurrent];
  190. hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
  191. if (SUCCEEDED(hres) && (dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
  192. {
  193.     IDirectSoundBuffer_Stop(pDSB);
  194.     IDirectSoundBuffer_SetCurrentPosition(pDSB, 0);
  195. }
  196.     }
  197.     else
  198.     {
  199. pDSB = NULL;
  200.     }
  201. }
  202. if (pDSB && (dwStatus & DSBSTATUS_BUFFERLOST))
  203. {
  204.     if (FAILED(IDirectSoundBuffer_Restore(pDSB)) ||
  205. !DSFillSoundBuffer(pDSB, pSO->pbWaveData, pSO->cbWaveSize))
  206.     {
  207. pDSB = NULL;
  208.     }
  209. }
  210.     }
  211.     return pDSB;
  212. }
  213. ///////////////////////////////////////////////////////////////////////////////
  214. ///////////////////////////////////////////////////////////////////////////////
  215. BOOL SndObjPlay(SNDOBJ *pSO, DWORD dwPlayFlags)
  216. {
  217.     BOOL result = FALSE;
  218.     if (pSO == NULL)
  219. return FALSE;
  220.     if ((!(dwPlayFlags & DSBPLAY_LOOPING) || (pSO->iAlloc == 1)))
  221.     {
  222. IDirectSoundBuffer *pDSB = SndObjGetFreeBuffer(pSO);
  223. if (pDSB != NULL) {
  224.     result = SUCCEEDED(IDirectSoundBuffer_Play(pDSB, 0, 0, dwPlayFlags));
  225. }
  226.     }
  227.     return result;
  228. }
  229. ///////////////////////////////////////////////////////////////////////////////
  230. ///////////////////////////////////////////////////////////////////////////////
  231. BOOL SndObjStop(SNDOBJ *pSO)
  232. {
  233.     int i;
  234.     if (pSO == NULL)
  235. return FALSE;
  236.     for (i=0; i<pSO->iAlloc; i++)
  237.     {
  238. IDirectSoundBuffer_Stop(pSO->Buffers[i]);
  239. IDirectSoundBuffer_SetCurrentPosition(pSO->Buffers[i], 0);
  240.     }
  241.     return TRUE;
  242. }
  243. ///////////////////////////////////////////////////////////////////////////////
  244. ///////////////////////////////////////////////////////////////////////////////
  245. BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize)
  246. {
  247.     if (pDSB && pbWaveData && cbWaveSize)
  248.     {
  249. LPVOID pMem1, pMem2;
  250. DWORD dwSize1, dwSize2;
  251. if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize,
  252.     &pMem1, &dwSize1, &pMem2, &dwSize2, 0)))
  253. {
  254.     CopyMemory(pMem1, pbWaveData, dwSize1);
  255.     if ( 0 != dwSize2 )
  256. CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2);
  257.     IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2);
  258.     return TRUE;
  259. }
  260.     }
  261.     return FALSE;
  262. }
  263. ///////////////////////////////////////////////////////////////////////////////
  264. ///////////////////////////////////////////////////////////////////////////////
  265. BOOL DSParseWaveResource(void *pvRes, WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData,DWORD *pcbWaveSize)
  266. {
  267.     DWORD *pdw;
  268.     DWORD *pdwEnd;
  269.     DWORD dwRiff;
  270.     DWORD dwType;
  271.     DWORD dwLength;
  272.     if (ppWaveHeader)
  273. *ppWaveHeader = NULL;
  274.     if (ppbWaveData)
  275. *ppbWaveData = NULL;
  276.     if (pcbWaveSize)
  277. *pcbWaveSize = 0;
  278.     pdw = (DWORD *)pvRes;
  279.     dwRiff = *pdw++;
  280.     dwLength = *pdw++;
  281.     dwType = *pdw++;
  282.     if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
  283. goto exit;      // not even RIFF
  284.     if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
  285. goto exit;      // not a WAV
  286.     pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
  287.     while (pdw < pdwEnd)
  288.     {
  289. dwType = *pdw++;
  290. dwLength = *pdw++;
  291. switch (dwType)
  292. {
  293. case mmioFOURCC('f', 'm', 't', ' '):
  294.     if (ppWaveHeader && !*ppWaveHeader)
  295.     {
  296. if (dwLength < sizeof(WAVEFORMAT))
  297.     goto exit;      // not a WAV
  298. *ppWaveHeader = (WAVEFORMATEX *)pdw;
  299. if ((!ppbWaveData || *ppbWaveData) &&
  300.     (!pcbWaveSize || *pcbWaveSize))
  301. {
  302.     return TRUE;
  303. }
  304.     }
  305.     break;
  306. case mmioFOURCC('d', 'a', 't', 'a'):
  307.     if ((ppbWaveData && !*ppbWaveData) ||
  308. (pcbWaveSize && !*pcbWaveSize))
  309.     {
  310. if (ppbWaveData)
  311.     *ppbWaveData = (LPBYTE)pdw;
  312. if (pcbWaveSize)
  313.     *pcbWaveSize = dwLength;
  314. if (!ppWaveHeader || *ppWaveHeader)
  315.     return TRUE;
  316.     }
  317.     break;
  318. }
  319. pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
  320.     }
  321. exit:
  322. OutputDebugString("Erro no parse do RESOURCE");
  323.     return FALSE;
  324. }