fysxasteroids/engine/SoundBase.cc

294 lines
6.6 KiB
C++

#include <cmath>
#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(4, 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 = 512;
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());
}
// Allocate a few channels
Mix_AllocateChannels(8);
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 at channel %d", sound_name.c_str(), iter->second->GetChannel());
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 at channel %d", sound_name.c_str(), iter->second->GetChannel());
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 at channel %d", sound_name.c_str(), iter->second->GetChannel());
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<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);
}
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);
}
/*
* 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();
}
};