#include #include "SoundBase.h" #include "SoundBaseGlobal.h" namespace Engine { static SoundBase* SoundInstance = NULL; /* Sound Sample */ SoundSample::~SoundSample() { Stop(); Mix_FreeChunk(mMixChunk); mMixChunk = NULL; } bool SoundSample::Load (const std::string &filename) { assert (mMixChunk == NULL); LogDebug("Loading SoundSample %s", filename.c_str()); mMixChunk = Mix_LoadWAV(filename.c_str()); if (mMixChunk == NULL) { LogError("Loading of SoundSample %s failed: %s", filename.c_str(), Mix_GetError()); return false; } return true; } void SoundSample::Play() { mChannel = Mix_PlayChannel(-1, mMixChunk, 0); } void SoundSample::Loop(int count) { mChannel = Mix_PlayChannel(-1, mMixChunk, count); } void SoundSample::Stop() { if (mChannel != -1) Mix_HaltChannel(mChannel); } int SoundBase::OnInit(int argc, char* argv[]) { SoundInstance = this; int audio_rate = 22050; Uint16 audio_format = AUDIO_S16; int audio_channels = 2; int audio_buffers = 4096; LogDebug("Sound Init"); if (Mix_OpenAudio (audio_rate, audio_format, audio_channels, audio_buffers)) { LogError ("Unable to initialize the sound system! Error message: %s", SDL_GetError()); } Mix_QuerySpec (&audio_rate, &audio_format, &audio_channels); LogDebug("Sound: rate: %d channels: %d format: %d", audio_rate, audio_channels, audio_format); mCurrentMusicName = ""; mCurrentMusic = NULL; Mix_VolumeMusic(MIX_MAX_VOLUME/2); return 0; } void SoundBase::OnDestroy() { LogDebug ("Sound Destroy"); // stop music HaltMusic(); // stop and clear all samples mSamples.clear(); Mix_CloseAudio(); SoundInstance = NULL; } /* Module specific functions */ void SoundBase::PlaySound (const std::string &sound_name) { if (!SoundInstance) { LogError("Could not play sound %s: sound system not initialized!", sound_name.c_str()); } SampleIter iter = mSamples.find(sound_name); if (iter == mSamples.end()) { SoundSamplePtr sample (new SoundSample); sample->Load(sound_name); mSamples[sound_name] = sample; iter = mSamples.find(sound_name); } LogDebug ("Playing sound %s", sound_name.c_str()); iter->second->Play(); } void SoundBase::PlaySoundLoop (const std::string &sound_name, int count) { if (!SoundInstance) { LogError("Could not play sound %s: sound system not initialized!", sound_name.c_str()); } SampleIter iter = mSamples.find(sound_name); if (iter == mSamples.end()) { SoundSamplePtr sample (new SoundSample); sample->Load(sound_name); mSamples[sound_name] = sample; iter = mSamples.find(sound_name); } LogDebug ("Playing sound loop %s", sound_name.c_str()); iter->second->Loop(count); } void SoundBase::HaltSoundLoop (const std::string &sound_name) { if (!SoundInstance) { LogError("Could not play sound %s: sound system not initialized!", sound_name.c_str()); } SampleIter iter = mSamples.find(sound_name); if (iter == mSamples.end()) { // nothing to stop return; } LogDebug ("Halting sound loop %s", sound_name.c_str()); iter->second->Stop(); } void SoundBase::LoadSound (const std::string &sound_name) { SampleIter iter = mSamples.find(sound_name); if (iter == mSamples.end()) { SoundSamplePtr sample (new SoundSample); sample->Load(sound_name); mSamples[sound_name] = sample; } } void SoundBase::PlayMusic (const std::string &music_name) { if (!SoundInstance) { LogError("Could not play music %s: sound system not initialized!", music_name.c_str()); } if (music_name == mCurrentMusicName) return; if (mCurrentMusic) { Mix_HaltMusic(); Mix_FreeMusic(mCurrentMusic); mCurrentMusic = NULL; } LogDebug("Loading Music %s", music_name.c_str()); mCurrentMusic = Mix_LoadMUS(music_name.c_str()); if (mCurrentMusic == NULL) { LogError("Loading of Music failed: %s", Mix_GetError()); return; } Mix_PlayMusic(mCurrentMusic, -1); } void SoundBase::HaltMusic () { if (!SoundInstance) { LogError("Could not stop music: sound system not initialized!"); } Mix_HaltMusic(); Mix_FreeMusic(mCurrentMusic); mCurrentMusic = NULL; } void SoundBase::SetMusicVolume(const float &music_volume) { int mix_volume = static_cast (fabsf(music_volume) * MIX_MAX_VOLUME); Mix_VolumeMusic(mix_volume); } float SoundBase::GetMusicVolume() { return static_cast(Mix_VolumeMusic(-1)) / static_cast(MIX_MAX_VOLUME); } void SoundBase::SetEffectsVolume(const float &effects_volume) { int mix_volume = static_cast (fabsf(effects_volume) * MIX_MAX_VOLUME); Mix_Volume(-1, mix_volume); } float SoundBase::GetEffectsVolume() { return static_cast(Mix_Volume(-1, -1)) / static_cast(MIX_MAX_VOLUME); } /* * Global Functions */ void PlaySound (const std::string &sound_name) { if (!SoundInstance) { LogError("Could not play sound %s: sound system not initialized!", sound_name.c_str()); } SoundInstance->PlaySound(sound_name); } void PlayMusic (const std::string &music_name) { if (!SoundInstance) { LogError("Could not play sound %s: sound system not initialized!", music_name.c_str()); } SoundInstance->PlayMusic(music_name); } void PlaySoundLoop (const std::string &sound_name, int count) { if (!SoundInstance) { LogError("Could not play sound loop %s: sound system not initialized!", sound_name.c_str()); } SoundInstance->PlaySoundLoop(sound_name, count); } void HaltSoundLoop (const std::string &sound_name) { if (!SoundInstance) { LogError("Could not halt sound %s: sound system not initialized!", sound_name.c_str()); } SoundInstance->HaltSoundLoop(sound_name); } void LoadSound (const std::string &sound_name) { if (!SoundInstance) { LogError("Could not music volume: sound system not initialized!"); } SoundInstance->LoadSound (sound_name); } void SetMusicVolume (const float &music_volume) { if (!SoundInstance) { LogError("Could not set music volume: sound system not initialized!"); } SoundInstance->SetMusicVolume(music_volume); } float GetMusicVolume () { if (!SoundInstance) { LogError("Could not get music volume: sound system not initialized!"); } return SoundInstance->GetMusicVolume(); } void SetEffectsVolume (const float &effects_volume) { if (!SoundInstance) { LogError("Could not set effects volume: sound system not initialized!"); } SoundInstance->SetEffectsVolume(effects_volume); } float GetEffectsVolume () { if (!SoundInstance) { LogError("Could not get effects volume: sound system not initialized!"); } return SoundInstance->GetEffectsVolume(); } };