snd_bank.py adds Dark Souls III sounds to cs_c4340.bnk, the bank MoreWeapons uses for player skills. It can also trim
levels, swap media, re-route mixers and add Stop events. Everything for one stage sits in a job file.
Checked against code: the command line (argparse in snd_bank.py), the resample values and the op kinds. The job file keys
are from tools/snd-py/README.md and the 0.0.88 job files; I did not read every op's code. Nothing was run for this page.
EB means py -3.12 -I -B S:/eclipse-build/eb.py.
What you need
- The pinned Python:
S:/toolchains/python-ds2/Scripts/python.exe. - vgmstream and the DS3 sound files.
EB tool build vgmstream ds3_fdp_main_soundprints the two folders. They holdvgmstream_cmd.exe(r1776) and DS3'sfdp_main.fsbandfdp_main.fev. - The input bank: the release's
cs_c4340.bnk, or the bank of the stage you chain on. - The FSB stream name or FEV event name of each DS3 sound, and the Nightreign event name you want (
Play_c<id>).
Steps
-
Copy a job from
S:/eclipse-build/tools/snd-py/jobs-0088/to a file beside your stage and edit it. Do not copy the oldsnd_*_088.pyscripts. -
Run it as an eb job:
EB run --mem 1 -- S:/toolchains/python-ds2/Scripts/python.exe -I -B S:/eclipse-build/tools/snd-py/snd_bank.py run <job.toml> --in-bank <chain bank> --out-bank <out.bnk> --fsb <fdp_main.fsb> [--fev <fdp_main.fev>] --vgmstream <vgmstream_cmd.exe> --work <dir> [--report <map>]--in-bankand--out-bankare required.--fsb,--vgmstreamand--workare needed by jobs that decode samples (add-sounds,replace-media).--fevis needed when a sound names afevevent.--reportwrites the job's report text. -
Read the output. The tool reads the bank back and checks that only the objects it touched differ. It exits 1 if that fails.
-
Point the TAE sound events at the new ids (see port-a-weapon-skill.md,
soundMap). -
If your bank builds on another stage's bank, add
base_stage = "<that stage's id>"to the file's[[file]]instage.toml.
Job file
[job] # optional
resample = "none" # none (default) | poly | legacy-interp ; rate is required for the last two
[report] # optional; written to --report
header = "col1\tcol2"
footer = "read-back: {n_changed} objects changed, {n_added} added, {n_media} media written: {ok}"
[[op]]
kind = "add-sounds"
mixer = "my-stage_mixer" # a NEW actor-mixer, or use into_mixer for an existing one
parent = 61849273
template_mixer = "smallest"
row = "{name}\t{mid}\t{stem} ({nvar} variant(s), {nch} ch, {sr} Hz, {dur:.2f} s)"
[[op.sound]]
stream = "c000004332" # FSB stream name, or fev = "s000090007" for a DS3 FEV event
name = "Play_c281400201"
media = "my-stage/c281400201.wem"
Ops run in the order they appear.
kind |
What it does | Keys |
|---|---|---|
add-sounds |
decodes DS3 samples and wraps each as Sound, Play action and Event | mixer + parent for a new mixer, or into_mixer (+ optional require_parent) for an existing one; template_mixer, template_sound, template_play; per sound stream or fev, name, media, optional volume_db |
replace-media |
decodes a sample again and swaps the media of an existing Sound | per sound sound = "Play_x", stream |
trim |
adds a Volume property in dB to an existing Sound; refuses a Sound that already has one | sound = "Play_x", db = -4.0 |
reparent-mixers |
sets the parent of existing actor-mixers | parent, mixers = [..] |
add-stops |
makes Stop_<n> events that target Play_<n>_snd |
names = ["c281400101"] |
Rules:
- Exactly one of
mixerandinto_mixerperadd-soundsop. - Mixer 61849273 is the player-skill mixer.
- Event, Sound and Action ids are the FNV-1 hash of
name,name_sndandname_act. The media id is the hash ofmedia. - Templates are cloned from the bank as it was read, before any op ran.
template_sounddefaults to the bank's first PCM Sound,template_playto the first Play action,template_mixertosmallest. - Extra keys on a sound (the 0.0.88 jobs use
nidandwhy) can be used inrow.
Resample
none(default): the decoded sample goes in at its own rate. Nightreign's own media are 48 kHz.poly: band-limited resample torate(needs scipy).legacy-interp: linear interpolation with no low-pass. It aliases. Use it only to reproduce an old stage's bank byte for byte.
Chains
A later job can add sounds into a mixer that an earlier job of the same chain created, with into_mixer. The result holds the
same objects as one combined job, but in a different order, so the bank file's bytes differ.
Notes
- Boss music has no free slots. Dated note (memory
nr-boss-music-slots, 2026-11-07, Nightreign 1.3.3.0, from reverse engineering): the game looks boss music up in a fixed table of 114 names in the exe and silently drops any other name. Adding param rows or bank keys gives no new boss music slot. The only routes are trading an existing slot or a DLL remap, which was designed but not built when the note was written. This tool does not change that. - A sound that posts many times comes from the FXR or the effect row, not from the bank. See port-a-weapon-skill.md, "What goes wrong".