"""Wwise soundbanks (bank version 56): chunks, in-memory media (DIDX/DATA) and HIRC sound sources. Works on a buffer that may hold a bank anywhere (a loose .bnk file, a BKPK pack's embedded bank, or an uncompressed .upk package with many banks). Offsets are relative to the start of the bank. Format: docs/formats/banks.md. """ import re import struct from collections import namedtuple CHUNKS = (b"BKHD", b"DIDX", b"DATA", b"HIRC", b"STID", b"STMG", b"ENVS", b"FXPR") SOUND = 2 # HIRC object type of a Sound IN_MEMORY, STREAMED, PREFETCH = 0, 1, 2 Media = namedtuple("Media", "id off size") # off: from bank start Source = namedtuple("Source", "object stream media bank off size pos") # pos: of `off` field, from bank start class BankError(ValueError): pass class Bank: def __init__(self, buf, at=0): self.buf, self.at = buf, at self.chunks = {} p = at while p + 8 <= len(buf) and bytes(buf[p:p + 4]) in CHUNKS: tag = bytes(buf[p:p + 4]).decode() n = struct.unpack_from(" len(buf) or tag in self.chunks: break self.chunks[tag] = (p + 8 - at, n) p += 8 + n if "BKHD" not in self.chunks or self.chunks["BKHD"][1] < 8: raise BankError("no bank at 0x%X" % at) self.size = p - at o = at + self.chunks["BKHD"][0] self.version, self.id = struct.unpack_from(" end: raise BankError("HIRC overruns its chunk in bank %08X" % self.id) t = self.buf[p] ln = struct.unpack_from("= 28: obj, _plugin, stream, mid, bank = struct.unpack_from("<5I", self.buf, p + 5) off, size = struct.unpack_from("