2010-11-15 00:27:08 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
2010-10-18 00:40:50 +02:00
|
|
|
#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;
|
2011-03-24 08:26:06 +01:00
|
|
|
int audio_buffers = 2048;
|
2010-10-18 00:40:50 +02:00
|
|
|
|
|
|
|
LogDebug("Sound Init");
|
|
|
|
if (Mix_OpenAudio (audio_rate, audio_format, audio_channels, audio_buffers)) {
|
2010-11-15 22:49:35 +01:00
|
|
|
LogError ("Unable to initialize the sound system! Error message: %s", SDL_GetError());
|
2010-10-18 00:40:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
2010-11-01 22:22:50 +01:00
|
|
|
|
|
|
|
// stop music
|
|
|
|
HaltMusic();
|
|
|
|
|
|
|
|
// stop and clear all samples
|
|
|
|
mSamples.clear();
|
|
|
|
|
2010-10-18 00:40:50 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2011-03-24 08:26:06 +01:00
|
|
|
LogDebug ("Playing sound %s", sound_name.c_str());
|
|
|
|
|
2010-10-18 00:40:50 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2011-03-24 08:26:06 +01:00
|
|
|
LogDebug ("Playing sound loop %s", sound_name.c_str());
|
|
|
|
|
2010-10-18 00:40:50 +02:00
|
|
|
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);
|
|
|
|
|
2011-03-24 08:26:06 +01:00
|
|
|
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);
|
|
|
|
|
2010-10-18 00:40:50 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2010-11-01 22:22:50 +01:00
|
|
|
void SoundBase::HaltMusic () {
|
|
|
|
if (!SoundInstance) {
|
|
|
|
LogError("Could not stop music: sound system not initialized!");
|
|
|
|
}
|
|
|
|
|
|
|
|
Mix_HaltMusic();
|
|
|
|
Mix_FreeMusic(mCurrentMusic);
|
|
|
|
mCurrentMusic = NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-15 00:27:08 +01:00
|
|
|
void SoundBase::SetMusicVolume(const float &music_volume) {
|
|
|
|
int mix_volume = static_cast<int> (fabsf(music_volume) * MIX_MAX_VOLUME);
|
|
|
|
|
|
|
|
Mix_VolumeMusic(mix_volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
float SoundBase::GetMusicVolume() {
|
|
|
|
return static_cast<float>(Mix_VolumeMusic(-1)) / static_cast<float>(MIX_MAX_VOLUME);
|
|
|
|
}
|
2010-11-01 22:22:50 +01:00
|
|
|
|
2010-11-15 00:27:08 +01:00
|
|
|
void SoundBase::SetEffectsVolume(const float &effects_volume) {
|
|
|
|
int mix_volume = static_cast<int> (fabsf(effects_volume) * MIX_MAX_VOLUME);
|
|
|
|
|
|
|
|
Mix_Volume(-1, mix_volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
float SoundBase::GetEffectsVolume() {
|
|
|
|
return static_cast<float>(Mix_Volume(-1, -1)) / static_cast<float>(MIX_MAX_VOLUME);
|
|
|
|
}
|
2010-10-18 00:40:50 +02:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2011-03-24 08:26:06 +01:00
|
|
|
void LoadSound (const std::string &sound_name) {
|
|
|
|
if (!SoundInstance) {
|
|
|
|
LogError("Could not music volume: sound system not initialized!");
|
|
|
|
}
|
|
|
|
|
|
|
|
SoundInstance->LoadSound (sound_name);
|
|
|
|
}
|
|
|
|
|
2010-11-22 20:00:44 +01:00
|
|
|
void SetMusicVolume (const float &music_volume) {
|
|
|
|
if (!SoundInstance) {
|
2011-03-24 08:26:06 +01:00
|
|
|
LogError("Could not set music volume: sound system not initialized!");
|
2010-11-22 20:00:44 +01:00
|
|
|
}
|
|
|
|
|
2011-03-24 08:26:06 +01:00
|
|
|
|
2010-11-22 20:00:44 +01:00
|
|
|
SoundInstance->SetMusicVolume(music_volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
float GetMusicVolume () {
|
|
|
|
if (!SoundInstance) {
|
2011-03-24 08:26:06 +01:00
|
|
|
LogError("Could not get music volume: sound system not initialized!");
|
2010-11-22 20:00:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return SoundInstance->GetMusicVolume();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetEffectsVolume (const float &effects_volume) {
|
|
|
|
if (!SoundInstance) {
|
2011-03-24 08:26:06 +01:00
|
|
|
LogError("Could not set effects volume: sound system not initialized!");
|
2010-11-22 20:00:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
SoundInstance->SetEffectsVolume(effects_volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
float GetEffectsVolume () {
|
|
|
|
if (!SoundInstance) {
|
2011-03-24 08:26:06 +01:00
|
|
|
LogError("Could not get effects volume: sound system not initialized!");
|
2010-11-22 20:00:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return SoundInstance->GetEffectsVolume();
|
|
|
|
}
|
2010-10-18 00:40:50 +02:00
|
|
|
|
|
|
|
};
|