One language setting; localized in-memory speech per language

This commit is contained in:
2026-10-09 23:09:07 +02:00
parent 98ec2fe9c4
commit f29af40b37
40 changed files with 77414 additions and 77240 deletions

View File

@@ -89,11 +89,12 @@ def pack(media):
return bytes(hdr) + bank, bytes(payload)
def bank(bank_id, media, name=None, extra_sources=(), prefetch=(), events=()):
def bank(bank_id, media, name=None, extra_sources=(), prefetch=(), events=(), mem_events=()):
"""A v56 soundbank holding `media` {id: wem} in memory (DIDX/DATA, 16-byte aligned) with one HIRC
Sound object per media; extra_sources: [(media id, bank id, off, size)] for sources of other banks;
media ids in `prefetch` get a prefetch source (their DIDX data is the head of a streamed WEM);
events: [(event name, streamed media id)] -> event -> action -> streamed Sound object."""
events: [(event name, streamed media id)] -> event -> action -> streamed Sound object;
mem_events: [(event name, media id of this bank)] -> event -> action -> that media's in-memory Sound."""
data = bytearray()
didx = b""
for m in sorted(media):
@@ -110,14 +111,19 @@ def bank(bank_id, media, name=None, extra_sources=(), prefetch=(), events=()):
2 if m in prefetch else 0))
objs += [x + (0,) for x in extra_sources]
from ackit.bnk import fnv1
obj = (bank_id & 0xFFFFF000) + 0x100 # HIRC object ids: unique per bank, like real Wwise ids
hirc_objs = []
for i, (m, b, off, size, stream) in enumerate(objs):
hirc_objs.append((2, struct.pack("<7I", 0x100 + i, 0x00040001, stream, m, b, off, size) + bytes(6)))
hirc_objs.append((2, struct.pack("<7I", obj + i, 0x00040001, stream, m, b, off, size) + bytes(6)))
for i, (ev, m) in enumerate(events):
sid, aid = 0x300 + i, 0x400 + i
hirc_objs.append((2, struct.pack("<7I", sid, 0x00040001, 1, m, 0, 0, 0) + bytes(6)))
hirc_objs.append((3, struct.pack("<III", aid, 0x4011, sid) + bytes(8)))
hirc_objs.append((4, struct.pack("<III", fnv1(ev), 1, aid)))
for i, (ev, m) in enumerate(mem_events):
aid = 0x500 + i
hirc_objs.append((3, struct.pack("<III", aid, 0x4011, obj + sorted(media).index(m)) + bytes(8)))
hirc_objs.append((4, struct.pack("<III", fnv1(ev), 1, aid)))
hirc = struct.pack("<I", len(hirc_objs))
for t, body in hirc_objs:
hirc += bytes([t]) + struct.pack("<I", len(body)) + body
@@ -294,16 +300,36 @@ def make_banks(cooked, speech_wems):
ev_bank = bank(fnv1("NPC_SynthDialogue"), {DLG_MEDIA: dlg_wem}, name="NPC_SynthDialogue",
events=[(SPEECH_EVENT, LINE_MEDIA[1])])
objs = [("AkEvent", SPEECH_EVENT, bytes(8)), ("RDialogueEvent", "Radio_02", dlg)]
ue_package(os.path.join(cooked, "Synth_Dialogue.upk"), objs + [("AkBank", "NPC_SynthDialogue", ev_bank)])
# a localized bank (one AkBank export: language list + one bank per language) with an in-memory line
loc = localized_bank(GRUNT_BANK, {lang: {m: wem(0.4, 500 + 100 * i)} for i, (lang, m) in enumerate(GRUNT_MEDIA.items())},
GRUNT_EVENT)
grunt = [("AkEvent", GRUNT_EVENT, bytes(8)), ("RDialogueEvent", "Grunt_01", dialogue(GRUNT_EVENT, GRUNT_SUBS)),
("AkBank", GRUNT_BANK, loc)]
ue_package(os.path.join(cooked, "Synth_Dialogue.upk"),
objs + [("AkBank", "NPC_SynthDialogue", ev_bank)] + grunt)
ue_package(os.path.join(cooked, "Synth_Dialogue2.upk"), objs, prefix=bytes(3000))
with open(os.path.join(cooked, "CookedBanks.txt"), "a", newline="\r\n") as f:
f.write("NPC_SynthDialogue\n")
f.write("NPC_SynthDialogue\n%s\n" % GRUNT_BANK)
out = {"%08X" % m: w for m, w in list(foot.items()) + list(foley.items()) + list(gui.items())}
out["%08X" % DLG_MEDIA] = dlg_wem
return out
SPEECH_EVENT = "Speech_Synth_Radio_02"
GRUNT_BANK, GRUNT_EVENT = "Speech_Synth_Grunt", "Speech_Synth_Grunt_01"
GRUNT_MEDIA = {"INT": 0x0F000001, "ITA": 0x0F000002} # one media per language (localized bank)
GRUNT_SUBS = {"INT": ["Hey you!"], "ITA": ["Ehi, tu!"]}
def localized_bank(name, per_lang, event):
"""AkBank export data of a localized bank: language list, then one bank per language (same id)."""
from ackit.bnk import fnv1
langs = list(per_lang)
lst = struct.pack("<I", len(langs)) + b"".join(_fstr(l) for l in langs)
head = bytes(4) + struct.pack("<HHiiii", 9, 0x84, 0, 0, len(lst), 0) + lst
blobs = b"".join(bank(fnv1(name), media, name=name, mem_events=[(event, next(iter(media)))]) + bytes(16)
for media in per_lang.values())
return head + blobs
SUBTITLES = {"INT": ["Scanner line two.", "Second part."], "ITA": ["Riga due dello scanner."],
"RUS": ["Строка два"]}
DLG_MEDIA = 0x0E000001