diff options
author | Filippos Karapetis | 2008-12-17 14:48:57 +0000 |
---|---|---|
committer | Filippos Karapetis | 2008-12-17 14:48:57 +0000 |
commit | 10e471bb5b0b4ac6f2475c060703e55168601846 (patch) | |
tree | d8e266f43b0698daffd090f2710a40e05f3fd289 | |
parent | d0e2107b7e07587f732ae1f882b8ddae8c5ef5bd (diff) | |
download | scummvm-rg350-10e471bb5b0b4ac6f2475c060703e55168601846.tar.gz scummvm-rg350-10e471bb5b0b4ac6f2475c060703e55168601846.tar.bz2 scummvm-rg350-10e471bb5b0b4ac6f2475c060703e55168601846.zip |
- Added some disabled code for Smacker audio support (still incomplete, not working yet)
- Made the _image buffer protected instead of private (in case it's coped directly to the screen and not an intermediate buffer)
svn-id: r35411
-rw-r--r-- | engines/scumm/he/animation_he.cpp | 2 | ||||
-rw-r--r-- | graphics/smk_player.cpp | 105 | ||||
-rw-r--r-- | graphics/smk_player.h | 28 |
3 files changed, 117 insertions, 18 deletions
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp index 666660a573..82728a3f0d 100644 --- a/engines/scumm/he/animation_he.cpp +++ b/engines/scumm/he/animation_he.cpp @@ -33,7 +33,7 @@ namespace Scumm { MoviePlayer::MoviePlayer(ScummEngine_v90he *vm, Audio::Mixer *mixer) - : SMKPlayer(), _vm(vm), _mixer(mixer) { + : SMKPlayer(mixer), _vm(vm), _mixer(mixer) { _flags = 0; _wizResNum = 0; diff --git a/graphics/smk_player.cpp b/graphics/smk_player.cpp index ba7c556f82..415285bd12 100644 --- a/graphics/smk_player.cpp +++ b/graphics/smk_player.cpp @@ -33,6 +33,8 @@ #include "common/util.h" #include "common/array.h" #include "common/endian.h" +#include "sound/mixer.h" +#include "sound/audiostream.h" namespace Graphics { @@ -311,8 +313,8 @@ uint32 BigHuffmanTree::getCode(BitStream &bs) { return v; } -SMKPlayer::SMKPlayer() - : _currentSMKFrame(0), _fileStream(0) { +SMKPlayer::SMKPlayer(Audio::Mixer *mixer) + : _currentSMKFrame(0), _fileStream(0), _audioStarted(false), _audioStream(0), _mixer(mixer) { } SMKPlayer::~SMKPlayer() { @@ -415,6 +417,18 @@ bool SMKPlayer::loadFile(const char *fileName) { _header.audioInfo[i].hasV2Compression = !(audioInfo & 0x8000000) && !(audioInfo & 0x4000000); _header.audioInfo[i].sampleRate = audioInfo & 0xFFFFFF; + + if (_header.audioInfo[i].hasAudio && i == 0) { + byte flags = Audio::Mixer::FLAG_UNSIGNED; + + if (_header.audioInfo[i].is16Bits) + flags = flags | Audio::Mixer::FLAG_16BITS; + + if (_header.audioInfo[i].isStereo) + flags = flags | Audio::Mixer::FLAG_STEREO; + + _audioStream = Audio::makeAppendableAudioStream(_header.audioInfo[i].sampleRate, flags); + } } _header.dummy = _fileStream->readUint32LE(); @@ -449,6 +463,17 @@ void SMKPlayer::closeFile() { if (!_fileStream) return; + if (_audioStarted) { + _audioStream->finish(); + _mixer->stopHandle(_audioHandle); + _audioStarted = false; + } + + if (_audioStream) { + delete _audioStream; + _audioStream = 0; + } + delete _fileStream; delete _MMapTree; @@ -480,6 +505,8 @@ void SMKPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { bool SMKPlayer::decodeNextFrame() { uint i; + uint32 chunkSize = 0; + uint32 dataSizeUnpacked = 0; uint32 startPos = _fileStream->pos(); @@ -496,12 +523,45 @@ bool SMKPlayer::decodeNextFrame() { if (!(_frameTypes[_currentSMKFrame] & (2 << i))) continue; - uint32 len = _fileStream->readUint32LE(); + chunkSize = _fileStream->readUint32LE(); + chunkSize -= 4; // subtract the first 4 bytes (chunk size) - // TODO: Audio support + if (_header.audioInfo[i].isCompressed) { + dataSizeUnpacked = _fileStream->readUint32LE(); + chunkSize -= 4; // subtract the next 4 bytes (unpacked data size) + } else { + dataSizeUnpacked = 0; + } + + // TODO: sound support is deactivated for now, till queueCompressedBuffer() is finished + if (false) { + //if (_header.audioInfo[i].hasAudio && chunkSize > 0 && i == 0) { + // If it's track 0, play the audio data + byte *soundBuffer = new byte[chunkSize]; + + _fileStream->read(soundBuffer, chunkSize); + + if (_header.audioInfo[i].isCompressed) { + // Compressed audio (Huffman DPCM encoded) + queueCompressedBuffer(soundBuffer, chunkSize, dataSizeUnpacked, i); + delete soundBuffer; + } else { + // Uncompressed audio (PCM) + _audioStream->queueBuffer(soundBuffer, chunkSize); + // The sound buffer will be deleted by AppendableAudioStream + } - //uint32 unpackedLen = _fileStream->readUint32LE(); - _fileStream->skip(len - 4); + if (!_audioStarted) { + _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream); + _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); + } } uint32 frameSize = _frameSizes[_currentSMKFrame] & ~3; @@ -660,6 +720,39 @@ bool SMKPlayer::decodeNextFrame() { return ++_currentSMKFrame < _header.frames; } +void SMKPlayer::queueCompressedBuffer(byte *buffer, int bufferSize, int unpackedSize, int streamNum) { + BitStream audioBS(buffer, bufferSize); + bool dataPresent = audioBS.getBit(); + bool isStereo, is16Bits; + int numBytes = 1; + SmallHuffmanTree *audioTrees[4]; + int16 bases[2]; + int k; + + if (!dataPresent) + return; + + isStereo = audioBS.getBit(); + assert(isStereo == _header.audioInfo[streamNum].isStereo); + is16Bits = audioBS.getBit(); + assert(is16Bits == _header.audioInfo[streamNum].is16Bits); + + if (isStereo) numBytes *= 2; + if (is16Bits) numBytes *= 2; + + for (k = 0; k < numBytes; k++) + audioTrees[k] = new SmallHuffmanTree(audioBS); + + // Right channel + bases[0] = (!is16Bits) ? audioBS.getBits8() : (audioBS.getBits8() << 8) || audioBS.getBits8(); + + // Left channel, if the sample is stereo + if (isStereo) + bases[1] = (!is16Bits) ? audioBS.getBits8() : (audioBS.getBits8() << 8) || audioBS.getBits8(); + + // TODO: Finish the rest of this +} + void SMKPlayer::unpackPalette() { uint startPos = _fileStream->pos(); uint32 len = 4 * _fileStream->readByte(); diff --git a/graphics/smk_player.h b/graphics/smk_player.h index c184a3af2b..0e94ab0a39 100644 --- a/graphics/smk_player.h +++ b/graphics/smk_player.h @@ -32,6 +32,8 @@ #include "common/scummsys.h" #include "common/stream.h" +#include "sound/mixer.h" +#include "sound/audiostream.h" class OSystem; @@ -44,7 +46,7 @@ class BigHuffmanTree; */ class SMKPlayer { public: - SMKPlayer(); + SMKPlayer(Audio::Mixer *mixer); virtual ~SMKPlayer(); /** @@ -115,10 +117,13 @@ protected: Common::SeekableReadStream *_fileStream; + byte *_image; + private: void unpackPalette(); - - uint32 _currentSMKFrame; + // Possible runs of blocks + uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); } + void queueCompressedBuffer(byte *buffer, int bufferSize, int unpackedSize, int streamNum); struct AudioInfo { bool isCompressed; @@ -153,19 +158,20 @@ private: // and so on), so there can be up to 7 different audio tracks. When the lowest bit // (bit 0) is set, it denotes a frame that contains a palette record byte *_frameTypes; + byte *_frameData; + byte *_palette; + + Audio::Mixer *_mixer; + bool _audioStarted; + Audio::AppendableAudioStream *_audioStream; + Audio::SoundHandle _audioHandle; + + uint32 _currentSMKFrame; BigHuffmanTree *_MMapTree; BigHuffmanTree *_MClrTree; BigHuffmanTree *_FullTree; BigHuffmanTree *_TypeTree; - - byte *_frameData; - - byte *_image; - byte *_palette; - - // Possible runs of blocks - uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); } }; } // End of namespace Graphics |