aboutsummaryrefslogtreecommitdiff
path: root/audio/audiostream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/audiostream.cpp')
-rw-r--r--audio/audiostream.cpp55
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;