ACIDCAT . FILE FORMAT REFERENCE

Tracker Module Anatomy

MOD . XM . S3M . ITProTracker / FT2 / ST3 / Impulse
rev 2026.07
MOD magic @ 1080
XM "Extended Module: "
S3M "SCRM" @ 0x2C
IT "IMPM"

A tracker module is a small filesystem pretending to be a song: a header, a pattern order, the pattern data, then the instrument samples, all in one file. The three formats differ in signature and rigidity but share that shape. MOD has no leading magic at all; the only reliable tell is four bytes at offset 1080, and the audio location is computed, not stored. XM opens with the string "Extended Module: " and a self-describing header you must walk block by block. S3M hides its signature entirely — the "SCRM" magic sits 44 bytes in, after the title — and reaches its instruments and patterns through DOS paragraph pointers, a 16-bit value shifted left four. IT opens with "IMPM" and, uniquely, stores explicit on-disk pointer tables: one offset per instrument, sample, and pattern. The record drawn below is a real IT IMPS sample header; its sample pointer is an absolute file offset to the PCM, the pointer acidcat follows and carves. Hover any field to light its bytes; click a field with a + to open its table. Color marks kind (see the key).

the four formats

Same skeleton -- header, order, patterns, samples -- four ways of laying it out. acidcat maps all four down to the byte offset of every embedded sample, so each is carveable.

ProTracker MOD.mod . no signature

The oldest and the trickiest to detect. Everything before offset 1080 is fixed by position: a 20-byte title, 31 sample descriptors of 30 bytes each, a song length and restart byte, then a 128-entry order table. The audio location is stored nowhere; it is computed from the number of patterns (one greater than the highest index in the order table) times the pattern size (64 rows x channels x 4 bytes). That layout, and the offset-1080 tag, belong to the 31-sample format only: the original 15-sample Soundtracker MOD had neither, its patterns starting at offset 600 (0x258) with no magic anywhere -- the genuinely headerless case a detector falls back to heuristics for.

detection4-byte magic at offset 1080: M.K. (4ch, standardly read as coders Mahoney & Kaktus), M!K! (>64 patterns), 6CHN / 8CHN / 16CH (wider), FLT4 / FLT8 (Startrekker)
15-sample MODthe original Soundtracker: no 1080 tag at all, header 480 bytes shorter, patterns at 0x258 -- confirmed only by heuristics
sample descriptor30 bytes: name[22] . length(u16 BE, in words) . finetune . volume . loop start/len
finetunelow nibble only, signed -8..+7, each step 1/8 semitone (indexes an alternate period table)
loop lengthwords like length; a value of 1 (2 bytes) is the "no loop" sentinel, not a 2-byte loop
gotchalengths are in words, so double them for bytes; samples are signed 8-bit PCM
FastTracker II XM.xm . self-describing

Opens with "Extended Module: ", a module name, a tracker string, a version word, and a header whose size is a u32 field. From there it is a walk, not a fixed map: pattern blocks announce their own header and packed-data lengths, and instrument blocks announce their own size and sample count. To reach the last instrument's samples you traverse every pattern and every preceding instrument.

signature"Extended Module: " (17 bytes) at offset 0
0x1A markera DOS EOF byte at offset 37, after the 20-byte module name and before the tracker string -- so TYPE stops cleanly
headersong length, channels, patterns, instruments, tempo/BPM, 256-byte order table
samplesdelta-encoded PCM; acidcat resolves each sample's byte offset by walking the blocks
ScreamTracker 3 S3M.s3m . buried magic . parapointers . drawn below

ScreamTracker 3's format is the odd one out on detection: there is no signature at offset 0. The file opens with a 28-byte title, and the "SCRM" magic sits at offset 0x2C — you confirm an S3M by looking 44 bytes in. The header (below) then gives the counts, a file-format flag that decides signed vs unsigned samples, and the tracker version that wrote it. To reach an instrument or pattern, S3M uses parapointers: a 16-bit value you shift left four (multiply by 16) to get a byte offset — DOS paragraph addressing, so a two-byte pointer spans a one-megabyte file. The sample record's own memseg is a further parapointer to the PCM.

detection"SCRM" at offset 0x2C (not 0); byte 0x1D = 16 marks an ST3 module
gotchaflag at 0x2A: 1 = signed, 2 = unsigned PCM -- most ST3 modules are unsigned, so read it or the audio inverts
parapointersins / pat tables and the sample memseg are u16 paragraphs; byte offset = value << 4
Impulse Tracker IT.it . pointer tables . drawn below

The richest. After the "IMPM" header and the order list come three explicit tables: one 32-bit offset per instrument, sample, and pattern. These are absolute file offsets, a tiny on-disk filesystem. Following a sample-table entry lands on an IMPS sample header (below), whose sample pointer at +72 is a further absolute offset to the PCM. IT is a two-level pointer structure, and acidcat annotates both levels as followable xrefs, flagging one that dangles past EOF.

offset tablesins / smp / pat pointers, u32 absolute file offsets -- acidcat follows them (the x key in the TUI)
IMPS record80 bytes: magic, name, length, C5 speed, flags, and the sample pointer
sample data8/16-bit, mono/stereo, optionally IT-compressed; the pointer names where it lives
what acidcat reads

Header, pattern order, and every embedded sample at its real byte offset -- so a sample is a carveable region, and IT's pointer tables are followable. Decoding XM/IT delta or IT compression to playable audio is out of scope; this maps structure and extracts.

inspect + carvetracker
readtitle/tracker/version, channel and pattern counts, tempo, and the sample list
byte offseteach sample carries its resolved range; carve --offset lifts the raw PCM out
IT pointersoffset-table entries and the IMPS sample pointer are xrefs; the TUI follows them with x
MOD detectionno leading magic, so acidcat confirms MOD from disk by the offset-1080 tell