ACIDCAT . FILE FORMAT REFERENCE

GF1 Patch Anatomy

Gravis UltraSoundGF1PATCH . little-endian
rev 2026.07
magic "GF1PATCH"
endian little (x86)
container fixed headers
lineage UltraSound 1992

A .PAT file is one instrument for the Gravis UltraSound — the first mass PC wavetable card, which streamed samples from disk into its own on-board RAM. There is no chunk grid: it is a run of fixed-size headers nested four deep — a 129-byte patch header, then instrument (63 B), layer (47 B), and sample (96 B) records, each header immediately followed by its children, and the raw PCM sitting right after each sample header. Everything is little-endian (the card lived on the ISA bus of an x86 PC) — the mirror image of Kurzweil's 68k banks. The tabs open each structure, drawn byte by byte from a real factory patch. Hover a field to light its bytes, click a field with a + for its table. Color marks kind (see the key).

Where a SoundFont packs a whole bank into one file, a GUS patch is one instrument — a full General MIDI set is 100-plus separate .PAT files, loaded into the card's RAM one at a time as a song calls for them. Inside, the shape is a strict four-level nest: a patch header counts instruments; each instrument counts layers (velocity/zone splits); each layer counts samples; and each sample header is followed immediately by its raw PCM. No offsets, no tables — you walk it by adding fixed header sizes and the PCM length. The patch below is a real factory instrument, ALTOSAX.PAT.

a real patch, laid out
Patch "GF1PATCH110" 1 instrument, 3 waveforms — 129-byte header └─ Instrument #0 "Alto Sax" 1 layer — 63-byte header └─ Layer 0 3 samples — 47-byte header ├─ Sample "NoName" 7,140 B 16-bit 22321 Hz looped ├─ Sample ... ← PCM follows each header └─ Sample ... root ~E3, range A0..G4 PCM interleaved after each sample header — raw, little-endian
the UltraSound, dated
1992Advanced Gravis UltraSound — the first affordable PC card with real wavetable synthesis and on-board sample RAM (256 KB, up to 1 MB). Its GF1 chip plays up to 32 voices from RAM; instruments are .PAT patches streamed off disk.
1993GF1PATCH110 — the patch version this reference draws (v1.10). An older GF1PATCH100 exists; the magic's trailing three digits are the version.
1994DOS gaming — the GUS became the audiophile's choice for demos and MOD players. Its patch set (the ULTRASND directory) is the canonical GM-to-PAT mapping.
nowoutlived the hardware. TiMidity++, WildMIDI and DOSBox still render MIDI through GF1 patch sets — the format became a soft-synth patch standard long after the card was gone.
walk by size, not by offset. Every level is a fixed-width header carrying a child count, not a table of pointers. A reader advances by adding 129 (patch), then per instrument 63, per layer 47, per sample 96 + data_size. The PCM for a sample sits in the data_size bytes immediately after its 96-byte header — there is no separate audio region.
RAM streaming, not a bank. The GUS had no ROM voices — to make a sound it first loaded the instrument's samples into card RAM. So a patch is deliberately one instrument: a game or tracker uploads only the patches a piece needs. This is the opposite trade from a SoundFont, which carries the whole orchestra in one file and never streams.
little-endian throughout. Sizes, counts, rates and the frequency words are all little-endian — the GUS is an ISA card in an x86 PC. Read it the way you read RIFF/WAV, and the opposite way from a Kurzweil .KRZ or an E-mu .E4B, both of which are big-endian 68k machines.
size129 bytesmagic"GF1PATCH" + versiondesc60-byte ASCIIcountsinstruments / waveforms

The 129-byte file header. It opens with a 12-byte magic carrying the version, a 10-byte internal id, then a 60-byte ASCII description (the factory copyright line), and finally the small block of counts that drive the walk: how many instruments follow, and the total waveform (sample) count. The two byte maps below are the signature block and the counts block; the description between them is plain text.

signature (bytes 0x00–0x15)

Example: ALTOSAX.PAT. Hover the magic for the version split.

counts (bytes 0x52–0x5C)

The header fields at offset 82–92 that size the nest.

the version lives in the magic. The trailing digits of "GF1PATCH110" are the format version — 1.10 here, 1.00 in the oldest patches. The first 8 bytes ("GF1PATCH") identify the format; the full 12 give the exact version. The 10-byte "ID#000002" that follows is a fixed internal structure id, not a per-file value.
waveforms is the sample total. instruments (here 1) counts the top-level instruments; waveforms (here 3) is the total number of samples across all layers — a cross-check for the walk. The data_size word is the summed PCM byte total. voices and channels are card-mixing hints, not structural, and carry fixed quirk values in most factory patches.
instrument63 Blayer47 Bcountslayers, samplesnames16 / none

Between the patch header and the sample headers sit two thin framing records. An instrument (63 bytes) carries a numeric id, a 16-char name, its total size, and a layer count. A layer (47 bytes) is a velocity or key split: it carries a sample count and little else. Both are mostly reserved padding — their job is only to carry the next count down the nest. The maps are the fronts of the Instrument and Layer records from ALTOSAX.PAT.

instrument header (first 23 of 63 bytes)

Example: Instrument #0, "Alto Sax". The remaining 40 bytes are reserved.

layer header (first 7 of 47 bytes)

Example: Layer 0. Hover samples — it is the count a reader loops on.

layers are the split mechanism. A single instrument can stack multiple layers, each a full set of samples, to build velocity crossfades or key splits — the GF1 mixes the active layers. Most factory patches use one layer; the field exists so a richer instrument (a multi-velocity piano) can carry several. The samples byte in the layer is the innermost count of the nest.
header96 BPCMright aftermodes1 byte, 8 flagstuningfixed-point Hz

The sample header is where the format earns its keep: 96 bytes describing one waveform, then its raw PCM inline. It gives the data size, the loop points, the playback rate, three frequency words that set the key range and recorded pitch, an on-card 6-stage envelope, tremolo/vibrato, and the crucial modes byte whose eight bits pick 16- vs 8-bit, signed vs unsigned, and the loop behaviour. The map draws the first 60 meaningful bytes (the last 36 are reserved).

sample header (bytes 0x00–0x3B)

Example: sample "NoName" from ALTOSAX.PAT — 16-bit, looped, 22321 Hz. Hover modes for the bit flags.

the modes byte. One byte, eight independent flags — 0x01 16-bit, 0x02 unsigned, 0x04 loop-enable, 0x08 ping-pong (bidirectional loop), 0x10 reverse, 0x20 sustain, 0x40 envelope, 0x80 clamped-release. Here 0x67 = 16-bit + unsigned + loop + sustain + envelope. Bits 0 and 1 set the PCM width and sign; getting either wrong turns the audio to noise.
frequencies are milliHertz. low_frequency, high_frequency and root_frequency are fixed-point Hz × 1000. Here root = 164813 = 164.813 Hz (~E3, the pitch the sample was recorded at), spanning 26.986 Hz (~A0) to 399.765 Hz (~G4) — the key range this sample covers before the next one takes over. The GF1 pitches each key by ratio from root_frequency, not from a MIDI note number.
loop points are byte offsets. loop_start and loop_end are offsets into this sample's PCM in bytes, with the fractions byte giving a sub-byte remainder for fine loop tuning — not sample indices. For a 16-bit sample the reader rounds them to even byte boundaries. Loop is only honoured when modes & 0x04 is set; here it is, so playback loops over [5998, 7082].