From 3e47203d645b24b8d94cb2ac742072764e49ef04 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 10 Apr 2012 16:38:41 -0400 Subject: 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. --- audio/decoders/quicktime.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'audio/decoders') 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(); } -- cgit v1.2.3