diff --git a/src/framework/core/filestream.cpp b/src/framework/core/filestream.cpp index a38ab54e..2864f1cf 100644 --- a/src/framework/core/filestream.cpp +++ b/src/framework/core/filestream.cpp @@ -163,6 +163,14 @@ uint FileStream::tell() return m_pos; } +bool FileStream::eof() +{ + if(!m_caching) + return PHYSFS_eof(m_fileHandle); + else + return m_pos >= m_data.size(); +} + uint8 FileStream::getU8() { uint8 v = 0; diff --git a/src/framework/core/filestream.h b/src/framework/core/filestream.h index 2d237adb..0d219e6a 100644 --- a/src/framework/core/filestream.h +++ b/src/framework/core/filestream.h @@ -45,6 +45,7 @@ public: void skip(uint len); uint size(); uint tell(); + bool eof(); std::string name() { return m_name; } uint8 getU8(); diff --git a/src/framework/sound/combinedsoundsource.cpp b/src/framework/sound/combinedsoundsource.cpp index 6babe2a3..018ac669 100644 --- a/src/framework/sound/combinedsoundsource.cpp +++ b/src/framework/sound/combinedsoundsource.cpp @@ -43,6 +43,15 @@ void CombinedSoundSource::stop() source->stop(); } +bool CombinedSoundSource::isBuffering() +{ + for(const SoundSourcePtr& source : m_sources) { + if(source->isBuffering()) + return true; + } + return false; +} + bool CombinedSoundSource::isPlaying() { for(const SoundSourcePtr& source : m_sources) { diff --git a/src/framework/sound/combinedsoundsource.h b/src/framework/sound/combinedsoundsource.h index f814e372..1a7656b2 100644 --- a/src/framework/sound/combinedsoundsource.h +++ b/src/framework/sound/combinedsoundsource.h @@ -35,6 +35,8 @@ public: void play(); void stop(); + + bool isBuffering(); bool isPlaying(); void setLooping(bool looping); diff --git a/src/framework/sound/soundfile.h b/src/framework/sound/soundfile.h index e665a0fd..30fa1863 100644 --- a/src/framework/sound/soundfile.h +++ b/src/framework/sound/soundfile.h @@ -35,6 +35,7 @@ public: virtual int read(void *buffer, int bufferSize) = 0; virtual void reset() = 0; + bool eof() { return m_file->eof(); } ALenum getSampleFormat(); diff --git a/src/framework/sound/soundsource.cpp b/src/framework/sound/soundsource.cpp index c439c6c5..f143c789 100644 --- a/src/framework/sound/soundsource.cpp +++ b/src/framework/sound/soundsource.cpp @@ -63,7 +63,7 @@ void SoundSource::stop() } } -bool SoundSource::isPlaying() +bool SoundSource::isBuffering() { int state = AL_PLAYING; alGetSourcei(m_sourceId, AL_SOURCE_STATE, &state); diff --git a/src/framework/sound/soundsource.h b/src/framework/sound/soundsource.h index 3169cedc..5c2e4ee8 100644 --- a/src/framework/sound/soundsource.h +++ b/src/framework/sound/soundsource.h @@ -39,7 +39,9 @@ public: virtual void play(); virtual void stop(); - virtual bool isPlaying(); + + virtual bool isBuffering(); + virtual bool isPlaying() { return isBuffering(); } virtual void setLooping(bool looping); virtual void setRelative(bool relative); diff --git a/src/framework/sound/streamsoundsource.cpp b/src/framework/sound/streamsoundsource.cpp index e0b82a09..e44e2a37 100644 --- a/src/framework/sound/streamsoundsource.cpp +++ b/src/framework/sound/streamsoundsource.cpp @@ -45,6 +45,13 @@ void StreamSoundSource::setSoundFile(const SoundFilePtr& soundFile) void StreamSoundSource::play() { + m_playing = true; + + if(m_eof) { + m_soundFile->reset(); + m_eof = false; + } + if(!m_soundFile) { g_logger.error("there is not sound file to play the stream"); return; @@ -59,6 +66,7 @@ void StreamSoundSource::stop() { SoundSource::stop(); unqueueBuffers(); + m_playing = false; } void StreamSoundSource::queueBuffers() @@ -96,12 +104,15 @@ void StreamSoundSource::update() break; } - if(!isPlaying()) { - if(processed == 0 || !m_looping) - return; - - g_logger.traceError("restarting audio source because of buffer underrun"); - play(); + if(!isBuffering() && m_playing) { + if(!m_looping && m_eof) { + stop(); + } else if(processed == 0) { + g_logger.traceError("audio buffer underrun"); + play(); + } else if(m_looping) { + play(); + } } } @@ -123,8 +134,10 @@ bool StreamSoundSource::fillBufferAndQueue(uint buffer) if(bytesRead < maxRead) { if(m_looping) m_soundFile->reset(); - else + else { + m_eof = true; break; + } } } while(bytesRead < maxRead); @@ -152,7 +165,7 @@ bool StreamSoundSource::fillBufferAndQueue(uint buffer) } // return false if there aren't more buffers to fill - return bytesRead >= STREAM_FRAGMENT_SIZE; + return (bytesRead >= STREAM_FRAGMENT_SIZE && !m_eof); } void StreamSoundSource::downMix(StreamSoundSource::DownMix downMix) diff --git a/src/framework/sound/streamsoundsource.h b/src/framework/sound/streamsoundsource.h index 8c9fc693..55e412dd 100644 --- a/src/framework/sound/streamsoundsource.h +++ b/src/framework/sound/streamsoundsource.h @@ -28,7 +28,7 @@ class StreamSoundSource : public SoundSource { enum { - STREAM_BUFFER_SIZE = 1024 * 100, + STREAM_BUFFER_SIZE = 1024 * 200, STREAM_FRAGMENTS = 5, STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS }; @@ -42,6 +42,8 @@ public: void play(); void stop(); + bool isPlaying() { return m_playing; } + void setSoundFile(const SoundFilePtr& soundFile); void downMix(DownMix downMix); @@ -57,6 +59,8 @@ private: std::array m_buffers; DownMix m_downMix; stdext::boolean m_looping; + stdext::boolean m_playing; + stdext::boolean m_eof; }; #endif