# MGSV audio system — static analysis *Shard of mgsv-modding-pack — generated 2026-08-14. 1 files. Provenance is on every entry as `source:path`.* Hand-resolved function identifications from Ghidra traces of the retail exe. Addresses are build-specific. Names are SUSPECTED with the reasoning attached — dispute them against the reasoning, don't take them on faith. ## Ghidra audio traces (local) — static analysis of the retail exe ### `ghidra_audio:audio-pipeline-map.md` #### MGSV audio: the listener registry and sink pipeline **Domain:** audio / reverse engineering · **Confidence:** SUSPECTED throughout — names assigned from call-graph and string evidence in Ghidra, on build `085c2f82…`. Addresses are that build only. Static map of two parts of the runtime audio path: the listener registry, and the XAudio sink the mixed output leaves through. ##### The listener registry A fixed **16-slot listener registry** at `DAT_142B9E960`. Three operations were resolved against it: - `SoundCoreListenerRegistryAdd` — stores a (id, object) pair in a free slot. - `SoundCoreListenerRegistryRemove` — removes by matching the **low 48 bits** of the id. Ids are 64-bit but only the low 48 are the key — relevant if you ever construct or compare one. - `SoundCoreListenerRegistryResolve` — iterates the 16 slots during SoundCore construction. Fixed size: 16 is the ceiling on concurrent listeners. ##### Camera-to-listener binding `ActiveCamera_To_Listener_Bridge` selects the active camera and calls the listener wrapper quartet — the default listener follows the active camera, so audio is spatialized relative to the camera rather than the player body. The Tpp-side entry points are `TppListenerBridge_RegisterCandidate` / `_UnregisterCandidate`, each the sole caller of a SoundCore-side function (`FUN_14032D3F0` / `FUN_14032D430`). One caller each with clear register/unregister semantics — the cleanest points to hook on the listener side. ##### The output sink (Wwise/XAudio) Mixed audio leaves through an XAudio sink whose vtable was fully walked, ordered by role: - `SinkBackendInit` @ `1403d3020` — checks `XAudio2_7.dll`, creates the backend and master/source-voice object. - `SinkSubmitSourceBuffer` @ `1403d38e0` — builds an `XAUDIO2_BUFFER`-like descriptor, calls source-voice slot `+0xA8` (SubmitSourceBuffer). - `SinkSubmitMaintenance` @ `1403d34a0` — queries voice state, submits ring buffers. - `SinkMixedDataPath` @ `1403d35a0` — copies/clamps the **final mixed samples** into the XAudio ring buffer. Last place the PCM exists before XAudio; the natural tap point for any post-mix processing. - `SinkSilencePath`, `SinkSourceVoiceStart` / `Destroy`, destructors round out the vtable. ##### Scope and the untraced part Covered: the listener registry, the camera binding, and the sink data path. Not covered: per-source 3D positioning. No X3DAudio emitter math turned up in these traces, which suggests positioning happens Wwise-side before this sink rather than in XAudio's own 3D. Where a source's position feeds pan/attenuation, upstream of `SinkMixedDataPath`, is untraced. ##### Cross-reference The `wwise-rtpc` lookup table lists the runtime parameters that ride on this (attenuation and the rest); `audio-internals` carries the PostEvent/RTPC setter functions. This entry is the listener/sink *structure* those controls act on.