[Scummvm-cvs-logs] scummvm master -> 9c2ff87db77235fc32bb782f40a8b4ed96d1e602

fingolfin max at quendi.de
Wed Apr 13 11:56:00 CEST 2011


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

Summary:
79f514a397 TOON: Make ADPCM tables const
29962bfc73 SCUMM: Move ADPCM decoder into separate function
b52b6b8d2b SCUMM: Resolve some code duplication
9c2ff87db7 SCUMM: Fix bug #3187622 (COMI: incorrect decoding of audio codec 13/15)


Commit: 79f514a397c9e558e25a28fa5f92a02f42d7828a
    https://github.com/scummvm/scummvm/commit/79f514a397c9e558e25a28fa5f92a02f42d7828a
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T02:49:24-07:00

Commit Message:
TOON: Make ADPCM tables const

Changed paths:
    engines/toon/audio.cpp



diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index d76a63c..0003bb1 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -29,10 +29,10 @@
 
 namespace Toon {
 
-static int ADPCM_index[8] = {
+static const int ADPCM_index[8] = {
 	-1, -1, -1, -1, 2 , 4 , 6 , 8
 };
-static int ADPCM_table[89] = {
+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,


Commit: 29962bfc73879845da8c58e31f75d53ff51bd10b
    https://github.com/scummvm/scummvm/commit/29962bfc73879845da8c58e31f75d53ff51bd10b
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T02:49:24-07:00

Commit Message:
SCUMM: Move ADPCM decoder into separate function

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 62a006c..99fff4e 100644
--- a/engines/scumm/imuse_digi/dimuse_codecs.cpp
+++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp
@@ -183,8 +183,133 @@ static int32 compDecode(byte *src, byte *dst) {
 }
 #undef NextBit
 
+int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
+	byte *src;
+
+	// Decoder for the the IMA ADPCM variants used in COMI.
+	// Contrary to regular IMA ADPCM, this codec uses a variable
+	// bitsize for the encoded data.
+
+	const int MAX_CHANNELS = 2;
+	int32 outputSamplesLeft;
+	int32 destPos;
+	int16 firstWord;
+	byte initialTablePos[MAX_CHANNELS] = {0, 0};
+	//int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
+	int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
+	int32 totalBitOffset, curTablePos, outputWord;
+	byte *dst;
+	int i;
+
+	// We only support mono and stereo
+	assert(channels == 1 || channels == 2);
+
+	src = compInput;
+	dst = compOutput;
+	outputSamplesLeft = 0x1000;
+
+	// Every data packet contains 0x2000 bytes of audio data
+	// when extracted. In order to encode bigger data sets,
+	// one has to split the data into multiple blocks.
+	//
+	// Every block starts with a 2 byte word. If that word is
+	// non-zero, it indicates the size of a block of raw audio
+	// data (not encoded) following it. That data we simply copy
+	// to the output buffer and the proceed by decoding the
+	// remaining data.
+	//
+	// If on the other hand the word is zero, then what follows
+	// are 7*channels bytes containing seed data for the decoder.
+	firstWord = READ_BE_UINT16(src);
+	src += 2;
+	if (firstWord != 0) {
+		// Copy raw data
+		memcpy(dst, src, firstWord);
+		dst += firstWord;
+		src += firstWord;
+		assert((firstWord & 1) == 0);
+		outputSamplesLeft -= firstWord / 2;
+	} else {
+		// Read the seed values for the decoder.
+		for (i = 0; i < channels; i++) {
+			initialTablePos[i] = *src;
+			src += 1;
+			//initialimcTableEntry[i] = READ_BE_UINT32(src);
+			src += 4;
+			initialOutputWord[i] = READ_BE_UINT32(src);
+			src += 4;
+		}
+	}
+
+	totalBitOffset = 0;
+	// The channels are encoded separately.
+	for (int chan = 0; chan < channels; chan++) {
+		// Read initial state (this makes it possible for the data stream
+		// to be split & spread across multiple data chunks.
+		curTablePos = initialTablePos[chan];
+		//imcTableEntry = initialimcTableEntry[chan];
+		outputWord = initialOutputWord[chan];
+
+		// We need to interleave the channels in the output; we achieve
+		// that by using a variables dest offset:
+		destPos = chan * 2;
+
+		const int bound = (channels == 1)
+							? outputSamplesLeft
+							: ((chan == 0)
+								? (outputSamplesLeft+1) / 2
+								: outputSamplesLeft / 2);
+		for (i = 0; i < bound; ++i) {
+			// Determine the size (in bits) of the next data packet
+			const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos];
+			assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
+
+			// Read the next data packet
+			const byte *readPos = src + (totalBitOffset >> 3);
+			const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7));
+			const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount));
+
+			// Advance read position to the next data packet
+			totalBitOffset += curTableEntryBitCount;
+
+			// Decode the data packet into a delta value for the output signal.
+			const byte signBitMask = (1 << (curTableEntryBitCount - 1));
+			const byte dataBitMask = (signBitMask - 1);
+			const byte data = (packet & dataBitMask);
+
+			int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1);
+
+			// The topmost bit in the data packet tells is a sign bit
+			if ((packet & signBitMask) != 0) {
+				delta = -delta;
+			}
+
+			// Accumulate the delta onto the output data
+			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;
+			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;
+		}
+	}
+
+	return 0x2000;
+}
+
+
 int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize) {
-	int32 outputSize, channels;
+	int32 outputSize;
 	int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
 	byte *src, *t_table, *p, *ptr;
 	byte t_tmp1, t_tmp2;
@@ -506,132 +631,7 @@ int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inpu
 
 	case 13:
 	case 15:
-		if (codec == 13) {
-			channels = 1;
-		} else {
-			channels = 2;
-		}
-
-		{
-			// Decoder for the the IMA ADPCM variants used in COMI.
-			// Contrary to regular IMA ADPCM, this codec uses a variable
-			// bitsize for the encoded data.
-
-			const int MAX_CHANNELS = 2;
-			int32 outputSamplesLeft;
-			int32 destPos;
-			int16 firstWord;
-			byte initialTablePos[MAX_CHANNELS] = {0, 0};
-			//int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
-			int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
-			int32 totalBitOffset, curTablePos, outputWord;
-			byte *dst;
-			int i;
-
-			// We only support mono and stereo
-			assert(channels == 1 || channels == 2);
-
-			src = compInput;
-			dst = compOutput;
-			outputSize = 0x2000;
-			outputSamplesLeft = 0x1000;
-
-			// Every data packet contains 0x2000 bytes of audio data
-			// when extracted. In order to encode bigger data sets,
-			// one has to split the data into multiple blocks.
-			//
-			// Every block starts with a 2 byte word. If that word is
-			// non-zero, it indicates the size of a block of raw audio
-			// data (not encoded) following it. That data we simply copy
-			// to the output buffer and the proceed by decoding the
-			// remaining data.
-			//
-			// If on the other hand the word is zero, then what follows
-			// are 7*channels bytes containing seed data for the decoder.
-			firstWord = READ_BE_UINT16(src);
-			src += 2;
-			if (firstWord != 0) {
-				// Copy raw data
-				memcpy(dst, src, firstWord);
-				dst += firstWord;
-				src += firstWord;
-				assert((firstWord & 1) == 0);
-				outputSamplesLeft -= firstWord / 2;
-			} else {
-				// Read the seed values for the decoder.
-				for (i = 0; i < channels; i++) {
-					initialTablePos[i] = *src;
-					src += 1;
-					//initialimcTableEntry[i] = READ_BE_UINT32(src);
-					src += 4;
-					initialOutputWord[i] = READ_BE_UINT32(src);
-					src += 4;
-				}
-			}
-
-			totalBitOffset = 0;
-			// The channels are encoded separately.
-			for (int chan = 0; chan < channels; chan++) {
-				// Read initial state (this makes it possible for the data stream
-				// to be split & spread across multiple data chunks.
-				curTablePos = initialTablePos[chan];
-				//imcTableEntry = initialimcTableEntry[chan];
-				outputWord = initialOutputWord[chan];
-
-				// We need to interleave the channels in the output; we achieve
-				// that by using a variables dest offset:
-				destPos = chan * 2;
-
-				const int bound = (channels == 1)
-									? outputSamplesLeft
-									: ((chan == 0)
-										? (outputSamplesLeft+1) / 2
-										: outputSamplesLeft / 2);
-				for (i = 0; i < bound; ++i) {
-					// Determine the size (in bits) of the next data packet
-					const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos];
-					assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
-
-					// Read the next data packet
-					const byte *readPos = src + (totalBitOffset >> 3);
-					const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7));
-					const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount));
-
-					// Advance read position to the next data packet
-					totalBitOffset += curTableEntryBitCount;
-
-					// Decode the data packet into a delta value for the output signal.
-					const byte signBitMask = (1 << (curTableEntryBitCount - 1));
-					const byte dataBitMask = (signBitMask - 1);
-					const byte data = (packet & dataBitMask);
-
-					int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1);
-
-					// The topmost bit in the data packet tells is a sign bit
-					if ((packet & signBitMask) != 0) {
-						delta = -delta;
-					}
-
-					// Accumulate the delta onto the output data
-					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;
-					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;
-				}
-			}
-		}
+		outputSize = decompressADPCM(compInput, compOutput, (codec == 13) ? 1 : 2);
 		break;
 
 	default:


Commit: b52b6b8d2b5f038717c008362a9e11009dbf88d8
    https://github.com/scummvm/scummvm/commit/b52b6b8d2b5f038717c008362a9e11009dbf88d8
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T02:49:25-07:00

Commit Message:
SCUMM: Resolve some code duplication

Changed paths:
  A engines/scumm/imuse_digi/dimuse_codecs.h
    engines/scumm/imuse_digi/dimuse.cpp
    engines/scumm/imuse_digi/dimuse_bndmgr.cpp
    engines/scumm/imuse_digi/dimuse_bndmgr.h
    engines/scumm/imuse_digi/dimuse_codecs.cpp
    engines/scumm/imuse_digi/dimuse_sndmgr.cpp
    engines/scumm/smush/imuse_channel.cpp



diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp
index 516a049..3831689 100644
--- a/engines/scumm/imuse_digi/dimuse.cpp
+++ b/engines/scumm/imuse_digi/dimuse.cpp
@@ -31,6 +31,7 @@
 #include "scumm/sound.h"
 #include "scumm/imuse_digi/dimuse.h"
 #include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
 #include "scumm/imuse_digi/dimuse_track.h"
 
 #include "audio/audiostream.h"
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
index 1e526aa..cb894d7 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
@@ -28,6 +28,7 @@
 #include "scumm/util.h"
 #include "scumm/file.h"
 #include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
 
 namespace Scumm {
 
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.h b/engines/scumm/imuse_digi/dimuse_bndmgr.h
index a78697a..bed1ac6 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.h
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.h
@@ -107,14 +107,6 @@ public:
 	int32 decompressSampleByCurIndex(int32 offset, int32 size, byte **compFinal, int headerSize, bool headerOutside);
 };
 
-namespace BundleCodecs {
-
-uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
-void initializeImcTables();
-int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize);
-
-} // End of namespace BundleCodecs
-
 } // End of namespace Scumm
 
 #endif
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp
index 99fff4e..df4c9d9 100644
--- a/engines/scumm/imuse_digi/dimuse_codecs.cpp
+++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp
@@ -25,6 +25,7 @@
 #include "common/scummsys.h"
 #include "common/endian.h"
 #include "common/util.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
 
 namespace Scumm {
 
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.h b/engines/scumm/imuse_digi/dimuse_codecs.h
new file mode 100644
index 0000000..81158fa
--- /dev/null
+++ b/engines/scumm/imuse_digi/dimuse_codecs.h
@@ -0,0 +1,42 @@
+/* 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 SCUMM_IMUSE_DIGI_CODECS_H
+#define SCUMM_IMUSE_DIGI_CODECS_H
+
+#include "common/scummsys.h"
+
+namespace Scumm {
+
+namespace BundleCodecs {
+
+uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
+void initializeImcTables();
+int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize);
+
+} // End of namespace BundleCodecs
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index 3fcfc62..13f8a60 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -34,8 +34,9 @@
 #include "scumm/scumm.h"
 #include "scumm/util.h"
 #include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_sndmgr.h"
 #include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
+#include "scumm/imuse_digi/dimuse_sndmgr.h"
 
 namespace Scumm {
 
diff --git a/engines/scumm/smush/imuse_channel.cpp b/engines/scumm/smush/imuse_channel.cpp
index 5af3c9e..32fa99a 100644
--- a/engines/scumm/smush/imuse_channel.cpp
+++ b/engines/scumm/smush/imuse_channel.cpp
@@ -29,6 +29,7 @@
 #include "scumm/scumm.h"	// For DEBUG_SMUSH
 #include "scumm/util.h"
 #include "scumm/smush/channel.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"	// for decode12BitsSample
 
 namespace Scumm {
 
@@ -171,28 +172,10 @@ void ImuseChannel::decode() {
 		}
 	}
 
-	// FIXME: Code duplication! See decode12BitsSample() in imuse_digi/dimuse_codecs.cpp
-
-	int loop_size = _sbufferSize / 3;
-	int new_size = loop_size * 4;
-	byte *keep, *decoded;
-	uint32 value;
-	keep = decoded = (byte *)malloc(new_size);
-	assert(keep);
-	unsigned char * source = _sbuffer;
-
-	while (loop_size--) {
-		byte v1 = *source++;
-		byte v2 = *source++;
-		byte v3 = *source++;
-		value = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
-		WRITE_BE_UINT16(decoded, value); decoded += 2;
-		value = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
-		WRITE_BE_UINT16(decoded, value); decoded += 2;
-	}
+	byte *keep;
+	_sbufferSize = BundleCodecs::decode12BitsSample(_sbuffer, &keep, _sbufferSize);
 	free(_sbuffer);
 	_sbuffer = (byte *)keep;
-	_sbufferSize = new_size;
 }
 
 bool ImuseChannel::handleSubTags(int32 &offset) {


Commit: 9c2ff87db77235fc32bb782f40a8b4ed96d1e602
    https://github.com/scummvm/scummvm/commit/9c2ff87db77235fc32bb782f40a8b4ed96d1e602
Author: Max Horn (max at quendi.de)
Date: 2011-04-13T02:49:25-07:00

Commit Message:
SCUMM: Fix bug #3187622 (COMI: incorrect decoding of audio codec 13/15)

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



diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp
index df4c9d9..f526530 100644
--- a/engines/scumm/imuse_digi/dimuse_codecs.cpp
+++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp
@@ -60,7 +60,8 @@ uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) {
  * varies the size of each "packet" between 2 and 7 bits.
  */
 
-static byte _imcTableEntryBitCount[89];
+static byte *_destImcTable = NULL;
+static uint32 *_destImcTable2 = NULL;
 
 static const int16 imcTable[89] = {
 		7,	  8,	9,	 10,   11,	 12,   13,	 14,
@@ -117,23 +118,47 @@ static const byte imxOtherTable[6][64] = {
 	}
 };
 
+void releaseImcTables() {
+	free(_destImcTable);
+	free(_destImcTable2);
+}
+
 void initializeImcTables() {
 	int pos;
 
-	for (pos = 0; pos < ARRAYSIZE(imcTable); ++pos) {
-		byte put = 0;
+	if (!_destImcTable) _destImcTable = (byte *)calloc(89, sizeof(byte));
+	if (!_destImcTable2) _destImcTable2 = (uint32 *)calloc(89 * 64, sizeof(uint32));
+
+	for (pos = 0; pos <= 88; ++pos) {
+		byte put = 1;
 		int32 tableValue = ((imcTable[pos] * 4) / 7) / 2;
 		while (tableValue != 0) {
 			tableValue /= 2;
 			put++;
 		}
-		if (put < 2) {
-			put = 2;
+		if (put < 3) {
+			put = 3;
 		}
-		if (put > 7) {
-			put = 7;
+		if (put > 8) {
+			put = 8;
+		}
+		_destImcTable[pos] = put - 1;
+	}
+
+	for (int n = 0; n < 64; n++) {
+		for (pos = 0; pos <= 88; ++pos) {
+			int32 count = 32;
+			int32 put = 0;
+			int32 tableValue = imcTable[pos];
+			do {
+				if ((count & n) != 0) {
+					put += tableValue;
+				}
+				count /= 2;
+				tableValue /= 2;
+			} while (count != 0);
+			_destImcTable2[n + pos * 64] = put;
 		}
-		_imcTableEntryBitCount[pos] = put;
 	}
 }
 
@@ -196,7 +221,7 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
 	int32 destPos;
 	int16 firstWord;
 	byte initialTablePos[MAX_CHANNELS] = {0, 0};
-	//int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
+	int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
 	int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
 	int32 totalBitOffset, curTablePos, outputWord;
 	byte *dst;
@@ -235,7 +260,7 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
 		for (i = 0; i < channels; i++) {
 			initialTablePos[i] = *src;
 			src += 1;
-			//initialimcTableEntry[i] = READ_BE_UINT32(src);
+			initialimcTableEntry[i] = READ_BE_UINT32(src);
 			src += 4;
 			initialOutputWord[i] = READ_BE_UINT32(src);
 			src += 4;
@@ -262,7 +287,7 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
 								: outputSamplesLeft / 2);
 		for (i = 0; i < bound; ++i) {
 			// Determine the size (in bits) of the next data packet
-			const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos];
+			const int32 curTableEntryBitCount = _destImcTable[curTablePos];
 			assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
 
 			// Read the next data packet
@@ -278,7 +303,9 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
 			const byte dataBitMask = (signBitMask - 1);
 			const byte data = (packet & dataBitMask);
 
-			int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1);
+			const int32 tmpA = (data << (7 - curTableEntryBitCount));
+			const int32 imcTableEntry = imcTable[curTablePos] >> (curTableEntryBitCount - 1);
+			int32 delta = imcTableEntry + _destImcTable2[tmpA + (curTablePos * 64)];
 
 			// The topmost bit in the data packet tells is a sign bit
 			if ((packet & signBitMask) != 0) {
@@ -308,7 +335,6 @@ int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
 	return 0x2000;
 }
 
-
 int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize) {
 	int32 outputSize;
 	int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.h b/engines/scumm/imuse_digi/dimuse_codecs.h
index 81158fa..71fd24c 100644
--- a/engines/scumm/imuse_digi/dimuse_codecs.h
+++ b/engines/scumm/imuse_digi/dimuse_codecs.h
@@ -32,9 +32,11 @@ namespace Scumm {
 namespace BundleCodecs {
 
 uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
-void initializeImcTables();
 int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize);
 
+void initializeImcTables();
+void releaseImcTables();
+
 } // End of namespace BundleCodecs
 
 } // End of namespace Scumm
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index 13f8a60..2cd90c4 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -57,6 +57,7 @@ ImuseDigiSndMgr::~ImuseDigiSndMgr() {
 	}
 
 	delete _cacheBundleDir;
+	BundleCodecs::releaseImcTables();
 }
 
 void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers) {






More information about the Scummvm-git-logs mailing list