Files
llamamod/docs/reference/audio.md
T

4.3 KiB
Raw Blame History

Music and sound

Sound is the least explored part of the game. This page separates what is verified from what is only a guess. Custom music or sound effects are not supported yet by any LlamaMod tool.

Music

Fact Status
Music tracks are files music/<NAME>.asf on the CD (33 files) certain
A level does not reference music files directly: environment zones carry a music id, and the start zone's id plays when the level begins certain
Music ids map to names through a table in groove.exe at 0x578960 (20 bytes per entry, name pointer at +8), played by FUN_00546b70; id 0 stops the music certain
ASF here is Argonaut's own format (not Microsoft ASF): 4-bit ADPCM, 44.1 kHz stereo, 17-byte blocks, decoded by asfcodec.adl in the game folder certain (decoder reimplemented)
A second zone field (u16 at +0x56) is probably the ambience setting likely

The id table, as used by the editor's zone inspector (EnvMath.MUSIC):

Id Track Id Track Id Track Id Track
0 (stop) 10 GAMEOVER 20 SNKJUNG 30 TUNE1
1 VILLAGE 11 TALLY 21 FROG 31 CHACHA
2 JUNGLE1 12 TURRACE 22 KRONK 32 JJUNGLE2
3 RIVER 13 PACHASNK 23 KIDLLAMA 33 TUNE9
4 JUNGLE2 14 MOUNT2 24 TUNE8 34 TUNE6
5 MOUNTAIN 15 BALLOON 25 ROLLER 35 VICTORY
6 CITY 16 JUNGSPID 26 BUNNY 36 PUZZLE2
7 CATACOMB 17 JAGCHASE 27 BLOCK 37 PLATFORM
8 LAB 18 RIVER 28 TUNE5 38 (none)
9 TITLE 19 RIVRACE 29 CITYPUZZ 39 ENDGAME

Four names (GAMEOVER, TALLY, PUZZLE2, PLATFORM) have no .asf file on the German CD; what the game plays for them (probably nothing) was not checked.

Changing the music of a level works today: pick another id for the start zone (or any zone) in the editor's Environment panel (manual: Environment, tutorial: Edit an original level).

Listening to the tracks: tools/asf2wav.py in.asf out.wav decodes a track exactly like the game's codec (filter 0: s = s1 + (n << shift), filter 1: s = 2·s1 − s2 + (n << shift), 16-bit wrap-around instead of clipping – FFmpeg's decoder clips and drifts).

New music – open: there is no encoder yet. Writing one (the inverse of asf2wav.py) and replacing a track file through a mod would be the natural next step; the header fields after the block count (rate, flags with bit 1 = stereo) are read by the decoder, the others are unknown.

Sound effects

Fact Status
Each level has its own sample bank, chunk SMPC: u32 n, n × {u32 "cvg " tag, u32 length, data} certain (SoundMerge.java)
Strats play samples by index (soundPlay(sound:N), opcodes 0xd5 / 0x99 / 0x131 play, stop, is-playing); at most 128 samples per level, ids with bit 0x80 are the front-end sounds certain
The samples are PlayStation-style VAG ADPCM, decoded by Vagcodec.adl likely (tag and codec name; the sample header was not decoded)
AMPC holds ambient sound data (ambi / VABp blocks) likely, not decoded
FESOUND.WAD is the front-end sound bank (not a chunk file) likely

Samples can be moved between levels: the editor's cross-world import and the arena copy the samples an imported object needs into the target level and renumber the sound:N operands (notes/editor-cross-import.md). Changing which sample an object plays is a constant edit in its script (Strats). Exporting or replacing a sample's audio is not possible yet.

Speech and dialogue

  • LGPC holds the dialogue texts of a level in all languages plus a speech slot per line.
  • A speech slot #<hex> is an index into SRPC, whose entries are offset/size pairs into the global speech file music/<language>.cvs in the game folder (the German version ships english.cvs).
  • Strats show texts with opcodes 0xf0 / 0xfa (topSay text:N). Imported objects bring their texts and speech references along.

The CVS file format itself was not analysed.