A Monkey’s Audio file starts with the signature MAC and a 16-bit version: the
program’s version times 1000, so 3990 means version 3.99. All numbers are little-endian.
The layout changed in version 3.98, so a reader chooses a path from the version.
Signature and version
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | char[4] | cID | MAC , with a trailing space |
| 4 | 2 | uint16 | nVersion | Version × 1000. Below 3980 the old header follows; from 3980 the descriptor does |
The SDK allows other data before the signature, so that files with an ID3v2 tag still work, but advises against adding it. The offsets below count from the signature, and FFmpeg calls the distance to it the junk length.
FFmpeg accepts versions 3800 to 3990. Files below 3800 are not described by the sources used here.
Descriptor (version 3980 and later)
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | char[4] | cID | MAC |
| 4 | 2 | uint16 | nVersion | Version × 1000 |
| 6 | 2 | uint16 | Padding | Not used |
| 8 | 4 | uint32 | nDescriptorBytes | Size of the descriptor; 52 here. If larger, skip the extra bytes |
| 12 | 4 | uint32 | nHeaderBytes | Size of the header that follows; 24 here |
| 16 | 4 | uint32 | nSeekTableBytes | Size of the seek table |
| 20 | 4 | uint32 | nHeaderDataBytes | Size of the original file’s data before its audio (the WAV header) |
| 24 | 4 | uint32 | nAPEFrameDataBytes | Size of the compressed frames, low 32 bits |
| 28 | 4 | uint32 | nAPEFrameDataBytesHigh | The same, high 32 bits |
| 32 | 4 | uint32 | nTerminatingDataBytes | Size of the original file’s data after its audio, not counting tags |
| 36 | 16 | uint8[16] | cFileMD5 | MD5 hash of the file |
Header (version 3980 and later)
The header follows the descriptor, usually at offset 52.
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 2 | uint16 | nCompressionLevel | Compression level |
| 2 | 2 | uint16 | nFormatFlags | Format flags |
| 4 | 4 | uint32 | nBlocksPerFrame | Audio blocks (samples per channel) in a frame |
| 8 | 4 | uint32 | nFinalFrameBlocks | Blocks in the last frame |
| 12 | 4 | uint32 | nTotalFrames | Number of frames |
| 16 | 2 | uint16 | nBitsPerSample | Bits per sample |
| 18 | 2 | uint16 | nChannels | Channels |
| 20 | 4 | uint32 | nSampleRate | Sample rate in hertz |
The total number of blocks is
nFinalFrameBlocks + nBlocksPerFrame × (nTotalFrames − 1).
Old header (before version 3980)
Older files have one 32-byte header, then optional fields controlled by its flags.
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | char[4] | cID | MAC |
| 4 | 2 | uint16 | nVersion | Version × 1000 |
| 6 | 2 | uint16 | nCompressionLevel | Compression level |
| 8 | 2 | uint16 | nFormatFlags | Format flags |
| 10 | 2 | uint16 | nChannels | 1 or 2 |
| 12 | 4 | uint32 | nSampleRate | Sample rate in hertz |
| 16 | 4 | uint32 | nHeaderBytes | Bytes of WAV header stored after the MAC header |
| 20 | 4 | uint32 | nTerminatingBytes | Bytes stored after the audio |
| 24 | 4 | uint32 | nTotalFrames | Number of frames |
| 28 | 4 | uint32 | nFinalFrameBlocks | Blocks in the last frame |
| 32 | 4 | uint32 | nPeakLevel | Only with flag 4 |
| 32 or 36 | 4 | uint32 | nSeekElements | Only with flag 16: entries in the seek table. Without it there is one per frame |
Values the old header implies
| Value | Rule |
|---|---|
| Bits per sample | 8 with flag 1, 24 with flag 8, otherwise 16 |
| Blocks per frame | 294,912 (73,728 × 4) from version 3950 |
| 73,728 from version 3900, or from 3800 at compression level 4000 or above | |
| 9,216 otherwise |
Format flags
| Value | Name | Meaning |
|---|---|---|
| 1 | MAC_FORMAT_FLAG_8_BIT | 8-bit samples (obsolete) |
| 2 | MAC_FORMAT_FLAG_CRC | Uses CRC-32 error detection (obsolete) |
| 4 | MAC_FORMAT_FLAG_HAS_PEAK_LEVEL | A 32-bit peak level follows the header (obsolete) |
| 8 | MAC_FORMAT_FLAG_24_BIT | 24-bit samples (obsolete) |
| 16 | MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS | The number of seek elements follows the peak level |
| 32 | MAC_FORMAT_FLAG_CREATE_WAV_HEADER | No WAV header is stored; create one on decompression |
The program’s history records later additions: more than two channels (4.86), 32-bit encoding, floating-point audio (10.00), and AIFF, W64 and CAF input. The flag bits that mark these in current files could not be confirmed from any readable public source.
Compression levels
| Value | Name |
|---|---|
| 1000 | Fast |
| 2000 | Normal |
| 3000 | High |
| 4000 | Extra high |
| 5000 | Insane (FFmpeg rejects this level below version 3930) |
Each level selects the filters the decoder runs.
Worked example
The start of a version 3.99 file at Normal level, 16-bit stereo at 44,100 Hz:
4D 41 43 20 MAC
96 0F nVersion 3990
00 00 padding
34 00 00 00 nDescriptorBytes 52
18 00 00 00 nHeaderBytes 24
… sizes and the MD5 (offsets 16 to 51)
D0 07 nCompressionLevel 2000 (offset 52)
…