Marian's A-pac
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; } }