aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2008-12-17 14:48:57 +0000
committerFilippos Karapetis2008-12-17 14:48:57 +0000
commit10e471bb5b0b4ac6f2475c060703e55168601846 (patch)
treed8e266f43b0698daffd090f2710a40e05f3fd289
parentd0e2107b7e07587f732ae1f882b8ddae8c5ef5bd (diff)
downloadscummvm-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.cpp2
-rw-r--r--graphics/smk_player.cpp105
-rw-r--r--graphics/smk_player.h28
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