VIDEO: Support old-style stereo in VMDs
This format is used by the stereo audio VMDs in Lighthouse.
This commit is contained in:
parent
1d844978d6
commit
4ba87013a9
2 changed files with 157 additions and 96 deletions
|
@ -1543,6 +1543,93 @@ Graphics::PixelFormat IMDDecoder::getPixelFormat() const {
|
||||||
return Graphics::PixelFormat::createFormatCLUT8();
|
return Graphics::PixelFormat::createFormatCLUT8();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DPCMStream : public Audio::AudioStream {
|
||||||
|
public:
|
||||||
|
DPCMStream(Common::SeekableReadStream *stream, int rate, int channels, bool oldStereo) {
|
||||||
|
_stream = stream;
|
||||||
|
_rate = rate;
|
||||||
|
_channels = channels;
|
||||||
|
_oldStereo = oldStereo;
|
||||||
|
if (oldStereo) {
|
||||||
|
_buffer[0] = _buffer[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~DPCMStream() {
|
||||||
|
delete _stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readBuffer(int16 *buffer, const int numSamples);
|
||||||
|
bool isStereo() const { return _channels == 2; }
|
||||||
|
int getRate() const { return _rate; }
|
||||||
|
bool endOfData() const { return _stream->pos() >= _stream->size() || _stream->eos() || _stream->err(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Common::SeekableReadStream *_stream;
|
||||||
|
int _channels;
|
||||||
|
int _rate;
|
||||||
|
int _buffer[2];
|
||||||
|
bool _oldStereo;
|
||||||
|
};
|
||||||
|
|
||||||
|
int DPCMStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||||
|
static const uint16 tableDPCM[128] = {
|
||||||
|
0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080,
|
||||||
|
0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120,
|
||||||
|
0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0,
|
||||||
|
0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230,
|
||||||
|
0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280,
|
||||||
|
0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0,
|
||||||
|
0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320,
|
||||||
|
0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370,
|
||||||
|
0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0,
|
||||||
|
0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480,
|
||||||
|
0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700,
|
||||||
|
0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00,
|
||||||
|
0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
|
||||||
|
};
|
||||||
|
|
||||||
|
assert((numSamples % _channels) == 0);
|
||||||
|
|
||||||
|
int samples = 0;
|
||||||
|
|
||||||
|
// Our starting position
|
||||||
|
if (!_oldStereo && _stream->pos() == 0) {
|
||||||
|
for (int i = 0; i < _channels; i++)
|
||||||
|
*buffer++ = _buffer[i] = _stream->readSint16LE();
|
||||||
|
|
||||||
|
samples += _channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!endOfData() && samples < numSamples) {
|
||||||
|
if (_channels == 2 && _stream->size() == 1) {
|
||||||
|
warning("Buffer underrun in DPCMStream");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _channels; i++) {
|
||||||
|
byte data = _stream->readByte();
|
||||||
|
|
||||||
|
if (data & 0x80)
|
||||||
|
_buffer[i] -= tableDPCM[data & 0x7f];
|
||||||
|
else
|
||||||
|
_buffer[i] += tableDPCM[data];
|
||||||
|
|
||||||
|
// Emulating x86 16-bit signed register overflow
|
||||||
|
if (_buffer[i] > 32767) {
|
||||||
|
_buffer[i] -= 65536;
|
||||||
|
} else if (_buffer[i] < -32768) {
|
||||||
|
_buffer[i] += 65536;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer++ = _buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
samples += _channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
VMDDecoder::File::File() {
|
VMDDecoder::File::File() {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
@ -1581,7 +1668,7 @@ VMDDecoder::VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) :
|
||||||
_soundLastFilledFrame(0), _audioFormat(kAudioFormat8bitRaw),
|
_soundLastFilledFrame(0), _audioFormat(kAudioFormat8bitRaw),
|
||||||
_hasVideo(false), _videoCodec(0), _blitMode(0), _bytesPerPixel(0),
|
_hasVideo(false), _videoCodec(0), _blitMode(0), _bytesPerPixel(0),
|
||||||
_firstFramePos(0), _videoBufferSize(0), _externalCodec(false), _codec(0),
|
_firstFramePos(0), _videoBufferSize(0), _externalCodec(false), _codec(0),
|
||||||
_subtitle(-1), _isPaletted(true), _autoStartSound(true) {
|
_subtitle(-1), _isPaletted(true), _autoStartSound(true), _oldStereoBuffer(nullptr) {
|
||||||
|
|
||||||
_videoBuffer [0] = 0;
|
_videoBuffer [0] = 0;
|
||||||
_videoBuffer [1] = 0;
|
_videoBuffer [1] = 0;
|
||||||
|
@ -1625,7 +1712,7 @@ bool VMDDecoder::seek(int32 frame, int whence, bool restart) {
|
||||||
delete _audioStream;
|
delete _audioStream;
|
||||||
|
|
||||||
_soundStage = kSoundLoaded;
|
_soundStage = kSoundLoaded;
|
||||||
_audioStream = Audio::makeQueuingAudioStream(_soundFreq, _soundStereo != 0);
|
createAudioStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
_subtitle = -1;
|
_subtitle = -1;
|
||||||
|
@ -1915,13 +2002,19 @@ bool VMDDecoder::assessAudioProperties() {
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (_soundStereo == 2) {
|
||||||
|
supportedFormat = false;
|
||||||
|
}
|
||||||
|
|
||||||
_soundBytesPerSample = 1;
|
_soundBytesPerSample = 1;
|
||||||
_audioFormat = kAudioFormat8bitRaw;
|
|
||||||
_soundHeaderSize = 0;
|
_soundHeaderSize = 0;
|
||||||
_soundDataSize = _soundSliceSize;
|
_soundDataSize = _soundSliceSize;
|
||||||
|
|
||||||
if (_soundStereo > 0)
|
if (_soundStereo == 1) {
|
||||||
supportedFormat = false;
|
_audioFormat = kAudioFormat16bitDPCM;
|
||||||
|
} else {
|
||||||
|
_audioFormat = kAudioFormat8bitRaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supportedFormat) {
|
if (!supportedFormat) {
|
||||||
|
@ -1930,14 +2023,12 @@ bool VMDDecoder::assessAudioProperties() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_frameRate = Common::Rational(_soundFreq, _soundSliceSize);
|
_frameRate = Common::Rational(_soundFreq, _soundSliceSize / (_soundStereo == 1 ? 2 : 1));
|
||||||
|
|
||||||
_hasSound = true;
|
_hasSound = true;
|
||||||
_soundEnabled = true;
|
_soundEnabled = true;
|
||||||
_soundStage = kSoundLoaded;
|
_soundStage = kSoundLoaded;
|
||||||
|
createAudioStream();
|
||||||
_audioStream = Audio::makeQueuingAudioStream(_soundFreq, _soundStereo != 0);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2074,6 +2165,7 @@ void VMDDecoder::close() {
|
||||||
_soundDataSize = 0;
|
_soundDataSize = 0;
|
||||||
_soundLastFilledFrame = 0;
|
_soundLastFilledFrame = 0;
|
||||||
_audioFormat = kAudioFormat8bitRaw;
|
_audioFormat = kAudioFormat8bitRaw;
|
||||||
|
_oldStereoBuffer = nullptr;
|
||||||
|
|
||||||
_hasVideo = false;
|
_hasVideo = false;
|
||||||
_videoCodec = 0;
|
_videoCodec = 0;
|
||||||
|
@ -2123,9 +2215,9 @@ void VMDDecoder::processFrame() {
|
||||||
|
|
||||||
bool startSound = false;
|
bool startSound = false;
|
||||||
|
|
||||||
for (uint16 i = 0; i < _partsPerFrame; i++) {
|
_stream->seek(_frames[_curFrame].offset, SEEK_SET);
|
||||||
uint32 pos = _stream->pos();
|
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < _partsPerFrame; i++) {
|
||||||
Part &part = _frames[_curFrame].parts[i];
|
Part &part = _frames[_curFrame].parts[i];
|
||||||
|
|
||||||
if (part.type == kPartTypeAudio) {
|
if (part.type == kPartTypeAudio) {
|
||||||
|
@ -2147,7 +2239,7 @@ void VMDDecoder::processFrame() {
|
||||||
|
|
||||||
if (_soundEnabled) {
|
if (_soundEnabled) {
|
||||||
uint32 mask = _stream->readUint32LE();
|
uint32 mask = _stream->readUint32LE();
|
||||||
filledSoundSlices(part.size - 4, mask);
|
filledSoundSlices(part.size - /* mask size */ 4, mask);
|
||||||
|
|
||||||
if (_soundStage == kSoundLoaded)
|
if (_soundStage == kSoundLoaded)
|
||||||
startSound = true;
|
startSound = true;
|
||||||
|
@ -2176,8 +2268,6 @@ void VMDDecoder::processFrame() {
|
||||||
_stream->skip(part.size);
|
_stream->skip(part.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
_stream->seek(pos + part.size);
|
|
||||||
|
|
||||||
} else if ((part.type == kPartTypeVideo) && !_hasVideo) {
|
} else if ((part.type == kPartTypeVideo) && !_hasVideo) {
|
||||||
|
|
||||||
warning("VMDDecoder::processFrame(): Header claims there's no video, but video found (%d)", part.size);
|
warning("VMDDecoder::processFrame(): Header claims there's no video, but video found (%d)", part.size);
|
||||||
|
@ -2470,6 +2560,14 @@ void VMDDecoder::blit24(const Graphics::Surface &srcSurf, Common::Rect &rect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMDDecoder::emptySoundSlice(uint32 size) {
|
void VMDDecoder::emptySoundSlice(uint32 size) {
|
||||||
|
if (_soundStereo == 1) {
|
||||||
|
// Technically an empty slice could be used at the very beginning of the
|
||||||
|
// stream, but anywhere else it would need to dynamically calculate the
|
||||||
|
// delta between the current sample and zero sample level and the steps
|
||||||
|
// to get a zero level
|
||||||
|
error("Old-style stereo cannot be filled with an empty slice");
|
||||||
|
}
|
||||||
|
|
||||||
byte *soundBuf = (byte *)malloc(size);
|
byte *soundBuf = (byte *)malloc(size);
|
||||||
|
|
||||||
if (soundBuf) {
|
if (soundBuf) {
|
||||||
|
@ -2488,6 +2586,17 @@ void VMDDecoder::filledSoundSlice(uint32 size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_soundStereo == 1) {
|
||||||
|
void *buf = malloc(size);
|
||||||
|
assert(buf);
|
||||||
|
const uint32 numBytesRead = _stream->read(buf, size);
|
||||||
|
assert(numBytesRead == size);
|
||||||
|
const uint32 numBytesWritten = _oldStereoBuffer->write(buf, size);
|
||||||
|
assert(numBytesWritten == size);
|
||||||
|
free(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Common::SeekableReadStream *data = _stream->readStream(size);
|
Common::SeekableReadStream *data = _stream->readStream(size);
|
||||||
Audio::AudioStream *sliceStream = 0;
|
Audio::AudioStream *sliceStream = 0;
|
||||||
|
|
||||||
|
@ -2508,9 +2617,9 @@ void VMDDecoder::filledSoundSlices(uint32 size, uint32 mask) {
|
||||||
uint8 max;
|
uint8 max;
|
||||||
uint8 n = evaluateMask(mask, fillInfo, max);
|
uint8 n = evaluateMask(mask, fillInfo, max);
|
||||||
|
|
||||||
int32 extraSize;
|
// extraSize is needed by videos in some games (GK2) or audio data will be
|
||||||
|
// incomplete
|
||||||
extraSize = size - n * _soundDataSize;
|
int32 extraSize = size - n * _soundDataSize;
|
||||||
|
|
||||||
if (_soundSlicesCount > 32)
|
if (_soundSlicesCount > 32)
|
||||||
extraSize -= (_soundSlicesCount - 32) * _soundDataSize;
|
extraSize -= (_soundSlicesCount - 32) * _soundDataSize;
|
||||||
|
@ -2518,6 +2627,11 @@ void VMDDecoder::filledSoundSlices(uint32 size, uint32 mask) {
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
extraSize /= n;
|
extraSize /= n;
|
||||||
|
|
||||||
|
// extraSize cannot be negative or audio data will be incomplete in some
|
||||||
|
// games (old-style stereo videos in Lighthouse)
|
||||||
|
if (extraSize < 0)
|
||||||
|
extraSize = 0;
|
||||||
|
|
||||||
for (uint8 i = 0; i < max; i++)
|
for (uint8 i = 0; i < max; i++)
|
||||||
if (fillInfo[i])
|
if (fillInfo[i])
|
||||||
filledSoundSlice(_soundDataSize + extraSize);
|
filledSoundSlice(_soundDataSize + extraSize);
|
||||||
|
@ -2528,6 +2642,14 @@ void VMDDecoder::filledSoundSlices(uint32 size, uint32 mask) {
|
||||||
filledSoundSlice((_soundSlicesCount - 32) * _soundDataSize + _soundHeaderSize);
|
filledSoundSlice((_soundSlicesCount - 32) * _soundDataSize + _soundHeaderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMDDecoder::createAudioStream() {
|
||||||
|
_audioStream = Audio::makeQueuingAudioStream(_soundFreq, _soundStereo != 0);
|
||||||
|
if (_soundStereo == 1) {
|
||||||
|
_oldStereoBuffer = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
|
||||||
|
_audioStream->queueAudioStream(new DPCMStream(_oldStereoBuffer, _soundFreq, 2, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8 VMDDecoder::evaluateMask(uint32 mask, bool *fillInfo, uint8 &max) {
|
uint8 VMDDecoder::evaluateMask(uint32 mask, bool *fillInfo, uint8 &max) {
|
||||||
max = MIN<int>(_soundSlicesCount - 1, 31);
|
max = MIN<int>(_soundSlicesCount - 1, 31);
|
||||||
|
|
||||||
|
@ -2555,86 +2677,12 @@ Audio::AudioStream *VMDDecoder::create8bitRaw(Common::SeekableReadStream *stream
|
||||||
return Audio::makeRawStream(stream, _soundFreq, flags, DisposeAfterUse::YES);
|
return Audio::makeRawStream(stream, _soundFreq, flags, DisposeAfterUse::YES);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DPCMStream : public Audio::AudioStream {
|
|
||||||
public:
|
|
||||||
DPCMStream(Common::SeekableReadStream *stream, int rate, int channels) {
|
|
||||||
_stream = stream;
|
|
||||||
_rate = rate;
|
|
||||||
_channels = channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
~DPCMStream() {
|
|
||||||
delete _stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int readBuffer(int16 *buffer, const int numSamples);
|
|
||||||
bool isStereo() const { return _channels == 2; }
|
|
||||||
int getRate() const { return _rate; }
|
|
||||||
bool endOfData() const { return _stream->pos() >= _stream->size() || _stream->eos() || _stream->err(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Common::SeekableReadStream *_stream;
|
|
||||||
int _channels;
|
|
||||||
int _rate;
|
|
||||||
int _buffer[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
int DPCMStream::readBuffer(int16 *buffer, const int numSamples) {
|
|
||||||
static const uint16 tableDPCM[128] = {
|
|
||||||
0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080,
|
|
||||||
0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120,
|
|
||||||
0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0,
|
|
||||||
0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230,
|
|
||||||
0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280,
|
|
||||||
0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0,
|
|
||||||
0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320,
|
|
||||||
0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370,
|
|
||||||
0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0,
|
|
||||||
0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480,
|
|
||||||
0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700,
|
|
||||||
0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00,
|
|
||||||
0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
|
|
||||||
};
|
|
||||||
|
|
||||||
assert((numSamples % _channels) == 0);
|
|
||||||
|
|
||||||
int samples = 0;
|
|
||||||
|
|
||||||
// Our starting position
|
|
||||||
if (_stream->pos() == 0) {
|
|
||||||
for (int i = 0; i < _channels; i++)
|
|
||||||
*buffer++ = _buffer[i] = _stream->readSint16LE();
|
|
||||||
|
|
||||||
samples += _channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!endOfData() && samples < numSamples) {
|
|
||||||
for (int i = 0; i < _channels; i++) {
|
|
||||||
byte data = _stream->readByte();
|
|
||||||
|
|
||||||
if (data & 0x80)
|
|
||||||
_buffer[i] -= tableDPCM[data & 0x7f];
|
|
||||||
else
|
|
||||||
_buffer[i] += tableDPCM[data];
|
|
||||||
|
|
||||||
// Emulating x86 16-bit signed register overflow
|
|
||||||
if (_buffer[i] > 32767) {
|
|
||||||
_buffer[i] -= 65536;
|
|
||||||
} else if (_buffer[i] < -32768) {
|
|
||||||
_buffer[i] += 65536;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer++ = _buffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
samples += _channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
return samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio::AudioStream *VMDDecoder::create16bitDPCM(Common::SeekableReadStream *stream) {
|
Audio::AudioStream *VMDDecoder::create16bitDPCM(Common::SeekableReadStream *stream) {
|
||||||
return new DPCMStream(stream, _soundFreq, (_soundStereo == 0) ? 1 : 2);
|
// Old-style stereo audio blocks are not self-contained so cannot be played
|
||||||
|
// using this mechanism
|
||||||
|
assert(_soundStereo != 1);
|
||||||
|
|
||||||
|
return new DPCMStream(stream, _soundFreq, (_soundStereo == 0) ? 1 : 2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
class VMD_ADPCMStream : public Audio::DVI_ADPCMStream {
|
class VMD_ADPCMStream : public Audio::DVI_ADPCMStream {
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
struct Rect;
|
struct Rect;
|
||||||
|
class MemoryReadWriteStream;
|
||||||
class SeekableReadStream;
|
class SeekableReadStream;
|
||||||
}
|
}
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
@ -503,6 +504,17 @@ private:
|
||||||
AudioFormat _audioFormat;
|
AudioFormat _audioFormat;
|
||||||
bool _autoStartSound;
|
bool _autoStartSound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old stereo format packs a DPCM stream into audio packets without ensuring
|
||||||
|
* that each packet contains an even amount of samples. In order for the
|
||||||
|
* stream to play back correctly, all audio data needs to be pushed into a
|
||||||
|
* single data buffer and read from there.
|
||||||
|
*
|
||||||
|
* This buffer is owned by _audioStream and will be disposed when
|
||||||
|
* _audioStream is disposed.
|
||||||
|
*/
|
||||||
|
Common::MemoryReadWriteStream *_oldStereoBuffer;
|
||||||
|
|
||||||
// Video properties
|
// Video properties
|
||||||
bool _hasVideo;
|
bool _hasVideo;
|
||||||
uint32 _videoCodec;
|
uint32 _videoCodec;
|
||||||
|
@ -545,6 +557,7 @@ private:
|
||||||
void emptySoundSlice (uint32 size);
|
void emptySoundSlice (uint32 size);
|
||||||
void filledSoundSlice (uint32 size);
|
void filledSoundSlice (uint32 size);
|
||||||
void filledSoundSlices(uint32 size, uint32 mask);
|
void filledSoundSlices(uint32 size, uint32 mask);
|
||||||
|
void createAudioStream();
|
||||||
|
|
||||||
uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
|
uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue