WavArc

From MultimediaWiki
Jump to navigation Jump to search
  • Original link: WavArc
  • Extension: .wa
  • Developer: Dennis Lee

WA or WavArc is a program for manipulating archives of several compressed audio files. There are several audio compression formats employed.

Archive format

WA files do not have any special headers and contain a series of archive entries with the following header (all values are little-endian):

 1 byte - original filename length
 N bytes - original filename
 1 byte - should be in 0-5 range
 4 bytes - compression method name
 4 bytes - original file size
 4 bytes - compressed file size
 4 bytes - file timestamp (DOS format)
 4 bytes - CRC32 (Ethernet one, with 0xedb88320 polynomial)
 M bytes - the original WAV header (parsed by WA to get the audio parameters)

Known compression methods (actually only the digit matters):

  • 0CPY
  • 1DIF
  • 2SLP
  • 3NLP
  • 4ALP
  • 5ELP

The first one is simple copy, the others are based on LPC and Rice codes (method 5 may employ arithmetic coding as well). All methods (beside the copy, of course) split audio data into short blocks and may apply different compression to them. This is signalled by the block type.

Rice codes can be signed or unsigned. Unsigned Rice codes (or rice(k)) are represented as a run of zero bits plus additional k bits. Signed Rice codes (or rice_s(k)) are unsigned Rice codes mapped as 0, -1, 1, -2, 2... Bitstream is big-endian MSB first.

Compression method 1

Audio is split into interleaved chunks and have the same fixed prediction modes as Shorten. For stereo sound there's an additional flag between left and right channel blocks signalling whether right channel is coded as the difference to the left channel or not. Block types are signalled with rice(1) values, normal block size is 256 samples but it can be set to a lower value in block type 7.

Data is coded with Rice codes using a fixed parameter k transmitted before block data (for types 0-3). For 8-bit audio it's rice(1), for 16-bit audio it's rice(2). Delta values are transmitted as rice_s(k + 1).

Block types:

  • 0 - samples have no prediction;
  • 1 - samples are coded as the difference to the previous sample;
  • 2 - prediction is src[-1] * 2 - src[-2];
  • 3 - prediction is src[-1] * 3 - src[-2] * 3 + src[-3];
  • 4 - zero block;
  • 5 - fill block with constant 8- or 16-bit value (stored as unsigned);
  • 6 - read rice(2) shift for data samples and decode no data;
  • 7 - read new 8-bit block size and decode no data;
  • 8 - end of file

Compression methods 2-4

This is a development of compression method 1, now with arbitrary LPC filters, more block types and the default block size set to 570 samples. Block types 1-9 map to block types of 0-8 of compression method 1 except that block size is transmitted as rice(8) block size (it should be no more than 570). Block type 0 is a new LPC coding.

Block type 0:

 rice(2) - filter order (<= 70)
 Norder x rice_s(2) - filter coefficients
 Nsamples x rice_s(k + 1) - deltas

Sample prediction is performed as ((sum_(0..Norder) filter[i] * src[-(i + 1)]) + 15) >> 4.

Compression method 5

This is also a development of the previous compression methods, now with arithmetic coding for deltas as an alternative. Another feature is splitting LPC-predicted data in two parts, initial one with the same length as LPC filter and the rest. The second part is LPC predicted (in the same way as in compression method 4) using zeroes for initial sample history, the first part uses some fixed prediction.

Data coding order is still the same: Rice code parameter for modes 0-7, LPC filter for the modes with LPC. Modes 13-20 are coded with static arithmetic coding described below (modes 0-7 use Rice codes as before).

Block modes (residue coding is described above, only restoration part is mentioned):

  • 0/13 - LPC prediction with no split;
  • 1/14 - LPC with previous sample prediction for the initial samples;
  • 2/15 - LPC with src[-1] * 2 - src[-2] prediction for the initial samples;
  • 3/16 - predict from previous sample
  • 4/17 - no prediction
  • 5/18 - prediction is src[-1] * 2 - src[-2];
  • 6/19 - LPC with src[-1] * 3 - src[-2] * 3 + src[-3] prediction for the initial samples;
  • 7/20 - prediction is src[-1] * 3 - src[-2] * 3 + src[-3];
  • 8 - zero block
  • 9 - fill block
  • 10 - set shift
  • 11 - set block length
  • 12 - EOF

Arithmetic coding data has 12-bit prefix specifying compressed data size in bits. That data starts with the symbol frequencies table and followed by the arithmetic coder data. Frequencies are stored as ranges in form (start value, end value, probabilites for start, start+1,..., end). Zero start value except for the first pair means end of table. Model values represent deltas in -128..127 range.

Arithmetic coder is the classic one with 16-bit range.

Initialisation:

 high = 0xFFFF;
 low = 0;
 value = get 16 bits from the stream (MSB first)

Symbol decoding:

 model_range = model[256]; // total cumulative frequency
 ac_range = high - low + 1;
 helper = ((range - 1) * model_range + (model_range - 1)) / range;
 idx = index of the model symbol containing that entry
 high = low + range * model[idx + 1] / model_range - 1;
 low += range * model[idx] / model_range;
 return idx - 128;

Normalisation:

 for (;;) {
   if ((high & 0x8000) ^ (low & 0x8000) != 0) {
     if ((high & 0x4000) == 0 && (low & 0x4000) != 0)
       return;
     value ^= 0x8000;
     low &= 0x3FFF;
     high |= 0x4000;
   }
   low <<= 1;
   high = high * 2 + 1;
   value = value * 2 + get_bit();
 }