Files

74 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`](../../src/main/java/com/eliasmueller/llamamod/editor/tools/environment/EnvMath.java)):
| 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. The editor marks them *(no file on the CD)*.
**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](../manual/12-environment.md),
[tutorial: Edit an original level](../manual/tutorial-original-level.md)).
**Listening to the tracks:** [`tools/asf2wav.py`](../../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`](../../src/main/java/com/eliasmueller/llamamod/format/stpcmerge/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](../../notes/editor-cross-import.md)). Changing which sample an
object plays is a constant edit in its script ([Strats](../strats/custom-types.md)). 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.