Cluster layout

The cluster lives in SCUS_942.54 (the game's main executable) at RAM 0x8007B380 (file offset 0x6BB80):

Offset Bytes Meaning
0x8007B380 12 bytes Per-extension flag/mode metadata table: 00 01 FF FF FF FF 00 00 00 02 00 00.
0x8007B38C "sound\" Path prefix for streaming-asset loads.
0x8007B394 ".spk" SPU sample bank.
0x8007B39C ".LZS" Compressed wrapper (per-file).
0x8007B3A4 8 bytes Not sound data. The per-character equipment-swap selector bytes (3 equip-condition offsets at 0x8007B3A4 + 3 group indices at 0x8007B3A8) read by the graphics-side FUN_8001EBEC - see character-mesh. Adjacent to the path cluster in BSS but unrelated to it.
0x8007B3AC "bse.dat" Master sound-bank file name (loaded once at sound-init).
0x8007B3B4 ".dpk" Per-scene sound pack - the format FUN_8001FA88 loads.
0x8007B3BC ".MAP" Sound bank map (PsyQ SoundArtist output).
0x8007B3C4 ".PCH" Patch / instrument data (PsyQ output).
0x8007B3CC ".LZS" Duplicate, fallback.
0x8007B3D4 ".pac" Per-scene generic pack.
0x8007B3DC "STR" Streaming audio (raw PSX .STR containers).

Consumers

Two SCUS functions touch the cluster (located via ghidra/scripts/find_sound_path_builders.py):

Function Role Touch points
FUN_8001FA88 Sound subsystem init / .dpk loader. Allocates a 0x1800-byte buffer at _DAT_8007B8D0. Loads bse.dat via the path-based opener. Then assembles h:\main\bg\domepack\<name>.dpk (template at 0x800105C8 + extension at 0x8007B3B4) and opens it. 0x8007B3AC (bse.dat), 0x8007B3B4 (.dpk)
FUN_8001FC00 Streaming-asset loader. Builds paths under the sound\ prefix; the XA / .pac / STR consumer. 0x8007B38C (sound\)

Trap: FUN_8001EBEC looks like a third consumer (it reads _DAT_8007B824 + the tables at 0x8007B3A4/0x8007B3A8) but is not a sound function - it is the character-TMD equipment-conditional group-transform swap (it reads the loaded battle-character TMD pointers from DAT_8007C018[_DAT_8007B824 + 0..2], where _DAT_8007B824 is the party base index, and copies group transforms). The 0x8007B3A4/0x8007B3A8 bytes are its per-character selector tables, not sound-extension descriptors. See character-mesh.

Dev-build vs retail-build paths

Both FUN_8001FA88 and FUN_8001FC00 carry a _DAT_8007B8C2 (debug-flag) carve-out:

  • Dev branch (_DAT_8007B8C2 != 0) loads sound data via PROT indices. FUN_8001FA88's dev branch loads index 0x37A (= sound_data2) plus param_1 + 5 for per-scene variations, via the index-based loader (FUN_8003EB98).
  • Retail branch (_DAT_8007B8C2 == 0) loads via dev-style paths through the path-based opener (FUN_8003E6BC), which resolves h:\main\bg\domepack\… into the appropriate PROT entry through the CDNAME-driven name map.

Both paths land at the same files; only the indirection differs. The same dev/retail split appears in FUN_800255B8, so it's a pattern that repeats across asset-loading subsystems.

The .dpk / sound_data2 payload is a VAB + SEQ bundle

The sound-side chunk payload is a VAB followed by a SEQ, not a novel .MAP/.PCH/.spk layout:

Chunk typePayloadMagic
0VAB header sectionpBAV (0x5641_4270 LE)
1VAB sample section (SPU-ADPCM / VAG waveform pool)- (raw samples)
2SEQ (the stream terminator)pQES

The decisive invariant: type-0 + type-1 reconstitute one contiguous VAB whose header total_size (+0x0C) equals chunk[0].size + chunk[1].size. Byte-verified across 08770885 (e.g. 0877: 0x2820 + 0x1BA90 == 0x1E2B0); the reconstituted VAB parses with legaia_vab and the terminator SEQ with legaia_seq.

The type-1 chunk payload depends on the consumer: on the graphics battle-init walk, FUN_8001FE70's type-1 handler is the TIM/CLUT upload (FUN_800198E0); a sound pack's type-1 is the VAB's sample pool. The content shape matches the scene_vab_stream BGM wrapper (VAB + SEQ); only the container differs. Decoder: legaia_asset::sound_pack (extract returns the reconstituted VAB + SEQ); disc-gated sound_pack_vab_seq_real test.

The .MAP / .PCH PsyQ SoundArtist intermediates are the dev-side inputs that produce this VAB, not separate on-disc retail chunks - the retail disc does not carry them.

See also