SoundManager Class Reference

#include <sound_manager.hpp>

List of all members.

Public Member Functions

 SoundManager ()
virtual ~SoundManager ()
void enable_sound (bool sound_enabled)
SoundSourcecreate_sound_source (const std::string &filename)
 Creates a new sound source object which plays the specified soundfile.
void play (const std::string &name, const Vector &pos=Vector(-1,-1))
 Convenience function to simply play a sound at a given position.
void manage_source (SoundSource *source)
 Adds the source to the list of managed sources (= the source gets deleted when it finished playing).
void preload (const std::string &name)
 preloads a sound, so that you don't get a lag later when playing it
void set_listener_position (const Vector &position)
void set_listener_velocity (const Vector &velocity)
void enable_music (bool music_enabled)
void play_music (const std::string &filename, bool fade=false)
void stop_music (float fadetime=0)
bool is_music_enabled ()
bool is_sound_enabled ()
bool is_audio_enabled ()
void update ()
void register_for_update (StreamSoundSource *sss)
void remove_from_update (StreamSoundSource *sss)

Private Types

typedef std::map< std::string,
ALuint > 
SoundBuffers
typedef std::vector< OpenALSoundSource * > SoundSources
typedef std::vector< StreamSoundSource * > StreamSoundSources

Private Member Functions

OpenALSoundSourceintern_create_sound_source (const std::string &filename)
 creates a new sound source, might throw exceptions, never returns NULL
void print_openal_version ()
void check_alc_error (const char *message)
 SoundManager (const SoundManager &)
SoundManageroperator= (const SoundManager &)

Static Private Member Functions

static ALuint load_file_into_buffer (SoundFile *file)
static ALenum get_sample_format (SoundFile *file)
static void check_al_error (const char *message)

Private Attributes

ALCdevice * device
ALCcontext * context
bool sound_enabled
SoundBuffers buffers
SoundSources sources
StreamSoundSources update_list
StreamSoundSourcemusic_source
bool music_enabled
std::string current_music

Friends

class OpenALSoundSource
class StreamSoundSource


Detailed Description

Definition at line 34 of file sound_manager.hpp.


Member Typedef Documentation

typedef std::map<std::string, ALuint> SoundManager::SoundBuffers [private]

Definition at line 102 of file sound_manager.hpp.

typedef std::vector<OpenALSoundSource*> SoundManager::SoundSources [private]

Definition at line 104 of file sound_manager.hpp.

typedef std::vector<StreamSoundSource*> SoundManager::StreamSoundSources [private]

Definition at line 107 of file sound_manager.hpp.


Constructor & Destructor Documentation

SoundManager::SoundManager (  ) 

Definition at line 30 of file sound_manager.cpp.

References check_al_error(), check_alc_error(), context, device, log_warning, music_enabled, print_openal_version(), and sound_enabled.

00030                            :
00031   device(0), 
00032   context(0), 
00033   sound_enabled(false), 
00034   buffers(),
00035   sources(),
00036   update_list(),
00037   music_source(0),
00038   music_enabled(false),
00039   current_music()
00040 {
00041   try {
00042     device = alcOpenDevice(0);
00043     if (device == NULL) {
00044       throw std::runtime_error("Couldn't open audio device.");
00045     }
00046 
00047     int attributes[] = { 0 };
00048     context = alcCreateContext(device, attributes);
00049     check_alc_error("Couldn't create audio context: ");
00050     alcMakeContextCurrent(context);
00051     check_alc_error("Couldn't select audio context: ");
00052 
00053     check_al_error("Audio error after init: ");
00054     sound_enabled = true;
00055     music_enabled = true;
00056   } catch(std::exception& e) {
00057     if(context != NULL) {
00058       alcDestroyContext(context);
00059       context = NULL; 
00060     }
00061     if(device != NULL) {
00062       alcCloseDevice(device);
00063       device = NULL;
00064     }
00065     log_warning << "Couldn't initialize audio device: " << e.what() << std::endl;
00066     print_openal_version();
00067   }
00068 }

SoundManager::~SoundManager (  )  [virtual]

Definition at line 70 of file sound_manager.cpp.

References buffers, context, device, music_source, and sources.

00071 {
00072   delete music_source;
00073 
00074   for(SoundSources::iterator i = sources.begin(); i != sources.end(); ++i) {
00075     delete *i;
00076   }
00077 
00078   for(SoundBuffers::iterator i = buffers.begin(); i != buffers.end(); ++i) {
00079     ALuint buffer = i->second;
00080     alDeleteBuffers(1, &buffer);
00081   }
00082 
00083   if(context != NULL) {
00084     alcDestroyContext(context);
00085     context = NULL;
00086   }
00087   if(device != NULL) {
00088     alcCloseDevice(device);
00089     device = NULL;
00090   }
00091 }

SoundManager::SoundManager ( const SoundManager  )  [private]


Member Function Documentation

void SoundManager::enable_sound ( bool  sound_enabled  ) 

Definition at line 241 of file sound_manager.cpp.

References device, and sound_enabled.

Referenced by Main::init_audio(), and OptionsMenu::menu_action().

00242 {
00243   if(device == NULL)
00244     return;
00245 
00246   sound_enabled = enable;
00247 }

SoundSource * SoundManager::create_sound_source ( const std::string &  filename  ) 

Creates a new sound source object which plays the specified soundfile.

You are responsible for deleting the sound source later (this will stop the sound). This function never throws exceptions, but might return a DummySoundSource

Definition at line 150 of file sound_manager.cpp.

References create_dummy_sound_source(), intern_create_sound_source(), log_warning, and sound_enabled.

Referenced by WillOWisp::activate(), TreeWillOWisp::activate(), Flame::activate(), Dart::activate(), Bomb::Bomb(), and AmbientSound::start_playing().

00151 {
00152   if(!sound_enabled)
00153     return create_dummy_sound_source();
00154 
00155   try {
00156     return intern_create_sound_source(filename);
00157   } catch(std::exception &e) {
00158     log_warning << "Couldn't create audio source: " << e.what() << std::endl;
00159     return create_dummy_sound_source();
00160   }
00161 }

void SoundManager::play ( const std::string &  name,
const Vector pos = Vector(-1,-1) 
)

Convenience function to simply play a sound at a given position.

Definition at line 187 of file sound_manager.cpp.

References intern_create_sound_source(), log_warning, sound_enabled, sources, Vector::x, and Vector::y.

Referenced by Yeti::active_update(), GhostTree::active_update(), Sector::add_bullet(), PlayerStatus::add_coins(), Trampoline::collision(), PushButton::collision(), PowerUp::collision(), Lantern::collision(), GrowUp::collision(), Flower::collision(), Firefly::collision(), MoleRock::collision_badguy(), Dart::collision_badguy(), WillOWisp::collision_player(), MoleRock::collision_player(), Dart::collision_player(), Rock::collision_solid(), Snail::collision_solid(), MrIceBlock::collision_solid(), MoleRock::collision_solid(), Dart::collision_solid(), Stumpy::collision_squished(), Snail::collision_squished(), MrTree::collision_squished(), Mole::collision_squished(), Dispenser::collision_squished(), Player::collision_tile(), Player::do_backflip(), Player::do_jump(), Switch::event(), Door::event(), Explosion::explode(), DartTrap::fire(), Thunderstorm::flash(), Player::handle_horizontal_input(), InvisibleBlock::hit(), Totem::jump_on(), Player::kill(), KamikazeSnowball::kill_collision(), Mole::kill_fall(), BadGuy::kill_fall(), BadGuy::kill_squished(), Player::make_invincible(), scripting::play_sound(), Toad::set_state(), SkullyHop::set_state(), MrIceBlock::set_state(), Yeti::take_hit(), Mole::throw_rock(), Thunderstorm::thunder(), Brick::try_break(), BonusBlock::try_open(), worldmap::WorldMap::update(), and Fireworks::update().

00188 {
00189   if(!sound_enabled)
00190     return;
00191 
00192   try {
00193     std::auto_ptr<OpenALSoundSource> source
00194       (intern_create_sound_source(filename));
00195 
00196     if(pos.x < 0 || pos.y < 0) {
00197       source->set_relative(true);
00198     } else {
00199       source->set_position(pos);
00200     }
00201     source->play();
00202     sources.push_back(source.release());
00203   } catch(std::exception& e) {
00204     log_warning << "Couldn't play sound " << filename << ": " << e.what() << std::endl;
00205   }
00206 }

void SoundManager::manage_source ( SoundSource source  ) 

Adds the source to the list of managed sources (= the source gets deleted when it finished playing).

Definition at line 209 of file sound_manager.cpp.

References sources.

00210 {
00211   assert(source != NULL);
00212 
00213   OpenALSoundSource* openal_source = dynamic_cast<OpenALSoundSource*> (source);
00214   if(openal_source != NULL) {
00215     sources.push_back(openal_source);
00216   }
00217 }

void SoundManager::preload ( const std::string &  name  ) 

preloads a sound, so that you don't get a lag later when playing it

Definition at line 164 of file sound_manager.cpp.

References buffers, load_file_into_buffer(), load_sound_file(), log_warning, and sound_enabled.

Referenced by AmbientSound::AmbientSound(), BadGuy::BadGuy(), Block::Block(), Coin::Coin(), Dart::Dart(), DartTrap::DartTrap(), Dispenser::Dispenser(), Door::Door(), Explosion::Explosion(), Firefly::Firefly(), Fireworks::Fireworks(), Flame::Flame(), Flower::Flower(), GhostTree::GhostTree(), GrowUp::GrowUp(), Haywire::Haywire(), InvisibleBlock::InvisibleBlock(), KamikazeSnowball::KamikazeSnowball(), Lantern::Lantern(), Mole::Mole(), MoleRock::MoleRock(), MrBomb::MrBomb(), MrIceBlock::MrIceBlock(), MrTree::MrTree(), Player::Player(), PlayerStatus::PlayerStatus(), PowerUp::PowerUp(), PushButton::PushButton(), Rock::Rock(), Sector::Sector(), ShortFuse::ShortFuse(), SkullyHop::SkullyHop(), Snail::Snail(), Stumpy::Stumpy(), Switch::Switch(), Thunderstorm::Thunderstorm(), Toad::Toad(), Totem::Totem(), Trampoline::Trampoline(), TreeWillOWisp::TreeWillOWisp(), WillOWisp::WillOWisp(), worldmap::WorldMap::WorldMap(), and Yeti::Yeti().

00165 {
00166   if(!sound_enabled)
00167     return;
00168 
00169   SoundBuffers::iterator i = buffers.find(filename);
00170   // already loaded?
00171   if(i != buffers.end())
00172     return;
00173   try {
00174     std::auto_ptr<SoundFile> file (load_sound_file(filename));
00175     // only keep small files
00176     if(file->size >= 100000)
00177       return;
00178 
00179     ALuint buffer = load_file_into_buffer(file.get());
00180     buffers.insert(std::make_pair(filename, buffer));
00181   } catch(std::exception& e) {
00182     log_warning << "Error while preloading sound file: " << e.what() << std::endl;
00183   }
00184 }

void SoundManager::set_listener_position ( const Vector position  ) 

Definition at line 312 of file sound_manager.cpp.

References Vector::x, and Vector::y.

Referenced by GameSession::update().

00313 {
00314   static Uint32 lastticks = SDL_GetTicks();
00315 
00316   Uint32 current_ticks = SDL_GetTicks();
00317   if(current_ticks - lastticks < 300)
00318     return;
00319   lastticks = current_ticks;
00320 
00321   alListener3f(AL_POSITION, pos.x, pos.y, 0);
00322 }

void SoundManager::set_listener_velocity ( const Vector velocity  ) 

Definition at line 325 of file sound_manager.cpp.

References Vector::x, and Vector::y.

00326 {
00327   alListener3f(AL_VELOCITY, vel.x, vel.y, 0);
00328 }

void SoundManager::enable_music ( bool  music_enabled  ) 

Definition at line 250 of file sound_manager.cpp.

References current_music, device, music_enabled, music_source, and play_music().

Referenced by Main::init_audio(), and OptionsMenu::menu_action().

00251 {
00252   if(device == NULL)
00253     return;
00254 
00255   music_enabled = enable;
00256   if(music_enabled) {
00257     play_music(current_music);
00258   } else {
00259     if(music_source) {
00260       delete music_source;
00261       music_source = NULL;
00262     }
00263   }
00264 }

void SoundManager::play_music ( const std::string &  filename,
bool  fade = false 
)

Definition at line 281 of file sound_manager.cpp.

References current_music, StreamSoundSource::FadingOn, load_sound_file(), log_warning, music_enabled, music_source, and StreamSoundSource.

Referenced by enable_music(), Sector::play_music(), scripting::play_music(), worldmap::WorldMap::setup(), TextScroller::setup(), and GameSession::start_sequence().

00282 {
00283   if(filename == current_music && music_source != NULL)
00284     return;
00285   current_music = filename;
00286   if(!music_enabled)
00287     return;
00288 
00289   if(filename == "") {
00290     delete music_source;
00291     music_source = NULL;
00292     return;
00293   }
00294 
00295   try {
00296     std::auto_ptr<StreamSoundSource> newmusic (new StreamSoundSource());
00297     newmusic->set_sound_file(load_sound_file(filename));
00298     newmusic->set_looping(true);
00299     newmusic->set_relative(true);
00300     if(fade)
00301       newmusic->set_fading(StreamSoundSource::FadingOn, .5f);
00302     newmusic->play();
00303 
00304     delete music_source;
00305     music_source = newmusic.release();
00306   } catch(std::exception& e) {
00307     log_warning << "Couldn't play music file '" << filename << "': " << e.what() << std::endl;
00308   }
00309 }

void SoundManager::stop_music ( float  fadetime = 0  ) 

Definition at line 267 of file sound_manager.cpp.

References current_music, StreamSoundSource::FadingOff, StreamSoundSource::get_fade_state(), music_source, and StreamSoundSource::set_fading().

Referenced by MainMenu::check_menu(), ContribWorldMenu::check_menu(), Player::kill(), Sector::play_music(), and GameSession::restart_level().

00268 {
00269   if(fadetime > 0) {
00270     if(music_source
00271        && music_source->get_fade_state() != StreamSoundSource::FadingOff)
00272       music_source->set_fading(StreamSoundSource::FadingOff, fadetime);
00273   } else {
00274     delete music_source;
00275     music_source = NULL;
00276   }
00277   current_music = "";
00278 }

bool SoundManager::is_music_enabled (  )  [inline]

Definition at line 67 of file sound_manager.hpp.

00067 { return music_enabled; }

bool SoundManager::is_sound_enabled (  )  [inline]

Definition at line 68 of file sound_manager.hpp.

00068 { return sound_enabled; }

bool SoundManager::is_audio_enabled (  )  [inline]

Definition at line 70 of file sound_manager.hpp.

References context, and device.

Referenced by OptionsMenu::OptionsMenu().

00070                           {
00071     return device != 0 && context != 0;
00072   }

void SoundManager::update (  ) 

Definition at line 331 of file sound_manager.cpp.

References check_alc_error(), context, music_source, sources, StreamSoundSource::update(), and update_list.

Referenced by ScreenManager::run(), and Main::wait_for_event().

00332 {
00333   static Uint32 lasttime = SDL_GetTicks();
00334   Uint32 now = SDL_GetTicks();
00335 
00336   if(now - lasttime < 300)
00337     return;
00338   lasttime = now;
00339 
00340   // update and check for finished sound sources
00341   for(SoundSources::iterator i = sources.begin(); i != sources.end(); ) {
00342     OpenALSoundSource* source = *i;
00343 
00344     source->update();
00345 
00346     if(!source->playing()) {
00347       delete source;
00348       i = sources.erase(i);
00349     } else {
00350       ++i;
00351     }
00352   }
00353   // check streaming sounds
00354   if(music_source) {
00355     music_source->update();
00356   }
00357 
00358   if (context)
00359   {
00360     alcProcessContext(context);
00361     check_alc_error("Error while processing audio context: ");
00362   }
00363 
00364   //run update() for stream_sound_source
00365   StreamSoundSources::iterator s = update_list.begin();
00366   while( s != update_list.end() ){
00367     (*s)->update();
00368     s++;
00369   }
00370 }

void SoundManager::register_for_update ( StreamSoundSource sss  ) 

Definition at line 220 of file sound_manager.cpp.

References update_list.

Referenced by StreamSoundSource::StreamSoundSource().

00220                                                          {
00221   if( sss != NULL ){
00222     update_list.push_back( sss );
00223   }
00224 }

void SoundManager::remove_from_update ( StreamSoundSource sss  ) 

Definition at line 227 of file sound_manager.cpp.

References update_list.

Referenced by StreamSoundSource::~StreamSoundSource().

00227                                                          {
00228   if( sss != NULL ){
00229     StreamSoundSources::iterator i = update_list.begin();
00230     while( i != update_list.end() ){
00231       if( *i == sss ){
00232         i = update_list.erase(i);
00233       } else {
00234         i++;
00235       }
00236     }
00237   }
00238 }

OpenALSoundSource * SoundManager::intern_create_sound_source ( const std::string &  filename  )  [private]

creates a new sound source, might throw exceptions, never returns NULL

Definition at line 117 of file sound_manager.cpp.

References buffers, load_file_into_buffer(), load_sound_file(), log_debug, OpenALSoundSource, StreamSoundSource::set_sound_file(), sound_enabled, and StreamSoundSource.

Referenced by create_sound_source(), and play().

00118 {
00119   assert(sound_enabled);
00120 
00121   std::auto_ptr<OpenALSoundSource> source (new OpenALSoundSource());
00122 
00123   ALuint buffer;
00124 
00125   // reuse an existing static sound buffer
00126   SoundBuffers::iterator i = buffers.find(filename);
00127   if(i != buffers.end()) {
00128     buffer = i->second;
00129   } else {
00130     // Load sound file
00131     std::auto_ptr<SoundFile> file (load_sound_file(filename));
00132 
00133     if(file->size < 100000) {
00134       buffer = load_file_into_buffer(file.get());
00135       buffers.insert(std::make_pair(filename, buffer));
00136     } else {
00137       StreamSoundSource* source = new StreamSoundSource();
00138       source->set_sound_file(file.release());
00139       return source;
00140     }
00141 
00142     log_debug << "Uncached sound \"" << filename << "\" requested to be played" << std::endl;
00143   }
00144 
00145   alSourcei(source->source, AL_BUFFER, buffer);
00146   return source.release();
00147 }

ALuint SoundManager::load_file_into_buffer ( SoundFile file  )  [static, private]

Definition at line 94 of file sound_manager.cpp.

References check_al_error(), get_sample_format(), SoundFile::rate, SoundFile::read(), and SoundFile::size.

Referenced by intern_create_sound_source(), and preload().

00095 {
00096   ALenum format = get_sample_format(file);
00097   ALuint buffer;
00098   alGenBuffers(1, &buffer);
00099   check_al_error("Couldn't create audio buffer: ");
00100   char* samples = new char[file->size];
00101   try {
00102     file->read(samples, file->size);
00103     alBufferData(buffer, format, samples,
00104                  static_cast<ALsizei> (file->size),
00105                  static_cast<ALsizei> (file->rate));
00106     check_al_error("Couldn't fill audio buffer: ");
00107   } catch(...) {
00108     delete[] samples;
00109     throw;
00110   }
00111   delete[] samples;
00112 
00113   return buffer;
00114 }

ALenum SoundManager::get_sample_format ( SoundFile file  )  [static, private]

Definition at line 373 of file sound_manager.cpp.

References SoundFile::bits_per_sample, and SoundFile::channels.

Referenced by StreamSoundSource::fillBufferAndQueue(), and load_file_into_buffer().

00374 {
00375   if(file->channels == 2) {
00376     if(file->bits_per_sample == 16) {
00377       return AL_FORMAT_STEREO16;
00378     } else if(file->bits_per_sample == 8) {
00379       return AL_FORMAT_STEREO8;
00380     } else {
00381       throw std::runtime_error("Only 16 and 8 bit samples supported");
00382     }
00383   } else if(file->channels == 1) {
00384     if(file->bits_per_sample == 16) {
00385       return AL_FORMAT_MONO16;
00386     } else if(file->bits_per_sample == 8) {
00387       return AL_FORMAT_MONO8;
00388     } else {
00389       throw std::runtime_error("Only 16 and 8 bit samples supported");
00390     }
00391   }
00392 
00393   throw std::runtime_error("Only 1 and 2 channel samples supported");
00394 }

void SoundManager::print_openal_version (  )  [private]

Definition at line 397 of file sound_manager.cpp.

References log_info.

Referenced by SoundManager().

00398 {
00399   log_info << "OpenAL Vendor: " << alGetString(AL_VENDOR) << std::endl;
00400   log_info << "OpenAL Version: " << alGetString(AL_VERSION) << std::endl;
00401   log_info << "OpenAL Renderer: " << alGetString(AL_RENDERER) << std::endl;
00402   log_info << "OpenAl Extensions: " << alGetString(AL_EXTENSIONS) << std::endl;
00403 }

void SoundManager::check_alc_error ( const char *  message  )  [private]

Definition at line 406 of file sound_manager.cpp.

References device.

Referenced by SoundManager(), and update().

00407 {
00408   int err = alcGetError(device);
00409   if(err != ALC_NO_ERROR) {
00410     std::stringstream msg;
00411     msg << message << alcGetString(device, err);
00412     throw std::runtime_error(msg.str());
00413   }
00414 }

void SoundManager::check_al_error ( const char *  message  )  [static, private]

Definition at line 417 of file sound_manager.cpp.

Referenced by StreamSoundSource::fillBufferAndQueue(), load_file_into_buffer(), OpenALSoundSource::OpenALSoundSource(), OpenALSoundSource::play(), SoundManager(), OpenALSoundSource::stop(), StreamSoundSource::StreamSoundSource(), StreamSoundSource::update(), and StreamSoundSource::~StreamSoundSource().

00418 {
00419   int err = alGetError();
00420   if(err != AL_NO_ERROR) {
00421     std::stringstream msg;
00422     msg << message << alGetString(err);
00423     throw std::runtime_error(msg.str());
00424   }
00425 }

SoundManager& SoundManager::operator= ( const SoundManager  )  [private]


Friends And Related Function Documentation

friend class OpenALSoundSource [friend]

Definition at line 86 of file sound_manager.hpp.

Referenced by intern_create_sound_source().

friend class StreamSoundSource [friend]

Definition at line 87 of file sound_manager.hpp.

Referenced by intern_create_sound_source(), and play_music().


Member Data Documentation

ALCdevice* SoundManager::device [private]

Definition at line 98 of file sound_manager.hpp.

Referenced by check_alc_error(), enable_music(), enable_sound(), is_audio_enabled(), SoundManager(), and ~SoundManager().

ALCcontext* SoundManager::context [private]

Definition at line 99 of file sound_manager.hpp.

Referenced by is_audio_enabled(), SoundManager(), update(), and ~SoundManager().

bool SoundManager::sound_enabled [private]

Definition at line 100 of file sound_manager.hpp.

Referenced by create_sound_source(), enable_sound(), intern_create_sound_source(), play(), preload(), and SoundManager().

SoundBuffers SoundManager::buffers [private]

Definition at line 103 of file sound_manager.hpp.

Referenced by intern_create_sound_source(), preload(), and ~SoundManager().

SoundSources SoundManager::sources [private]

Definition at line 105 of file sound_manager.hpp.

Referenced by manage_source(), play(), update(), and ~SoundManager().

StreamSoundSources SoundManager::update_list [private]

Definition at line 108 of file sound_manager.hpp.

Referenced by register_for_update(), remove_from_update(), and update().

StreamSoundSource* SoundManager::music_source [private]

Definition at line 110 of file sound_manager.hpp.

Referenced by enable_music(), play_music(), stop_music(), update(), and ~SoundManager().

bool SoundManager::music_enabled [private]

Definition at line 112 of file sound_manager.hpp.

Referenced by enable_music(), play_music(), and SoundManager().

std::string SoundManager::current_music [private]

Definition at line 113 of file sound_manager.hpp.

Referenced by enable_music(), play_music(), and stop_music().


The documentation for this class was generated from the following files:
Generated on Mon Jun 9 03:38:36 2014 for SuperTux by  doxygen 1.5.1