- Main Page
- Classes
- Files

- File List
- File Members

# C:/Users/Public/AGS Final Folder/BFLETCHER D4010283/Source/Game/Source/SoundManager.cpp

Go to the documentation of this file.

    00001 #include "SoundManager.h"
    00002 #include "DebugUtil.h"
    00003
    00004 #include "SDL.h"
    00005
    00006 #include "TimeUtility.h"
    00007
    00008 #include "ISound.h"
    00009 #include "Song.h"
    00010
    00011 #include "InputEvents.h"
    00012 #include "EventManager.h"
    00013
    00014 #include "GameConfig.h"
    00015 #include "GameException.h"
    00016
    00017 #define MAX_WAVE_DIFF 20000
    00018
    00019 template<> SoundManager* TSingleton<SoundManager>::m_pInstance = NULL;
    00020
    00021 SoundManager::SoundManager()
    00022 : m_lastUpdate(0), m_volume(SOUND_MAX_VOLUME), m_pAudioSpec(0)
    00023 {
    00024
    00025 }
    00026
    00027 SoundManager::~SoundManager()
    00028 {
    00029 }
    00030
    00031 void SoundManager::Initialise(int freq /* = 44100 */, Uint16 samples /* = 1024 */, Uint8 channels /* = 1 */)
    00032 {
    00033         m_pAudioSpec = new SDL_AudioSpec();
    00034         SDL_AudioSpec* pDesiredSpec = new SDL_AudioSpec();
    00035
    00036         pDesiredSpec->freq = freq;
    00037         pDesiredSpec->format = AUDIO_S16;
    00038         pDesiredSpec->samples = samples;
    00039         pDesiredSpec->channels = channels;
    00040         pDesiredSpec->callback = SoundManager::SDLAudioCallback;
    00041         pDesiredSpec->userdata = 0;
    00042
    00043         if(SDL_OpenAudio(pDesiredSpec, m_pAudioSpec) == -1)
    00044         {
    00045                 throw GameException(eMajorError, "SoundManager: SDL_OpenAudio failed!");
    00046                 return;
    00047         }
    00048
    00049         SDL_PauseAudio(false);
    00050
    00051         EventManager::getSingleton()->AddEventListener(ButtonInputEvent::cEventName, this);
    00052 }
    00053
    00054 void SoundManager::Shutdown()
    00055 {
    00056         SDL_CloseAudio();
    00057         delete m_pAudioSpec;
    00058
    00059         for(size_t i = 0; i < m_vSounds.size(); i++)
    00060         {
    00061                 if(m_vSounds[i])
    00062                         delete m_vSounds[i];
    00063         }
    00064
    00065         m_vSounds.clear();
    00066 }
    00067
    00068 void SoundManager::Output()
    00069 {
    00070         for(size_t i = 0; i < m_vSounds.size(); i++)
    00071         {
    00072                 if(m_vSounds[i])
    00073                         m_vSounds[i]->Output();
    00074         }
    00075 }
    00076
    00077 SoundID SoundManager::CreateSoundSong(const bool &bPreCreate, const UInt &bpm, const UInt &numUniqueSections, const UInt &lengthInSections, const UInt &timePerSection)
    00078 {
    00079         Song* pSong = new Song();
    00080
    00081         pSong->Initialise(bPreCreate, bpm, numUniqueSections, lengthInSections, timePerSection);
    00082
    00083         m_vSounds.push_back((ISound*)pSong);
    00084
    00085         return m_vSounds.size() - 1;
    00086 }
    00087
    00088 SoundInstanceID SoundManager::PlaySoundID(const SoundID &sid, bool loop)
    00089 {
    00090         if(!m_vSounds[sid])
    00091         {
    00092                 throw GameException(eMinorError, "SoundManager: PlaySoundID failed on Sound ID: %d", (int)sid);
    00093                 return 0; //Throw exception
    00094         }
    00095
    00096         SoundInstance* pInstance = new SoundInstance();
    00097
    00098         pInstance->pSound = m_vSounds[sid];
    00099         pInstance->isPaused = false;
    00100         pInstance->isLooping = loop;
    00101         pInstance->position = 0;
    00102
    00103         m_vInstances.push_back(pInstance);
    00104
    00105         return m_vInstances.size() - 1;
    00106 }
    00107
    00108 bool SoundManager::PauseSound(const SoundInstanceID &siid)
    00109 {
    00110         if(m_vInstances[siid])
    00111         {
    00112                 m_vInstances[siid]->isPaused = !m_vInstances[siid]->isPaused;
    00113
    00114                 return true;
    00115         }
    00116
    00117         return false;
    00118 }
    00119
    00120 bool SoundManager::StopSound(const SoundInstanceID &siid)
    00121 {
    00122         if(m_vInstances[siid])
    00123         {
    00124                 delete m_vInstances[siid];
    00125                 m_vInstances[siid] = 0;
    00126
    00127                 return true;
    00128         }
    00129
    00130         return false;
    00131 }
    00132
    00133 void SoundManager::Update()
    00134 {
    00135 //      unsigned long dt = TimeUtility::getTime() - m_lastUpdate;
    00136 //      for(int i = 0; i < m_vInstances.size(); i++)
    00137 //      {
    00138 //              if(m_vInstances[i] && m_vInstances[i]->isPaused != true)
    00139 //                      m_vInstances[i]->position += dt;
    00140 //      }
    00141
    00142
    00143 }
    00144
    00145 void SoundManager::MixBuffers(Sint16 *pBuf1, Sint16 *pBuf2, size_t sz)
    00146 {
    00147         for(size_t i = 0; i < sz; i++)
    00148         {
    00149                 long int val = pBuf1[i] + pBuf2[i];
    00150                 if(val > 32767)
    00151                         val = 32767;
    00152                 if(val < -32768)
    00153                         val = -32768;
    00154
    00155                 pBuf1[i] = (Sint16)val;
    00156         }
    00157 }
    00158
    00159 void SoundManager::HandleAudioBuffer(void* userdata, Uint8* stream, int len)
    00160 {
    00161         unsigned long dt = TimeUtility::getTime() - m_lastUpdate;
    00162
    00163         memset(stream, 0, len * sizeof(Uint8));
    00164         Sint16* pRealStream = (Sint16*)stream;
    00165
    00166         int rlen = len / sizeof(Sint16);
    00167         Sint16* pTmpStream = new Sint16[rlen];
    00168
    00169         double secsPerSampleset = (double)m_pAudioSpec->samples / (double)m_pAudioSpec->freq;
    00170
    00171         for(size_t i = 0; i < m_vInstances.size(); i++)
    00172         {
    00173                 if(m_vInstances[i])
    00174                 {
    00175                         SoundInstance* pInst = m_vInstances[i];
    00176                         if(pInst->isPaused == false)
    00177                         {
    00178                                 m_vInstances[i]->position += dt;
    00179                                 Sint16* pBuffer = pInst->pSound->GetBuffer(pInst->position, rlen, pInst->isLooping);
    00180                                 if(pBuffer)
    00181                                         MixBuffers(pRealStream, pBuffer, rlen);
    00182                                         //SDL_MixAudio((Uint8*)pTmpStream)
    00183                                 else
    00184                                 {
    00185                                         delete pInst;
    00186                                         pInst = 0;
    00187                                 }
    00188                         }
    00189                 }
    00190         }
    00191
    00192         ApplyVolumeToStream(pRealStream, rlen);
    00193         m_lastUpdate = TimeUtility::getTime();
    00194
    00195 //      memcpy((Uint8*)pRealStream, (Uint8*)pTmpStream, rlen * sizeof(Sint16));
    00196 }
    00197
    00198 void SoundManager::IncreaseVolume()
    00199 {
    00200         m_volume += SOUND_VOLUME_STEP;
    00201         if(m_volume > SOUND_MAX_VOLUME)
    00202                 m_volume = SOUND_MAX_VOLUME;
    00203 }
    00204
    00205 void SoundManager::DecreaseVolume()
    00206 {
    00207         m_volume -= SOUND_VOLUME_STEP;
    00208         if(m_volume < 0)
    00209                 m_volume = 0;
    00210 }
    00211
    00212 bool SoundManager::HandleEvent(IEvent* pEvent)
    00213 {
    00214         if(pEvent->GetEventType() == ButtonInputEvent::cEventName)
    00215         {
    00216                 ButtonInputEvent* pButtonEvent = (ButtonInputEvent*)pEvent;
    00217                 int key = pButtonEvent->GetKey();
    00218
    00219                 if(key == eKeyButtonVolumeUp && pButtonEvent->IsKeyDown())
    00220                 {
    00221                         DebugUtil::outputDebugText("Volume Up Received!\n");
    00222                         IncreaseVolume();
    00223                         return true;
    00224                 }
    00225
    00226                 if(key == eKeyButtonVolumeDown && pButtonEvent->IsKeyDown())
    00227                 {
    00228                         DebugUtil::outputDebugText("Volume Down Received!\n");
    00229                         DecreaseVolume();
    00230                         return true;
    00231                 }
    00232         }
    00233
    00234         return false;
    00235 }
    00236
    00237 void SoundManager::SDLAudioCallback(void *userdata, Uint8 *stream, int len)
    00238 {
    00239         SoundManager::getSingleton()->HandleAudioBuffer(userdata, stream, len);
    00240 }
    00241
    00242 void SoundManager::ApplyVolumeToStream(Sint16 *pStream, size_t sz)
    00243 {
    00244         for(size_t i = 0; i < sz; i++)
    00245         {
    00246                 pStream[i] = (pStream[i] * m_volume) / SOUND_MAX_VOLUME;
    00247         }
    00248 }