diff options
| author | Max Horn | 2011-04-13 11:48:07 +0200 | 
|---|---|---|
| committer | Max Horn | 2011-04-13 11:49:25 +0200 | 
| commit | 9c2ff87db77235fc32bb782f40a8b4ed96d1e602 (patch) | |
| tree | 44ff2caf23776121d3737531d2b2f1d0f74bf20d /engines | |
| parent | b52b6b8d2b5f038717c008362a9e11009dbf88d8 (diff) | |
| download | scummvm-rg350-9c2ff87db77235fc32bb782f40a8b4ed96d1e602.tar.gz scummvm-rg350-9c2ff87db77235fc32bb782f40a8b4ed96d1e602.tar.bz2 scummvm-rg350-9c2ff87db77235fc32bb782f40a8b4ed96d1e602.zip  | |
SCUMM: Fix bug #3187622 (COMI: incorrect decoding of audio codec 13/15)
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse_codecs.cpp | 52 | ||||
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse_codecs.h | 4 | ||||
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse_sndmgr.cpp | 1 | 
3 files changed, 43 insertions, 14 deletions
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp index df4c9d97dc..f526530405 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 81158fafc9..71fd24c3ac 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 13f8a60332..2cd90c4f2b 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) {  | 
