diff options
author | Matthew Hoops | 2012-04-10 16:38:41 -0400 |
---|---|---|
committer | Matthew Hoops | 2012-04-10 16:44:41 -0400 |
commit | 3e47203d645b24b8d94cb2ac742072764e49ef04 (patch) | |
tree | e5de2e44a0b55c8a5055b27a7e53c3a07722d956 /audio/decoders | |
parent | db52618833920648b3ced9e2e8a7d692a4aba08f (diff) | |
download | scummvm-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.
Diffstat (limited to 'audio/decoders')
-rw-r--r-- | audio/decoders/quicktime.cpp | 47 |
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(); } |