home *** CD-ROM | disk | FTP | other *** search
/ Game Audio Programming / GameAudioProgramming.iso / Game_Audio / audio_sdk / src / AudioLib / BufferCache.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-07-16  |  4.3 KB  |  170 lines

  1. /***********************************************************\
  2. Copyright (C) James Boer, 2002. 
  3. All rights reserved worldwide.
  4.  
  5. This software is provided "as is" without express or implied
  6. warranties. You may freely copy and compile this source into
  7. applications you distribute provided that the copyright text
  8. below is included in the resulting source code, for example:
  9. "Portions Copyright (C) James Boer, 2002"
  10. \***********************************************************/
  11.  
  12. #include "BufferCache.h"
  13. #include "AudioMgr.h"
  14.  
  15. using namespace Audio;
  16.  
  17.  
  18. bool operator == (const WAVEFORMATEX& left, const WAVEFORMATEX& right)
  19. {
  20.     if((left.nAvgBytesPerSec == right.nAvgBytesPerSec) &&
  21.         (left.nBlockAlign == right.nBlockAlign) &&
  22.         (left.nChannels == right.nChannels) &&
  23.         (left.nSamplesPerSec == right.nSamplesPerSec) &&
  24.         (left.wBitsPerSample == right.wBitsPerSample) &&
  25.         (left.wFormatTag == right.wFormatTag) &&
  26.         (left.cbSize == right.cbSize))
  27.         return true;
  28.     return false;
  29. }
  30.  
  31. bool operator == (const DSBUFFERDESC& left, const DSBUFFERDESC& right)
  32. {
  33.     if((left.dwBufferBytes == right.dwBufferBytes) &&
  34.         (left.dwFlags == right.dwFlags) &&
  35.         (*left.lpwfxFormat == *right.lpwfxFormat))
  36.         return true;
  37.     return false;
  38. }
  39.  
  40. BufferCache::BufferCache()
  41. {
  42. }
  43.  
  44. BufferCache::~BufferCache()
  45. {
  46. }
  47.  
  48. void BufferCache::Clear()
  49. {
  50.     m_Free.clear();
  51.     m_Used.clear();
  52. }
  53.  
  54.  
  55. void BufferCache::Init()
  56. {
  57.     m_Free.reserve(128);
  58.     m_Used.reserve(128);
  59. }
  60.  
  61. void BufferCache::Term()
  62. {
  63.     BufferInfoVector::iterator itr;
  64.     for(itr = m_Free.begin(); itr != m_Free.end(); ++itr)
  65.     {
  66.         (*itr)->m_pBuffer->Release();
  67.         delete (*itr);
  68.     }
  69.     for(itr = m_Used.begin(); itr != m_Used.end(); ++itr)
  70.     {
  71.         (*itr)->m_pBuffer->Release();
  72.         delete (*itr);
  73.     }
  74. }
  75.  
  76.  
  77. bool BufferCache::Acquire(const DSBUFFERDESC& desc, IDirectSoundBuffer8*& pBuffer, bool bUseCache)
  78. {
  79.  
  80.     // If buffer caching is enabled, try to find a 
  81.     // buffer with a matching description structure
  82.     if(DXAudioMgr()->GetInit()->m_bCacheBuffers && bUseCache)
  83.     {
  84.         BufferInfoVector::iterator itr;
  85.         for(itr = m_Free.begin(); itr != m_Free.end(); ++itr)
  86.         {
  87.             if((*itr)->m_Desc == desc)
  88.             {
  89.                 pBuffer = (*itr)->m_pBuffer;
  90.                 pBuffer->SetCurrentPosition(0);
  91.                 pBuffer->AddRef();
  92.                 m_Used.push_back(*itr);
  93.                 m_Free.erase(itr);
  94.                 return true;
  95.             }
  96.         }
  97.     }
  98.  
  99.     // Create a buffer normally
  100.     IDirectSoundBuffer* pDSBuffer;
  101.     HRESULT hr = DXAudioMgr()->DirectSound()->CreateSoundBuffer(&desc, &pDSBuffer, NULL);
  102.     if(FAILED(hr))
  103.     {
  104.         DebugOut(3, "First attempt at sound buffer creation failed.  Error = %s.  Attempting again...", DXGetErrorString(hr));
  105.         if(desc.dwFlags & DSBCAPS_CTRL3D)
  106.         {
  107.             DXAudioMgr()->ResetSound3DLimit();
  108.             if(!DXAudioMgr()->RemoveSound3D(0))
  109.                 return Error::Handle("Could not create sound buffer.  Error = %s", DXGetErrorString(hr));
  110.         }
  111.         else
  112.         {
  113.             DXAudioMgr()->ResetSoundLimit();
  114.             if(!DXAudioMgr()->RemoveSound(0))
  115.                 return Error::Handle("Could not create sound buffer.  Error = %s", DXGetErrorString(hr));
  116.         }
  117.  
  118.         hr = DXAudioMgr()->DirectSound()->CreateSoundBuffer(&desc, &pDSBuffer, NULL);
  119.         if(FAILED(hr))
  120.             return Error::Handle("Could not create sound buffer.  Error = %s", DXGetErrorString(hr));
  121.     }
  122.  
  123.     // Get the IDirectSoundBuffer8 interface
  124.     hr = pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&pBuffer);
  125.     if(FAILED(hr))
  126.         return Error::Handle("Could not obtain DirectSoundBuffer8 interface.  Error = %s", DXGetErrorString(hr));
  127.  
  128.     // Release the temporary DirectSoundBuffer interface
  129.     pDSBuffer->Release();
  130.  
  131.     // If buffer caching is enabled,
  132.     if(DXAudioMgr()->GetInit()->m_bCacheBuffers && bUseCache)
  133.     {
  134.         BufferInfo* pInfo = new BufferInfo;
  135.         pInfo->m_pBuffer = pBuffer;
  136.         pInfo->m_pBuffer->AddRef();
  137.         memcpy(&pInfo->m_Format, desc.lpwfxFormat, sizeof(WAVEFORMATEX));
  138.         memcpy(&pInfo->m_Desc, &desc, sizeof(DSBUFFERDESC));
  139.         pInfo->m_Desc.lpwfxFormat = &pInfo->m_Format;
  140.         m_Used.push_back(pInfo);
  141.     }
  142.  
  143.     return true;
  144. }
  145.  
  146. void BufferCache::Free(IDirectSoundBuffer8* pBuffer)
  147. {
  148.     if(pBuffer && DXAudioMgr()->GetInit()->m_bCacheBuffers)
  149.     {
  150.         BufferInfoVector::iterator itr;
  151.         for(itr = m_Used.begin(); itr != m_Used.end();)
  152.         {
  153.             BufferInfo* pInfo = (*itr);
  154.             if(pInfo->m_pBuffer == pBuffer)
  155.             {
  156.                 m_Free.push_back(*itr);
  157.                 itr = m_Used.erase(itr);
  158.                 return;
  159.             }
  160.             else
  161.                 ++itr;
  162.         }
  163.     }
  164. }
  165.  
  166.  
  167.  
  168.  
  169.  
  170.