|
|
Line 67: |
Line 67: |
| | | |
| Delta=StepTable[lIndexLeft]>>3; | | Delta=StepTable[lIndexLeft]>>3; |
| if (Code & 4) | | if (Code |
| Delta+=StepTable[lIndexLeft];
| |
| if (Code & 2)
| |
| Delta+=StepTable[lIndexLeft]>>1;
| |
| if (Code & 1)
| |
| Delta+=StepTable[lIndexLeft]>>2;
| |
| if (Code & 8) // sign bit
| |
| lCurSampleLeft-=Delta;
| |
| else
| |
| lCurSampleLeft+=Delta;
| |
|
| |
| // clip sample
| |
| if (lCurSampleLeft>32767)
| |
| lCurSampleLeft=32767;
| |
| else if (lCurSampleLeft<-32768)
| |
| lCurSampleLeft=-32768;
| |
|
| |
| lIndexLeft+=IndexAdjust[Code]; // adjust index
| |
|
| |
| // clip index
| |
| if (lIndexLeft<0)
| |
| lIndexLeft=0;
| |
| else if (lIndexLeft>88)
| |
| lIndexLeft=88;
| |
|
| |
| Code=LONIBBLE(Input); // get LOWER 4-bit nibble
| |
|
| |
| Delta=StepTable[lIndexRight]>>3;
| |
| if (Code & 4)
| |
| Delta+=StepTable[lIndexRight];
| |
| if (Code & 2)
| |
| Delta+=StepTable[lIndexRight]>>1;
| |
| if (Code & 1)
| |
| Delta+=StepTable[lIndexRight]>>2;
| |
| if (Code & 8) // sign bit
| |
| lCurSampleRight-=Delta;
| |
| else
| |
| lCurSampleRight+=Delta;
| |
|
| |
| // clip sample
| |
| if (lCurSampleRight>32767)
| |
| lCurSampleRight=32767;
| |
| else if (lCurSampleRight<-32768)
| |
| lCurSampleRight=-32768;
| |
|
| |
| lIndexRight+=IndexAdjust[Code]; // adjust index
| |
|
| |
| // clip index
| |
| if (lIndexRight<0)
| |
| lIndexRight=0;
| |
| else if (lIndexRight>88)
| |
| lIndexRight=88;
| |
|
| |
| // Now we've got lCurSampleLeft and lCurSampleRight which form one stereo
| |
| // sample and all is set for the next input byte...
| |
| Output((SHORT)lCurSampleLeft,(SHORT)lCurSampleRight); // send the sample to output
| |
|
| |
| HINIBBLE and LONIBBLE are higher and lower 4-bit nibbles:
| |
| #define HINIBBLE(byte) ((byte) >> 4)
| |
| #define LONIBBLE(byte) ((byte) & 0x0F)
| |
| Note that depending on your compiler you may need to use additional nibble
| |
| separation in these defines, e.g. ''(((byte) >> 4) & 0x0F)''.
| |
| | |
| StepTable and IndexAdjust are the tables given in the next section of
| |
| this document.
| |
| | |
| Output() is just a placeholder for any action you would like to perform for
| |
| decompressed sample value.
| |
| | |
| Of course, this decompression routine may be greatly optimized.
| |
| | |
| As to mono sound, it's just analoguous:
| |
| | |
| Code=HINIBBLE(Input); // get HIGHER 4-bit nibble
| |
|
| |
| Delta=StepTable[lIndex]>>3;
| |
| if (Code & 4)
| |
| Delta+=StepTable[lIndex];
| |
| if (Code & 2)
| |
| Delta+=StepTable[lIndex]>>1;
| |
| if (Code & 1)
| |
| Delta+=StepTable[lIndex]>>2;
| |
| if (Code & 8) // sign bit
| |
| lCurSample-=Delta;
| |
| else
| |
| lCurSample+=Delta;
| |
|
| |
| // clip sample
| |
| if (lCurSample>32767)
| |
| lCurSample=32767;
| |
| else if (lCurSample<-32768)
| |
| lCurSample=-32768;
| |
|
| |
| lIndex+=IndexAdjust[Code]; // adjust index
| |
|
| |
| // clip index
| |
| if (lIndex<0)
| |
| lIndex=0;
| |
| else if (lIndex>88)
| |
| lIndex=88;
| |
|
| |
| Output((SHORT)lCurSample); // send the sample to output
| |
|
| |
| Code=LONIBBLE(Input); // get LOWER 4-bit nibble
| |
| // ...just the same as above for lower nibble
| |
| | |
| Note that HIGHER nibble is processed first for mono sound and corresponds to
| |
| LEFT channel for stereo.
| |
| | |
| == IMA ADPCM Tables ==
| |
| | |
| LONG IndexAdjust[]=
| |
| {
| |
| -1,
| |
| -1,
| |
| -1,
| |
| -1,
| |
| 2,
| |
| 4,
| |
| 6,
| |
| 8,
| |
| -1,
| |
| -1,
| |
| -1,
| |
| -1,
| |
| 2,
| |
| 4,
| |
| 6,
| |
| 8
| |
| };
| |
|
| |
| LONG StepTable[]=
| |
| {
| |
| 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
| |
| };
| |
| | |
| == HNM Movie Soundtracks ==
| |
| | |
| .HNM movie hasn't got soundtrack inside the HNM movie file itself.
| |
| However the soundtrack for HNM movie is a stand-alone APC file, as a rule,
| |
| with the same file title. The format of such APC soundtracks is just the
| |
| same as described above.
| |
| | |
| == APC Audio Files in BF Archives ==
| |
| | |
| When stored in .BF resources, APC audio files are stored "as is", without
| |
| compression or encryption. That means if you want to play/extract APC
| |
| file from the BF resource you just need to search for (''szID'') id-string
| |
| ("CRYO_APC") and read APC header starting at the beginning position of
| |
| found id-string. This will give you starting point of the file and the size
| |
| of the file will be the sum of APCHeader size and the compressed audio stream
| |
| size correspondent to (''dwOutSize'') header field (that is, (''dwOutSize'') for
| |
| stereo stream and (''dwOutSize)/2'' for mono stream).
| |
| | |
| == ZIK Audio Files ==
| |
| | |
| In the game Chine music is in ZIK files. Most of them are simple RAW files:
| |
| 16-bit signed stereo 22050 Hz (no header), except for only one which is a
| |
| regular WAV file. So, you can just load and play those ZIKs as RAWs (except
| |
| for one which is WAV).
| |
| | |
| ==PC Games Using CRYO APC==
| |
| *[http://www.mobygames.com/game/windows/atlantis-the-lost-tales Atlantis: The Lost Tales]
| |
| *[http://www.mobygames.com/game/windows/sacred-amulet Aztec: The Curse in the Heart of the "City of Gold" a.k.a Sacred Amulet]
| |
| *[http://www.mobygames.com/game/windows/egypt-ii-the-heliopolis-prophecy Egypt II]
| |
| *[http://www.mobygames.com/game/odyssey-the-search-for-ulysses Odyssey: The Search For Ulysses]
| |
| *[http://www.mobygames.com/game/china-the-forbidden-city China: The Forbidden City]
| |
| * Atlantis 2
| |
| * Zero Zone a.k.a Onderzoek 2098 [http://www.mobygames.com/game/windows/zero-zone] [http://en.wikipedia.org/wiki/ZeroZone]
| |
| | |
| [[Category:Game Formats]]
| |