Marian's A-pac

From MultimediaWiki
Jump to navigation Jump to search

This is a simple lossless audio codec that uses prediction and fixed bit fields coding in very small blocks.

File format

 4 bytes - "APAC"
 4 bytes - file size minus 8 bytes
 4 bytes - "PROF"
 4 bytes - "NAD " (chunk for the original file headers)
 4 bytes - chunk size
 N bytes - e.g. RIFF WAVE header up to 'data' chunk
 4 bytes - "PFRT" (packed audio format chunk)
 4 bytes - chunk size
 2 bytes - unknown
 2 bytes - number of channels
 4 bytes - sampling rate
 2 bytes - source format TwoCC
 2 bytes - bits per sample
 4 bytes - probably CRC
 N bytes - zero-terminated original file name
 4 bytes - "PAD " (packed audio data chunk)
 4 bytes - chunk size
 N bytes - packed audio

Compression algorithm

Audio is packed as small blocks (8 samples by default) and the second derivative of the prediction (the change from the last difference between predicted and actual sample) is coded as bit fields of fixed size that may change between blocks. Blocks have the following header:

 0   - no changes in parameters
 100 - decrease bit length by one
 101 - increase bit length by one
 110 - read 5-bit new bit length
 111 - read 4-bit new block length and read the header again (for possible bit length change)

Overall decoding goes like this:

 last_sample = 0;
 last_delta = 0;
 bit_length = bits_per_sample; // 8 or 16
 block_length = 8;
 while (data left) {
   mode = get_code();
   switch (mode) {
   case "0": break;
   case "100": bit_length--; break;
   case "101": bit_length++; break;
   case "110": bit_length = get_bits(5); break;
   case "111": block_length = get_bits(4); continue;
   }
   
   for (i = 0; i < block_length; i++) {
     val = get_bits(bit_length);
     delta = (val & 1) ? ~(val >> 1) : (val >> 1);
     delta += last_delta;
     sample = last_sample + delta;
     last_delta = delta;
     last_sample = sample;
   }
 }