VIDEO: Factor out handleAudioTrack() to be used by Toons engine

svn-id: r53086
This commit is contained in:
Eugene Sandulenko 2010-10-08 22:17:03 +00:00
parent 8785bce190
commit 741e7c7f5e
2 changed files with 52 additions and 45 deletions

View File

@ -389,12 +389,13 @@ bool SmackerDecoder::load(Common::SeekableReadStream *stream) {
_frameCount = _fileStream->readUint32LE();
int32 frameRate = _fileStream->readSint32LE();
// framerate contains 2 digits after the comma, so 1497 is actually 14.97 fps
if (frameRate > 0)
_frameRate = Common::Rational(1000, frameRate);
else if (frameRate < 0)
_frameRate = Common::Rational(100000, -frameRate);
else
_frameRate = 10;
_frameRate = 1000;
// Flags are determined by which bit is set, which can be one of the following:
// 0 - set to 1 if file contains a ring frame.
@ -540,53 +541,18 @@ Surface *SmackerDecoder::decodeNextFrame() {
chunkSize = _fileStream->readUint32LE();
chunkSize -= 4; // subtract the first 4 bytes (chunk size)
if (_header.audioInfo[i].compression != kCompressionNone) {
if (_header.audioInfo[i].compression == kCompressionNone) {
dataSizeUnpacked = chunkSize;
} else {
dataSizeUnpacked = _fileStream->readUint32LE();
chunkSize -= 4; // subtract the next 4 bytes (unpacked data size)
} else {
dataSizeUnpacked = 0;
}
if (_header.audioInfo[i].hasAudio && chunkSize > 0 && i == 0) {
// If it's track 0, play the audio data
byte *soundBuffer = (byte *)malloc(chunkSize);
_fileStream->read(soundBuffer, chunkSize);
if (_header.audioInfo[i].compression == kCompressionRDFT || _header.audioInfo[i].compression == kCompressionDCT) {
// TODO: Compressed audio (Bink RDFT/DCT encoded)
free(soundBuffer);
continue;
} else if (_header.audioInfo[i].compression == kCompressionDPCM) {
// Compressed audio (Huffman DPCM encoded)
queueCompressedBuffer(soundBuffer, chunkSize, dataSizeUnpacked, i);
free(soundBuffer);
} else {
// Uncompressed audio (PCM)
byte flags = 0;
if (_header.audioInfo[0].is16Bits)
flags = flags | Audio::FLAG_16BITS;
if (_header.audioInfo[0].isStereo)
flags = flags | Audio::FLAG_STEREO;
_audioStream->queueBuffer(soundBuffer, chunkSize, DisposeAfterUse::YES, flags);
// The sound buffer will be deleted by QueuingAudioStream
}
if (!_audioStarted) {
_mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
_audioStarted = true;
}
} else {
// Ignore the rest of the audio tracks, if they exist
// TODO: Are there any Smacker videos with more than one audio stream?
// If yes, we should play the rest of the audio streams as well
if (chunkSize > 0)
_fileStream->skip(chunkSize);
}
}
handleAudioTrack(i, chunkSize, dataSizeUnpacked);
}
uint32 frameSize = _frameSizes[_curFrame] & ~3;
// uint32 remainder = _frameSizes[_curFrame] & 3;
if (_fileStream->pos() - startPos > frameSize)
error("Smacker actual frame size exceeds recorded frame size");
@ -746,6 +712,46 @@ Surface *SmackerDecoder::decodeNextFrame() {
return _surface;
}
void SmackerDecoder::handleAudioTrack(const byte &track, const uint32 &chunkSize, const uint32 &unpackedSize) {
if (_header.audioInfo[track].hasAudio && chunkSize > 0 && track == 0) {
// If it's track 0, play the audio data
byte *soundBuffer = (byte *)malloc(chunkSize);
_fileStream->read(soundBuffer, chunkSize);
if (_header.audioInfo[track].compression == kCompressionRDFT || _header.audioInfo[track].compression == kCompressionDCT) {
// TODO: Compressed audio (Bink RDFT/DCT encoded)
free(soundBuffer);
return;
} else if (_header.audioInfo[track].compression == kCompressionDPCM) {
// Compressed audio (Huffman DPCM encoded)
queueCompressedBuffer(soundBuffer, chunkSize, unpackedSize, track);
free(soundBuffer);
} else {
// Uncompressed audio (PCM)
byte flags = 0;
if (_header.audioInfo[track].is16Bits)
flags = flags | Audio::FLAG_16BITS;
if (_header.audioInfo[track].isStereo)
flags = flags | Audio::FLAG_STEREO;
_audioStream->queueBuffer(soundBuffer, chunkSize, DisposeAfterUse::YES, flags);
// The sound buffer will be deleted by QueuingAudioStream
}
if (!_audioStarted) {
_mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
_audioStarted = true;
}
} else {
// Ignore the rest of the audio tracks, if they exist
// TODO: Are there any Smacker videos with more than one audio stream?
// If yes, we should play the rest of the audio streams as well
if (chunkSize > 0)
_fileStream->skip(chunkSize);
}
}
void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
uint32 unpackedSize, int streamNum) {
@ -808,7 +814,7 @@ void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
bases[k] += (int16) (audioTrees[k * 2]->getCode(audioBS) |
(audioTrees[k * 2 + 1]->getCode(audioBS) << 8));
WRITE_BE_UINT16(curPointer, CLIP<int32>(bases[k], -32768, 32767));
WRITE_BE_UINT16(curPointer, bases[k]);
curPointer += 2;
curPos += 2;
}

View File

@ -69,12 +69,13 @@ public:
PixelFormat getPixelFormat() const { return PixelFormat::createFormatCLUT8(); }
byte *getPalette() { _dirtyPalette = false; return _palette; }
bool hasDirtyPalette() const { return _dirtyPalette; }
virtual void handleAudioTrack(const byte &track, const uint32 &chunkSize, const uint32 &unpackedSize);
protected:
Common::Rational getFrameRate() const { return _frameRate; }
Common::SeekableReadStream *_fileStream;
private:
protected:
void unpackPalette();
// Possible runs of blocks
uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }