mirror of
https://github.com/sal063/AC6_recomp
synced 2026-06-25 02:02:10 -04:00
300 lines
12 KiB
Plaintext
300 lines
12 KiB
Plaintext
================================================================================
|
|
AC6 AUDIO EXTRACTION WALKTHROUGH
|
|
================================================================================
|
|
|
|
This walkthrough takes you from a fresh AC6_recomp checkout to playable .wav
|
|
files for every track of music, every voiceline, and every cutscene mix in
|
|
Ace Combat 6. It also explains why in-game sound effects (engines, missile
|
|
lock, explosions, weapons) are NOT covered yet, and what would be required to
|
|
extract them.
|
|
|
|
If you've never extracted assets from this repo before, do the texture
|
|
walkthrough first (docs/ac6_asset_extraction_walkthrough.txt). It gets the
|
|
runtime PAC dumps populated, which this walkthrough also benefits from.
|
|
|
|
|
|
================================================================================
|
|
0. WHAT YOU GET
|
|
================================================================================
|
|
|
|
After running this walkthrough you will have, in
|
|
out/ac6_runtime_audio/packs/ :
|
|
|
|
bgmpack__00000_off00000000.xma (47 BGM tracks; one .xma each)
|
|
bgmpack__00001_off01450000.xma
|
|
...
|
|
voicepack_eng__00000_off00000000.xma (7523 voicelines, English)
|
|
...
|
|
voicepack_jpn__00000_off00000000.xma (7523 voicelines, Japanese)
|
|
...
|
|
demopack_eng__00000_off00000000.xma (31 cutscene mixes)
|
|
...
|
|
|
|
If vgmstream is installed, each .xma also has a sibling .wav next to it.
|
|
|
|
You will ALSO have, in out/ac6_runtime_audio/, the runtime-captured FHM
|
|
RIFFs (currently 42 voice/event clips from the dumps you've already
|
|
collected).
|
|
|
|
You will NOT yet have:
|
|
|
|
- In-game SFX (engines, weapons, lock-on, explosions). See section 6.
|
|
- Cutscene video. moviepack.bin is standard ASF/WMV — see section 5.
|
|
|
|
|
|
================================================================================
|
|
1. PREREQUISITES
|
|
================================================================================
|
|
|
|
- The repo is built and ac6recomp.exe runs (texture walkthrough covers this).
|
|
- Python 3.10+ on PATH.
|
|
- Asset directory exists at:
|
|
out/build/win-amd64-relwithdebinfo/assets/
|
|
containing bgmpack.bin, voicepack_eng.bin, voicepack_jpn.bin,
|
|
demopack_eng.bin, demopack_jpn.bin, moviepack.bin.
|
|
- (Optional, for .wav decoding) vgmstream-cli.exe.
|
|
Download "vgmstream-win64-cli.zip" from https://vgmstream.org/downloads
|
|
and extract anywhere — e.g. C:\tools\vgmstream\.
|
|
|
|
|
|
================================================================================
|
|
2. THE QUICK PATH
|
|
================================================================================
|
|
|
|
From the repo root:
|
|
|
|
python tools/export_ac6_audio.py --packs ^
|
|
--vgmstream "C:/tools/vgmstream/vgmstream-cli.exe"
|
|
|
|
That's it. Output:
|
|
|
|
out/ac6_runtime_audio/ (FHM-channel RIFFs as .xma + .wav)
|
|
out/ac6_runtime_audio/packs/ (pack-channel streams as .xma + .wav)
|
|
|
|
Without vgmstream installed, omit --vgmstream and you'll get .xma files
|
|
only — no .wav. The .xma files are still the actual audio, just in the
|
|
Xbox 360 codec; any vgmstream-aware player (foobar2000 + vgmstream
|
|
plugin, vgmstream-cli later, etc.) will play them.
|
|
|
|
|
|
================================================================================
|
|
3. WHAT THE TOOL DOES, IN DETAIL
|
|
================================================================================
|
|
|
|
AC6 ships audio in two structurally different shapes. The exporter handles
|
|
each one differently.
|
|
|
|
----------------------------------------------------------------------------
|
|
3a) Standalone "pack" files in the asset directory
|
|
----------------------------------------------------------------------------
|
|
|
|
bgmpack.bin / voicepack_*.bin / demopack_*.bin are flat concatenations of
|
|
independent RIFF/WAVE streams, each aligned to a 0x800-byte sector.
|
|
|
|
Layout per pack:
|
|
|
|
+-------------------+ offset 0
|
|
| RIFF <size> WAVE | ----+
|
|
| fmt / x2st / data | | sub-stream 0 = 8 + declared_size bytes
|
|
+-------------------+ ----+
|
|
| (zero padding) | | aligned up to 0x800
|
|
+-------------------+
|
|
| RIFF <size> WAVE |
|
|
| ... | sub-stream 1
|
|
+-------------------+
|
|
...
|
|
|
|
The splitter reads the declared RIFF size at offset 4, copies
|
|
8 + declared_size bytes to its own .xma file, then advances to the next
|
|
sector boundary and looks for another RIFF. The codec inside is XMA2 for
|
|
bgmpack and XMA1 for voicepack/demopack — both decoded fine by vgmstream.
|
|
|
|
----------------------------------------------------------------------------
|
|
3b) FHM-embedded RIFF entries
|
|
----------------------------------------------------------------------------
|
|
|
|
When AC6 runtime-decompresses a PAC entry containing audio, the FHM
|
|
extractor (tools/extract_ac6_runtime_fhm.py) writes each audio child
|
|
as <NNN>_RIFF.bin. Those have the Project Aces RIFF/WAVE quirks:
|
|
|
|
- The RIFF size field is set to file_size, NOT file_size - 8. The tool
|
|
patches this on export.
|
|
- The fmt chunk uses wFormatTag = 0x0165 (XMA1) but actually carries
|
|
XMA2 streams (an "x2st" chunk follows). Decoders that key off
|
|
wFormatTag alone will misread channels/sample rate; vgmstream knows
|
|
to look at x2st.
|
|
|
|
The current corpus only has 42 RIFF entries, all from idx_0214 and
|
|
idx_0227 — these are voice/event clips. Adding more requires either
|
|
playing more of the game with AC6_DUMP_PAC_DECODED=1 or implementing the
|
|
offline mode-1 decompressor (see section 6).
|
|
|
|
|
|
================================================================================
|
|
4. COMMAND REFERENCE
|
|
================================================================================
|
|
|
|
Default (FHM corpus only, decode if vgmstream is on PATH):
|
|
|
|
python tools/export_ac6_audio.py
|
|
|
|
FHM corpus + asset packs:
|
|
|
|
python tools/export_ac6_audio.py --packs
|
|
|
|
Asset packs only, skip FHM corpus:
|
|
|
|
python tools/export_ac6_audio.py --packs-only
|
|
|
|
Dry-run (list what would be exported, write nothing):
|
|
|
|
python tools/export_ac6_audio.py --packs --dry-run
|
|
|
|
Skip the vgmstream decode step (write .xma only):
|
|
|
|
python tools/export_ac6_audio.py --packs --no-decode
|
|
|
|
Point at a specific vgmstream binary:
|
|
|
|
python tools/export_ac6_audio.py --packs ^
|
|
--vgmstream "C:/tools/vgmstream/vgmstream-cli.exe"
|
|
|
|
Custom asset directory (if your build output is elsewhere):
|
|
|
|
python tools/export_ac6_audio.py --packs ^
|
|
--assets "D:/games/AC6/assets"
|
|
|
|
|
|
================================================================================
|
|
5. CUTSCENE VIDEO (moviepack.bin)
|
|
================================================================================
|
|
|
|
moviepack.bin starts with the ASF GUID 30 26 B2 75 8E 66 CF 11 — it's a
|
|
standard Microsoft ASF container with WMV9 video and WMA audio inside.
|
|
Use ffmpeg directly (not vgmstream, not this tool):
|
|
|
|
ffmpeg -i moviepack.bin -map 0 -c copy out/movies/all.wmv
|
|
|
|
Or to remux into mp4 (re-encodes audio):
|
|
|
|
ffmpeg -i moviepack.bin -c:v copy -c:a aac out/movies/all.mp4
|
|
|
|
The ASF object index identifies individual cutscenes; ffmpeg's segment
|
|
muxer can split them, but moviepack also tends to be a single concatenated
|
|
ASF, in which case ffmpeg will emit one file. Use ffprobe to inspect.
|
|
|
|
|
|
================================================================================
|
|
6. THE MISSING SFX, AND WHAT IT TAKES TO GET THEM
|
|
================================================================================
|
|
|
|
If you extract everything above and play the .wavs, you'll hear: music,
|
|
dialogue, cutscene mixes. You will NOT hear: jet engines, missile lock
|
|
warnings, gun fire, explosions, ECM bursts, ground impacts, cockpit
|
|
warnings. Those live in a third channel that the current pipeline cannot
|
|
yet open.
|
|
|
|
Why:
|
|
|
|
- There is no sfxpack.bin. Look at the asset directory and you'll see
|
|
bgmpack / voicepack / demopack / moviepack — and that's it for audio.
|
|
- SFX waveforms are inside DATA00.PAC / DATA01.PAC, packed as RIFF/XMA
|
|
entries inside FHM containers like the voice clips above.
|
|
- Those FHM containers are mode-1 compressed. The runtime mode-1 hook
|
|
(see ac6_extraction_roadmap.md) decompresses entries as the game
|
|
requests them. Anything the game hasn't requested in your sessions
|
|
so far is still sitting in DATA*.PAC compressed.
|
|
- The cue tables that name the SFX are present already — idx_0000/
|
|
001_BSN_.bsn (sound bank), idx_0000/00{2,3,4}_BFX_.bfx (effects),
|
|
idx_0001/000_nusc.bin (Namco cue table) — but they only contain
|
|
pointers. The waveform data they point to is in the un-decompressed
|
|
SFX banks.
|
|
|
|
Two ways forward:
|
|
|
|
(a) Capture more at runtime.
|
|
Set AC6_DUMP_PAC_DECODED=1 and play missions with combat. The
|
|
SFX-bearing PAC entries will get decompressed by the game and
|
|
written to out/ac6_pac_runtime_dump/ as new entry_*_mode1_*.bin
|
|
files. Then re-run:
|
|
|
|
python tools/run_ac6_asset_pipeline.py --skip-pac-extract
|
|
python tools/export_ac6_audio.py --packs
|
|
|
|
New idx_<N> directories under out/ac6_runtime_fhm_typed/ should
|
|
contain new RIFF entries.
|
|
|
|
(b) Finish the offline mode-1 decompressor.
|
|
docs/ac6_extraction_roadmap.md "Path B" — port the guest mode-1
|
|
decoder to Python so every compressed PAC entry can be materialized
|
|
without launching the game. This is the only way to guarantee all
|
|
SFX are extracted, regardless of what mission state you've reached.
|
|
|
|
The recommended near-term option is (a). For a complete archive (b) is
|
|
the right answer.
|
|
|
|
|
|
================================================================================
|
|
7. TROUBLESHOOTING
|
|
================================================================================
|
|
|
|
"found 0 RIFF entries"
|
|
Your FHM corpus is empty. Run the asset pipeline first:
|
|
python tools/run_ac6_asset_pipeline.py
|
|
If that produces no output either, you don't yet have any runtime
|
|
dumps — see ac6_asset_extraction_walkthrough.txt.
|
|
|
|
"assets dir not found"
|
|
Pass --assets pointing at the directory that contains bgmpack.bin
|
|
etc. The default assumes a standard build at
|
|
out/build/win-amd64-relwithdebinfo/assets/.
|
|
|
|
"vgmstream-cli not on PATH; writing .xma only"
|
|
Not an error — the .xma files are valid. Install vgmstream
|
|
(https://vgmstream.org/downloads) or pass --vgmstream <path> and
|
|
re-run. vgmstream is also available as a foobar2000 plugin if you
|
|
just want to listen, not convert.
|
|
|
|
"truncated stream at 0x... ; stopping"
|
|
The pack walker found a RIFF whose declared size runs past the end
|
|
of the file. Usually means the pack file is partial / damaged.
|
|
Verify the file size against your install media.
|
|
|
|
vgmstream decode fails with "unknown format"
|
|
Confirm the .xma file starts with 'RIFF' and that bytes 8..12 are
|
|
'WAVE'. If they aren't, the splitter mis-stepped and the file is
|
|
junk. Try running with --no-decode and inspect the output bytes.
|
|
|
|
The .wav plays as silence / noise
|
|
For the 42 FHM-channel clips: if vgmstream warns about the format
|
|
tag, that's the 0x0165-but-actually-XMA2 quirk. vgmstream handles
|
|
it correctly when an x2st chunk is present. If you patched the
|
|
file by hand and removed x2st, restore from out/ac6_runtime_fhm_typed
|
|
and re-run the exporter.
|
|
|
|
|
|
================================================================================
|
|
8. WHERE THINGS LIVE
|
|
================================================================================
|
|
|
|
Inputs:
|
|
out/build/win-amd64-relwithdebinfo/assets/bgmpack.bin
|
|
out/build/win-amd64-relwithdebinfo/assets/voicepack_*.bin
|
|
out/build/win-amd64-relwithdebinfo/assets/demopack_*.bin
|
|
out/build/win-amd64-relwithdebinfo/assets/moviepack.bin
|
|
out/ac6_runtime_fhm_typed/idx_*/ (FHM-channel RIFFs)
|
|
|
|
Outputs:
|
|
out/ac6_runtime_audio/ (FHM-channel .xma/.wav)
|
|
out/ac6_runtime_audio/packs/ (pack-channel .xma/.wav)
|
|
|
|
Tools:
|
|
tools/export_ac6_audio.py (this walkthrough's tool)
|
|
tools/extract_ac6_runtime_fhm.py (FHM extractor)
|
|
tools/run_ac6_asset_pipeline.py (orchestrator)
|
|
|
|
Reference:
|
|
docs/ac6_extraction_roadmap.md ("Audio extraction"
|
|
section, channel 1/2/3)
|
|
docs/ac6_asset_pipeline.md (overall pipeline)
|