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

游戏

开发平台:

Visual C++

  1. // CMAIN LIB - APPLICATION AND DIRECT WRAPPER
  2. //
  3. // Written by Mauricio Teichmann Ritter
  4. //
  5. // Copyright (C) 2002, Brazil. All rights reserved.
  6. // 
  7. //
  8. // cSound.cpp: implementation of the cSound class.
  9. //
  10. //////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "cSound.h"
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. cSound::cSound()
  17. {
  18. m_bIsPlaying = FALSE;
  19. m_sFileName  = NULL;
  20. m_pWaveFile = NULL;
  21. m_pSoundBuffer = NULL;
  22. m_p3DInterface = NULL;
  23. }
  24. cSound::~cSound()
  25. {
  26. if(m_sFileName)
  27. free(m_sFileName);
  28. if(m_pWaveFile)
  29. delete m_pWaveFile;
  30. if(m_pSoundBuffer)
  31. {
  32. Stop();
  33. m_pSoundBuffer->Release();
  34. m_pSoundBuffer = NULL;
  35. }
  36. }
  37. HRESULT cSound::Create(LPTSTR lpszFileName, DWORD dwCreationFlags, GUID guid3DAlgorithm)
  38. {
  39. Destroy();
  40.     HRESULT hr;
  41.     HRESULT hrRet = S_OK;
  42.     DWORD                dwDSBufferSize = NULL;
  43. cSoundInterface  pSoundInterface;
  44. /* if(MAKEINTRESOURCE(lpszFileName))
  45. {
  46. m_sFileName = (char*)malloc(strlen(lpszFileName)+1);
  47. strcpy(m_sFileName, lpszFileName);
  48. }
  49. else
  50. {
  51. m_sFileName = lpszFileName;
  52. }*/
  53.     if( lpszFileName == NULL )
  54.         return E_INVALIDARG;
  55.     m_pWaveFile = new cWavFile();
  56.     if( m_pWaveFile == NULL )
  57.     {
  58.         hr = E_OUTOFMEMORY;
  59.         goto LFail;
  60.     }
  61.     if(m_pWaveFile->Open( lpszFileName, NULL, WAVEFILE_READ ) != 0)
  62. {
  63. DXTRACE_MSG("Didn磘 find resource!");
  64. }
  65.     if( m_pWaveFile->GetSize() == 0 )
  66.     {
  67.         // Wave is blank, so don't create it.
  68.         hr = E_FAIL;
  69.         goto LFail;
  70.     }
  71.     // Make the DirectSound buffer the same size as the wav file
  72.     dwDSBufferSize = m_pWaveFile->GetSize();
  73. m_dwDSBufferSize = dwDSBufferSize;
  74.     // Create the direct sound buffer, and only request the flags needed
  75.     // since each requires some overhead and limits if the buffer can 
  76.     // be hardware accelerated
  77.     DSBUFFERDESC dsbd;
  78.     ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
  79.     dsbd.dwSize          = sizeof(DSBUFFERDESC);
  80.     dsbd.dwFlags         = dwCreationFlags;
  81.     dsbd.dwBufferBytes   = dwDSBufferSize;
  82.     dsbd.guid3DAlgorithm = guid3DAlgorithm;
  83.     dsbd.lpwfxFormat     = m_pWaveFile->m_pwfx;
  84.     // DirectSound is only guarenteed to play PCM data.  Other
  85.     // formats may or may not work depending the sound card driver.
  86.     hr = pSoundInterface.GetDirectSound()->CreateSoundBuffer( &dsbd, &m_pSoundBuffer, NULL );
  87.     // Be sure to return this error code if it occurs so the
  88.     // callers knows this happened.
  89.     if( hr == DS_NO_VIRTUALIZATION )
  90.         hrRet = DS_NO_VIRTUALIZATION;
  91.             
  92.     if( FAILED(hr) )
  93.     {
  94.         // DSERR_BUFFERTOOSMALL will be returned if the buffer is
  95.         // less than DSBSIZE_FX_MIN (100ms) and the buffer is created
  96.         // with DSBCAPS_CTRLFX.
  97.         if( hr != DSERR_BUFFERTOOSMALL )
  98.             DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );
  99.             
  100.         goto LFail;
  101.     }
  102.     // Make sure we have focus, and we didn't just switch in from
  103.     // an app which had a DirectSound device
  104.     if( FAILED( hr = RestoreBuffer( NULL ) ) ) 
  105.         return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
  106. FillBuffer();
  107.     return S_OK;
  108. LFail:
  109.     // Cleanup
  110.     return hr;
  111. }
  112. HRESULT cSound::Play(DWORD dwPriority, DWORD dwFlags)
  113. {
  114. BOOL bRestored;
  115. HRESULT hRet;
  116. DWORD dwStatus;
  117. hRet = m_pSoundBuffer->GetStatus(&dwStatus);
  118. if(hRet != 0)
  119. return -1;
  120. if( !(dwStatus & DSBSTATUS_PLAYING) )
  121. m_bIsPlaying = FALSE;
  122. if(m_bIsPlaying == TRUE)
  123. return S_OK;
  124. RestoreBuffer(&bRestored);
  125. if(bRestored)
  126. FillBuffer();
  127. // else
  128. // DXTRACE_MSG("BUFFER NOT RESTORED");
  129. // DXTRACE_MSG("START PLAY");
  130. m_pSoundBuffer->Play(0, dwPriority, dwFlags);
  131. m_bIsPlaying = TRUE;
  132. return S_OK;
  133. }
  134. HRESULT cSound::RestoreBuffer(BOOL *bRestored)
  135. {
  136.     HRESULT hr;
  137.     if( m_pSoundBuffer == NULL )
  138.         return CO_E_NOTINITIALIZED;
  139.     if( bRestored )
  140.         *bRestored = FALSE;
  141.     DWORD dwStatus;
  142.     if( FAILED( hr = m_pSoundBuffer->GetStatus( &dwStatus ) ) )
  143.         return DXTRACE_ERR( TEXT("GetStatus"), hr );
  144.     if( dwStatus & DSBSTATUS_BUFFERLOST )
  145.     {
  146.         // Since the app could have just been activated, then DirectSound 
  147.         // may not be giving us control yet, so restoring the buffer may fail.  
  148.         // If it does, sleep until DirectSound gives us control.
  149.         do 
  150.         {
  151.             hr = m_pSoundBuffer->Restore();
  152.             if( hr == DSERR_BUFFERLOST )
  153.                 Sleep( 10 );
  154.         }
  155.         while( hr != DS_OK );
  156.         if( bRestored != NULL )
  157.             *bRestored = TRUE;
  158.         return S_OK;
  159.     }
  160.     else
  161.     {
  162.         return S_FALSE;
  163.     }
  164. }
  165. LPDIRECTSOUND3DBUFFER cSound::Get3DInterface()
  166. {
  167.     if(!m_p3DInterface)
  168. {
  169. m_pSoundBuffer->QueryInterface( IID_IDirectSound3DBuffer, 
  170.                                                   (VOID**)&m_p3DInterface );
  171. }
  172. return m_p3DInterface;
  173. }
  174. HRESULT cSound::Stop(BOOL bOverride)
  175. {
  176. if(bOverride)
  177. {
  178. if(m_bIsPlaying == FALSE)
  179. return S_OK;
  180. }
  181. // DXTRACE_MSG("SOUND STOPPED");
  182. m_pSoundBuffer->Stop();
  183. m_bIsPlaying = FALSE;
  184. return S_OK;
  185. }
  186. HRESULT cSound::FillBuffer()
  187. {
  188. HRESULT hr;
  189.     VOID*   pDSLockedBuffer      = NULL; // Pointer to locked buffer memory
  190.     DWORD   dwDSLockedBufferSize = 0;    // Size of the locked DirectSound buffer
  191.     DWORD   dwWavDataRead        = 0;    // Amount of data read from the wav file 
  192.     // Lock the buffer down
  193.     if( FAILED( hr = m_pSoundBuffer->Lock( 0, m_dwDSBufferSize, 
  194.                                  &pDSLockedBuffer, &dwDSLockedBufferSize, 
  195.                                  NULL, NULL, 0L ) ) )
  196.         return DXTRACE_ERR( TEXT("Lock"), hr );
  197.     // Reset the wave file to the beginning 
  198.     m_pWaveFile->ResetFile();
  199.     if( FAILED( hr = m_pWaveFile->Read( (BYTE*) pDSLockedBuffer,
  200.                                         dwDSLockedBufferSize, 
  201.                                         &dwWavDataRead ) ) )           
  202.         return DXTRACE_ERR( TEXT("Read"), hr );
  203.     if( dwWavDataRead == 0 )
  204.     {
  205.         // Wav is blank, so just fill with silence
  206.         FillMemory( (BYTE*) pDSLockedBuffer, 
  207.                     dwDSLockedBufferSize, 
  208.                     (BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
  209.     }
  210.     // Unlock the buffer, we don't need it anymore.
  211.     m_pSoundBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
  212. return 0;
  213. }
  214. void cSound::SetPosition(float fX, float fY, float fZ)
  215. {
  216. Get3DInterface()->SetPosition(fX, fY, fZ, DS3D_IMMEDIATE);
  217. }
  218. void cSound::SetVelocity(float fX, float fY, float fZ)
  219. {
  220. Get3DInterface()->SetVelocity(fX, fY, fZ, DS3D_IMMEDIATE);
  221. }
  222. void cSound::Destroy()
  223. {
  224. if(m_sFileName)
  225. free(m_sFileName);
  226. if(m_pWaveFile)
  227. delete m_pWaveFile;
  228. if(m_p3DInterface)
  229. {
  230. m_p3DInterface->Release();
  231. m_p3DInterface = NULL;
  232. }
  233. if(m_pSoundBuffer)
  234. {
  235. Stop();
  236. m_pSoundBuffer->Release();
  237. m_pSoundBuffer = NULL;
  238. }
  239. }