diff options
author | Paul Gilbert | 2011-04-13 21:30:26 +1000 |
---|---|---|
committer | Paul Gilbert | 2011-04-13 21:30:26 +1000 |
commit | 4852a38f3648d7778da29402addb87590662a1ce (patch) | |
tree | 3cbec95cfc04e10fa12660267fa25782b4c0b9d6 | |
parent | 0600f0c018942c2a3e09b1696b2dc71b2e00d0b3 (diff) | |
parent | 169512852e7ddf06061075e142bdb5331ed25053 (diff) | |
download | scummvm-rg350-4852a38f3648d7778da29402addb87590662a1ce.tar.gz scummvm-rg350-4852a38f3648d7778da29402addb87590662a1ce.tar.bz2 scummvm-rg350-4852a38f3648d7778da29402addb87590662a1ce.zip |
Merge branch 'master' of github.com:scummvm/scummvm
-rw-r--r-- | audio/decoders/adpcm.cpp | 409 | ||||
-rw-r--r-- | audio/decoders/adpcm.h | 7 | ||||
-rw-r--r-- | audio/decoders/adpcm_intern.h | 230 | ||||
-rw-r--r-- | engines/scumm/imuse_digi/dimuse_codecs.cpp | 34 | ||||
-rw-r--r-- | engines/tinsel/adpcm.cpp | 168 | ||||
-rw-r--r-- | engines/tinsel/adpcm.h | 105 | ||||
-rw-r--r-- | engines/tinsel/module.mk | 1 | ||||
-rw-r--r-- | engines/tinsel/music.cpp | 5 | ||||
-rw-r--r-- | engines/tinsel/sound.cpp | 3 | ||||
-rw-r--r-- | engines/toon/audio.cpp | 26 | ||||
-rw-r--r-- | video/coktel_decoder.cpp | 27 | ||||
-rw-r--r-- | video/coktel_decoder.h | 2 |
12 files changed, 541 insertions, 476 deletions
diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp index 7def89b688..43b5a0b3da 100644 --- a/audio/decoders/adpcm.cpp +++ b/audio/decoders/adpcm.cpp @@ -26,44 +26,12 @@ #include "common/endian.h" #include "audio/decoders/adpcm.h" +#include "audio/decoders/adpcm_intern.h" #include "audio/audiostream.h" namespace Audio { -class ADPCMStream : public RewindableAudioStream { -protected: - Common::SeekableReadStream *_stream; - const DisposeAfterUse::Flag _disposeAfterUse; - const int32 _startpos; - const int32 _endpos; - const int _channels; - const uint32 _blockAlign; - uint32 _blockPos[2]; - const int _rate; - - struct { - // OKI/IMA - struct { - int32 last; - int32 stepIndex; - } ima_ch[2]; - } _status; - - virtual void reset(); - int16 stepAdjust(byte); - -public: - ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign); - ~ADPCMStream(); - - virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); } - virtual bool isStereo() const { return _channels == 2; } - virtual int getRate() const { return _rate; } - - virtual bool rewind(); -}; - // Routines to convert 12 bit linear samples to the // Dialogic or Oki ADPCM coding format aka VOX. // See also <http://www.comptek.ru/telephony/tnotes/tt1-13.html> @@ -107,17 +75,6 @@ bool ADPCMStream::rewind() { #pragma mark - -class Oki_ADPCMStream : public ADPCMStream { -public: - Oki_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} - - virtual int readBuffer(int16 *buffer, const int numSamples); - -protected: - int16 decodeOKI(byte); -}; - int Oki_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { int samples; byte data; @@ -153,7 +110,7 @@ int16 Oki_ADPCMStream::decodeOKI(byte code) { samp = CLIP<int16>(samp, -2048, 2047); _status.ima_ch[0].last = samp; - _status.ima_ch[0].stepIndex += stepAdjust(code); + _status.ima_ch[0].stepIndex += _stepAdjustTable[code]; _status.ima_ch[0].stepIndex = CLIP<int32>(_status.ima_ch[0].stepIndex, 0, ARRAYSIZE(okiStepSize) - 1); // * 16 effectively converts 12-bit input to 16-bit output @@ -164,19 +121,6 @@ int16 Oki_ADPCMStream::decodeOKI(byte code) { #pragma mark - -class Ima_ADPCMStream : public ADPCMStream { -protected: - int16 decodeIMA(byte code, int channel = 0); // Default to using the left channel/using one channel - -public: - Ima_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - memset(&_status, 0, sizeof(_status)); - } - - virtual int readBuffer(int16 *buffer, const int numSamples); -}; - int Ima_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { int samples; byte data; @@ -194,34 +138,6 @@ int Ima_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { #pragma mark - -class Apple_ADPCMStream : public Ima_ADPCMStream { -protected: - // Apple QuickTime IMA ADPCM - int32 _streamPos[2]; - int16 _buffer[2][2]; - uint8 _chunkPos[2]; - - void reset() { - Ima_ADPCMStream::reset(); - _chunkPos[0] = 0; - _chunkPos[1] = 0; - _streamPos[0] = 0; - _streamPos[1] = _blockAlign; - } - -public: - Apple_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - _chunkPos[0] = 0; - _chunkPos[1] = 0; - _streamPos[0] = 0; - _streamPos[1] = _blockAlign; - } - - virtual int readBuffer(int16 *buffer, const int numSamples); - -}; - int Apple_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { // Need to write at least one samples per channel assert((numSamples % _channels) == 0); @@ -288,28 +204,6 @@ int Apple_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { #pragma mark - -class MSIma_ADPCMStream : public Ima_ADPCMStream { -public: - MSIma_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign, bool invertSamples = false) - : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign), _invertSamples(invertSamples) { - if (blockAlign == 0) - error("ADPCMStream(): blockAlign isn't specified for MS IMA ADPCM"); - } - - virtual int readBuffer(int16 *buffer, const int numSamples) { - if (_channels == 1) - return readBufferMSIMA1(buffer, numSamples); - else - return readBufferMSIMA2(buffer, numSamples); - } - - int readBufferMSIMA1(int16 *buffer, const int numSamples); - int readBufferMSIMA2(int16 *buffer, const int numSamples); - -private: - bool _invertSamples; // Some implementations invert the way samples are decoded -}; - int MSIma_ADPCMStream::readBufferMSIMA1(int16 *buffer, const int numSamples) { int samples = 0; byte data; @@ -382,41 +276,6 @@ static const int MSADPCMAdaptationTable[] = { }; -class MS_ADPCMStream : public ADPCMStream { -protected: - struct ADPCMChannelStatus { - byte predictor; - int16 delta; - int16 coeff1; - int16 coeff2; - int16 sample1; - int16 sample2; - }; - - struct { - // MS ADPCM - ADPCMChannelStatus ch[2]; - } _status; - - void reset() { - ADPCMStream::reset(); - memset(&_status, 0, sizeof(_status)); - } - -public: - MS_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - if (blockAlign == 0) - error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM"); - memset(&_status, 0, sizeof(_status)); - } - - virtual int readBuffer(int16 *buffer, const int numSamples); - -protected: - int16 decodeMS(ADPCMChannelStatus *c, byte); -}; - int16 MS_ADPCMStream::decodeMS(ADPCMChannelStatus *c, byte code) { int32 predictor; @@ -478,246 +337,9 @@ int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { } - #pragma mark - -class Tinsel_ADPCMStream : public ADPCMStream { -protected: - struct { - // Tinsel - double predictor; - double K0, K1; - double d0, d1; - } _status; - - void reset() { - ADPCMStream::reset(); - memset(&_status, 0, sizeof(_status)); - } - - int16 decodeTinsel(int16, double); - void readBufferTinselHeader(); - -public: - Tinsel_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - - if (blockAlign == 0) - error("Tinsel_ADPCMStream(): blockAlign isn't specified"); - - if (channels != 1) - error("Tinsel_ADPCMStream(): Tinsel ADPCM only supports mono"); - - memset(&_status, 0, sizeof(_status)); - } - -}; - -static const double TinselFilterTable[4][2] = { - {0, 0 }, - {0.9375, 0}, - {1.796875, -0.8125}, - {1.53125, -0.859375} -}; - -void Tinsel_ADPCMStream::readBufferTinselHeader() { - uint8 start = _stream->readByte(); - uint8 filterVal = (start & 0xC0) >> 6; - - if ((start & 0x20) != 0) { - //Lower 6 bit are negative - - // Negate - start = ~(start | 0xC0) + 1; - - _status.predictor = 1 << start; - } else { - // Lower 6 bit are positive - - // Truncate - start &= 0x1F; - - _status.predictor = ((double) 1.0) / (1 << start); - } - - _status.K0 = TinselFilterTable[filterVal][0]; - _status.K1 = TinselFilterTable[filterVal][1]; -} - -int16 Tinsel_ADPCMStream::decodeTinsel(int16 code, double eVal) { - double sample; - - sample = (double) code; - sample *= eVal * _status.predictor; - sample += (_status.d0 * _status.K0) + (_status.d1 * _status.K1); - - _status.d1 = _status.d0; - _status.d0 = sample; - - return (int16) CLIP<double>(sample, -32768.0, 32767.0); -} - -class Tinsel4_ADPCMStream : public Tinsel_ADPCMStream { -public: - Tinsel4_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} - - virtual int readBuffer(int16 *buffer, const int numSamples); -}; - -int Tinsel4_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { - int samples; - uint16 data; - const double eVal = 1.142822265; - - samples = 0; - - assert(numSamples % 2 == 0); - - while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { - if (_blockPos[0] == _blockAlign) { - readBufferTinselHeader(); - _blockPos[0] = 0; - } - - for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2, _blockPos[0]++) { - // Read 1 byte = 8 bits = two 4 bit blocks - data = _stream->readByte(); - buffer[samples] = decodeTinsel((data << 8) & 0xF000, eVal); - buffer[samples+1] = decodeTinsel((data << 12) & 0xF000, eVal); - } - } - - return samples; -} - -class Tinsel6_ADPCMStream : public Tinsel_ADPCMStream { -protected: - uint8 _chunkPos; - uint16 _chunkData; - - void reset() { - ADPCMStream::reset(); - _chunkPos = 0; - _chunkData = 0; - } - -public: - Tinsel6_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - _chunkPos = 0; - _chunkData = 0; - } - - virtual int readBuffer(int16 *buffer, const int numSamples); -}; - -int Tinsel6_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { - int samples; - const double eVal = 1.032226562; - - samples = 0; - - while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { - if (_blockPos[0] == _blockAlign) { - readBufferTinselHeader(); - _blockPos[0] = 0; - _chunkPos = 0; - } - - for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _chunkPos = (_chunkPos + 1) % 4) { - - switch (_chunkPos) { - case 0: - _chunkData = _stream->readByte(); - buffer[samples] = decodeTinsel((_chunkData << 8) & 0xFC00, eVal); - break; - case 1: - _chunkData = (_chunkData << 8) | (_stream->readByte()); - buffer[samples] = decodeTinsel((_chunkData << 6) & 0xFC00, eVal); - _blockPos[0]++; - break; - case 2: - _chunkData = (_chunkData << 8) | (_stream->readByte()); - buffer[samples] = decodeTinsel((_chunkData << 4) & 0xFC00, eVal); - _blockPos[0]++; - break; - case 3: - _chunkData = (_chunkData << 8); - buffer[samples] = decodeTinsel((_chunkData << 2) & 0xFC00, eVal); - _blockPos[0]++; - break; - } - - } - - } - - return samples; -} - -class Tinsel8_ADPCMStream : public Tinsel_ADPCMStream { -public: - Tinsel8_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} - - virtual int readBuffer(int16 *buffer, const int numSamples); -}; - -int Tinsel8_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { - int samples; - byte data; - const double eVal = 1.007843258; - - samples = 0; - - while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { - if (_blockPos[0] == _blockAlign) { - readBufferTinselHeader(); - _blockPos[0] = 0; - } - - for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _blockPos[0]++) { - // Read 1 byte = 8 bits = one 8 bit block - data = _stream->readByte(); - buffer[samples] = decodeTinsel(data << 8, eVal); - } - } - - return samples; -} - - -#pragma mark - - -// Duck DK3 IMA ADPCM Decoder -// Based on FFmpeg's decoder and http://wiki.multimedia.cx/index.php?title=Duck_DK3_IMA_ADPCM - -class DK3_ADPCMStream : public Ima_ADPCMStream { -protected: - - void reset() { - Ima_ADPCMStream::reset(); - _topNibble = false; - } - -public: - DK3_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) - : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { - - // DK3 only works as a stereo stream - assert(channels == 2); - _topNibble = false; - } - - virtual int readBuffer(int16 *buffer, const int numSamples); - -private: - byte _nibble, _lastByte; - bool _topNibble; -}; - #define DK3_READ_NIBBLE() \ do { \ if (_topNibble) { \ @@ -782,14 +404,15 @@ int DK3_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { #pragma mark - -// adjust the step for use on the next sample. -int16 ADPCMStream::stepAdjust(byte code) { - static const int16 adjusts[] = {-1, -1, -1, -1, 2, 4, 6, 8}; - - return adjusts[code & 0x07]; -} +// This table is used to adjust the step for use on the next sample. +// We could half the table, but since the lookup index used is always +// a 4-bit nibble, it's more efficient to just keep it as it is. +const int16 ADPCMStream::_stepAdjustTable[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 +}; -static const uint16 imaStepTable[89] = { +const int16 Ima_ADPCMStream::_imaTable[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, @@ -805,13 +428,13 @@ static const uint16 imaStepTable[89] = { }; int16 Ima_ADPCMStream::decodeIMA(byte code, int channel) { - int32 E = (2 * (code & 0x7) + 1) * imaStepTable[_status.ima_ch[channel].stepIndex] / 8; + int32 E = (2 * (code & 0x7) + 1) * _imaTable[_status.ima_ch[channel].stepIndex] / 8; int32 diff = (code & 0x08) ? -E : E; int32 samp = CLIP<int32>(_status.ima_ch[channel].last + diff, -32768, 32767); _status.ima_ch[channel].last = samp; - _status.ima_ch[channel].stepIndex += stepAdjust(code); - _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(imaStepTable) - 1); + _status.ima_ch[channel].stepIndex += _stepAdjustTable[code]; + _status.ima_ch[channel].stepIndex = CLIP<int32>(_status.ima_ch[channel].stepIndex, 0, ARRAYSIZE(_imaTable) - 1); return samp; } @@ -830,12 +453,6 @@ RewindableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, Dispo return new MSIma_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign, true); case kADPCMMS: return new MS_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign); - case kADPCMTinsel4: - return new Tinsel4_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign); - case kADPCMTinsel6: - return new Tinsel6_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign); - case kADPCMTinsel8: - return new Tinsel8_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign); case kADPCMIma: return new Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign); case kADPCMApple: diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h index 38ec870a27..06cda69225 100644 --- a/audio/decoders/adpcm.h +++ b/audio/decoders/adpcm.h @@ -38,7 +38,9 @@ #define SOUND_ADPCM_H #include "common/scummsys.h" -#include "common/stream.h" +#include "common/types.h" + +namespace Common { class SeekableReadStream; } namespace Audio { @@ -56,9 +58,6 @@ enum typesADPCM { kADPCMMSIma, // Microsoft IMA ADPCM kADPCMMSImaLastExpress, // Microsoft IMA ADPCM (with inverted samples) kADPCMMS, // Microsoft ADPCM - kADPCMTinsel4, // 4-bit ADPCM used by the Tinsel engine - kADPCMTinsel6, // 6-bit ADPCM used by the Tinsel engine - kADPCMTinsel8, // 8-bit ADPCM used by the Tinsel engine kADPCMIma, // Standard IMA ADPCM kADPCMApple, // Apple QuickTime IMA ADPCM kADPCMDK3 // Duck DK3 IMA ADPCM diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h new file mode 100644 index 0000000000..b566f2c765 --- /dev/null +++ b/audio/decoders/adpcm_intern.h @@ -0,0 +1,230 @@ +/* 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$ + * + */ + +/** + * Internal interfaces to the ADPCM encoders. + * + * These can be used to make custom ADPCM decoder subclasses, + * or to at least share some common data tables between various + * ADPCM decoder implementations. + */ + +#ifndef SOUND_ADPCM_INTERN_H +#define SOUND_ADPCM_INTERN_H + +#include "audio/audiostream.h" +#include "common/endian.h" +#include "common/stream.h" + + +namespace Audio { + +class ADPCMStream : public RewindableAudioStream { +protected: + Common::SeekableReadStream *_stream; + const DisposeAfterUse::Flag _disposeAfterUse; + const int32 _startpos; + const int32 _endpos; + const int _channels; + const uint32 _blockAlign; + uint32 _blockPos[2]; + const int _rate; + + struct { + // OKI/IMA + struct { + int32 last; + int32 stepIndex; + } ima_ch[2]; + } _status; + + virtual void reset(); + +public: + ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign); + ~ADPCMStream(); + + virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); } + virtual bool isStereo() const { return _channels == 2; } + virtual int getRate() const { return _rate; } + + virtual bool rewind(); + + + /** + * This table is used by some ADPCM variants (IMA and OKI) to adjust the + * step for use on the next sample. + * The first 8 entries are identical to the second 8 entries. Hence, we + * could half the table in size. But since the lookup index is always a + * 4-bit nibble, it is more efficient to just keep it as it is. + */ + static const int16 _stepAdjustTable[16]; +}; + +class Oki_ADPCMStream : public ADPCMStream { +public: + Oki_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} + + virtual int readBuffer(int16 *buffer, const int numSamples); + +protected: + int16 decodeOKI(byte); +}; + +class Ima_ADPCMStream : public ADPCMStream { +protected: + int16 decodeIMA(byte code, int channel = 0); // Default to using the left channel/using one channel + +public: + Ima_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + memset(&_status, 0, sizeof(_status)); + } + + virtual int readBuffer(int16 *buffer, const int numSamples); + + + /** + * This table is used by decodeIMA. + */ + static const int16 _imaTable[89]; +}; + +class Apple_ADPCMStream : public Ima_ADPCMStream { +protected: + // Apple QuickTime IMA ADPCM + int32 _streamPos[2]; + int16 _buffer[2][2]; + uint8 _chunkPos[2]; + + void reset() { + Ima_ADPCMStream::reset(); + _chunkPos[0] = 0; + _chunkPos[1] = 0; + _streamPos[0] = 0; + _streamPos[1] = _blockAlign; + } + +public: + Apple_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + _chunkPos[0] = 0; + _chunkPos[1] = 0; + _streamPos[0] = 0; + _streamPos[1] = _blockAlign; + } + + virtual int readBuffer(int16 *buffer, const int numSamples); + +}; + +class MSIma_ADPCMStream : public Ima_ADPCMStream { +public: + MSIma_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign, bool invertSamples = false) + : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign), _invertSamples(invertSamples) { + if (blockAlign == 0) + error("ADPCMStream(): blockAlign isn't specified for MS IMA ADPCM"); + } + + virtual int readBuffer(int16 *buffer, const int numSamples) { + if (_channels == 1) + return readBufferMSIMA1(buffer, numSamples); + else + return readBufferMSIMA2(buffer, numSamples); + } + + int readBufferMSIMA1(int16 *buffer, const int numSamples); + int readBufferMSIMA2(int16 *buffer, const int numSamples); + +private: + bool _invertSamples; // Some implementations invert the way samples are decoded +}; + +class MS_ADPCMStream : public ADPCMStream { +protected: + struct ADPCMChannelStatus { + byte predictor; + int16 delta; + int16 coeff1; + int16 coeff2; + int16 sample1; + int16 sample2; + }; + + struct { + // MS ADPCM + ADPCMChannelStatus ch[2]; + } _status; + + void reset() { + ADPCMStream::reset(); + memset(&_status, 0, sizeof(_status)); + } + +public: + MS_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + if (blockAlign == 0) + error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM"); + memset(&_status, 0, sizeof(_status)); + } + + virtual int readBuffer(int16 *buffer, const int numSamples); + +protected: + int16 decodeMS(ADPCMChannelStatus *c, byte); +}; + +// Duck DK3 IMA ADPCM Decoder +// Based on FFmpeg's decoder and http://wiki.multimedia.cx/index.php?title=Duck_DK3_IMA_ADPCM + +class DK3_ADPCMStream : public Ima_ADPCMStream { +protected: + + void reset() { + Ima_ADPCMStream::reset(); + _topNibble = false; + } + +public: + DK3_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + + // DK3 only works as a stereo stream + assert(channels == 2); + _topNibble = false; + } + + virtual int readBuffer(int16 *buffer, const int numSamples); + +private: + byte _nibble, _lastByte; + bool _topNibble; +}; + +} // End of namespace Audio + +#endif diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp index f526530405..fd9deb7b44 100644 --- a/engines/scumm/imuse_digi/dimuse_codecs.cpp +++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp @@ -27,6 +27,8 @@ #include "common/util.h" #include "scumm/imuse_digi/dimuse_codecs.h" +#include "audio/decoders/adpcm_intern.h" + namespace Scumm { namespace BundleCodecs { @@ -63,21 +65,7 @@ uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) { static byte *_destImcTable = NULL; static uint32 *_destImcTable2 = NULL; -static const int16 imcTable[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493,10442,11487,12635,13899, - 15289,16818,18500,20350,22385,24623,27086,29794, - 32767 -}; - +// This table is the "big brother" of Audio::ADPCMStream::_stepAdjustTable. static const byte imxOtherTable[6][64] = { { 0xFF, @@ -131,7 +119,7 @@ void initializeImcTables() { for (pos = 0; pos <= 88; ++pos) { byte put = 1; - int32 tableValue = ((imcTable[pos] * 4) / 7) / 2; + int32 tableValue = ((Audio::Ima_ADPCMStream::_imaTable[pos] * 4) / 7) / 2; while (tableValue != 0) { tableValue /= 2; put++; @@ -149,7 +137,7 @@ void initializeImcTables() { for (pos = 0; pos <= 88; ++pos) { int32 count = 32; int32 put = 0; - int32 tableValue = imcTable[pos]; + int32 tableValue = Audio::Ima_ADPCMStream::_imaTable[pos]; do { if ((count & n) != 0) { put += tableValue; @@ -304,7 +292,7 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) { const byte data = (packet & dataBitMask); const int32 tmpA = (data << (7 - curTableEntryBitCount)); - const int32 imcTableEntry = imcTable[curTablePos] >> (curTableEntryBitCount - 1); + const int32 imcTableEntry = Audio::Ima_ADPCMStream::_imaTable[curTablePos] >> (curTableEntryBitCount - 1); int32 delta = imcTableEntry + _destImcTable2[tmpA + (curTablePos * 64)]; // The topmost bit in the data packet tells is a sign bit @@ -316,19 +304,13 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) { outputWord += delta; // Clip outputWord to 16 bit signed, and write it into the destination stream - if (outputWord > 0x7fff) - outputWord = 0x7fff; - if (outputWord < -0x8000) - outputWord = -0x8000; + outputWord = CLIP<int32>(outputWord, -0x8000, 0x7fff); WRITE_BE_UINT16(dst + destPos, outputWord); destPos += channels << 1; // Adjust the curTablePos curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data]; - if (curTablePos < 0) - curTablePos = 0; - else if (curTablePos >= ARRAYSIZE(imcTable)) - curTablePos = ARRAYSIZE(imcTable) - 1; + curTablePos = CLIP<int32>(curTablePos, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1); } } diff --git a/engines/tinsel/adpcm.cpp b/engines/tinsel/adpcm.cpp new file mode 100644 index 0000000000..ec51d150dc --- /dev/null +++ b/engines/tinsel/adpcm.cpp @@ -0,0 +1,168 @@ +/* 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$ + * + */ + +#include "tinsel/adpcm.h" + +namespace Tinsel { + +static const double TinselFilterTable[4][2] = { + {0, 0 }, + {0.9375, 0}, + {1.796875, -0.8125}, + {1.53125, -0.859375} +}; + +void Tinsel_ADPCMStream::readBufferTinselHeader() { + uint8 start = _stream->readByte(); + uint8 filterVal = (start & 0xC0) >> 6; + + if ((start & 0x20) != 0) { + //Lower 6 bit are negative + + // Negate + start = ~(start | 0xC0) + 1; + + _status.predictor = 1 << start; + } else { + // Lower 6 bit are positive + + // Truncate + start &= 0x1F; + + _status.predictor = ((double) 1.0) / (1 << start); + } + + _status.K0 = TinselFilterTable[filterVal][0]; + _status.K1 = TinselFilterTable[filterVal][1]; +} + +int16 Tinsel_ADPCMStream::decodeTinsel(int16 code, double eVal) { + double sample; + + sample = (double) code; + sample *= eVal * _status.predictor; + sample += (_status.d0 * _status.K0) + (_status.d1 * _status.K1); + + _status.d1 = _status.d0; + _status.d0 = sample; + + return (int16) CLIP<double>(sample, -32768.0, 32767.0); +} + +int Tinsel4_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { + int samples; + uint16 data; + const double eVal = 1.142822265; + + samples = 0; + + assert(numSamples % 2 == 0); + + while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { + if (_blockPos[0] == _blockAlign) { + readBufferTinselHeader(); + _blockPos[0] = 0; + } + + for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2, _blockPos[0]++) { + // Read 1 byte = 8 bits = two 4 bit blocks + data = _stream->readByte(); + buffer[samples] = decodeTinsel((data << 8) & 0xF000, eVal); + buffer[samples+1] = decodeTinsel((data << 12) & 0xF000, eVal); + } + } + + return samples; +} + +int Tinsel6_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { + int samples; + const double eVal = 1.032226562; + + samples = 0; + + while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { + if (_blockPos[0] == _blockAlign) { + readBufferTinselHeader(); + _blockPos[0] = 0; + _chunkPos = 0; + } + + for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _chunkPos = (_chunkPos + 1) % 4) { + + switch (_chunkPos) { + case 0: + _chunkData = _stream->readByte(); + buffer[samples] = decodeTinsel((_chunkData << 8) & 0xFC00, eVal); + break; + case 1: + _chunkData = (_chunkData << 8) | (_stream->readByte()); + buffer[samples] = decodeTinsel((_chunkData << 6) & 0xFC00, eVal); + _blockPos[0]++; + break; + case 2: + _chunkData = (_chunkData << 8) | (_stream->readByte()); + buffer[samples] = decodeTinsel((_chunkData << 4) & 0xFC00, eVal); + _blockPos[0]++; + break; + case 3: + _chunkData = (_chunkData << 8); + buffer[samples] = decodeTinsel((_chunkData << 2) & 0xFC00, eVal); + _blockPos[0]++; + break; + } + + } + + } + + return samples; +} + +int Tinsel8_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) { + int samples; + byte data; + const double eVal = 1.007843258; + + samples = 0; + + while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) { + if (_blockPos[0] == _blockAlign) { + readBufferTinselHeader(); + _blockPos[0] = 0; + } + + for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _blockPos[0]++) { + // Read 1 byte = 8 bits = one 8 bit block + data = _stream->readByte(); + buffer[samples] = decodeTinsel(data << 8, eVal); + } + } + + return samples; +} + + +} // End of namespace Tinsel diff --git a/engines/tinsel/adpcm.h b/engines/tinsel/adpcm.h new file mode 100644 index 0000000000..79d537eef6 --- /dev/null +++ b/engines/tinsel/adpcm.h @@ -0,0 +1,105 @@ +/* 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 TINSEL_ADPCM_H +#define TINSEL_ADPCM_H + +#include "audio/decoders/adpcm_intern.h" + +namespace Tinsel { + +class Tinsel_ADPCMStream : public Audio::ADPCMStream { +protected: + struct { + // Tinsel + double predictor; + double K0, K1; + double d0, d1; + } _status; + + void reset() { + ADPCMStream::reset(); + memset(&_status, 0, sizeof(_status)); + } + + int16 decodeTinsel(int16, double); + void readBufferTinselHeader(); + +public: + Tinsel_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + + if (blockAlign == 0) + error("Tinsel_ADPCMStream(): blockAlign isn't specified"); + + if (channels != 1) + error("Tinsel_ADPCMStream(): Tinsel ADPCM only supports mono"); + + memset(&_status, 0, sizeof(_status)); + } + +}; + +class Tinsel4_ADPCMStream : public Tinsel_ADPCMStream { +public: + Tinsel4_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} + + virtual int readBuffer(int16 *buffer, const int numSamples); +}; + +class Tinsel6_ADPCMStream : public Tinsel_ADPCMStream { +protected: + uint8 _chunkPos; + uint16 _chunkData; + + void reset() { + ADPCMStream::reset(); + _chunkPos = 0; + _chunkData = 0; + } + +public: + Tinsel6_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { + _chunkPos = 0; + _chunkData = 0; + } + + virtual int readBuffer(int16 *buffer, const int numSamples); +}; + +class Tinsel8_ADPCMStream : public Tinsel_ADPCMStream { +public: + Tinsel8_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign) + : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {} + + virtual int readBuffer(int16 *buffer, const int numSamples); +}; + + +} // End of namespace Tinsel + +#endif diff --git a/engines/tinsel/module.mk b/engines/tinsel/module.mk index 2778cec3df..2ab94b830a 100644 --- a/engines/tinsel/module.mk +++ b/engines/tinsel/module.mk @@ -2,6 +2,7 @@ MODULE := engines/tinsel MODULE_OBJS := \ actors.o \ + adpcm.o \ anim.o \ background.o \ bg.o \ diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp index 49eacce9ae..12bcff829b 100644 --- a/engines/tinsel/music.cpp +++ b/engines/tinsel/music.cpp @@ -38,6 +38,7 @@ #include "common/file.h" #include "common/memstream.h" +#include "tinsel/adpcm.h" #include "tinsel/config.h" #include "tinsel/sound.h" #include "tinsel/music.h" @@ -785,8 +786,8 @@ bool PCMMusicPlayer::getNextChunk() { sampleStream = new Common::MemoryReadStream(buffer, sampleCLength, DisposeAfterUse::YES); delete _curChunk; - _curChunk = makeADPCMStream(sampleStream, DisposeAfterUse::YES, sampleCLength, - Audio::kADPCMTinsel8, 22050, 1, 32); + _curChunk = new Tinsel8_ADPCMStream(sampleStream, DisposeAfterUse::YES, sampleCLength, + 22050, 1, 32); _state = S_MID; return true; diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp index a76d26eade..1fcdb4dcf9 100644 --- a/engines/tinsel/sound.cpp +++ b/engines/tinsel/sound.cpp @@ -26,6 +26,7 @@ #include "tinsel/sound.h" +#include "tinsel/adpcm.h" #include "tinsel/dw.h" #include "tinsel/config.h" #include "tinsel/music.h" @@ -319,7 +320,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p #endif break; default: - sampleStream = Audio::makeADPCMStream(compressedStream, DisposeAfterUse::YES, sampleLen, Audio::kADPCMTinsel6, 22050, 1, 24); + sampleStream = new Tinsel6_ADPCMStream(compressedStream, DisposeAfterUse::YES, sampleLen, 22050, 1, 24); break; } diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp index 0003bb1972..c2e0bf7b20 100644 --- a/engines/toon/audio.cpp +++ b/engines/toon/audio.cpp @@ -26,24 +26,10 @@ #include "toon/audio.h" #include "common/memstream.h" #include "common/substream.h" +#include "audio/decoders/adpcm_intern.h" namespace Toon { -static const int ADPCM_index[8] = { - -1, -1, -1, -1, 2 , 4 , 6 , 8 -}; -static const int ADPCM_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 -}; - AudioManager::AudioManager(ToonEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { for (int32 i = 0; i < 16; i++) _channels[i] = NULL; @@ -372,7 +358,7 @@ void AudioStreamInstance::decodeADPCM(uint8 *comp, int16 *dest, int32 packetSize int32 v31 = v30 & 0x8; int32 v32 = v30 & 0x7; - int32 v33 = ADPCM_table[v19]; + int32 v33 = Audio::Ima_ADPCMStream::_imaTable[v19]; int32 v34 = v33 >> 3; if (v32 & 4) v34 += v33; @@ -383,12 +369,8 @@ void AudioStreamInstance::decodeADPCM(uint8 *comp, int16 *dest, int32 packetSize if (v32 & 1) v34 += v33 >> 2; - v19 += ADPCM_index[v32]; - if (v19 < 0) - v19 = 0; - - if (v19 > 88) - v19 = 88; + v19 += Audio::ADPCMStream::_stepAdjustTable[v32]; + v19 = CLIP<int32>(v19, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1); if (v31) v18 -= v34; diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp index a755d18bb0..0ab12e91cc 100644 --- a/video/coktel_decoder.cpp +++ b/video/coktel_decoder.cpp @@ -34,6 +34,7 @@ #include "audio/audiostream.h" #include "audio/decoders/raw.h" +#include "audio/decoders/adpcm_intern.h" #include "common/memstream.h" static const uint32 kVideoCodecIndeo3 = MKTAG('i','v','3','2'); @@ -1516,26 +1517,6 @@ const uint16 VMDDecoder::_tableDPCM[128] = { 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 }; -const int32 VMDDecoder::_tableADPCM[] = { - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, - 32767, 0 -}; - -const int32 VMDDecoder::_tableADPCMStep[] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 -}; - VMDDecoder::VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : CoktelDecoder(mixer, soundType), _stream(0), _version(0), _flags(0), _frameInfoOffset(0), _partsPerFrame(0), _frames(0), _soundFlags(0), _soundFreq(0), _soundSliceSize(0), _soundSlicesCount(0), @@ -2617,7 +2598,7 @@ byte *VMDDecoder::deADPCM(const byte *data, uint32 &size, int32 init, int32 inde index = CLIP<int32>(index, 0, 88); - int32 predictor = _tableADPCM[index]; + int32 predictor = Audio::Ima_ADPCMStream::_imaTable[index]; uint32 dataByte = 0; bool newByte = true; @@ -2634,7 +2615,7 @@ byte *VMDDecoder::deADPCM(const byte *data, uint32 &size, int32 init, int32 inde newByte = !newByte; - index += _tableADPCMStep[code]; + index += Audio::ADPCMStream::_stepAdjustTable[code]; index = CLIP<int32>(index, 0, 88); int32 value = predictor / 8; @@ -2653,7 +2634,7 @@ byte *VMDDecoder::deADPCM(const byte *data, uint32 &size, int32 init, int32 inde init = CLIP<int32>(init, -32768, 32767); - predictor = _tableADPCM[index]; + predictor = Audio::Ima_ADPCMStream::_imaTable[index]; *out++ = TO_BE_16(init); } diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h index 9c8263be9d..e83e1d29ed 100644 --- a/video/coktel_decoder.h +++ b/video/coktel_decoder.h @@ -431,8 +431,6 @@ private: // Tables for the audio decompressors static const uint16 _tableDPCM[128]; - static const int32 _tableADPCM[]; - static const int32 _tableADPCMStep[]; Common::SeekableReadStream *_stream; |