X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faudio%2Fstream_sound_source.cpp;h=d27856342649ce4023c659639e79adf256973f15;hb=07ddaed2a657e4d2a3d038fed223fc5827159caf;hp=4074a7021fe87d584c11ffcf437e1c97cf2f6ec1;hpb=249d7138cb5c5e071c563a03f4955942cf997dde;p=supertux.git diff --git a/src/audio/stream_sound_source.cpp b/src/audio/stream_sound_source.cpp index 4074a7021..d27856342 100644 --- a/src/audio/stream_sound_source.cpp +++ b/src/audio/stream_sound_source.cpp @@ -1,54 +1,82 @@ +// $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.hpp" #include "sound_manager.hpp" #include "sound_file.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); - } } StreamSoundSource::~StreamSoundSource() { + 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(); } if(fade_state == FadingOn) { @@ -63,7 +91,7 @@ StreamSoundSource::update() } else if(fade_state == FadingOff) { Uint32 ticks = SDL_GetTicks(); float time = (ticks - fade_start_ticks) / 1000.0; - if(time >= fade_time) { + if(time >= fade_time) { stop(); fade_state = NoFading; } else { @@ -73,14 +101,14 @@ StreamSoundSource::update() } void -StreamSoundSource::setFading(FadeState state, float fade_time) +StreamSoundSource::set_fading(FadeState state, float fade_time) { this->fade_state = state; this->fade_time = fade_time; this->fade_start_ticks = SDL_GetTicks(); } -void +bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) { // fill buffer @@ -89,15 +117,26 @@ 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; } +