diff options
Diffstat (limited to 'audio/audiostream.cpp')
-rw-r--r-- | audio/audiostream.cpp | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/audio/audiostream.cpp b/audio/audiostream.cpp index 4dd5d236be..c413edb73d 100644 --- a/audio/audiostream.cpp +++ b/audio/audiostream.cpp @@ -98,7 +98,7 @@ LoopingAudioStream::LoopingAudioStream(RewindableAudioStream *stream, uint loops // TODO: Properly indicate error _loops = _completeIterations = 1; } - if (stream->endOfData()) { + if (stream->endOfStream()) { // Apparently this is an empty stream _loops = _completeIterations = 1; } @@ -122,7 +122,7 @@ int LoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) { _loops = _completeIterations = 1; return samplesRead; } - if (_parent->endOfData()) { + if (_parent->endOfStream()) { // Apparently this is an empty stream _loops = _completeIterations = 1; } @@ -134,7 +134,11 @@ int LoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) { } bool LoopingAudioStream::endOfData() const { - return (_loops != 0 && (_completeIterations == _loops)); + return (_loops != 0 && _completeIterations == _loops) || _parent->endOfData(); +} + +bool LoopingAudioStream::endOfStream() const { + return _loops != 0 && _completeIterations == _loops; } AudioStream *makeLoopingAudioStream(RewindableAudioStream *stream, uint loops) { @@ -189,7 +193,7 @@ int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) { int framesRead = _parent->readBuffer(buffer, framesLeft); _pos = _pos.addFrames(framesRead); - if (framesRead < framesLeft && _parent->endOfData()) { + if (framesRead < framesLeft && _parent->endOfStream()) { // TODO: Proper error indication. _done = true; return framesRead; @@ -216,6 +220,18 @@ int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) { } } +bool SubLoopingAudioStream::endOfData() const { + // We're out of data if this stream is finished or the parent + // has run out of data for now. + return _done || _parent->endOfData(); +} + +bool SubLoopingAudioStream::endOfStream() const { + // The end of the stream has been reached only when we've gone + // through all the iterations. + return _done; +} + #pragma mark - #pragma mark --- SubSeekableAudioStream --- #pragma mark - @@ -315,18 +331,27 @@ public: virtual int readBuffer(int16 *buffer, const int numSamples); virtual bool isStereo() const { return _stereo; } virtual int getRate() const { return _rate; } + virtual bool endOfData() const { - //Common::StackLock lock(_mutex); - return _queue.empty(); + Common::StackLock lock(_mutex); + return _queue.empty() || _queue.front()._stream->endOfData(); + } + + virtual bool endOfStream() const { + Common::StackLock lock(_mutex); + return _finished && _queue.empty(); } - virtual bool endOfStream() const { return _finished && _queue.empty(); } // Implement the QueuingAudioStream API virtual void queueAudioStream(AudioStream *stream, DisposeAfterUse::Flag disposeAfterUse); - virtual void finish() { _finished = true; } + + virtual void finish() { + Common::StackLock lock(_mutex); + _finished = true; + } uint32 numQueuedStreams() const { - //Common::StackLock lock(_mutex); + Common::StackLock lock(_mutex); return _queue.size(); } }; @@ -356,11 +381,17 @@ int QueuingAudioStreamImpl::readBuffer(int16 *buffer, const int numSamples) { AudioStream *stream = _queue.front()._stream; samplesDecoded += stream->readBuffer(buffer + samplesDecoded, numSamples - samplesDecoded); - if (stream->endOfData()) { + // Done with the stream completely + if (stream->endOfStream()) { StreamHolder tmp = _queue.pop(); if (tmp._disposeAfterUse == DisposeAfterUse::YES) delete stream; + continue; } + + // Done with data but not the stream, bail out + if (stream->endOfData()) + break; } return samplesDecoded; @@ -416,12 +447,14 @@ public: return samplesRead; } - bool endOfData() const { return _parentStream->endOfData() || _samplesRead >= _totalSamples; } + bool endOfData() const { return _parentStream->endOfData() || reachedLimit(); } + bool endOfStream() const { return _parentStream->endOfStream() || reachedLimit(); } bool isStereo() const { return _parentStream->isStereo(); } int getRate() const { return _parentStream->getRate(); } private: int getChannels() const { return isStereo() ? 2 : 1; } + bool reachedLimit() const { return _samplesRead >= _totalSamples; } AudioStream *_parentStream; DisposeAfterUse::Flag _disposeAfterUse; |