X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faudio%2Fsound_manager.cpp;h=0576fe6ba9cd6d1fbcd9a6cba820250512317fa0;hb=d99e2443318865c0f379170b4ef2aa30f515b235;hp=933ddcffb2b9d28ce9857d2c284b35d125682b04;hpb=249d7138cb5c5e071c563a03f4955942cf997dde;p=supertux.git diff --git a/src/audio/sound_manager.cpp b/src/audio/sound_manager.cpp index 933ddcffb..0576fe6ba 100644 --- a/src/audio/sound_manager.cpp +++ b/src/audio/sound_manager.cpp @@ -1,3 +1,22 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + #include "sound_manager.hpp" #include @@ -8,15 +27,18 @@ #include "sound_file.hpp" #include "sound_source.hpp" #include "stream_sound_source.hpp" +#include "log.hpp" +#include "timer.hpp" + +SoundManager* sound_manager = 0; SoundManager::SoundManager() : device(0), context(0), sound_enabled(false), music_source(0), - next_music_source(0) + music_enabled(true) { try { device = alcOpenDevice(0); - if(device == 0) { - print_openal_version(); + if (device == NULL) { throw std::runtime_error("Couldn't open audio device."); } @@ -29,9 +51,13 @@ SoundManager::SoundManager() check_al_error("Audio error after init: "); sound_enabled = true; } catch(std::exception& e) { - device = 0; - context = 0; - std::cerr << "Couldn't initialize audio device:" << e.what() << "\n"; + if(context != NULL) + alcDestroyContext(context); + context = NULL; + if(device != NULL) + alcCloseDevice(device); + device = NULL; + log_warning << "Couldn't initialize audio device: " << e.what() << std::endl; print_openal_version(); } } @@ -39,7 +65,6 @@ SoundManager::SoundManager() SoundManager::~SoundManager() { delete music_source; - delete next_music_source; for(SoundSources::iterator i = sources.begin(); i != sources.end(); ++i) { delete *i; @@ -50,22 +75,18 @@ SoundManager::~SoundManager() alDeleteBuffers(1, &buffer); } - if(context != 0) { - alcMakeContextCurrent(0); + if(context != NULL) { alcDestroyContext(context); } - if(device != 0) { + if(device != NULL) { alcCloseDevice(device); } } ALuint -SoundManager::load_file_into_buffer(const std::string& filename) +SoundManager::load_file_into_buffer(SoundFile* file) { - // open sound file - std::auto_ptr file (load_sound_file(filename)); - - ALenum format = get_sample_format(file.get()); + ALenum format = get_sample_format(file); ALuint buffer; alGenBuffers(1, &buffer); check_al_error("Couldn't create audio buffer: "); @@ -98,8 +119,17 @@ SoundManager::create_sound_source(const std::string& filename) if(i != buffers.end()) { buffer = i->second; } else { - buffer = load_file_into_buffer(filename); - buffers.insert(std::make_pair(filename, buffer)); + // Load sound file + std::auto_ptr file (load_sound_file(filename)); + + if(file->size < 100000) { + buffer = load_file_into_buffer(file.get()); + buffers.insert(std::make_pair(filename, buffer)); + } else { + StreamSoundSource* source = new StreamSoundSource(); + source->set_sound_file(file.release()); + return source; + } } SoundSource* source = new SoundSource(); @@ -112,7 +142,7 @@ SoundManager::play(const std::string& filename, const Vector& pos) { try { SoundSource* source = create_sound_source(filename); - if(source == 0) + if(source == NULL) return; if(pos == Vector(-1, -1)) { alSourcef(source->source, AL_ROLLOFF_FACTOR, 0); @@ -122,23 +152,40 @@ SoundManager::play(const std::string& filename, const Vector& pos) source->play(); sources.push_back(source); } catch(std::exception& e) { - std::cout << "Couldn't play sound " << filename << ": " << e.what() << "\n"; + log_warning << "Couldn't play sound " << filename << ": " << e.what() << std::endl; + } +} + +void +SoundManager::play_and_delete(SoundSource* source) +{ + if (!source) { + log_debug << "ignoring NULL SoundSource" << std::endl; + return; + } + try { + source->play(); + sources.push_back(source); + } catch(std::exception& e) { + log_warning << "Couldn't play SoundSource: " << e.what() << std::endl; } } void SoundManager::enable_sound(bool enable) { - if(device == 0) + if(device == NULL) return; + sound_enabled = enable; } void SoundManager::enable_music(bool enable) { - if(device == 0) + if(device == NULL) return; + music_enabled = enable; if(music_enabled) { play_music(current_music); @@ -151,45 +198,65 @@ SoundManager::enable_music(bool enable) } void +SoundManager::stop_music(float fadetime) +{ + if(fadetime > 0) { + if(music_source + && music_source->get_fade_state() != StreamSoundSource::FadingOff) + music_source->set_fading(StreamSoundSource::FadingOff, fadetime); + } else { + delete music_source; + music_source = NULL; + } + current_music = ""; +} + +void SoundManager::play_music(const std::string& filename, bool fade) { - if(filename == current_music) + if(filename == current_music && music_source != NULL) return; current_music = filename; if(!music_enabled) return; - try { - StreamSoundSource* newmusic - = new StreamSoundSource(load_sound_file(filename)); + if(filename == "") { + delete music_source; + music_source = NULL; + return; + } + try { + std::auto_ptr newmusic (new StreamSoundSource()); alSourcef(newmusic->source, AL_ROLLOFF_FACTOR, 0); - - if(fade) { - if(music_source) - music_source->setFading(StreamSoundSource::FadingOff, .25f); - delete next_music_source; - next_music_source = newmusic; - } else { - delete music_source; - music_source = newmusic; - music_source->play(); - next_music_source = 0; - } + newmusic->set_sound_file(load_sound_file(filename)); + newmusic->set_looping(true); + if(fade) + newmusic->set_fading(StreamSoundSource::FadingOn, .5f); + newmusic->play(); + + delete music_source; + music_source = newmusic.release(); } catch(std::exception& e) { - std::cerr << "Couldn't play music file '" << filename << "': " - << e.what() << "\n"; + log_warning << "Couldn't play music file '" << filename << "': " << e.what() << std::endl; } } void -SoundManager::set_listener_position(Vector pos) +SoundManager::set_listener_position(const Vector& pos) { + static Uint32 lastticks = 0; + + Uint32 current_ticks = SDL_GetTicks(); + if(current_ticks - lastticks < 300) + return; + lastticks = current_ticks; + alListener3f(AL_POSITION, pos.x, pos.y, 0); } void -SoundManager::set_listener_velocity(Vector vel) +SoundManager::set_listener_velocity(const Vector& vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, 0); } @@ -197,9 +264,18 @@ SoundManager::set_listener_velocity(Vector vel) void SoundManager::update() { - // check for finished sound sources + static float lasttime = real_time; + + if(real_time - lasttime < 0.3) + return; + lasttime = real_time; + + // update and check for finished sound sources for(SoundSources::iterator i = sources.begin(); i != sources.end(); ) { SoundSource* source = *i; + + source->update(); + if(!source->playing()) { delete source; i = sources.erase(i); @@ -211,17 +287,12 @@ SoundManager::update() if(music_source) { music_source->update(); } - - if(next_music_source && !music_source || !music_source->playing()) { - delete music_source; - music_source = next_music_source; - //music_source->setFading(StreamSoundSource::FadingOn, 1.0f); - music_source->play(); - next_music_source = 0; + + if (context) + { + alcProcessContext(context); + check_alc_error("Error while processing audio context: "); } - - alcProcessContext(context); - check_alc_error("Error while processing audio context: "); } ALenum @@ -251,10 +322,10 @@ SoundManager::get_sample_format(SoundFile* file) void SoundManager::print_openal_version() { - std::cout << "OpenAL Vendor: " << alGetString(AL_VENDOR) << "\n" - << "OpenAL Version: " << alGetString(AL_VERSION) << "\n" - << "OpenAL Renderer: " << alGetString(AL_RENDERER) << "\n" - << "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n"; + log_info << "OpenAL Vendor: " << alGetString(AL_VENDOR) << std::endl; + log_info << "OpenAL Version: " << alGetString(AL_VERSION) << std::endl; + log_info << "OpenAL Renderer: " << alGetString(AL_RENDERER) << std::endl; + log_info << "OpenAl Extensions: " << alGetString(AL_EXTENSIONS) << std::endl; } void