X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faudio%2Fstream_sound_source.cpp;h=958ef6f58f8c00960a78ead45faa419482ff1112;hb=ca86583fae991aa3280c5d70bf20dbf0504a93cb;hp=d282c4dbfd68453b1c906d718d206809c41c1f6d;hpb=795f0b283fcb1c8777723dc1cc850826d39c6806;p=supertux.git diff --git a/src/audio/stream_sound_source.cpp b/src/audio/stream_sound_source.cpp index d282c4dbf..958ef6f58 100644 --- a/src/audio/stream_sound_source.cpp +++ b/src/audio/stream_sound_source.cpp @@ -1,59 +1,117 @@ +// $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 +#include + +#include -#include "stream_sound_source.h" -#include "sound_manager.h" -#include "sound_file.h" +#include "stream_sound_source.hpp" +#include "sound_manager.hpp" +#include "sound_file.hpp" +#include "timer.hpp" +#include "log.hpp" -StreamSoundSource::StreamSoundSource(SoundFile* file) +StreamSoundSource::StreamSoundSource() + : file(0), fade_state(NoFading), looping(false) { - this->file = file; alGenBuffers(STREAMFRAGMENTS, buffers); SoundManager::check_al_error("Couldn't allocate audio buffers: "); - format = SoundManager::get_sample_format(file); - try { - for(size_t i = 0; i < STREAMFRAGMENTS; ++i) { - fillBufferAndQueue(buffers[i]); - } - } catch(...) { - alDeleteBuffers(STREAMFRAGMENTS, buffers); - } + //add me to update list + sound_manager->register_for_update( this ); } StreamSoundSource::~StreamSoundSource() { + //don't update me any longer + sound_manager->remove_from_update( this ); + delete file; + stop(); alDeleteBuffers(STREAMFRAGMENTS, buffers); SoundManager::check_al_error("Couldn't delete audio buffers: "); } void -StreamSoundSource::update() +StreamSoundSource::set_sound_file(SoundFile* newfile) { - if(!playing()) - return; + delete file; + file = newfile; + + ALint queued; + alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); + for(size_t i = 0; i < STREAMFRAGMENTS - queued; ++i) { + if(fillBufferAndQueue(buffers[i]) == false) + break; + } +} +void +StreamSoundSource::update() +{ ALint processed = 0; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); - while(processed > 0) { - processed--; - + for(ALint i = 0; i < processed; ++i) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); SoundManager::check_al_error("Couldn't unqueu audio buffer: "); - fillBufferAndQueue(buffer); + if(fillBufferAndQueue(buffer) == false) + break; } - - // we might have to restart the source if we had a buffer underrun + if(!playing()) { - std::cerr << "Restarting audio source because of buffer underrun.\n"; - alSourcePlay(source); - SoundManager::check_al_error("Couldn't restart audio source: "); + if(processed == 0 || !looping) + return; + + // we might have to restart the source if we had a buffer underrun + log_info << "Restarting audio source because of buffer underrun" << std::endl; + play(); } - // TODO handle fading + if(fade_state == FadingOn) { + float time = real_time - fade_start_time; + if(time >= fade_time) { + set_gain(1.0); + fade_state = NoFading; + } else { + set_gain(time / fade_time); + } + } else if(fade_state == FadingOff) { + float time = real_time - fade_start_time; + if(time >= fade_time) { + stop(); + fade_state = NoFading; + } else { + set_gain( (fade_time-time) / fade_time); + } + } } void +StreamSoundSource::set_fading(FadeState state, float fade_time) +{ + this->fade_state = state; + this->fade_time = fade_time; + this->fade_start_time = real_time; +} + +bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) { // fill buffer @@ -62,15 +120,25 @@ StreamSoundSource::fillBufferAndQueue(ALuint buffer) do { bytesread += file->read(bufferdata + bytesread, STREAMFRAGMENTSIZE - bytesread); + // end of sound file if(bytesread < STREAMFRAGMENTSIZE) { - file->reset(); + if(looping) + file->reset(); + else + break; } } while(bytesread < STREAMFRAGMENTSIZE); - - alBufferData(buffer, format, bufferdata, STREAMFRAGMENTSIZE, file->rate); - delete[] bufferdata; - SoundManager::check_al_error("Couldn't refill audio buffer: "); - alSourceQueueBuffers(source, 1, &buffer); - SoundManager::check_al_error("Couldn't queue audio buffer: "); + if(bytesread > 0) { + ALenum format = SoundManager::get_sample_format(file); + alBufferData(buffer, format, bufferdata, bytesread, file->rate); + delete[] bufferdata; + SoundManager::check_al_error("Couldn't refill audio buffer: "); + + alSourceQueueBuffers(source, 1, &buffer); + SoundManager::check_al_error("Couldn't queue audio buffer: "); + } + + // return false if there aren't more buffers to fill + return bytesread >= STREAMFRAGMENTSIZE; }