Skip to content

Instantly share code, notes, and snippets.

@aklaswad
Created January 12, 2025 04:17
Show Gist options
  • Select an option

  • Save aklaswad/f56b517033c335d2777857e0e996663a to your computer and use it in GitHub Desktop.

Select an option

Save aklaswad/f56b517033c335d2777857e0e996663a to your computer and use it in GitHub Desktop.

AMXD file analysis

This document is a personal memo summarizing the results of my own analysis of amxd file format. It was originally written around the end of 2023. Please do not expect any correctness here. A parser is now publicly available at https://github.com/Ableton/maxdevtools/tree/main/maxdiff, so please refer to that for the correct specifications and further details.


I examined the AMXD file and found it to be an uncompressed format that combines the contents of multiple files. The overall structure resembles a simple chunk-based binary file, similar to RIFF. However, perhaps due to historical reasons, it contains two different chunk styles.

File structure overview

Entire file structure are looks like RIFF format but some difference. In this note, I'll call it Global Chunks. Global chunks looks like;

  • There are no inclusion chunks such as RIFF chunks. The entire file is an array of multiple chunks.
  • Each chunk has
    • 4 byte identifier field
    • 4 byte size field as little-endian 32bit unsigned int (except this field itself and the chunk identifier)
  • Has no null padding ( I guess. Some text fields looks C-like null terminated string so there are null bytes but it seems they don't respect the even byte order.)

And, there are one more chunk series which appears in ptch chunk, which included in mx@c chunk. In this note, I call it MX Chunks or mx@c archive format. MX chunks looks like;

  • There are inclusion chunk with identifier mx@c.
  • Each chunk has
    • 4 byte identifier field
    • 4 byte size field as big-endian 32bit unsigned int (includes this field itself and the chunk identifier. it means this size will always 8 larger than (R)IFF style size value.)
  • Has null padding ( I guess. )

known global chunks

name type optional note
ampf enum aaaa, iiii or mmmm The file signature, and/or M4L plugin type field. (Ableton Max Plugin (Format or File))?
The value might be m4l plugin type
- aaaa audio effect
- iiii instrument
- mmmm MIDI effect
anno c-style null terminated string? yes annotation field which could be set via Max's project inspector
meta unknown yes Some amxd file has this meta chunk but I've never seen meaningful value here by now 🙈
ptch JSON text OR mx@c archive content(s) of the M4L plugin

mx@c archive format

mx@c archive is made up of 3 sections;

  • mx@c chunk - size info for data field
  • data field - concatenated file contents
  • dlst chunk - list of meta info for file contents

mx@c chunk

mx@c chunk is a standalone chunk but the value is for size of next data section.

size type note
4 const mx@c Must be a chunk signature
4 Int32BE const 16? May be the size of this header chunk. Maybe always 16.
4 ? const 0x00000000? Unknown null field. ( Combine with next field as 64bit bigint? 1)
4 UInt32BE size of data section (includes size of this mx@c chunk (16 bytes))

data section

This section is not chunk style. Binary stream of the concatenated files. (Almost of them are JSON text, though) It appears to be padded with null bytes, but the regularity is not clear because after this area is finished, the chunks may have odd starts. To split this stream into original files, need to decode next meta data chunks first.

dlst chunk

A collection of hierarchically structured metadata chunks for splitting and restoring archived contents. dlst chunk has children chunks called dire. Each dire chunks represent file info for archived files and have meta info as various child chunks.

chunk name content type note
dlst dire chunks directory list? data list?
dire combination of multiple chunks described below - type, fnam, sz32, of32, vers, flag and mdat. directory entry?
type ascii content type. I saw 'JSON', 'TEXT', 'gDSP' and 'WAVE' by now. There must be more variations.
fnam ascii filename
sz32 UInt32BE num of bytes of this file in data contents area
of32 UInt32BE start position of this file content, byte offset from top of mx@c chunk
vers ? Unknown - version info?
flag ? Unknown
mdat UInt32BE(Macintosh Time) Modification Date in Macintosh Time (seconds, elapsed after Jan 1, 1904)

Afterword

Although at first glance it looks like a straightforward RIFF file, it actually mixes endianness and uses Macintosh epoch dates (this is the first time I’ve ever seen it used. I figured out it was some kind of epoch time, so I worked backward from the current time to find what seemed like the origin date. When I searched for it and got a Wikipedia hit, I was as excited as when I finally solved Return of the Obra Dinn.), making the reverse-engineering of this file format feel like a great puzzle game—and I thoroughly enjoyed it. Also, I felt a long great history of Max.

Footnotes

  1. But this must be smaller than parent ptch chunk's size field which is 32bit... 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment