#include <sound_manager.hpp>
Public Member Functions | |
SoundManager () | |
virtual | ~SoundManager () |
void | enable_sound (bool sound_enabled) |
SoundSource * | create_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 | |
OpenALSoundSource * | intern_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 &) | |
SoundManager & | operator= (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 |
StreamSoundSource * | music_source |
bool | music_enabled |
std::string | current_music |
Friends | |
class | OpenALSoundSource |
class | StreamSoundSource |
Definition at line 34 of file sound_manager.hpp.
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.
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] |
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 }
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 | ) |
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] |
bool SoundManager::is_sound_enabled | ( | ) | [inline] |
bool SoundManager::is_audio_enabled | ( | ) | [inline] |
Definition at line 70 of file sound_manager.hpp.
References context, and device.
Referenced by OptionsMenu::OptionsMenu().
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] |
friend class OpenALSoundSource [friend] |
friend class StreamSoundSource [friend] |
Definition at line 87 of file sound_manager.hpp.
Referenced by intern_create_sound_source(), and play_music().
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().