- audio.fmt structure
- audio.dat structure
- Retail archive facts
- Exporting a sound to WAV
- Editing
- Reference (names & addresses)
Final Fantasy VIII’s sound effects live in two files under Data/Sound/. audio.dat holds the actual waveforms (MS-ADPCM, 4-bit), and audio.fmt is the locator/format table describing each sound’s position and format inside the dat.
audio.fmt structure
All values little-endian.
| Offset | Size | Description |
|---|---|---|
| 0x00 | 2 bytes | soundCount |
| 0x02 | varies | soundCount + 1 sound entries (see below) |
The number of entries is soundCount + 1. Entry 0 is a blank placeholder (a 38-byte all-zero entry), so the first real sound is entry 1 at offset 0x28. Reading soundCount as a 4-byte value yields the same number because the high two bytes fall inside that zero entry.
Each entry is variable-length: 70 bytes for an ADPCM sound (cbSize = 32) or 38 bytes for a blank/PCM entry (cbSize = 0). Fields:
| Offset | Size | Description |
|---|---|---|
| 0x00 | 4 bytes | dataLength — size of the waveform in audio.dat |
| 0x04 | 4 bytes | dataOffset — offset of the waveform in audio.dat |
| 0x08 | 1 byte | bufferFlags — DirectSound buffer flag; 1 = looping, 0 = one-shot |
| 0x09 | 3 bytes | Padding (0) |
| 0x0C | 4 bytes | bufferReadCursor (DirectSound buffer state, normally 0) |
| 0x10 | 4 bytes | bufferWriteCursor (DirectSound buffer state, normally 0) |
| 0x14 | 18 bytes | Microsoft WAVEFORMATEX (wFormatTag, nChannels, nSamplesPerSec, nAvgBytesPerSec, nBlockAlign, wBitsPerSample, cbSize) |
| 0x26 | cbSize bytes | Extra format bytes. For MS-ADPCM (wFormatTag = 2, cbSize = 32): samples-per-block (2), coefficient count (2, always 7), then the 28-byte standard ADPCM coefficient set |
The first 20 bytes (0x00–0x14) are the game’s own locator/buffer record; the rest is a standard WAVEFORMATEX (+ ADPCM tail) that can be copied verbatim into a WAV fmt chunk.
audio.dat structure
audio.dat is a raw concatenation of the waveform bodies. Sound i occupies [dataOffset, dataOffset + dataLength). There is no per-sound header in the dat — the engine locates every sound purely from audio.fmt’s offset/length, so on a rebuild the waveforms may be packed in any order/alignment as long as audio.fmt matches.
Retail archive facts
The shipped audio.fmt holds 2791 entries (soundCount = 2790), of which 1544 are valid sounds (the rest are blank placeholders). Every valid sound is MS-ADPCM, 44100 Hz, mono. The valid entries’ dataOffset + dataLength values tile audio.dat exactly up to its full size (~105 MB), confirming the layout.
Sound entries are addressed by their index (0-based) in audio.fmt. The battle actor sound table stores world-sound ids, which GetSoundID_ForWorld converts to these archive indices. For example, world id 400000 becomes archive entry #1230; the world id is not itself the archive index.
Exporting a sound to WAV
A standalone WAV is built by wrapping the entry’s format and its audio.dat bytes:
"RIFF" + u32(dataLength + 38 + cbSize) + "WAVE"
"fmt " + u32(18 + cbSize) + WAVEFORMATEX(18) + extra(cbSize)
"data" + u32(dataLength) + <dataLength bytes from audio.dat>
Both PCM and MS-ADPCM WAVs round-trip this way. (Note: FF8SND/ff8-sound-remixed use dataLength + 36 for the RIFF size, which is two bytes short because they still emit the full 18-byte WAVEFORMATEX; + 38 is the correct size for strict WAV parsers.)
Editing
The Julia sound editor in FF8UltimateEditor reads audio.fmt/audio.dat, plays and exports sounds to WAV, replaces a sound from a WAV (PCM or MS-ADPCM), and rebuilds both files (repacking audio.dat and rewriting audio.fmt offsets). It also shows which battle actor uses each sound via the battle actor sound table.
Opening audio.fmt in Julia automatically reads audio.dat from the same folder. In Audio archive, select the resolved archive index and click Play: G-Soldier’s world id 400000 is sound #1230 here. The category groups used by the conversion do not refer to separate audio files; the samples are stored in this same archive.
Julia’s Actor sound IDs tab edits FFNx’s battle_actor_sounds.bin, a table of references rather than audio samples. The main Import selects audio.fmt and audio.dat on either tab; Import complementary opens the BIN side file. Save writes the archive on Audio archive and the BIN on Actor sound IDs. With the archive loaded, select a slot and use Play slot to preview the resolved sound directly. See world-id conversion and the FFNx table format for the category bases, worked examples and file layout.
Reference (names & addresses)
FF8_EN.exe:
| Name | Address | Role |
|---|---|---|
GetSoundID_ForWorld | 0x46B120 | Maps a world-sound id to an audio.fmt index |
PlaySound | 0x4699A0 | Plays an audio.fmt entry through DirectSound |