aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2012-04-10 16:38:41 -0400
committerMatthew Hoops2012-04-10 16:44:41 -0400
commit3e47203d645b24b8d94cb2ac742072764e49ef04 (patch)
treee5de2e44a0b55c8a5055b27a7e53c3a07722d956
parentdb52618833920648b3ced9e2e8a7d692a4aba08f (diff)
downloadscummvm-rg350-3e47203d645b24b8d94cb2ac742072764e49ef04.tar.gz
scummvm-rg350-3e47203d645b24b8d94cb2ac742072764e49ef04.tar.bz2
scummvm-rg350-3e47203d645b24b8d94cb2ac742072764e49ef04.zip
AUDIO: Force QuickTime stereo samples to mono if needed
The number of channels in AAC can differ from the actual number of channels needed making us require this. The channel count inside the container is always the correct one.
-rw-r--r--audio/decoders/quicktime.cpp47
1 files changed, 46 insertions, 1 deletions
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 762e86959d..48e76a94da 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -96,6 +96,45 @@ private:
uint32 _totalSamples, _samplesRead;
};
+/**
+ * An AudioStream wrapper that forces audio to be played in mono.
+ * It currently just ignores the right channel if stereo.
+ */
+class ForcedMonoAudioStream : public AudioStream {
+public:
+ ForcedMonoAudioStream(AudioStream *parentStream, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) :
+ _parentStream(parentStream), _disposeAfterUse(disposeAfterUse) {}
+
+ ~ForcedMonoAudioStream() {
+ if (_disposeAfterUse == DisposeAfterUse::YES)
+ delete _parentStream;
+ }
+
+ int readBuffer(int16 *buffer, const int numSamples) {
+ if (!_parentStream->isStereo())
+ return _parentStream->readBuffer(buffer, numSamples);
+
+ int16 temp[2];
+ int samples = 0;
+
+ while (samples < numSamples && !endOfData()) {
+ _parentStream->readBuffer(temp, 2);
+ *buffer++ = temp[0];
+ samples++;
+ }
+
+ return samples;
+ }
+
+ bool endOfData() const { return _parentStream->endOfData(); }
+ bool isStereo() const { return false; }
+ int getRate() const { return _parentStream->getRate(); }
+
+private:
+ AudioStream *_parentStream;
+ DisposeAfterUse::Flag _disposeAfterUse;
+};
+
QuickTimeAudioDecoder::QuickTimeAudioDecoder() : Common::QuickTimeParser() {
}
@@ -495,7 +534,13 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::enterNewEdit(const Timestamp &p
}
void QuickTimeAudioDecoder::QuickTimeAudioTrack::queueStream(AudioStream *stream, const Timestamp &length) {
- _queue->queueAudioStream(stream, DisposeAfterUse::YES);
+ // If the samples are stereo and the container is mono, force the samples
+ // to be mono.
+ if (stream->isStereo() && !isStereo())
+ _queue->queueAudioStream(new ForcedMonoAudioStream(stream, DisposeAfterUse::YES), DisposeAfterUse::YES);
+ else
+ _queue->queueAudioStream(stream, DisposeAfterUse::YES);
+
_samplesQueued += length.convertToFramerate(getRate()).totalNumberOfFrames();
}