X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faudio%2Fstream_sound_source.cpp;h=5a0172362c4669fbc300482e55c5dd9796ed0b4c;hb=6b0c80bde84af0bf9323320d99f2fccd7c9eeedd;hp=61197962594d3ca5f4bfc68b23f755ac6ffddd34;hpb=63ccedcdc3dd65f3677c012f3d3e6e6233e5b002;p=supertux.git diff --git a/src/audio/stream_sound_source.cpp b/src/audio/stream_sound_source.cpp index 611979625..5a0172362 100644 --- a/src/audio/stream_sound_source.cpp +++ b/src/audio/stream_sound_source.cpp @@ -1,20 +1,48 @@ +// $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 "timer.hpp" +#include "log.hpp" StreamSoundSource::StreamSoundSource() - : file(0), fade_state(NoFading) + : file(0), fade_state(NoFading), looping(false) { alGenBuffers(STREAMFRAGMENTS, buffers); SoundManager::check_al_error("Couldn't allocate audio 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: "); } @@ -28,7 +56,8 @@ StreamSoundSource::set_sound_file(SoundFile* newfile) ALint queued; alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); for(size_t i = 0; i < STREAMFRAGMENTS - queued; ++i) { - fillBufferAndQueue(buffers[i]); + if(fillBufferAndQueue(buffers[i]) == false) + break; } } @@ -42,27 +71,21 @@ StreamSoundSource::update() alSourceUnqueueBuffers(source, 1, &buffer); SoundManager::check_al_error("Couldn't unqueu audio buffer: "); - fillBufferAndQueue(buffer); + if(fillBufferAndQueue(buffer) == false) + break; } if(!playing()) { - if(processed == 0) + if(processed == 0 || !looping) return; - - // we might have to restart the source if we had a buffer underrun - std::cerr << "Restarting audio source because of buffer underrun.\n"; + + // 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(); } -#ifdef DEBUG - ALint queued; - alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - assert(queued == (ALint) STREAMFRAGMENTS); -#endif - if(fade_state == FadingOn) { - Uint32 ticks = SDL_GetTicks(); - float time = (ticks - fade_start_ticks) / 1000.0; + float time = real_time - fade_start_time; if(time >= fade_time) { set_gain(1.0); fade_state = NoFading; @@ -70,8 +93,7 @@ StreamSoundSource::update() set_gain(time / fade_time); } } else if(fade_state == FadingOff) { - Uint32 ticks = SDL_GetTicks(); - float time = (ticks - fade_start_ticks) / 1000.0; + float time = real_time - fade_start_time; if(time >= fade_time) { stop(); fade_state = NoFading; @@ -86,10 +108,10 @@ StreamSoundSource::set_fading(FadeState state, float fade_time) { this->fade_state = state; this->fade_time = fade_time; - this->fade_start_ticks = SDL_GetTicks(); + this->fade_start_time = real_time; } -void +bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) { // fill buffer @@ -98,16 +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); - - ALenum format = SoundManager::get_sample_format(file); - 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; }