X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faudio%2Fstream_sound_source.cpp;h=bb178725d4cee6dc9538b19f51cc2b516d08f99a;hb=25da12d34b356745dcf3669f234e17ee5bfa6b80;hp=88e67c015885721960ae438bc81f912b38f23019;hpb=5b7f9214cb929399f1a855ef5807018a9447d510;p=supertux.git diff --git a/src/audio/stream_sound_source.cpp b/src/audio/stream_sound_source.cpp index 88e67c015..bb178725d 100644 --- a/src/audio/stream_sound_source.cpp +++ b/src/audio/stream_sound_source.cpp @@ -1,59 +1,113 @@ -#include +// 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 3 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, see . -#include "stream_sound_source.hpp" -#include "sound_manager.hpp" -#include "sound_file.hpp" +#include "audio/sound_file.hpp" +#include "audio/sound_manager.hpp" +#include "audio/stream_sound_source.hpp" +#include "supertux/timer.hpp" +#include "util/log.hpp" -StreamSoundSource::StreamSoundSource(SoundFile* file) +StreamSoundSource::StreamSoundSource() : + file(0), + fade_state(NoFading), + fade_start_time(), + fade_time(), + 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: "); + SoundManager::check_al_error("Couldn't unqueue 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 @@ -61,16 +115,28 @@ StreamSoundSource::fillBufferAndQueue(ALuint buffer) size_t bytesread = 0; do { bytesread += file->read(bufferdata + bytesread, - STREAMFRAGMENTSIZE - 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); + + if(bytesread > 0) { + ALenum format = SoundManager::get_sample_format(file); + alBufferData(buffer, format, bufferdata, bytesread, file->rate); + SoundManager::check_al_error("Couldn't refill audio buffer: "); + + alSourceQueueBuffers(source, 1, &buffer); + SoundManager::check_al_error("Couldn't queue audio buffer: "); + } 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; } + +/* EOF */