| RecursivePowerFunction.h | String.h | StringReverse.h | CSoundManager.h | CSoundManager.cpp |

One of my responsibilities during my final project at Full Sail was to wrap an OpenAL implementation to use sound files. We used OGG Vorbis and Wave files, so I wrote a system that would give us only the power that we needed, as my responsibilities were stretched across the board. This included a SoundManager which contained instances of the Sound class and StreamingSound class through the ISound interface. The SoundManager was the entry point into the sound system and could Load, Play, Stop, and Fade sounds and was responsible for Initializing the Device.

CSoundManager.cpp
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //     Name     : CSoundManager.cpp
  3. //
  4. //     Date     : 2007.02.08
  5. //
  6. //     Purpose     : Maintains the creation of all of the Sound objects in the game.
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #include "../../../Engine/Header/sound/CSoundManager.h"
  9. #include "../../../Libs/OpenAL/al.h"
  10. #include "../../../Libs/OpenAL/alc.h"
  11. #include "../../../Engine/Header/Sound/CWavLoader.h"
  12. #include "../../../Engine/Header/Sound/COggLoader.h"
  13. #include "../../../Engine/Header/Sound/CSound.h"
  14. #include "../../../Engine/Header/Sound/CStreamingSound.h"
  15. #include "../../../Engine/Header/Errors.h"
  16. #include "../../../Engine/Header/Enums.h"
  17. #include "../../../Engine/Header/MessageEnums.h"
  18. #include "../../../Engine/Header/Core/CMessageFactory.h"
  19. #include "../../../Engine/Header/Core/CStaticEntity3D.h"
  20. #include "../../../Engine/Header/Core/tVector3d.h"
  21. #include "../../../Engine/Header/Core/tMatrix4.h"
  22.  
  23. #pragma comment (lib, "Libs/OpenAL32.lib")
  24.  
  25. #define MAX_CHANNELS 64
  26.  
  27. IL::SOUND::CSoundManager* IL::SOUND::CSoundManager::m_pOnlyInstance = 0;
  28.  
  29. //////////////////////////////////////////////////////////////////////////
  30. //     Name     : clear
  31. //
  32. //     Date     : 2007.02.08
  33. //
  34. //     Author   : Chad Stewart
  35. //
  36. //     Purpose  : Frees all allocated memory and returns the object to its
  37. //                    default state.
  38. //////////////////////////////////////////////////////////////////////////
  39. void IL::SOUND::CSoundManager::clear()
  40. {
  41.      ALCdevice*   pDevice;
  42.      ALCcontext*  pContext;
  43.      unsigned int Size = 0;
  44.  
  45.      // Delete all of the sounds.
  46.      clearSounds();
  47.  
  48.      // Delete all of the unused sounds.
  49.      Size = (unsigned int)m_UnusedSounds.size();
  50.      for ( unsigned int i = 0; i < Size; i++ )
  51.           delete m_UnusedSounds[i];
  52.      m_UnusedSounds.clear();
  53.  
  54.      // Delete all of the sounds.
  55.      Size = (unsigned int)m_UnusedStreams.size();
  56.      for ( unsigned int i = 0; i < Size; i++ )
  57.           delete m_UnusedStreams[i];
  58.      m_UnusedStreams.clear();
  59.  
  60.      // Delete all of the channels.
  61.      Size = (unsigned int)m_vSoundChannels.size();
  62.      for ( unsigned int i = 0; i < Size; i++ )
  63.           alDeleteSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
  64.      m_vSoundChannels.clear();
  65.  
  66.      Size = (unsigned int)m_vSoundBuffers.size();
  67.      for ( unsigned int i = 0; i < Size; i++ )
  68.           alDeleteBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
  69.      m_vSoundBuffers.clear();
  70.  
  71.      // Exit
  72.      pContext = alcGetCurrentContext();
  73.      pDevice = alcGetContextsDevice(pContext);
  74.      alcMakeContextCurrent(0);
  75.      alcDestroyContext(pContext);
  76.      alcCloseDevice(pDevice);
  77.  
  78.      // If you haven't initialized, you're going to be a jerk and call new just to delete.
  79.      IL::SOUND::CWavLoader::getInstance()->deleteInstance();
  80.      IL::SOUND::COggLoader::getInstance()->deleteInstance();
  81. }
  82.  
  83. //////////////////////////////////////////////////////////////////////////
  84. //     Name     : getInstance
  85. //////////////////////////////////////////////////////////////////////////
  86. IL::SOUND::CSoundManager * IL::SOUND::CSoundManager::getInstance()
  87. {
  88.      if (!m_pOnlyInstance)
  89.      {
  90.           m_pOnlyInstance = new IL::SOUND::CSoundManager;
  91.      }
  92.  
  93.      return m_pOnlyInstance;
  94. }
  95.  
  96.  
  97. //////////////////////////////////////////////////////////////////////////
  98. //     Name     : deleteInstance
  99. //////////////////////////////////////////////////////////////////////////
  100. void IL::SOUND::CSoundManager::deleteInstance()
  101. {
  102.      if (m_pOnlyInstance)
  103.      {
  104.           delete m_pOnlyInstance;
  105.      }
  106.  
  107.      m_pOnlyInstance = 0;
  108. }
  109.  
  110. ///////////////////////////////////////////////////////////////////////////////
  111. //  Name     : initialize
  112. //
  113. //     Date     : 2007.02.12
  114. //
  115. //  Author     : Chad Stewart
  116. //
  117. //     Purpose     : Set up OpenAL
  118. ///////////////////////////////////////////////////////////////////////////////
  119. ILENUM IL::SOUND::CSoundManager::initialize(void)
  120. {
  121.      // Device and Context required!
  122.      ALCdevice*                 pDevice                   = 0;
  123.      ALCcontext*                pContext                  = 0;
  124.      ALboolean                  m_EAX                     = AL_FALSE;
  125.      ALfloat                    ListenerPosition[]        = { 0.0f, 0.0f, 0.0f };
  126.      ALfloat                    ListenerVelocity[]        = { 0.0f, 0.0f, 0.0f };
  127.      ALfloat                    ListenerOrientation[]     = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
  128.      IL::CORE::ILVECTOR3DF*     pListenerPositionToUse    = NULL;
  129.      IL::CORE::tMatrix4<float>* pListenerOrientationToUse = NULL;
  130.      tChannel                   IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector;
  131.      ILINT                      i                         = 0;
  132.  
  133.      // We'll need to have our Loaders in order to begin.
  134.      IL::SOUND::CWavLoader::getInstance();
  135.      IL::SOUND::COggLoader::getInstance();
  136.  
  137.      // Acquire us an open sound device.
  138.      pDevice = alcOpenDevice(NULL);
  139.  
  140.      // If we have the device now, let's create our context.
  141.      if (pDevice)
  142.      {
  143.           pContext = alcCreateContext(pDevice, 0);
  144.           if (NULL == pContext || !alcMakeContextCurrent(pContext))
  145.                return IL::EEC_CANNOT_CREATE_AL_CONTEXT;
  146.      }
  147.      else
  148.           return IL::EEC_CANNOT_CREATE_AL_DEVICE;
  149.  
  150.      // Check for EAX 2.0 support
  151.      // m_EAX = alIsExtensionPresent("EAX2.0");
  152.  
  153.      alDistanceModel(AL_EXPONENT_DISTANCE);
  154.  
  155.      // Place the listener.
  156.      alListenerfv(AL_POSITION,    ListenerPosition);
  157.      alListenerfv(AL_VELOCITY,    ListenerVelocity);
  158.      alListenerfv(AL_ORIENTATION, ListenerOrientation);
  159.      alListenerf(AL_GAIN, 1.0f);
  160.  
  161.      // This channel is not in use... yet.
  162.      IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector.m_InUse = false;
  163.  
  164.      // Create all the sources.
  165.      do
  166.      {
  167.           // Create a source.
  168.           alGenSources(1, (ALuint*)&IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector.m_SourceID);
  169.  
  170.           // Make sure that source worked.
  171.           if(AL_NO_ERROR != alGetError())
  172.                break;
  173.  
  174.           // Hell yeah, in the vector.
  175.           m_vSoundChannels.push_back(IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector);
  176.      } while (i++ < MAX_CHANNELS);
  177.  
  178.      return IL::EEC_OK;
  179. }
  180.  
  181. ///////////////////////////////////////////////////////////////////////////////
  182. //  Name     : changeDevice
  183. ///////////////////////////////////////////////////////////////////////////////
  184. ILENUM IL::SOUND::CSoundManager::changeDevice(const char* vDeviceName)
  185. {
  186.      ILUINT              VectorSize    = 0;
  187.      ILUINT              Size          = 0;
  188.      ILUINT              SoundID       = 0;
  189.      ILUINT              j             = 0;
  190.      ALCdevice*          pDevice       = 0;
  191.      ALCcontext*         pContext      = 0;
  192.      ALCchar             Buffer[256]   = {0};
  193.      std::vector<ILINT>  vPausedSounds;
  194.  
  195.      vPausedSounds = pauseAllSounds(true);
  196.  
  197.      pContext = alcGetCurrentContext();
  198.      pDevice = alcGetContextsDevice( pContext );
  199.  
  200.      // Close that stuff.
  201.      alcDestroyContext(pContext);
  202.      alcCloseDevice(pDevice);
  203.  
  204.      pDevice = NULL;
  205.      pContext = NULL;
  206.  
  207.      // Acquire us an open sound device.
  208.      pDevice = alcOpenDevice((ALCchar*)vDeviceName);
  209.  
  210.      // If we have the device now, let's create our context.
  211.      if (pDevice)
  212.      {
  213.           pContext = alcCreateContext(pDevice, 0);
  214.           if (NULL == pContext || !alcMakeContextCurrent(pContext))
  215.                return IL::EEC_CANNOT_CREATE_AL_CONTEXT;
  216.      }
  217.      else
  218.           return IL::EEC_CANNOT_CREATE_AL_DEVICE;
  219.      
  220.      // We created a new device. Re-load all of the sources and buffers.
  221.      // First we will loop through the sounds and re-load them.
  222.      VectorSize = (ILUINT)m_Sounds.size();
  223.      for (unsigned int i = 0; i < VectorSize; i++)
  224.           m_Sounds[i]->reloadSound();
  225.  
  226.      // Channels.
  227.      VectorSize = (ILUINT)m_vSoundChannels.size();
  228.      for (unsigned int i = 0; i < VectorSize; i++)
  229.      {
  230.           // Did we already free the channel?
  231.           if (!m_vSoundChannels[i].m_InUse)
  232.           {
  233.                alDeleteSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
  234.                alGenSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
  235.           }
  236.      }
  237.  
  238.      // Buffers.
  239.      VectorSize = (ILUINT)m_vSoundBuffers.size();
  240.      for (unsigned int i = 0; i < VectorSize; i++)
  241.      {
  242.           // Would this buffer have already re-loaded?
  243.           if (m_vSoundBuffers[i].m_References == 0)
  244.           {
  245.                alDeleteBuffers( 1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
  246.                alGenBuffers( 1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
  247.           }
  248.      }
  249.  
  250.      // And now un-pause all of the songs.
  251.      VectorSize = (ILUINT)vPausedSounds.size();
  252.      Size = (ILUINT)m_Sounds.size();
  253.      for (unsigned int i = 0; i < VectorSize; i++)
  254.      {
  255.           SoundID = vPausedSounds[i];
  256.  
  257.           for (j = 0; j < Size; j++)
  258.           {
  259.                if (m_Sounds[j]->getUniqueID() == SoundID)
  260.                {
  261.                     m_Sounds[j]->unpauseSound();
  262.                     break;
  263.                }
  264.           }
  265.      }
  266.  
  267.      return IL::EEC_OK;
  268. }
  269.  
  270. //////////////////////////////////////////////////////////////////////////
  271. //     Name     : handleMessage
  272. //////////////////////////////////////////////////////////////////////////
  273. void IL::SOUND::CSoundManager::handleMessage(const IL::CORE::tMessage * vMessage)
  274. {
  275.      ILINT MessageData = -1;
  276.      unsigned int Size = 0;
  277.  
  278.      // Handle ALL the messages we can.
  279.      switch (vMessage->m_OpCode)
  280.      {
  281.           // Specified play channel can be used by someone else.
  282.      case IL::EMSG_FREE_CHANNEL:
  283.           if (-1 != (MessageData = vMessage->m_Data))
  284.                m_vSoundChannels[MessageData].m_InUse = false;
  285.           break;
  286.  
  287.           // A sound has run it's course and wishes to make benefit glorious sound system.
  288.      case IL::EMSG_RECYCLE_SOUND:
  289.           if (IL::EID_INVALID != (MessageData = vMessage->m_Data))
  290.           {
  291.                recycleSound(MessageData);
  292.           }
  293.           break;
  294.  
  295.           // A sound is done with a buffer.
  296.      case IL::EMSG_FREE_BUFFER:
  297.           if (-1 != (MessageData = vMessage->m_Data))
  298.           {
  299.                Size = (unsigned int)m_vSoundBuffers.size();
  300.                for (unsigned int i = 0; i < Size; i++)
  301.                     if (m_vSoundBuffers[i].m_BufferID == MessageData)
  302.                     {
  303.                          m_vSoundBuffers[i].m_References--;
  304.                          if (m_vSoundBuffers[i].m_References == 0)
  305.                          {
  306.                               alDeleteBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
  307.                               alGetError();
  308.                               alGenBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
  309.                          }
  310.                     }
  311.           }
  312.           break;
  313.  
  314.           // A sound is done with a buffer.
  315.      case IL::EMSG_ADD_BUFFER_REF:
  316.           if (-1 != (MessageData = vMessage->m_Data))
  317.           {
  318.                Size = (unsigned int)m_vSoundBuffers.size();
  319.                for (unsigned int i = 0; i < Size; i++)
  320.                     if (m_vSoundBuffers[i].m_BufferID == MessageData)
  321.                          m_vSoundBuffers[i].m_References++;
  322.           }
  323.           break;
  324.  
  325.      default:
  326.           break;
  327.      };
  328. }
  329.  
  330. ///////////////////////////////////////////////////////////////////////////////
  331. //  Name     : getFreeSound
  332. ///////////////////////////////////////////////////////////////////////////////
  333. IL::SOUND::CSound* IL::SOUND::CSoundManager::getFreeSound(void)
  334. {
  335.      IL::SOUND::CSound* ReturnSound = NULL;
  336.  
  337.      if (m_UnusedSounds.size() != 0)
  338.      {
  339.           ReturnSound = m_UnusedSounds.back();
  340.           m_UnusedSounds.pop_back();
  341.      }
  342.      else
  343.           ReturnSound = new IL::SOUND::CSound;
  344.  
  345.      return ReturnSound;
  346. }
  347.  
  348. ///////////////////////////////////////////////////////////////////////////////
  349. //  Name     : loadSoundFromFile
  350. ///////////////////////////////////////////////////////////////////////////////
  351. ILINT IL::SOUND::CSoundManager::loadSoundFromFile(const ILCHAR* vFilename, ILBOOL vStream)
  352. {
  353.      ISound*     NewSound;
  354.      unsigned int Size = (unsigned int)m_Sounds.size();
  355.      IL::CORE::CString PassThisStringIntoTheSetFileNameFunction;
  356.      PassThisStringIntoTheSetFileNameFunction = vFilename;
  357.  
  358.      if (vFilename == NULL)
  359.           return IL::EID_INVALID;
  360.  
  361.      // Check the names.
  362.      for (unsigned int i = 0; i < Size; i++)
  363.      {
  364.           if (0 == _stricmp(vFilename, m_Sounds[i]->getFileName().asMultiByteString()))
  365.                return m_Sounds[i]->getUniqueID();
  366.      }
  367.  
  368.      if (vStream)
  369.      {
  370.           // Take a sound from the factory, or create a new one.
  371.           if (!m_UnusedStreams.empty())
  372.           {
  373.                // Grab it from the vector.
  374.                NewSound = m_UnusedStreams[m_UnusedStreams.size()-1];
  375.                m_UnusedStreams.pop_back();
  376.           }
  377.           else
  378.                NewSound = new CStreamingSound;
  379.      }
  380.      else
  381.      {
  382.           // Take a sound from the factory, or create a new one.
  383.           if (!m_UnusedSounds.empty())
  384.           {
  385.                // Grab it from the vector.
  386.                NewSound = (IL::SOUND::CSound*)m_UnusedSounds[m_UnusedSounds.size()-1];
  387.                m_UnusedSounds.pop_back();
  388.           }
  389.           else
  390.                NewSound = new CSound;
  391.  
  392.           ((IL::SOUND::CSound*)NewSound)->setBufferID(getFreeBufferi());
  393.      }
  394.  
  395.      // Did they pass in a file name?
  396.      if (IL::EEC_OK != NewSound->loadSoundFromFile(vFilename))
  397.      {
  398.           delete NewSound;
  399.           return IL::EID_INVALID;    
  400.      }
  401.  
  402.      // Put it in the vector.
  403.      m_Sounds.push_back(NewSound);
  404.      
  405.      NewSound->setFileName(PassThisStringIntoTheSetFileNameFunction);
  406.      NewSound->setUniqueID(++m_UniqueIDGenerator);
  407.  
  408.      return m_UniqueIDGenerator;
  409. }
  410. ILINT IL::SOUND::CSoundManager::loadSoundFromFile(const ILWCHAR* vFilename, ILBOOL vStream)
  411. {
  412.      ISound*     NewSound;
  413.      unsigned int Size = (unsigned int)m_Sounds.size();
  414.      IL::CORE::CString PassThisStringIntoTheSetFileNameFunction(vFilename);
  415.  
  416.      // Did they pass in a file name?
  417.      if (vFilename == NULL)
  418.           return IL::EID_INVALID;
  419.  
  420.      // Check the names.
  421.      for (unsigned int i = 0; i < Size; i++)
  422.      {
  423.           if (wcsicmp(vFilename, m_Sounds[i]->getFileName().asWideCharacterString()))
  424.                return m_Sounds[i]->getUniqueID();
  425.      }
  426.      
  427.      if (vStream)
  428.      {
  429.           // Take a sound from the factory, or create a new one.
  430.           if (!m_UnusedStreams.empty())
  431.           {
  432.                // Grab it from the vector.
  433.                NewSound = m_UnusedStreams[m_UnusedStreams.size()-1];
  434.                m_UnusedStreams.pop_back();
  435.           }
  436.           else
  437.                NewSound = new CStreamingSound;
  438.      }
  439.      else
  440.      {
  441.           // Take a sound from the factory, or create a new one.
  442.           if (!m_UnusedSounds.empty())
  443.           {
  444.                // Grab it from the vector.
  445.                NewSound = m_UnusedSounds[m_UnusedSounds.size()-1];
  446.                m_UnusedSounds.pop_back();
  447.           }
  448.           else
  449.                NewSound = new CSound;
  450.  
  451.           ((IL::SOUND::CSound*)NewSound)->setBufferID(getFreeBufferi());
  452.      }
  453.  
  454.      if (IL::EEC_OK != NewSound->loadSoundFromFile(vFilename))
  455.      {
  456.           delete NewSound;
  457.           return IL::EID_INVALID;
  458.      }
  459.  
  460.      // Put it in the vector.
  461.      m_Sounds.push_back(NewSound);
  462.  
  463.      NewSound->setFileName(PassThisStringIntoTheSetFileNameFunction);
  464.      NewSound->setUniqueID(++m_UniqueIDGenerator);
  465.  
  466.      return m_UniqueIDGenerator;
  467. }
  468.  
  469. ///////////////////////////////////////////////////////////////////////////////
  470. //    Name     : playSound
  471. //
  472. //    Date     : 2007.02.16
  473. //
  474. //    Author   : Chad Stewart
  475. //
  476. //    Purpose  : Plays the sound specified.
  477. //
  478. //    Note     : Returns the ID of the song if it is played correctly. Otherwise,
  479. //                    it is -1 for an error.
  480. ///////////////////////////////////////////////////////////////////////////////
  481. ILINT IL::SOUND::CSoundManager::playSound(ILINT vID, ILENUM vPlayMode, ILFLOAT vFadeInLength, ILFLOAT vMaxVolume,
  482.                                                   ILFLOAT vFadeOutLength, ILFLOAT vFadeOutStartTime, ILFLOAT vReferenceDistance)
  483. {
  484.      unsigned int Size = (unsigned int)m_Sounds.size();
  485.      ISound*           NewSound = NULL;
  486.      ILINT           CloneID = 0;
  487.      ILINT           ChannelID = 0;
  488.  
  489.      // For every sound in the manager, check for a valid ID.
  490.      for (unsigned int i = 0; i < Size; i++)
  491.           if(m_Sounds[i]->getUniqueID() == vID)
  492.           {
  493.                if ((IL::ESPM_OVERLAP & vPlayMode) && (IL::ESPM_POSITIONAL & vPlayMode))
  494.                {
  495.                     if (-1 != (ChannelID = getFreeChannel()))
  496.                     {
  497.                          CloneID = cloneSound(i, &NewSound);
  498.                          m_Sounds[CloneID]->setPlayChannel(ChannelID);
  499.                          m_Sounds[CloneID]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
  500.                          if (m_Sounds[CloneID]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance))
  501.                               return m_Sounds[CloneID]->getUniqueID();
  502.                          else
  503.                          {
  504.                               recycleSound(m_Sounds[CloneID]);
  505.                               return -1;
  506.                          }
  507.                     }
  508.                }
  509.                else
  510.                {
  511.                     if (-1 != m_Sounds[i]->getPlayChannel())
  512.                          m_Sounds[i]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance);
  513.                     else if (-1 != (ChannelID = getFreeChannel()))
  514.                     {
  515.                          m_Sounds[i]->setPlayChannel(ChannelID);
  516.                          m_Sounds[i]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
  517.                          if (IL::EID_INVALID != m_Sounds[i]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance))
  518.                               return m_Sounds[i]->getUniqueID();
  519.                          else
  520.                          {
  521.                               m_vSoundChannels[ChannelID].m_InUse = false;
  522.                               m_Sounds[i]->setPlayChannel(-1);
  523.                               m_Sounds[i]->setSourceID(0);
  524.                               return -1;
  525.                          }
  526.                     }
  527.                }
  528.           }
  529.  
  530.      // Error. Invalid ID.
  531.      return -1;
  532. }
  533.  
  534. ///////////////////////////////////////////////////////////////////////////////
  535. //    Name     : stopSound
  536. //
  537. //    Date     : 2007.02.26
  538. //
  539. //    Author   : Chad Stewart
  540. //
  541. //    Purpose  : Stop a currently playing sound.
  542. ///////////////////////////////////////////////////////////////////////////////
  543. ILBOOL IL::SOUND::CSoundManager::stopSound(ILINT vID)
  544. {
  545.      unsigned int Size = (unsigned int)m_Sounds.size();
  546.  
  547.      // For every sound in the manager, check for a valid ID.
  548.      for (unsigned int i = 0; i < Size; i++)
  549.           if(m_Sounds[i]->getUniqueID() == vID)
  550.           {
  551.                if (-1 != m_Sounds[i]->getPlayChannel())
  552.                {
  553.                     m_Sounds[i]->stopSound();
  554.  
  555.                     m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
  556.                     m_Sounds[i]->setPlayChannel(-1);
  557.                     m_Sounds[i]->setSourceID(0);
  558.  
  559.                     return true;
  560.                }
  561.           }
  562.  
  563.      return false;
  564. }
  565.  
  566. ///////////////////////////////////////////////////////////////////////////////
  567. //    Name     : pauseSound
  568. //
  569. //    Date     : 2007.02.26
  570. //
  571. //    Author   : Chad Stewart
  572. //
  573. //    Purpose  : Pause a currently playing sound.
  574. ///////////////////////////////////////////////////////////////////////////////
  575. ILBOOL IL::SOUND::CSoundManager::pauseSound(ILINT vID)
  576. {
  577.      unsigned int Size = (unsigned int)m_Sounds.size();
  578.  
  579.      // For every sound in the manager, check for a valid ID.
  580.      for (unsigned int i = 0; i < Size; i++)
  581.           if(m_Sounds[i]->getUniqueID() == vID)
  582.           {
  583.                return m_Sounds[i]->pauseSound();
  584.           }
  585.  
  586.      return false;
  587. }
  588.  
  589.  
  590. ///////////////////////////////////////////////////////////////////////////////
  591. //    Name     : pauseSound
  592. //
  593. //    Date     : 2007.02.26
  594. //
  595. //    Author   : Chad Stewart
  596. //
  597. //    Purpose  : Pause a currently playing sound.
  598. ///////////////////////////////////////////////////////////////////////////////
  599. ILBOOL IL::SOUND::CSoundManager::unpauseSound(ILINT vID)
  600. {
  601.      unsigned int Size = (unsigned int)m_Sounds.size();
  602.  
  603.      // For every sound in the manager, check for a valid ID.
  604.      for (unsigned int i = 0; i < Size; i++)
  605.           if(m_Sounds[i]->getUniqueID() == vID)
  606.           {
  607.                return m_Sounds[i]->unpauseSound();
  608.           }
  609.  
  610.           return false;
  611. }
  612.  
  613.  
  614. ///////////////////////////////////////////////////////////////////////////////
  615. //    Name     : update
  616. //
  617. //    Date     : 2007.02.17
  618. //
  619. //    Author   : Chad Stewart
  620. //
  621. //    Purpose  : Update all of the sounds contained in the manager.
  622. ///////////////////////////////////////////////////////////////////////////////
  623. ILBOOL IL::SOUND::CSoundManager::update(ILFLOAT vEllapsedTime, IL::CORE::CStaticEntity3D* vListener)
  624. {
  625.      IL::CORE::ILVECTOR3DF         ListenerPosition(0.0f, 0.0f, 0.0f);
  626.      IL::CORE::ILVECTOR3DF         ListenerVelocity(0.0f, 0.0f, 0.0f);
  627.      IL::CORE::tMatrix4<float>     ListenerOrientation(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
  628.                                                        0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
  629.      ALfloat                       Orientation[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
  630.      unsigned int                  Size = 0;
  631.  
  632.      // Listener != Origin?
  633.      if(vListener)
  634.      {
  635.           // Get the listener data.
  636.           ListenerPosition = vListener->getPosition();
  637.           ListenerOrientation = vListener->getOrientation();
  638.  
  639.           // Put the orientation in a format we can use.
  640.           Orientation[0] = ListenerOrientation[8];
  641.           Orientation[1] = ListenerOrientation[9];
  642.           Orientation[2] = ListenerOrientation[10];
  643.           Orientation[3] = ListenerOrientation[4];
  644.           Orientation[4] = ListenerOrientation[5];
  645.           Orientation[5] = ListenerOrientation[6];
  646.      }
  647.  
  648.      // Update the listener. // Now slower! Yay!
  649.      alListener3f(AL_POSITION, ListenerPosition.x, ListenerPosition.y, ListenerPosition.z);
  650.      alListener3f(AL_VELOCITY, ListenerVelocity.x, ListenerVelocity.y, ListenerVelocity.z);
  651.      alListenerfv(AL_ORIENTATION, Orientation);
  652.  
  653.      // For every sound.
  654.      Size = (unsigned int)m_Sounds.size();
  655.      for(unsigned int i = 0; i < Size; i++)
  656.      {
  657.           if (IL::EID_INVALID != m_Sounds[i]->getPlayChannel())
  658.                m_Sounds[i]->update(vEllapsedTime);
  659.      }
  660.  
  661.      return true;
  662. }
  663.  
  664.  
  665. ///////////////////////////////////////////////////////////////////////////////
  666. //    Name     : fadeSoundOut
  667. //
  668. //    Date     : 2007.03.10
  669. //
  670. //    Author   : Chad Stewart
  671. //
  672. //    Purpose  : Fade a sound out.
  673. ///////////////////////////////////////////////////////////////////////////////
  674. ILBOOL IL::SOUND::CSoundManager::fadeSoundOut(ILINT vID, ILFLOAT vFadeOutLength, ILFLOAT vFadeOutStartTime)
  675. {
  676.      unsigned int Size = (unsigned int)m_Sounds.size();
  677.  
  678.      // For every sound in the manager, check for a valid ID.
  679.      for (unsigned int i = 0; i < Size; i++)
  680.           if(m_Sounds[i]->getUniqueID() == vID)
  681.           {
  682.                // Make sure that said sound is playing.
  683.                if (-1 != m_Sounds[i]->getPlayChannel())
  684.                     return m_Sounds[i]->fadeSoundOut(vFadeOutLength, vFadeOutStartTime);
  685.           }
  686.  
  687.      return false;
  688. }
  689.  
  690.  
  691. ///////////////////////////////////////////////////////////////////////////////
  692. //    Name     : crossFadeSounds
  693. //
  694. //    Date     : 2007.03.10
  695. //
  696. //    Author   : Chad Stewart
  697. //
  698. //    Purpose  : Fades one sound out while another sound is introduced.
  699. ///////////////////////////////////////////////////////////////////////////////
  700. ILBOOL IL::SOUND::CSoundManager::crossFadeSounds(ILINT vFirstID, ILFLOAT vFadeOutLength, ILINT vSecondID,
  701.                                                              ILFLOAT vFadeInLength, ILENUM vPlayMode, ILFLOAT vReferenceDistance)
  702. {
  703.      unsigned int     Size          = (unsigned int)m_Sounds.size();
  704.      ILINT               ChannelID     = 0;
  705.  
  706.      // For every sound in the manager, check for a valid ID.
  707.      for (unsigned int i = 0; i < Size; i++)
  708.           if(m_Sounds[i]->getUniqueID() == vFirstID)
  709.           {
  710.                // For every sound in the manager, check for a valid ID.
  711.                for (unsigned int j = 0; j < Size; j++)
  712.                     if(m_Sounds[j]->getUniqueID() == vSecondID)
  713.                     {
  714.                          // Make sure that said sound is playing.
  715.                          if (-1 != m_Sounds[i]->getPlayChannel())
  716.                               m_Sounds[i]->fadeSoundOut(vFadeOutLength, 0.0f);
  717.  
  718.                          if (-1 != (ChannelID = getFreeChannel()))
  719.                          {
  720.                               m_Sounds[i]->setPlayChannel(ChannelID);
  721.                               m_Sounds[i]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
  722.                               if (!m_Sounds[i]->playSound(vPlayMode, vFadeInLength, 0.0f, 0.0f, vReferenceDistance))
  723.                               {
  724.                                    m_Sounds[i]->setPlayChannel(-1);
  725.                                    m_Sounds[i]->setSourceID(0);
  726.                                    m_vSoundChannels[ChannelID].m_InUse = false;
  727.  
  728.                                    return false;
  729.                               }
  730.  
  731.                               return true;
  732.                          }
  733.                     }
  734.           }
  735.  
  736.      return false;
  737. }
  738.  
  739.  
  740. ///////////////////////////////////////////////////////////////////////////////
  741. //    Name     : deleteSound
  742. //
  743. //    Date     : 2007.02.19
  744. //
  745. //    Author   : Chad Stewart
  746. //
  747. //    Purpose  : Completely trod all over the functionality of the factory. :(
  748. ///////////////////////////////////////////////////////////////////////////////
  749. void IL::SOUND::CSoundManager::deleteSound(ILINT vID)
  750. {
  751.      unsigned int Size = (unsigned int)m_Sounds.size();
  752.  
  753.      // For every sound in the manager, check for a valid ID.
  754.      for (unsigned int i = 0; i < Size; i++)
  755.           if(m_Sounds[i]->getUniqueID() == vID)
  756.           {
  757.                // Is the song occupying a channel?
  758.                if (-1 != m_Sounds[i]->getPlayChannel())
  759.                {
  760.                     m_Sounds[i]->stopSound();
  761.  
  762.                     m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
  763.                     m_Sounds[i]->setPlayChannel(-1);
  764.                     m_Sounds[i]->setSourceID(0);
  765.                }
  766.  
  767.                delete m_Sounds[i];
  768.                m_Sounds.erase(m_Sounds.begin() + i);
  769.  
  770.                break;
  771.           }
  772. }
  773.  
  774. ///////////////////////////////////////////////////////////////////////////////
  775. //    Name     : clearSounds
  776. //
  777. //    Date     : 2007.02.19
  778. //
  779. //    Author   : Chad Stewart
  780. //
  781. //    Purpose  : If delete wasn't bad enough, you can clear them all.
  782. ///////////////////////////////////////////////////////////////////////////////
  783. void IL::SOUND::CSoundManager::clearSounds(void)
  784. {
  785.      unsigned int Size = (unsigned int)m_Sounds.size();
  786.  
  787.      // Delete all of the sounds.
  788.      for ( unsigned int i = 0; i < Size; i++ )
  789.           delete m_Sounds[i];
  790.      m_Sounds.clear();
  791.  
  792.      // Set all of the channels to being not in use.
  793.      Size = (unsigned int)m_vSoundChannels.size();
  794.      for (unsigned int i = 0; i < Size; i++)
  795.           m_vSoundChannels[i].m_InUse = false;
  796. }
  797.  
  798. ///////////////////////////////////////////////////////////////////////////////
  799. //    Name     : stopAllSounds
  800. ///////////////////////////////////////////////////////////////////////////////
  801. void IL::SOUND::CSoundManager::stopAllSounds(void)
  802. {
  803.      unsigned int Size = (unsigned int)m_Sounds.size();
  804.  
  805.      for (unsigned int i = 0; i < Size; i++)
  806.      {
  807.           if (-1 != m_Sounds[i]->getPlayChannel() && m_Sounds[i]->stopSound())
  808.           {
  809.                m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
  810.                m_Sounds[i]->setPlayChannel(-1);
  811.                m_Sounds[i]->setSourceID(0);
  812.           }
  813.      }
  814. }
  815.  
  816. ///////////////////////////////////////////////////////////////////////////////
  817. //    Name     : pauseAllSounds
  818. ///////////////////////////////////////////////////////////////////////////////
  819. vector<ILINT>& IL::SOUND::CSoundManager::pauseAllSounds(ILBOOL vSavePlayingSoundsIDs)
  820. {
  821.      unsigned int Size = (unsigned int)m_Sounds.size();
  822.      static vector<ILINT> SoundIDs;
  823.  
  824.      if (vSavePlayingSoundsIDs)
  825.      {
  826.           SoundIDs.clear();
  827.  
  828.           for (unsigned int i = 0; i < Size; i++)
  829.           {
  830.                if (m_Sounds[i]->isPlaying())
  831.                {
  832.                     SoundIDs.push_back(m_Sounds[i]->getUniqueID());
  833.                     m_Sounds[i]->pauseSound();
  834.                }
  835.           }
  836.      }
  837.      else
  838.           for (unsigned int i = 0; i < Size; i++)
  839.                m_Sounds[i]->pauseSound();
  840.  
  841.      return SoundIDs;
  842. }
  843.  
  844. ///////////////////////////////////////////////////////////////////////////////
  845. //    Name     : recycleSound
  846. //
  847. //    Date     : 2007.02.17
  848. //
  849. //    Author   : Chad Stewart
  850. //
  851. //    Purpose  : Clears the sound and puts it in the list for re-use.
  852. ///////////////////////////////////////////////////////////////////////////////
  853. void IL::SOUND::CSoundManager::recycleSound(ILINT vID)
  854. {
  855.      ISound* SoundToRecycle;
  856.      unsigned int Size = (unsigned int)m_Sounds.size();
  857.  
  858.      // For every sound in the manager, check for a valid ID.
  859.      for (unsigned int i = 0; i < Size; i++)
  860.           if(m_Sounds[i]->getUniqueID() == vID)
  861.           {
  862.                // Sound or stream?
  863.                if(m_Sounds[i]->isStream())
  864.                     SoundToRecycle = (CStreamingSound*)m_Sounds[i];
  865.                else
  866.                     SoundToRecycle = (CSound*)m_Sounds[i];
  867.  
  868.                m_Sounds.erase(m_Sounds.begin() + i);
  869.                break;
  870.           }
  871.  
  872.      // Is the song occupying a channel?
  873.      if (-1 != SoundToRecycle->getPlayChannel())
  874.      {
  875.           m_vSoundChannels[SoundToRecycle->getPlayChannel()].m_InUse = false;
  876.           SoundToRecycle->setPlayChannel(-1);
  877.           SoundToRecycle->setSourceID(0);
  878.      }
  879.  
  880.      // Clear the sound for re-use.
  881.      SoundToRecycle->clear();
  882.      
  883.      // Add it to the list of unused sounds.
  884.      if(SoundToRecycle->isStream())
  885.           m_UnusedStreams.push_back((CStreamingSound*)SoundToRecycle);
  886.      else
  887.           m_UnusedSounds.push_back((CSound*)SoundToRecycle);
  888. }
  889.  
  890. void IL::SOUND::CSoundManager::recycleSound(ISound* vSound)
  891. {
  892.      ILINT UniqueID = vSound->getUniqueID();
  893.      unsigned int Size = (unsigned int)m_Sounds.size();
  894.      unsigned int i = 0;
  895.  
  896.      // For every sound in the manager, check for a valid ID.
  897.      for (i = 0; i < Size; i++)
  898.           if(m_Sounds[i]->getUniqueID() == UniqueID)
  899.           {
  900.                m_Sounds.erase(m_Sounds.begin() + i);
  901.                break;
  902.           }
  903.  
  904.      if (i == Size)
  905.           return;
  906.  
  907.      // Is the song occupying a channel?
  908.      if (-1 != vSound->getPlayChannel())
  909.      {
  910.           m_vSoundChannels[vSound->getPlayChannel()].m_InUse = false;
  911.           vSound->setPlayChannel(-1);
  912.           vSound->setSourceID(0);
  913.      }
  914.  
  915.      // Clear the sound for re-use.
  916.      vSound->clear();
  917.      
  918.      // Add it to the list of unused sounds.
  919.      if(vSound->isStream())
  920.           m_UnusedStreams.push_back((CStreamingSound*)vSound);
  921.      else
  922.           m_UnusedSounds.push_back((CSound*)vSound);
  923. }
  924.  
  925. ///////////////////////////////////////////////////////////////////////////////
  926. //    Name     : getSound
  927. //
  928. //    Date     : 2007.02.22
  929. //
  930. //    Author   : Chad Stewart
  931. //
  932. //    Purpose  : Return a sound by ID.
  933. ///////////////////////////////////////////////////////////////////////////////
  934. IL::SOUND::ISound* IL::SOUND::CSoundManager::getSound(ILINT vID)
  935. {
  936.      unsigned int Size = (unsigned int)m_Sounds.size();
  937.  
  938.      // For every sound in the manager, check for a valid ID.
  939.      for (unsigned int i = 0; i < Size; i++)
  940.           if(m_Sounds[i]->getUniqueID() == vID)
  941.           {
  942.                m_Sounds[i]->addReference();
  943.                return m_Sounds[i];
  944.           }
  945.  
  946.      return NULL;
  947. }
  948.  
  949. ///////////////////////////////////////////////////////////////////////////////
  950. //  Accessors
  951. ///////////////////////////////////////////////////////////////////////////////
  952. void IL::SOUND::CSoundManager::getPosition(ILINT vID, IL::CORE::ILVECTOR3DF& vPosition) const
  953. {
  954.      unsigned int Size = (unsigned int)m_Sounds.size();
  955.  
  956.      // For every sound in the manager, check for a valid ID.
  957.      for (unsigned int i = 0; i < Size; i++)
  958.           if(m_Sounds[i]->getUniqueID() == vID)
  959.           {
  960.                m_Sounds[i]->getPosition(vPosition);
  961.                break;
  962.           }
  963. }
  964. void IL::SOUND::CSoundManager::getPosition(ILINT vID, ILFLOAT* vPosition) const
  965. {
  966.      unsigned int Size = (unsigned int)m_Sounds.size();
  967.  
  968.      // For every sound in the manager, check for a valid ID.
  969.      for (unsigned int i = 0; i < Size; i++)
  970.           if(m_Sounds[i]->getUniqueID() == vID)
  971.           {
  972.                m_Sounds[i]->getPosition(vPosition);
  973.                break;
  974.           }
  975. }
  976. void IL::SOUND::CSoundManager::getVelocity(ILINT vID, IL::CORE::ILVECTOR3DF& vVelocity) const
  977. {
  978.      unsigned int Size = (unsigned int)m_Sounds.size();
  979.  
  980.      // For every sound in the manager, check for a valid ID.
  981.      for (unsigned int i = 0; i < Size; i++)
  982.           if(m_Sounds[i]->getUniqueID() == vID)
  983.           {
  984.                m_Sounds[i]->getVelocity(vVelocity);
  985.                break;
  986.           }
  987. }
  988. void IL::SOUND::CSoundManager::getVelocity(ILINT vID, ILFLOAT* vVelocity) const
  989. {
  990.      unsigned int Size = (unsigned int)m_Sounds.size();
  991.  
  992.      // For every sound in the manager, check for a valid ID.
  993.      for (unsigned int i = 0; i < Size; i++)
  994.           if(m_Sounds[i]->getUniqueID() == vID)
  995.           {
  996.                m_Sounds[i]->getVelocity(vVelocity);
  997.                break;
  998.           }
  999. }
  1000. ILULONG IL::SOUND::CSoundManager::getFormat(ILINT vID) const
  1001. {
  1002.      unsigned int Size = (unsigned int)m_Sounds.size();
  1003.  
  1004.      // For every sound in the manager, check for a valid ID.
  1005.      for (unsigned int i = 0; i < Size; i++)
  1006.           if(m_Sounds[i]->getUniqueID() == vID)
  1007.                return m_Sounds[i]->getFormat();
  1008.  
  1009.      return NULL;
  1010. }
  1011. ILULONG IL::SOUND::CSoundManager::getChannels(ILINT vID) const
  1012. {
  1013.      unsigned int Size = (unsigned int)m_Sounds.size();
  1014.  
  1015.      // For every sound in the manager, check for a valid ID.
  1016.      for (unsigned int i = 0; i < Size; i++)
  1017.           if(m_Sounds[i]->getUniqueID() == vID)
  1018.                return m_Sounds[i]->getChannels();
  1019.  
  1020.      return NULL;
  1021. }
  1022. ILULONG IL::SOUND::CSoundManager::getFrequency(ILINT vID) const
  1023. {
  1024.      unsigned int Size = (unsigned int)m_Sounds.size();
  1025.  
  1026.      // For every sound in the manager, check for a valid ID.
  1027.      for (unsigned int i = 0; i < Size; i++)
  1028.           if(m_Sounds[i]->getUniqueID() == vID)
  1029.                return m_Sounds[i]->getFrequency();
  1030.  
  1031.      return NULL;
  1032. }
  1033. ILFLOAT IL::SOUND::CSoundManager::getVolume(ILINT vID) const
  1034. {
  1035.      unsigned int Size = (unsigned int)m_Sounds.size();
  1036.  
  1037.      // For every sound in the manager, check for a valid ID.
  1038.      for (unsigned int i = 0; i < Size; i++)
  1039.           if(m_Sounds[i]->getUniqueID() == vID)
  1040.                return m_Sounds[i]->getVolume();
  1041.  
  1042.      return NULL;
  1043. }
  1044. ILUINT IL::SOUND::CSoundManager::getSourceID(ILINT vID) const
  1045. {
  1046.      unsigned int Size = (unsigned int)m_Sounds.size();
  1047.  
  1048.      // For every sound in the manager, check for a valid ID.
  1049.      for (unsigned int i = 0; i < Size; i++)
  1050.           if(m_Sounds[i]->getUniqueID() == vID)
  1051.                return m_Sounds[i]->getSourceID();
  1052.  
  1053.      return NULL;
  1054. }
  1055. ILUINT IL::SOUND::CSoundManager::getUniqueID(ILINT vID) const
  1056. {
  1057.      unsigned int Size = (unsigned int)m_Sounds.size();
  1058.  
  1059.      // For every sound in the manager, check for a valid ID.
  1060.      for (unsigned int i = 0; i < Size; i++)
  1061.           if(m_Sounds[i]->getUniqueID() == vID)
  1062.                return m_Sounds[i]->getUniqueID();
  1063.  
  1064.      return NULL;
  1065. }
  1066. void IL::SOUND::CSoundManager::getDeviceUsed(char* vDeviceString) const
  1067. {
  1068.      ALCdevice*     pDevice          = 0;
  1069.      ALCcontext*     pContext     = 0;
  1070.      
  1071.      pContext = alcGetCurrentContext();
  1072.      pDevice = alcGetContextsDevice( pContext );
  1073.  
  1074.      if (pDevice)
  1075.           strcpy(vDeviceString, (char*)alcGetString(pDevice, ALC_DEVICE_SPECIFIER));
  1076. }
  1077. void IL::SOUND::CSoundManager::getDevicesPossible(std::vector<IL::CORE::CString>& vDeviceStrings) const
  1078. {
  1079.      ALCdevice*               pDevice          = 0;
  1080.      ALCcontext*               pContext     = 0;
  1081.      char*                    DeviceBuffer = NULL;
  1082.      ILINT                    CharactersRead          = 0;
  1083.      char                    CurrentDevice[128]     = {0};
  1084.      IL::CORE::CString     StringBuffer          = NULL;
  1085.  
  1086.      pContext = alcGetCurrentContext();
  1087.      pDevice = alcGetContextsDevice( pContext );
  1088.  
  1089.      if (pDevice)
  1090.      {
  1091.           DeviceBuffer = (char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
  1092.  
  1093.           // Go team!
  1094.           strcpy(CurrentDevice, DeviceBuffer + CharactersRead);
  1095.           while ( 0 != strlen(CurrentDevice) )
  1096.           {
  1097.                StringBuffer = CurrentDevice;
  1098.                CharactersRead += StringBuffer.getLength() + 1;
  1099.                vDeviceStrings.push_back(StringBuffer);
  1100.                strcpy(CurrentDevice, DeviceBuffer + CharactersRead);
  1101.           }
  1102.      }
  1103. }
  1104. ILBOOL IL::SOUND::CSoundManager::isPaused(ILINT vID) const
  1105. {
  1106.      unsigned int Size = (unsigned int)m_Sounds.size();
  1107.  
  1108.      // For every sound in the manager, check for a valid ID.
  1109.      for (unsigned int i = 0; i < Size; i++)
  1110.           if(m_Sounds[i]->getUniqueID() == vID)
  1111.                return m_Sounds[i]->isPaused();
  1112.  
  1113.      return NULL;
  1114. }
  1115. ILBOOL IL::SOUND::CSoundManager::isStream(ILINT vID) const
  1116. {
  1117.      unsigned int Size = (unsigned int)m_Sounds.size();
  1118.  
  1119.      // For every sound in the manager, check for a valid ID.
  1120.      for (unsigned int i = 0; i < Size; i++)
  1121.           if(m_Sounds[i]->getUniqueID() == vID)
  1122.                return m_Sounds[i]->isStream();
  1123.  
  1124.      return NULL;
  1125. }
  1126.  
  1127. //////////////////////////////////////////////////////////////////////////
  1128. //     Name     : Mutators
  1129. //////////////////////////////////////////////////////////////////////////
  1130. void IL::SOUND::CSoundManager::setPosition(ILINT vID, IL::CORE::ILVECTOR3DF& vPosition)
  1131. {
  1132.      unsigned int Size = (unsigned int)m_Sounds.size();
  1133.  
  1134.      // For every sound in the manager, check for a valid ID.
  1135.      for (unsigned int i = 0; i < Size; i++)
  1136.           if(m_Sounds[i]->getUniqueID() == vID)
  1137.           {
  1138.                m_Sounds[i]->setPosition(vPosition);
  1139.                break;
  1140.           }
  1141. }
  1142. void IL::SOUND::CSoundManager::setPosition(ILINT vID, ILFLOAT* vPosition)
  1143. {
  1144.      unsigned int Size = (unsigned int)m_Sounds.size();
  1145.  
  1146.      // For every sound in the manager, check for a valid ID.
  1147.      for (unsigned int i = 0; i < Size; i++)
  1148.           if(m_Sounds[i]->getUniqueID() == vID)
  1149.           {
  1150.                m_Sounds[i]->setPosition(vPosition);
  1151.                break;
  1152.           }
  1153. }
  1154. void IL::SOUND::CSoundManager::setPosition(ILINT vID, ILFLOAT vX, ILFLOAT vY, ILFLOAT vZ)
  1155. {
  1156.      unsigned int Size = (unsigned int)m_Sounds.size();
  1157.  
  1158.      // For every sound in the manager, check for a valid ID.
  1159.      for (unsigned int i = 0; i < Size; i++)
  1160.           if(m_Sounds[i]->getUniqueID() == vID)
  1161.           {
  1162.                m_Sounds[i]->setPosition(vX, vY, vZ);
  1163.                break;
  1164.           }
  1165. }
  1166. void IL::SOUND::CSoundManager::setPosition2D(ILINT vID, ILFLOAT vX, ILFLOAT vY)
  1167. {
  1168.      unsigned int Size = (unsigned int)m_Sounds.size();
  1169.  
  1170.      // For every sound in the manager, check for a valid ID.
  1171.      for (unsigned int i = 0; i < Size; i++)
  1172.           if(m_Sounds[i]->getUniqueID() == vID)
  1173.           {
  1174.                m_Sounds[i]->setPosition2D(vX, vY);
  1175.                break;
  1176.           }
  1177. }
  1178. void IL::SOUND::CSoundManager::setVelocity(ILINT vID, IL::CORE::ILVECTOR3DF& vVelocity)
  1179. {
  1180.      unsigned int Size = (unsigned int)m_Sounds.size();
  1181.  
  1182.      // For every sound in the manager, check for a valid ID.
  1183.      for (unsigned int i = 0; i < Size; i++)
  1184.           if(m_Sounds[i]->getUniqueID() == vID)
  1185.           {
  1186.                m_Sounds[i]->setVelocity(vVelocity);
  1187.                break;
  1188.           }
  1189. }
  1190. void IL::SOUND::CSoundManager::setVelocity(ILINT vID, ILFLOAT* vVelocity)
  1191. {
  1192.      unsigned int Size = (unsigned int)m_Sounds.size();
  1193.  
  1194.      // For every sound in the manager, check for a valid ID.
  1195.      for (unsigned int i = 0; i < Size; i++)
  1196.           if(m_Sounds[i]->getUniqueID() == vID)
  1197.           {
  1198.                m_Sounds[i]->setVelocity(vVelocity);
  1199.                break;
  1200.           }
  1201. }
  1202. void IL::SOUND::CSoundManager::setFormat(ILINT vID, ILULONG vFormat)
  1203. {
  1204.      unsigned int Size = (unsigned int)m_Sounds.size();
  1205.  
  1206.      // For every sound in the manager, check for a valid ID.
  1207.      for (unsigned int i = 0; i < Size; i++)
  1208.           if(m_Sounds[i]->getUniqueID() == vID)
  1209.           {
  1210.                m_Sounds[i]->setFormat(vFormat);
  1211.                break;
  1212.           }
  1213. }
  1214. void IL::SOUND::CSoundManager::setChannels(ILINT vID, ILULONG vChannels)
  1215. {
  1216.      unsigned int Size = (unsigned int)m_Sounds.size();
  1217.  
  1218.      // For every sound in the manager, check for a valid ID.
  1219.      for (unsigned int i = 0; i < Size; i++)
  1220.           if(m_Sounds[i]->getUniqueID() == vID)
  1221.           {
  1222.                m_Sounds[i]->setChannels(vChannels);
  1223.                break;
  1224.           }
  1225. }
  1226. void IL::SOUND::CSoundManager::setFrequency(ILINT vID, ILULONG vFrequency)
  1227. {
  1228.      unsigned int Size = (unsigned int)m_Sounds.size();
  1229.  
  1230.      // For every sound in the manager, check for a valid ID.
  1231.      for (unsigned int i = 0; i < Size; i++)
  1232.           if(m_Sounds[i]->getUniqueID() == vID)
  1233.           {
  1234.                m_Sounds[i]->setFrequency(vFrequency);
  1235.                break;
  1236.           }
  1237. }
  1238. void IL::SOUND::CSoundManager::setMaxVolume(ILINT vID, ILFLOAT vGain)
  1239. {
  1240.      unsigned int Size = (unsigned int)m_Sounds.size();
  1241.  
  1242.      // For every sound in the manager, check for a valid ID.
  1243.      for (unsigned int i = 0; i < Size; i++)
  1244.           if(m_Sounds[i]->getUniqueID() == vID)
  1245.           {
  1246.                m_Sounds[i]->setMaxVolume(vGain);
  1247.                break;
  1248.           }
  1249. }
  1250. void IL::SOUND::CSoundManager::setVolume(ILINT vID, ILFLOAT vGain)
  1251. {
  1252.      unsigned int Size = (unsigned int)m_Sounds.size();
  1253.  
  1254.      // For every sound in the manager, check for a valid ID.
  1255.      for (unsigned int i = 0; i < Size; i++)
  1256.           if(m_Sounds[i]->getUniqueID() == vID)
  1257.           {
  1258.                m_Sounds[i]->setVolume(vGain);
  1259.                break;
  1260.           }
  1261. }
  1262.  
  1263.  
  1264. ///////////////////////////////////////////////////////////////////////////////
  1265. //    Name     : cloneSound
  1266. //
  1267. //    Date     : 2007.03.05
  1268. //
  1269. //    Author   : Chad Stewart
  1270. //
  1271. //    Purpose  : Create a new sound from an old one. This is how overlap works,
  1272. //                    because otherwise each ISound would be a vector of sounds playing
  1273. //                    instead of a single sound. Then you'd have to know the ID of the
  1274. //                    sound you want as well as the ID of that specific source. Unless
  1275. //                    of course you want to stop all sounds of said type everytime.
  1276. ///////////////////////////////////////////////////////////////////////////////
  1277. ILUINT IL::SOUND::CSoundManager::cloneSound(ILINT vVectorID, ISound** vCloneSound)
  1278. {
  1279.      // Ok, seriously, we need to copy stuff.
  1280.      *vCloneSound = m_Sounds[vVectorID]->cloneSound();
  1281.  
  1282.      // Push that bad boy onto the Sound vector.
  1283.      m_Sounds.push_back(*vCloneSound);
  1284.  
  1285.      (*vCloneSound)->setUniqueID(++m_UniqueIDGenerator);
  1286.      (*vCloneSound)->setFileName(m_Sounds[vVectorID]->getFileName());
  1287.  
  1288.      // Return it's location.
  1289.      return (ILUINT)m_Sounds.size() - 1;
  1290. }
  1291.  
  1292. ///////////////////////////////////////////////////////////////////////////////
  1293. //    Name     : getFreeChannel
  1294. ///////////////////////////////////////////////////////////////////////////////
  1295. ILINT IL::SOUND::CSoundManager::getFreeChannel(void)
  1296. {
  1297.      unsigned int Size = (unsigned int)m_vSoundChannels.size();
  1298.  
  1299.      // In use?
  1300.      for (unsigned int i = 0; i < Size; i++)
  1301.           if (m_vSoundChannels[i].m_InUse == false)
  1302.           {
  1303.                m_vSoundChannels[i].m_InUse = true;
  1304.                return i;
  1305.           }
  1306.  
  1307.      // No free channels
  1308.      return -1;
  1309. }
  1310.  
  1311. ///////////////////////////////////////////////////////////////////////////////
  1312. //    Name     : getFreeBufferi
  1313. ///////////////////////////////////////////////////////////////////////////////
  1314. ILINT IL::SOUND::CSoundManager::getFreeBufferi(void)
  1315. {
  1316.      unsigned int Size          = (unsigned int)m_vSoundBuffers.size();
  1317.      unsigned int i               = 0;
  1318.      ILINT           BufferID     = 0;
  1319.  
  1320.      for(i = 0; i < Size; i++)
  1321.           if (0 == m_vSoundBuffers[i].m_References)
  1322.                break;
  1323.  
  1324.      if (i != Size)
  1325.      {
  1326.           BufferID = m_vSoundBuffers[i].m_BufferID;
  1327.           m_vSoundBuffers[i].m_References++;
  1328.      }
  1329.      else
  1330.      {
  1331.           // Create a new buffer.
  1332.           tBuffer newBuffer;
  1333.          
  1334.           // Generate a buffer in OpenAL.
  1335.           alGetError();
  1336.           alGenBuffers(1, (ALuint*)&newBuffer.m_BufferID);
  1337.           newBuffer.m_References++;
  1338.  
  1339.           // Add it to our vector.
  1340.           m_vSoundBuffers.push_back(newBuffer);
  1341.  
  1342.           BufferID = newBuffer.m_BufferID;
  1343.      }
  1344.  
  1345.      return BufferID;
  1346. }