diff options
author | Paweł Kołodziejski | 2003-01-25 18:41:32 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2003-01-25 18:41:32 +0000 |
commit | 8e8575003bbfecfad605dc3fa8b3723d3f55027d (patch) | |
tree | 424d8d9a83875ac1558cc467da0a59cd7039306a /scumm | |
parent | d942441f7f33a5d6898892fc64d777040a399b06 (diff) | |
download | scummvm-rg350-8e8575003bbfecfad605dc3fa8b3723d3f55027d.tar.gz scummvm-rg350-8e8575003bbfecfad605dc3fa8b3723d3f55027d.tar.bz2 scummvm-rg350-8e8575003bbfecfad605dc3fa8b3723d3f55027d.zip |
implemented properly comi sound codecs
svn-id: r6538
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/bundle.cpp | 238 | ||||
-rw-r--r-- | scumm/bundle.h | 10 | ||||
-rw-r--r-- | scumm/sound.cpp | 6 |
3 files changed, 125 insertions, 129 deletions
diff --git a/scumm/bundle.cpp b/scumm/bundle.cpp index 52fc3da875..9b2bb39660 100644 --- a/scumm/bundle.cpp +++ b/scumm/bundle.cpp @@ -24,7 +24,7 @@ #include "bundle.h" #include "file.h" -uint16 imcTable1[] = { +int16 imcTable[] = { 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025, 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076, @@ -86,8 +86,8 @@ byte imxOtherTable6[] = { 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 }; -uint16 imxShortTable[] = { - 0x0000, 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F +byte imxShortTable[] = { + 0, 0, 1, 3, 7, 15, 31, 63 }; Bundle::Bundle() @@ -115,13 +115,13 @@ void Bundle::initializeImcTables() int32 destTablePos = 0; int32 imcTable1Pos = 0; do { - int16 put = 1; - int32 tableValue = ((imcTable1[imcTable1Pos] << 2) / 7) / 2; + byte put = 1; + int32 tableValue = ((imcTable[imcTable1Pos] << 2) / 7) >> 1; if (tableValue != 0) { do { - tableValue /= 2; + tableValue >>= 1; put++; - } while (tableValue != 0); + } while (tableValue != 0); } if (put < 3) { put = 3; @@ -130,30 +130,28 @@ void Bundle::initializeImcTables() put = 8; } put--; - imcTable1Pos++; - _destImcTable[destTablePos] = (byte)put; + _destImcTable[destTablePos] = put; destTablePos++; - } while (imcTable1Pos <= 88); + } while (++imcTable1Pos <= 88); _destImcTable[89] = 0; - for (int n = 0; n < 63; n++) { + for (int n = 0; n < 64; n++) { imcTable1Pos = 0; - int32 destTable2Pos = n; + destTablePos = n; do { int32 count = 32; - int32 putD = 0; - int32 tableValue = imcTable1[imcTable1Pos]; + int32 put = 0; + int32 tableValue = imcTable[imcTable1Pos]; do { if ((count & n) != 0) { - putD = putD + tableValue; + put += tableValue; } count >>= 1; tableValue >>= 1; } while (count != 0); - _destImcTable2[destTable2Pos] = putD; - destTable2Pos += 64; - imcTable1Pos++; - } while (imcTable1Pos <= 88); + _destImcTable2[destTablePos] = put; + destTablePos += 64; + } while (++imcTable1Pos <= 88); } _initializedImcTables = true; @@ -245,7 +243,7 @@ bool Bundle::openMusicFile(const char *filename, const char *directory) return true; } -int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 & channels) +int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final) { int32 i, tag, num, final_size, output_size; byte *comp_input, *comp_output; @@ -262,15 +260,14 @@ int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 _voiceFile.readUint32BE(); if (tag != MKID_BE('COMP')) { - warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8, - tag); + warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8, tag); return 0; } if (_compVoiceTable) free(_compVoiceTable); - _compVoiceTable = (CompTable*)malloc(sizeof(CompTable) * num); + _compVoiceTable = (CompTable *)malloc(sizeof(CompTable) * num); for (i = 0; i < num; i++) { _compVoiceTable[i].offset = _voiceFile.readUint32BE(); _compVoiceTable[i].size = _voiceFile.readUint32BE(); @@ -280,7 +277,7 @@ int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 final_size = 0; - comp_output = (byte *)malloc(10000); + comp_output = (byte *)malloc(0x2000); for (i = 0; i < num; i++) { comp_input = (byte *)malloc(_compVoiceTable[i].size); @@ -288,9 +285,8 @@ int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 _voiceFile.seek(_bundleVoiceTable[index].offset + _compVoiceTable[i].offset, SEEK_SET); _voiceFile.read(comp_input, _compVoiceTable[i].size); - output_size = - decompressCodec(_compVoiceTable[i].codec, comp_input, comp_output, _compVoiceTable[i].size, i, channels); - assert(output_size <= 10000); + output_size = decompressCodec(_compVoiceTable[i].codec, comp_input, comp_output, _compVoiceTable[i].size); + assert(output_size <= 0x2000); memcpy(comp_final + final_size, comp_output, output_size); final_size += output_size; @@ -301,7 +297,7 @@ int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 return final_size; } -int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp_final, int32 & channels) +int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp_final) { int32 i = 0; int tag, num, final_size; @@ -320,14 +316,13 @@ int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp _musicFile.readUint32BE(); if (tag != MKID_BE('COMP')) { - warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8, - tag); + warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8, tag); return 0; } if (_compMusicTable) free(_compMusicTable); - _compMusicTable = (CompTable*)malloc(sizeof(CompTable) * num); + _compMusicTable = (CompTable *)malloc(sizeof(CompTable) * num); for (i = 0; i < num; i++) { _compMusicTable[i].offset = _musicFile.readUint32BE(); @@ -335,6 +330,8 @@ int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp _compMusicTable[i].codec = _musicFile.readUint32BE(); _musicFile.readUint32BE(); } + + _lastSong = index; } comp_input = (byte *)malloc(_compMusicTable[number].size); @@ -342,18 +339,14 @@ int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp _musicFile.seek(_bundleMusicTable[index].offset + _compMusicTable[number].offset, SEEK_SET); _musicFile.read(comp_input, _compMusicTable[number].size); - // FIXME - if _lastSong == index then i will be 0 - is the right / the desired behaviour?!? - final_size = - decompressCodec(_compMusicTable[number].codec, comp_input, comp_final, _compMusicTable[number].size, number, channels); + final_size = decompressCodec(_compMusicTable[number].codec, comp_input, comp_final, _compMusicTable[number].size); free(comp_input); - _lastSong = index; - return final_size; } -int32 Bundle::decompressVoiceSampleByName(char *name, byte *comp_final, int32 & channels) +int32 Bundle::decompressVoiceSampleByName(char *name, byte *comp_final) { int32 final_size = 0, i; @@ -364,7 +357,7 @@ int32 Bundle::decompressVoiceSampleByName(char *name, byte *comp_final, int32 & for (i = 0; i < _numVoiceFiles; i++) { if (!scumm_stricmp(name, _bundleVoiceTable[i].filename)) { - final_size = decompressVoiceSampleByIndex(i, comp_final, channels); + final_size = decompressVoiceSampleByIndex(i, comp_final); return final_size; } } @@ -372,7 +365,7 @@ int32 Bundle::decompressVoiceSampleByName(char *name, byte *comp_final, int32 & return final_size; } -int32 Bundle::decompressMusicSampleByName(char *name, int32 number, byte *comp_final, int32 & channels) { +int32 Bundle::decompressMusicSampleByName(char *name, int32 number, byte *comp_final) { int32 final_size = 0, i; if (!name) { @@ -387,7 +380,7 @@ int32 Bundle::decompressMusicSampleByName(char *name, int32 number, byte *comp_f for (i = 0; i < _numMusicFiles; i++) { if (!scumm_stricmp(name, _bundleMusicTable[i].filename)) { - final_size = decompressMusicSampleByIndex(i, number, comp_final, channels); + final_size = decompressMusicSampleByIndex(i, number, comp_final); return final_size; } } @@ -461,9 +454,9 @@ int32 Bundle::compDecode(byte *src, byte *dst) } #undef NextBit -int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 input_size, int32 index, int32 & channels) +int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 input_size) { - int32 output_size; + int32 output_size, channels; int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z; byte *src, *t_table, *p, *ptr; byte t_tmp1, t_tmp2; @@ -790,113 +783,120 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output, case 13: case 15: + if (codec == 13) { + channels = 1; + } else { + channels = 2; + } + { - uint16 firstWord; - int32 startPos; - byte sByte[4]; - int32 sDWord[4]; - int32 channel; - int32 left, origLeft; - int32 tableEntrySum; - int32 curTablePos; - int32 outputWord; - int32 imcTableEntry; - int32 destPos = 0; - int32 curTableEntry; - byte decompTable; + int32 left, startPos, origLeft, curTableEntry, destPos, esiReg; + int16 firstWord; + byte sByte1, sByte2; + int32 sDWord1, sDWord2, sDWord3, sDWord4; + int32 tableEntrySum, imcTableEntry, curTablePos, outputWord, adder; + byte decompTable, otherTablePos, var3b; + byte *readPos, *dst; uint16 readWord; - byte * readPos; - byte otherTablePos; - int32 esiReg; - byte var3b; - int32 adder; - - byte *endPos = comp_input + input_size; - + src = comp_input; - memset (comp_output, 0, 0x2000); + dst = comp_output; + if (channels == 2) { + output_size = left = 0x2000; + } else { + left = 0x1000; + output_size = 0x2000; + } firstWord = READ_BE_UINT16(src); src += 2; - assert(src < endPos); - - if (firstWord != 0) { - if (index != 0) { - startPos = 0; + memcpy(dst, src, firstWord); + dst += firstWord; + src += firstWord; + startPos = 0; + if (channels == 2) { + left = 0x2000 - firstWord; + output_size = left; } else { - memcpy(comp_output, src, firstWord); - startPos = firstWord; - uint32 tag; - ptr = src; - do { - tag = READ_BE_UINT32(ptr); ptr += 4; - } while (tag != MKID_BE('FRMT')); - channels = READ_BE_UINT32(ptr + 20); + left = 0x1000 - (firstWord >> 1); + output_size = left << 1; } - src += firstWord; - origLeft = 0x2000 - firstWord; - // At this point we are at the start of the content of the 'DATA' chunk. } else { - sByte[0] = *src++; - sDWord[0] = (int32)READ_BE_UINT32(src); + startPos = 1; + sByte1 = *(src++); + sDWord1 = READ_BE_UINT32(src); src += 4; - sDWord[1] = (int32)READ_BE_UINT32(src); + sDWord2 = READ_BE_UINT32(src); src += 4; - if (channels > 1) { - sByte[1] = *src++; - sDWord[2] = (int32)READ_BE_UINT32(src); + if (channels == 2) { + sByte2 = *(src++); + sDWord3 = READ_BE_UINT32(src); src += 4; - sDWord[3] = (int32)READ_BE_UINT32(src); + sDWord4 = READ_BE_UINT32(src); src += 4; } - startPos = 0; - origLeft = 0x2000; } - assert(src < endPos); + origLeft = left >> (channels - 1); tableEntrySum = 0; - for (channel = 0; channel < channels; channel++) { - if (firstWord == 0) { - curTablePos = sByte[channel]; - outputWord = sDWord[channel * 2 + 1]; - imcTableEntry = sDWord[channel * 2]; + for (int l = 0; l < channels; l++) { + if (startPos != 0) { + if (l == 0) { + curTablePos = sByte1; + imcTableEntry = sDWord1; + outputWord = sDWord2; + } else { + curTablePos = sByte2; + imcTableEntry = sDWord3; + outputWord = sDWord4; + } } else { + imcTableEntry = 7; curTablePos = 0; outputWord = 0; - imcTableEntry = 7; } - - left = (origLeft - 1) / (2 * (channels - channel)) + 1; - origLeft -= 2* left; - destPos = startPos + 2 * channel; - while (left--) { + left = origLeft; + destPos = l * 2; + + if (channels == 2) { + if (l == 0) { + if (left == 0) + return output_size; + left++; + left >>= 1; + } else { + if (left <= 1) + return output_size; + left >>= 1; + } + } else { + if (left == 0) + return output_size; + } + + do { curTableEntry = _destImcTable[curTablePos]; decompTable = curTableEntry - 2; var3b = (1 << decompTable) << 1; readPos = src + (tableEntrySum >> 3); - if (readPos >= endPos) { - error("readPos exceeds endPos: %d >= %d (%d, %d)!" , readPos, endPos, left, origLeft); - } - assert(readPos < endPos); readWord = (uint16)(READ_BE_UINT16(readPos) << (tableEntrySum & 7)); otherTablePos = (byte)(readWord >> (16 - curTableEntry)); tableEntrySum += curTableEntry; - esiReg = imxShortTable[curTableEntry]; - esiReg = (esiReg & otherTablePos) << (7 - curTableEntry); - esiReg += (curTablePos << 6); + esiReg = ((imxShortTable[curTableEntry] & otherTablePos) + << (7 - curTableEntry)) + (curTablePos << 6); imcTableEntry >>= (curTableEntry - 1); adder = imcTableEntry + _destImcTable2[esiReg]; if ((otherTablePos & var3b) != 0) { adder = -adder; } outputWord += adder; - if (outputWord > 0x7fff) + if (outputWord > 0x7fff) outputWord = 0x7fff; if (outputWord < -0x8000) outputWord = -0x8000; - comp_output[destPos] = (byte)(outputWord >> 8); - comp_output[destPos + 1] = (byte)(outputWord); + dst[destPos] = ((int16)outputWord) >> 8; + dst[destPos + 1] = (byte)(outputWord); switch (decompTable) { case 0: curTablePos += (signed char)imxOtherTable1[otherTablePos]; break; @@ -911,21 +911,17 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output, case 5: curTablePos += (signed char)imxOtherTable6[otherTablePos]; break; } - if (curTablePos < 0) - curTablePos = 0; if (curTablePos > 88) curTablePos = 88; - destPos += 2 * channels; - imcTableEntry = imcTable1[curTablePos]; - } - } - if (index == 0) { - output_size = 0x2000 - firstWord; - } else { - output_size = 0x2000; + if (curTablePos < 0) + curTablePos = 0; + destPos += channels << 1; + imcTableEntry = imcTable[curTablePos]; + } while (--left != 0); } } break; + default: warning("Bundle: Unknown codec %d!", (int)codec); output_size = 0; diff --git a/scumm/bundle.h b/scumm/bundle.h index 0c29e7f960..982f69ee82 100644 --- a/scumm/bundle.h +++ b/scumm/bundle.h @@ -41,7 +41,7 @@ struct BundleAudioTable { }; int32 compDecode(byte *src, byte *dst); - int32 decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 size, int32 index, int32 & channels); + int32 decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 size); CompTable *_compVoiceTable; CompTable *_compMusicTable; BundleAudioTable *_bundleVoiceTable; @@ -63,10 +63,10 @@ public: void initializeImcTables(); bool openVoiceFile(const char *filename, const char *directory); bool openMusicFile(const char *filename, const char *directory); - int32 decompressVoiceSampleByName(char *name, byte *comp_final, int32 & channels); - int32 decompressVoiceSampleByIndex(int32 index, byte *comp_final, int32 & channels); - int32 decompressMusicSampleByName(char *name, int32 number, byte *comp_final, int32 & channels); - int32 decompressMusicSampleByIndex(int32 index, int32 number, byte *comp_final, int32 & channels); + int32 decompressVoiceSampleByName(char *name, byte *comp_final); + int32 decompressVoiceSampleByIndex(int32 index, byte *comp_final); + int32 decompressMusicSampleByName(char *name, int32 number, byte *comp_final); + int32 decompressMusicSampleByIndex(int32 index, int32 number, byte *comp_final); int32 getNumberOfMusicSamplesByIndex(int32 index); int32 getNumberOfMusicSamplesByName(char *name); }; diff --git a/scumm/sound.cpp b/scumm/sound.cpp index 3a8fd9c9c5..d1a2e97047 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -1050,7 +1050,7 @@ void Sound::bundleMusicHandler(Scumm * scumm) { ptr = _musicBundleBufOutput; for (k = 0, l = _currentSampleBundleMusic; l < num; k++) { - length = _scumm->_bundle->decompressMusicSampleByName(_nameBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic)), _bundleSampleChannels); + length = _scumm->_bundle->decompressMusicSampleByName(_nameBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic))); _offsetSampleBundleMusic += length; if (l == 0) { @@ -1169,13 +1169,13 @@ int Sound::playBundleSound(char *sound) { strcpy(name, sound); strcat(name, ".IMX"); ptr = (byte *)malloc(1000000); - if (_scumm->_bundle->decompressVoiceSampleByName(name, ptr, channels) == 0) { + if (_scumm->_bundle->decompressVoiceSampleByName(name, ptr) == 0) { delete ptr; return -1; } } else { ptr = (byte *)malloc(1000000); - if (_scumm->_bundle->decompressVoiceSampleByName(sound, ptr, channels) == 0) { + if (_scumm->_bundle->decompressVoiceSampleByName(sound, ptr) == 0) { delete ptr; return -1; } |