CRYO APC

From MultimediaWiki
Revision as of 11:01, 10 April 2007 by MlzIy5 (talk | contribs)
Jump to navigation Jump to search

This covers the audio format for one of the versions of CRYO's video formats.


Credit

This file comes from wotsit.org and was originally written by Valery V. Anisimovsky.

APC Audio Files

The music, sfx, speech and video (.HNM) soundtracks in some CRYO Interactive games are .APC stand-alone files. APC file has the following header:

struct APCHeader
{
 char	szID[8];
 char	szVersion[4];
 DWORD dwOutSize;
 DWORD dwSampleRate;
 LONG	lSampleLeft;
 LONG	lSampleRight;
 DWORD dwStereo;
};

szID -- ID string, which is "CRYO_APC".

szVersion -- version ID string, all files in the mentioned games have this set to "1.20". Note that this field may, in principle, vary.

dwOutSize -- number of samples in the file. May be used for song length (in seconds) calculation.

dwSampleRate -- sample rate for the file.

lSampleLeft -- the initial value for the left sample (see below).

lSampleRight -- the initial value for the right sample (see below).

dwStereo -- this seems to be boolean stereo flag: if this is not zero, the audio stream in the file is stereo (music and partly video soundtracks), otherwise it's mono (sfx, speech).

The resolution is NOT specified in the header, so the default value (16-bit) should be used.

After the APCHeader IMA ADPCM compressed sound data comes. You may find IMA ADPCM decompression scheme description further in this document.

IMA ADPCM Decompression Algorithm

During the decompression four LONG variables must be maintained for stereo stream: lIndexLeft, lIndexRight, lCurSampleLeft, lCurSampleRight and two -- for mono stream: lIndex, lCurSample. At the beginning of the file you must initialize lCurSampleLeft/Right variables to the values from APCHeader while lIndexLeft/Right are initialized to zeroes. Note that LONG here is signed.

Here's the code which decompresses one byte of IMA ADPCM compressed stereo stream. Other bytes are processed in the same way.

BYTE Input; // current byte of compressed data
BYTE Code;
LONG Delta;

Code=HINIBBLE(Input); // get HIGHER 4-bit nibble

Delta=StepTable[lIndexLeft]>>3;
if (Code