[Scummvm-cvs-logs] scummvm master -> 46aabed3f5bdb3549e3c804793b5198de4b1702c
clone2727
clone2727 at gmail.com
Sun Jul 10 21:53:48 CEST 2011
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c46aa548d6 AUDIO: Fix remaining AAC bugs by decoding with the same AAC context
46aabed3f5 AUDIO: Fix QDM2 sound in QuickTime files
Commit: c46aa548d6d8a1eabb968bfd0152215490bf746c
https://github.com/scummvm/scummvm/commit/c46aa548d6d8a1eabb968bfd0152215490bf746c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-07-10T12:50:47-07:00
Commit Message:
AUDIO: Fix remaining AAC bugs by decoding with the same AAC context
This introduces a new Audio::Codec class, based on DrMcCoy's solution for WMA in eos.
Changed paths:
A audio/decoders/codec.h
audio/decoders/aac.cpp
audio/decoders/aac.h
audio/decoders/quicktime.cpp
audio/decoders/quicktime_intern.h
diff --git a/audio/decoders/aac.cpp b/audio/decoders/aac.cpp
index 874062a..50325dc 100644
--- a/audio/decoders/aac.cpp
+++ b/audio/decoders/aac.cpp
@@ -28,74 +28,34 @@
#ifdef USE_FAAD
#include "common/debug.h"
+#include "common/memstream.h"
#include "common/stream.h"
#include "common/textconsole.h"
#include "common/util.h"
#include "audio/audiostream.h"
+#include "audio/decoders/codec.h"
+#include "audio/decoders/raw.h"
#include <neaacdec.h>
namespace Audio {
-class AACStream : public AudioStream {
+class AACDecoder : public Codec {
public:
- AACStream(Common::SeekableReadStream *stream,
- DisposeAfterUse::Flag disposeStream,
- Common::SeekableReadStream *extraData,
+ AACDecoder(Common::SeekableReadStream *extraData,
DisposeAfterUse::Flag disposeExtraData);
- ~AACStream();
+ ~AACDecoder();
- int readBuffer(int16 *buffer, const int numSamples);
-
- bool endOfData() const { return _inBufferPos >= _inBufferSize && !_remainingSamples; }
- bool isStereo() const { return _channels == 2; }
- int getRate() const { return _rate; }
+ AudioStream *decodeFrame(Common::SeekableReadStream &stream);
private:
NeAACDecHandle _handle;
byte _channels;
unsigned long _rate;
-
- byte *_inBuffer;
- uint32 _inBufferSize;
- uint32 _inBufferPos;
-
- int16 *_remainingSamples;
- uint32 _remainingSamplesSize;
- uint32 _remainingSamplesPos;
-
- void init(Common::SeekableReadStream *extraData);
};
-AACStream::AACStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeStream,
- Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
-
- _remainingSamples = 0;
- _inBufferPos = 0;
-
- init(extraData);
-
- // Copy all the data to a pointer so it can be passed through
- // (At least MPEG-4 chunks shouldn't be large)
- _inBufferSize = stream->size();
- _inBuffer = new byte[_inBufferSize];
- stream->read(_inBuffer, _inBufferSize);
-
- if (disposeStream == DisposeAfterUse::YES)
- delete stream;
-
- if (disposeExtraData == DisposeAfterUse::YES)
- delete extraData;
-}
-
-AACStream::~AACStream() {
- NeAACDecClose(_handle);
- delete[] _inBuffer;
- delete[] _remainingSamples;
-}
-
-void AACStream::init(Common::SeekableReadStream *extraData) {
+AACDecoder::AACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
// Open the library
_handle = NeAACDecOpen();
@@ -117,59 +77,55 @@ void AACStream::init(Common::SeekableReadStream *extraData) {
if (err < 0)
error("Could not initialize AAC decoder: %s", NeAACDecGetErrorMessage(err));
-}
-
-int AACStream::readBuffer(int16 *buffer, const int numSamples) {
- int samples = 0;
- assert((numSamples % _channels) == 0);
+ if (disposeExtraData == DisposeAfterUse::YES)
+ delete extraData;
+}
- // Dip into our remaining samples pool if it's available
- if (_remainingSamples) {
- samples = MIN<int>(numSamples, _remainingSamplesSize - _remainingSamplesPos);
+AACDecoder::~AACDecoder() {
+ NeAACDecClose(_handle);
+}
- memcpy(buffer, _remainingSamples + _remainingSamplesPos, samples * 2);
- _remainingSamplesPos += samples;
+AudioStream *AACDecoder::decodeFrame(Common::SeekableReadStream &stream) {
+ // read everything into a buffer
+ uint32 inBufferPos = 0;
+ uint32 inBufferSize = stream.size();
+ byte *inBuffer = new byte[inBufferSize];
+ stream.read(inBuffer, inBufferSize);
- if (_remainingSamplesPos == _remainingSamplesSize) {
- delete[] _remainingSamples;
- _remainingSamples = 0;
- }
- }
+ QueuingAudioStream *audioStream = makeQueuingAudioStream(_rate, _channels == 2);
// Decode until we have enough samples (or there's no more left)
- while (samples < numSamples && !endOfData()) {
+ while (inBufferPos < inBufferSize) {
NeAACDecFrameInfo frameInfo;
- uint16 *decodedSamples = (uint16 *)NeAACDecDecode(_handle, &frameInfo, _inBuffer + _inBufferPos, _inBufferSize - _inBufferPos);
+ void *decodedSamples = NeAACDecDecode(_handle, &frameInfo, inBuffer + inBufferPos, inBufferSize - inBufferPos);
if (frameInfo.error != 0)
error("Failed to decode AAC frame: %s", NeAACDecGetErrorMessage(frameInfo.error));
- int decodedSampleSize = frameInfo.samples;
- int copySamples = (decodedSampleSize > (numSamples - samples)) ? (numSamples - samples) : decodedSampleSize;
+ byte *buffer = (byte *)malloc(frameInfo.samples * 2);
+ memcpy(buffer, decodedSamples, frameInfo.samples * 2);
- memcpy(buffer + samples, decodedSamples, copySamples * 2);
- samples += copySamples;
+ byte flags = FLAG_16BITS;
- // Copy leftover samples for use in a later readBuffer() call
- if (copySamples != decodedSampleSize) {
- _remainingSamplesSize = decodedSampleSize - copySamples;
- _remainingSamples = new int16[_remainingSamplesSize];
- _remainingSamplesPos = 0;
- memcpy(_remainingSamples, decodedSamples + copySamples, _remainingSamplesSize * 2);
- }
+ if (_channels == 2)
+ flags |= FLAG_STEREO;
- _inBufferPos += frameInfo.bytesconsumed;
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= FLAG_LITTLE_ENDIAN;
+#endif
+
+ audioStream->queueBuffer(buffer, frameInfo.samples * 2, DisposeAfterUse::YES, flags);
+
+ inBufferPos += frameInfo.bytesconsumed;
}
- return samples;
+ return audioStream;
}
// Factory function
-AudioStream *makeAACStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeStream,
- Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
-
- return new AACStream(stream, disposeStream, extraData, disposeExtraData);
+Codec *makeAACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
+ return new AACDecoder(extraData, disposeExtraData);
}
} // End of namespace Audio
diff --git a/audio/decoders/aac.h b/audio/decoders/aac.h
index efcbcc6..c5085fa 100644
--- a/audio/decoders/aac.h
+++ b/audio/decoders/aac.h
@@ -43,23 +43,19 @@ namespace Common {
namespace Audio {
-class AudioStream;
+class Codec;
/**
- * Create a new AudioStream from the AAC data of an MPEG-4 file in the given stream.
+ * Create a new Codec for decoding AAC data of an MPEG-4 file in the given stream.
*
* @note This should *only* be called by our QuickTime/MPEG-4 decoder since it relies
* on the MPEG-4 extra data. If you want to decode a file using AAC, go use
* makeQuickTimeStream() instead!
- * @param stream the SeekableReadStream from which to read the AAC data
- * @param disposeStream whether to delete the stream after use
* @param extraData the SeekableReadStream from which to read the AAC extra data
* @param disposeExtraData whether to delete the extra data stream after use
- * @return a new AudioStream, or NULL, if an error occurred
+ * @return a new Codec, or NULL, if an error occurred
*/
-AudioStream *makeAACStream(
- Common::SeekableReadStream *stream,
- DisposeAfterUse::Flag disposeStream,
+Codec *makeAACDecoder(
Common::SeekableReadStream *extraData,
DisposeAfterUse::Flag disposeExtraData = DisposeAfterUse::NO);
diff --git a/audio/decoders/codec.h b/audio/decoders/codec.h
new file mode 100644
index 0000000..fde7e59
--- /dev/null
+++ b/audio/decoders/codec.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef AUDIO_DECODERS_CODEC_H
+#define AUDIO_DECODERS_CODEC_H
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace Audio {
+
+class AudioStream;
+
+class Codec {
+public:
+ Codec() {}
+ virtual ~Codec() {}
+
+ virtual AudioStream *decodeFrame(Common::SeekableReadStream &data) = 0;
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 0ad2821..4531cce 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -30,6 +30,7 @@
#include "common/textconsole.h"
#include "audio/audiostream.h"
+#include "audio/decoders/codec.h"
#include "audio/decoders/quicktime.h"
#include "audio/decoders/quicktime_intern.h"
@@ -86,6 +87,9 @@ void QuickTimeAudioDecoder::init() {
// Make sure the bits per sample transfers to the sample size
if (entry->getCodecTag() == MKTAG('r', 'a', 'w', ' ') || entry->getCodecTag() == MKTAG('t', 'w', 'o', 's'))
_tracks[_audioTrackIndex]->sampleSize = (entry->_bitsPerSample / 8) * entry->_channels;
+
+ // Initialize the codec (if necessary)
+ entry->initCodec();
}
}
}
@@ -217,6 +221,9 @@ void QuickTimeAudioDecoder::setAudioStreamPos(const Timestamp &where) {
Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0];
_audStream = Audio::makeQueuingAudioStream(entry->_sampleRate, entry->_channels == 2);
+ // Reinitialize the codec
+ entry->initCodec();
+
// First, we need to track down what audio sample we need
Audio::Timestamp curAudioTime = where.convertToFramerate(_tracks[_audioTrackIndex]->timeScale);
uint32 sample = curAudioTime.totalNumberOfFrames();
@@ -266,6 +273,11 @@ QuickTimeAudioDecoder::AudioSampleDesc::AudioSampleDesc(Common::QuickTimeParser:
_samplesPerFrame = 0;
_bytesPerFrame = 0;
_bitsPerSample = 0;
+ _codec = 0;
+}
+
+QuickTimeAudioDecoder::AudioSampleDesc::~AudioSampleDesc() {
+ delete _codec;
}
bool QuickTimeAudioDecoder::AudioSampleDesc::isAudioCodecSupported() const {
@@ -313,7 +325,12 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S
if (!stream)
return 0;
- if (_codecTag == MKTAG('t', 'w', 'o', 's') || _codecTag == MKTAG('r', 'a', 'w', ' ')) {
+ if (_codec) {
+ // If we've loaded a codec, make sure we use first
+ AudioStream *audioStream = _codec->decodeFrame(*stream);
+ delete stream;
+ return audioStream;
+ } else if (_codecTag == MKTAG('t', 'w', 'o', 's') || _codecTag == MKTAG('r', 'a', 'w', ' ')) {
// Fortunately, most of the audio used in Myst videos is raw...
uint16 flags = 0;
if (_codecTag == MKTAG('r', 'a', 'w', ' '))
@@ -330,12 +347,6 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S
} else if (_codecTag == MKTAG('i', 'm', 'a', '4')) {
// Riven uses this codec (as do some Myst ME videos)
return makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), kADPCMApple, _sampleRate, _channels, 34);
- } else if (_codecTag == MKTAG('m', 'p', '4', 'a')) {
- // The 7th Guest iOS uses an MPEG-4 codec
-#ifdef USE_FAAD
- if (_parentTrack->objectTypeMP4 == 0x40)
- return makeAACStream(stream, DisposeAfterUse::YES, _parentTrack->extraData);
-#endif
#ifdef AUDIO_QDM2_H
} else if (_codecTag == MKTAG('Q', 'D', 'M', '2')) {
// Myst ME uses this codec for many videos
@@ -344,10 +355,24 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S
}
error("Unsupported audio codec");
-
return NULL;
}
+void QuickTimeAudioDecoder::AudioSampleDesc::initCodec() {
+ delete _codec; _codec = 0;
+
+ switch (_codecTag) {
+ case MKTAG('m', 'p', '4', 'a'):
+#ifdef USE_FAAD
+ if (_parentTrack->objectTypeMP4 == 0x40)
+ _codec = makeAACDecoder(_parentTrack->extraData);
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
/**
* A wrapper around QuickTimeAudioDecoder that implements the RewindableAudioStream API
*/
diff --git a/audio/decoders/quicktime_intern.h b/audio/decoders/quicktime_intern.h
index f288d56..7ce06b8 100644
--- a/audio/decoders/quicktime_intern.h
+++ b/audio/decoders/quicktime_intern.h
@@ -45,6 +45,7 @@ namespace Common {
namespace Audio {
class AudioStream;
+class Codec;
class QueuingAudioStream;
class QuickTimeAudioDecoder : public Common::QuickTimeParser {
@@ -68,10 +69,12 @@ protected:
class AudioSampleDesc : public Common::QuickTimeParser::SampleDesc {
public:
AudioSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag);
+ ~AudioSampleDesc();
bool isAudioCodecSupported() const;
uint32 getAudioChunkSampleCount(uint chunk) const;
AudioStream *createAudioStream(Common::SeekableReadStream *stream) const;
+ void initCodec();
// TODO: Make private in the long run
uint16 _bitsPerSample;
@@ -79,6 +82,8 @@ protected:
uint32 _sampleRate;
uint32 _samplesPerFrame;
uint32 _bytesPerFrame;
+
+ Codec *_codec;
};
// Common::QuickTimeParser API
Commit: 46aabed3f5bdb3549e3c804793b5198de4b1702c
https://github.com/scummvm/scummvm/commit/46aabed3f5bdb3549e3c804793b5198de4b1702c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2011-07-10T12:50:47-07:00
Commit Message:
AUDIO: Fix QDM2 sound in QuickTime files
Changed paths:
audio/decoders/qdm2.cpp
audio/decoders/qdm2.h
audio/decoders/quicktime.cpp
diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp
index a178c36..ec2911e 100644
--- a/audio/decoders/qdm2.cpp
+++ b/audio/decoders/qdm2.cpp
@@ -28,7 +28,9 @@
#ifdef AUDIO_QDM2_H
#include "audio/audiostream.h"
+#include "audio/decoders/codec.h"
#include "audio/decoders/qdm2data.h"
+#include "audio/decoders/raw.h"
#include "common/array.h"
#include "common/debug.h"
@@ -150,19 +152,14 @@ struct RDFTContext {
FFTContext fft;
};
-class QDM2Stream : public AudioStream {
+class QDM2Stream : public Codec {
public:
- QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData);
+ QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData);
~QDM2Stream();
- bool isStereo() const { return _channels == 2; }
- bool endOfData() const { return _stream->pos() >= _stream->size() && _outputSamples.size() == 0 && _subPacket == 0; }
- int getRate() const { return _sampleRate; }
- int readBuffer(int16 *buffer, const int numSamples);
+ AudioStream *decodeFrame(Common::SeekableReadStream &stream);
private:
- Common::SeekableReadStream *_stream;
-
// Parameters from codec header, do not change during playback
uint8 _channels;
uint16 _sampleRate;
@@ -204,7 +201,6 @@ private:
// I/O data
uint8 *_compressedData;
float _outputBuffer[1024];
- Common::Array<int16> _outputSamples;
// Synthesis filter
int16 ff_mpa_synth_window[512];
@@ -285,7 +281,7 @@ private:
void qdm2_fft_tone_synthesizer(uint8 sub_packet);
void qdm2_calculate_fft(int channel);
void qdm2_synthesis_filter(uint8 index);
- int qdm2_decodeFrame(Common::SeekableReadStream *in);
+ bool qdm2_decodeFrame(Common::SeekableReadStream &in, QueuingAudioStream *audioStream);
};
// Fix compilation for non C99-compliant compilers, like MSVC
@@ -1711,7 +1707,7 @@ void QDM2Stream::initVlc(void) {
}
}
-QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData) {
+QDM2Stream::QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
uint32 tmp;
int32 tmp_s;
int tmp_val;
@@ -1719,7 +1715,6 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadS
debug(1, "QDM2Stream::QDM2Stream() Call");
- _stream = stream;
_compressedData = NULL;
_subPacket = 0;
_superBlockStart = 0;
@@ -1906,11 +1901,13 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadS
initNoiseSamples();
_compressedData = new uint8[_packetSize];
+
+ if (disposeExtraData == DisposeAfterUse::YES)
+ delete extraData;
}
QDM2Stream::~QDM2Stream() {
delete[] _compressedData;
- delete _stream;
}
static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) {
@@ -3158,30 +3155,30 @@ void QDM2Stream::qdm2_synthesis_filter(uint8 index)
_outputBuffer[_channels * i + ch] += (float)(samples[_channels * sub_sampling * i + ch] >> (sizeof(int16)*8-16));
}
-int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) {
- debug(1, "QDM2Stream::qdm2_decodeFrame in->pos(): %d in->size(): %d", in->pos(), in->size());
+bool QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream &in, QueuingAudioStream *audioStream) {
+ debug(1, "QDM2Stream::qdm2_decodeFrame in.pos(): %d in.size(): %d", in.pos(), in.size());
int ch, i;
const int frame_size = (_sFrameSize * _channels);
// If we're in any packet but the first, seek back to the first
if (_subPacket == 0)
- _superBlockStart = in->pos();
+ _superBlockStart = in.pos();
else
- in->seek(_superBlockStart);
+ in.seek(_superBlockStart);
// select input buffer
- if (in->eos() || in->pos() >= in->size()) {
+ if (in.eos() || in.pos() >= in.size()) {
debug(1, "QDM2Stream::qdm2_decodeFrame End of Input Stream");
- return 0;
+ return false;
}
- if ((in->size() - in->pos()) < _packetSize) {
- debug(1, "QDM2Stream::qdm2_decodeFrame Insufficient Packet Data in Input Stream Found: %d Need: %d", in->size() - in->pos(), _packetSize);
- return 0;
+ if ((in.size() - in.pos()) < _packetSize) {
+ debug(1, "QDM2Stream::qdm2_decodeFrame Insufficient Packet Data in Input Stream Found: %d Need: %d", in.size() - in.pos(), _packetSize);
+ return false;
}
- if (!in->eos()) {
- in->read(_compressedData, _packetSize);
+ if (!in.eos()) {
+ in.read(_compressedData, _packetSize);
debug(1, "QDM2Stream::qdm2_decodeFrame constructed input data");
}
@@ -3190,7 +3187,7 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) {
memset(&_outputBuffer[frame_size], 0, frame_size * sizeof(float));
debug(1, "QDM2Stream::qdm2_decodeFrame cleared outputBuffer");
- if (!in->eos()) {
+ if (!in.eos()) {
// decode block of QDM2 compressed data
debug(1, "QDM2Stream::qdm2_decodeFrame decode block of QDM2 compressed data");
if (_subPacket == 0) {
@@ -3218,7 +3215,7 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) {
if (!_hasErrors && _subPacketListC[0].packet != NULL) {
error("QDM2 : has errors, and C list is not empty");
- return 0;
+ return false;
}
}
@@ -3236,6 +3233,12 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) {
debug(1, "QDM2Stream::qdm2_decodeFrame clip and convert output float[] to 16bit signed samples");
}
+ if (frame_size == 0)
+ return false;
+
+ // Prepare a buffer for queuing
+ uint16 *outputBuffer = (uint16 *)malloc(frame_size * 2);
+
for (i = 0; i < frame_size; i++) {
int value = (int)_outputBuffer[i];
@@ -3244,34 +3247,35 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) {
else if (value < -SOFTCLIP_THRESHOLD)
value = (value < -HARDCLIP_THRESHOLD) ? -32767 : -_softclipTable[-value - SOFTCLIP_THRESHOLD];
- _outputSamples.push_back(value);
+ outputBuffer[i] = value;
}
- return frame_size;
-}
-int QDM2Stream::readBuffer(int16 *buffer, const int numSamples) {
- debug(1, "QDM2Stream::readBuffer numSamples: %d", numSamples);
- int32 decodedSamples = _outputSamples.size();
- int32 i;
+ // Queue the translated buffer to our stream
+ byte flags = FLAG_16BITS;
- while (decodedSamples < numSamples) {
- i = qdm2_decodeFrame(_stream);
- if (i == 0)
- break; // Out Of Decode Frames...
- decodedSamples += i;
- }
+ if (_channels == 2)
+ flags |= FLAG_STEREO;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= FLAG_LITTLE_ENDIAN;
+#endif
+
+ audioStream->queueBuffer((byte *)outputBuffer, frame_size * 2, DisposeAfterUse::YES, flags);
+
+ return true;
+}
- if (decodedSamples > numSamples)
- decodedSamples = numSamples;
+AudioStream *QDM2Stream::decodeFrame(Common::SeekableReadStream &stream) {
+ QueuingAudioStream *audioStream = makeQueuingAudioStream(_sampleRate, _channels == 2);
- for (i = 0; i < decodedSamples; i++)
- buffer[i] = _outputSamples.remove_at(0);
+ while (qdm2_decodeFrame(stream, audioStream))
+ ;
- return decodedSamples;
+ return audioStream;
}
-AudioStream *makeQDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData) {
- return new QDM2Stream(stream, extraData);
+Codec *makeQDM2Decoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
+ return new QDM2Stream(extraData, disposeExtraData);
}
} // End of namespace Audio
diff --git a/audio/decoders/qdm2.h b/audio/decoders/qdm2.h
index c0ec647..f0793e3 100644
--- a/audio/decoders/qdm2.h
+++ b/audio/decoders/qdm2.h
@@ -26,22 +26,25 @@
#ifndef AUDIO_QDM2_H
#define AUDIO_QDM2_H
+#include "common/types.h"
+
namespace Common {
class SeekableReadStream;
}
namespace Audio {
-class AudioStream;
+class Codec;
/**
- * Create a new AudioStream from the QDM2 data in the given stream.
+ * Create a new Codec from the QDM2 data in the given stream.
*
- * @param stream the SeekableReadStream from which to read the FLAC data
- * @param extraData the QuickTime extra data stream
- * @return a new AudioStream, or NULL, if an error occurred
+ * @param extraData the QuickTime extra data stream
+ * @param disposeExtraData the QuickTime extra data stream
+ * @return a new Codec, or NULL, if an error occurred
*/
-AudioStream *makeQDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData);
+Codec *makeQDM2Decoder(Common::SeekableReadStream *extraData,
+ DisposeAfterUse::Flag disposeExtraData = DisposeAfterUse::NO);
} // End of namespace Audio
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 4531cce..a39fedc 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -347,11 +347,6 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S
} else if (_codecTag == MKTAG('i', 'm', 'a', '4')) {
// Riven uses this codec (as do some Myst ME videos)
return makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), kADPCMApple, _sampleRate, _channels, 34);
-#ifdef AUDIO_QDM2_H
- } else if (_codecTag == MKTAG('Q', 'D', 'M', '2')) {
- // Myst ME uses this codec for many videos
- return makeQDM2Stream(stream, _parentTrack->extraData);
-#endif
}
error("Unsupported audio codec");
@@ -362,6 +357,11 @@ void QuickTimeAudioDecoder::AudioSampleDesc::initCodec() {
delete _codec; _codec = 0;
switch (_codecTag) {
+ case MKTAG('Q', 'D', 'M', '2'):
+#ifdef AUDIO_QDM2_H
+ _codec = makeQDM2Decoder(_parentTrack->extraData);
+#endif
+ break;
case MKTAG('m', 'p', '4', 'a'):
#ifdef USE_FAAD
if (_parentTrack->objectTypeMP4 == 0x40)
More information about the Scummvm-git-logs
mailing list