[Scummvm-cvs-logs] scummvm master -> 169512852e7ddf06061075e142bdb5331ed25053

fingolfin max at quendi.de
Wed Apr 13 12:50:41 CEST 2011


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
b9296a189e AUDIO: Expose ADPCM decoder internals via a new header
7607e351cc TINSEL: Move custom ADPCM decoders to tinsel engine
e0a30e0039 AUDIO: Stop adpcm.h from including common/stream.h
393c6f6ade AUDIO: Expose some internal ADPCM data tables
1759209b3b SCUMM: Use shared ADPCM data tables
8f70e089ac VIDEO: Use shared ADPCM data tables in VMDDecoder
169512852e TOON: Use shared ADPCM data tables


Commit: b9296a189e12c94e110ea15c490d9f46dcf4a802
    https://github.com/scummvm/scummvm/commit/b9296a189e12c94e110ea15c490d9f46dcf4a802
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:57-07:00

Commit Message:
AUDIO: Expose ADPCM decoder internals via a new header

There are tons of ADPCM variants out there, and it is impractical to
stuff them all into a single adpcm.cpp file. By exposing the internals,
engines can implement their ADPCM decoder variants more easily.

Changed paths:
  A audio/decoders/adpcm_intern.h
    audio/decoders/adpcm.cpp



diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index 7def89b..1ade3dc 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;
@@ -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;
 
@@ -691,33 +550,6 @@ int Tinsel8_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
 
 #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) { \
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
new file mode 100644
index 0000000..8e092e6
--- /dev/null
+++ b/audio/decoders/adpcm_intern.h
@@ -0,0 +1,215 @@
+/* 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();
+	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();
+};
+
+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);
+};
+
+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


Commit: 7607e351cc7b58efb90e14839bc4cd4af7e6371e
    https://github.com/scummvm/scummvm/commit/7607e351cc7b58efb90e14839bc4cd4af7e6371e
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:57-07:00

Commit Message:
TINSEL: Move custom ADPCM decoders to tinsel engine

Changed paths:
  A engines/tinsel/adpcm.cpp
  A engines/tinsel/adpcm.h
    audio/decoders/adpcm.cpp
    audio/decoders/adpcm.h
    engines/tinsel/module.mk
    engines/tinsel/music.cpp
    engines/tinsel/sound.cpp



diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index 1ade3dc..2391bdc 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -337,219 +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 -
-
 #define DK3_READ_NIBBLE() \
 do { \
 	if (_topNibble) { \
@@ -662,12 +452,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 38ec870..a41da3a 100644
--- a/audio/decoders/adpcm.h
+++ b/audio/decoders/adpcm.h
@@ -56,9 +56,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/engines/tinsel/adpcm.cpp b/engines/tinsel/adpcm.cpp
new file mode 100644
index 0000000..ec51d15
--- /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 0000000..79d537e
--- /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 2778cec..2ab94b8 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 49eacce..12bcff8 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 a76d26e..1fcdb4d 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;
 	}
 


Commit: e0a30e00399366f0a7130071c961cb368444d1b3
    https://github.com/scummvm/scummvm/commit/e0a30e00399366f0a7130071c961cb368444d1b3
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:57-07:00

Commit Message:
AUDIO: Stop adpcm.h from including common/stream.h

Changed paths:
    audio/decoders/adpcm.h



diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h
index a41da3a..06cda69 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 {


Commit: 393c6f6ade927c332aecc1271b3363891f256423
    https://github.com/scummvm/scummvm/commit/393c6f6ade927c332aecc1271b3363891f256423
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:57-07:00

Commit Message:
AUDIO: Expose some internal ADPCM data tables

Changed paths:
    audio/decoders/adpcm.cpp
    audio/decoders/adpcm_intern.h



diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp
index 2391bdc..43b5a0b 100644
--- a/audio/decoders/adpcm.cpp
+++ b/audio/decoders/adpcm.cpp
@@ -110,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
@@ -404,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,
@@ -427,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;
 }
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index 8e092e6..b566f2c 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -61,7 +61,6 @@ protected:
 	} _status;
 
 	virtual void reset();
-	int16 stepAdjust(byte);
 
 public:
 	ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign);
@@ -72,6 +71,16 @@ public:
 	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 {
@@ -96,6 +105,12 @@ public:
 	}
 
 	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 {


Commit: 1759209b3b89b0edacaa79383ea54f850f22235b
    https://github.com/scummvm/scummvm/commit/1759209b3b89b0edacaa79383ea54f850f22235b
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:58-07:00

Commit Message:
SCUMM: Use shared ADPCM data tables

Changed paths:
    engines/scumm/imuse_digi/dimuse_codecs.cpp



diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp
index f526530..fd9deb7 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);
 		}
 	}
 


Commit: 8f70e089ac721176fb543b88f00b4c97ac945b14
    https://github.com/scummvm/scummvm/commit/8f70e089ac721176fb543b88f00b4c97ac945b14
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:58-07:00

Commit Message:
VIDEO: Use shared ADPCM data tables in VMDDecoder

Changed paths:
    video/coktel_decoder.cpp
    video/coktel_decoder.h



diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index a755d18..0ab12e9 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 9c8263b..e83e1d2 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;
 


Commit: 169512852e7ddf06061075e142bdb5331ed25053
    https://github.com/scummvm/scummvm/commit/169512852e7ddf06061075e142bdb5331ed25053
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T03:48:58-07:00

Commit Message:
TOON: Use shared ADPCM data tables

Changed paths:
    engines/toon/audio.cpp



diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index 0003bb1..c2e0bf7 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;






More information about the Scummvm-git-logs mailing list