src/SoundSystem.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * SoundSystem Code
00003  */
00004 
00005 #include <list>
00006 #include <vector>
00007 #include <algorithm>
00008 #include "Log.h"
00009 #include <AL/al.h>
00010 #include <AL/alut.h>
00011 #include "OpenALSource.h"
00012 #include "ISound.h"
00013 #include "ISubSystem.h"
00014 #include "SoundSystem.h"
00015 
00016 using namespace std;
00017 
00018 SoundSystem *SoundSystem::s_soundSystem = NULL;
00019 
00020 void SoundSystem::Initialize(unsigned int numSources) {
00021   if (s_soundSystem != NULL) {
00022     Log::s_log->Message("Warning: Attempt to re-initialize sound subsystem");
00023     return;
00024   }
00025 
00026   s_soundSystem = new SoundSystem(numSources);
00027 }
00028 
00029 void SoundSystem::Shutdown() {
00030   if (s_soundSystem == NULL) {
00031     Log::s_log->Message("Warning: Attempt to re-shutdown sound subsystem");
00032     return;
00033   }
00034   delete s_soundSystem;
00035 }
00036 
00037 SoundSystem::SoundSystem(unsigned int numSources) {
00038   alutInit(0, NULL);
00039 
00040   SetListener();
00041 
00042   m_sources.resize(numSources);
00043   for (unsigned int i = 0; i < numSources; i++) {
00044     m_sources[i] = new OpenALSource();
00045   }
00046   m_availSources = m_sources;
00047 
00048   Log::s_log->DebugMessage("Post-initialization...");
00049   LogDebugInfo();
00050 
00051   Log::s_log->Message("Audio initialized");
00052 }
00053 
00054 SoundSystem::~SoundSystem() {
00055   Log::s_log->DebugMessage("Pre-shutdown...");
00056   LogDebugInfo();
00057   StopAll();
00058   if (!m_playingSounds.empty()) {
00059     Log::s_log->Message("Sound system shutdown with sounds still active (likely memory leak!)");
00060     m_playingSounds.clear();
00061   }
00062 
00063   m_availSources.clear();
00064 
00065   for (unsigned int i = 0; i < m_sources.size(); i++) {
00066     delete m_sources[i];
00067   }
00068   m_sources.clear();
00069 
00070   Log::s_log->DebugMessage("Post-shutdown...");
00071   LogDebugInfo();
00072 
00073   alutExit();
00074   alGetError();
00075   Log::s_log->Message("Audio shutdown");
00076 }
00077 
00078 void SoundSystem::LogDebugInfo() {
00079   Log::s_log->DebugMessage("%d sources", m_sources.size());
00080   Log::s_log->DebugMessage("%d sources available", m_availSources.size());
00081   Log::s_log->DebugMessage("%d sounds playing", m_playingSounds.size());
00082 }
00083 
00084 void SoundSystem::SetListener() {
00085   ALfloat listenerPos[] = { 0.0, 0.0, 0.0 };
00086   ALfloat listenerVel[] = { 0.0, 0.0, 0.0 };
00087 
00088   // Orientation of the listener. (first 3 elements are "at", second 3 are "up")
00089   ALfloat listenerOri[] = { 0.0, 0.0, -1.0,  0.0, 1.0, 0.0 };
00090 
00091   alListenerfv(AL_POSITION, listenerPos);
00092   alListenerfv(AL_VELOCITY, listenerVel);
00093   alListenerfv(AL_ORIENTATION, listenerOri);
00094 }
00095 
00096 void SoundSystem::Update(unsigned int ticks) {
00097   list< ISound* >::iterator p;
00098   list< ISound* >::iterator endIterator;
00099 
00100   endIterator = m_playingSounds.end();
00101   for (p = m_playingSounds.begin(); p != endIterator; ++p) {
00102     (*p)->Update(ticks);
00103   }
00104 }
00105 
00106 void SoundSystem::Play(ISound *sound) {
00107   sound->Prepare();
00108   MoveToFrontOfQueue(sound);
00109   sound->Play();
00110 }
00111 
00112 OpenALSource* SoundSystem::AquireSource() {
00113   OpenALSource *source;
00114   list< ISound* >::reverse_iterator p;
00115   list< ISound* >::reverse_iterator endIterator;
00116   ISound *victim;
00117 
00118   if (!m_availSources.empty()) {
00119     // We have a free source
00120     source = m_availSources.back();
00121     m_availSources.pop_back();
00122 
00123     return source;
00124   } else {
00125     // There isn't a free source, so we have to take the least recently used source
00126     p = m_playingSounds.rbegin();
00127     endIterator = m_playingSounds.rend();
00128     while (p != endIterator) {
00129       victim = (*p);
00130       if ((!victim->m_locked) && (victim->m_source != NULL)) {
00131         source = victim->m_source;
00132         victim->RevokeSource();
00133 
00134         return source;
00135       }
00136       ++p;
00137     }
00138   }
00139   throw string("Could not aquire source");
00140 }
00141 
00142 void SoundSystem::ReleaseSound(ISound *sound) {
00143   OpenALSource *source;
00144 
00145   sound->Stop();
00146   m_playingSounds.remove(sound);
00147 
00148   source = sound->GetSource();
00149   if (source != NULL) {
00150     m_availSources.push_back(sound->GetSource());
00151   }
00152 }
00153 
00154 void SoundSystem::PauseAll() {
00155   list< ISound* >::iterator p;
00156   list< ISound* >::const_iterator endIterator = m_playingSounds.end();
00157 
00158   for (p = m_playingSounds.begin(); p != endIterator; ++p) {
00159     (*p)->Pause();
00160   }
00161 }
00162 
00163 void SoundSystem::StopAll() {
00164   list< ISound* >::const_iterator p;
00165   list< ISound* >::const_iterator endIterator = m_playingSounds.end();
00166 
00167   for (p = m_playingSounds.begin(); p != endIterator; ++p) {
00168     (*p)->Stop();
00169   }
00170 }
00171 
00172 void SoundSystem::MoveToFrontOfQueue(ISound *sound) {
00173   m_playingSounds.remove(sound);
00174   m_playingSounds.push_front(sound);
00175 }

Generated on Mon Jan 8 22:34:12 2007 for CrownandCutlass by  doxygen 1.4.7