You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(audio): preserve completed AudioOut2 grains across threads - #5198
Lost Soul Aside (PPSA26358) rewrites the same 512-frame, 12-channel float PCM buffer on its producer thread, calls sceAudioOut2ContextAdvance, and pushes from another thread. Advance previously did nothing; Push retained the borrowed pointer and read it on the next Push. This read repeated or partially rewritten buffers, causing startup crackles.
Snapshot PCM and gain at Advance and consume completed grains in order at Push. A blocking Push waits for the producer when no completed grain is available. Callers that never Advance keep their existing deferred-buffer behavior. Snapshot timing is inferred from the title, not measured on console hardware; the ownership and error-code gaps are recorded in audio debt. Unsupported empty nonblocking pushes and more than 16 outstanding completed grains throw.
Tested
Rebased onto main 84b01f9cd042e1d2e9e112f8783aa5a9d26399ee on 2026-10-14; PR head bb4ec482d2868af3f6bbe3ecd9eee03b10e9cbd2. Standalone branch verification (this PR alone), Windows 11 Pro 10.0.26300, WinLibs GCC 15.2, Release, SPIRV-Tools OFF: runtime and selected native test targets built successfully. All 11 focused tests passed without skips in 10.58 s. Conventions and whitespace checks passed. The conflict resolution retains main's controller-audio routing, including the main-output route for pad speakers when no pad device is selected, while retaining the captured PCM and gain. No new title/gameplay run, Linux, full-suite or CI result is claimed.
Earlier validation, on the bases stated below:
Windows 11, Ryzen 7 7800X3D, RTX 5070, WinLibs GCC 15.2, Release.
Standalone build: current main 759c66564f0890541ca0e59afd89ed686ed64ec9 plus this PR alone. Full Windows build passes. All 10 audio_out* tests pass without skips in 9.66 s. Conventions and whitespace checks pass.
The new native regressions check reuse of one mutable PCM buffer, volume changes between Advance and Push, and a pushing thread waiting for the producer. With the new tests retained but all three runtime files restored to main 91ed4ce62 (audio files byte-identical to 759c66564), audio_out2_port_buffers fails; restoring the fix passes. Existing no-Advance buffer, timing, routing and layout checks remain included.
Separate game A/B: the same playable integration based on main 5b083445852c3dc2a02231f97b6f2c254c39791b, with identical rendering/memory fixes, differing in this audio fix. Bounded in-memory instrumentation captured 43.69 seconds of generated stereo float input before SDL output per run:
Measurement
Baseline
Fixed
Repeated adjacent non-silent 512-frame blocks
1,083 / 3,067 (35.31%)
0 / 3,068 (0%)
Block-boundary jumps larger than 0.03
86
0
Nonfinite samples
0
0
The tester confirmed startup/title audio sounds clean. The temporary probes are absent from this PR. These are generated-input measurements, not a host loopback recording or a clean-main title run. Complete gameplay, console semantics, Linux and CI are not claimed.
Checklist
Based on current main; no other open PR implements the same functions
One topic per PR; follow-ups go in a new PR
No comments added to code
Unimplemented paths throw; inferred behavior and remaining gaps are documented in technical debt
No investigation files, recordings, logs, game assets or images added to the repository
Windows test: head 79dae11d1 merged onto current mainef42c5f2a, together with 9 other open pull requests in one build (the merges were conflict-free); a failure would have been bisected per PR. Windows 10, MinGW GCC (WinLibs), Ninja Release, -j2: full build 0 errors; ctest for the tests this change adds or touches: audio_out2_port_buffers passed; python tools/check_conventions.py --base upstream/main passed for the combined tree. I did not run the new tests against main without the change.
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Checked the Advance/Push grain snapshot (PCM + gain), the blocking wait, the no-Advance fallback and the debt entry. Linux build and audio_out2_port_buffers pass, and the test fails with the runtime changes reverted. The third-party Windows and Linux runs above agree; merging.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Lost Soul Aside (PPSA26358) rewrites the same 512-frame, 12-channel float PCM buffer on its producer thread, calls
sceAudioOut2ContextAdvance, and pushes from another thread. Advance previously did nothing; Push retained the borrowed pointer and read it on the next Push. This read repeated or partially rewritten buffers, causing startup crackles.Snapshot PCM and gain at Advance and consume completed grains in order at Push. A blocking Push waits for the producer when no completed grain is available. Callers that never Advance keep their existing deferred-buffer behavior. Snapshot timing is inferred from the title, not measured on console hardware; the ownership and error-code gaps are recorded in audio debt. Unsupported empty nonblocking pushes and more than 16 outstanding completed grains throw.
Tested
Rebased onto main
84b01f9cd042e1d2e9e112f8783aa5a9d26399eeon 2026-10-14; PR headbb4ec482d2868af3f6bbe3ecd9eee03b10e9cbd2. Standalone branch verification (this PR alone), Windows 11 Pro 10.0.26300, WinLibs GCC 15.2, Release, SPIRV-Tools OFF: runtime and selected native test targets built successfully. All 11 focused tests passed without skips in 10.58 s. Conventions and whitespace checks passed. The conflict resolution retains main's controller-audio routing, including the main-output route for pad speakers when no pad device is selected, while retaining the captured PCM and gain. No new title/gameplay run, Linux, full-suite or CI result is claimed.Earlier validation, on the bases stated below:
Windows 11, Ryzen 7 7800X3D, RTX 5070, WinLibs GCC 15.2, Release.
Standalone build: current main
759c66564f0890541ca0e59afd89ed686ed64ec9plus this PR alone. Full Windows build passes. All 10audio_out*tests pass without skips in 9.66 s. Conventions and whitespace checks pass.The new native regressions check reuse of one mutable PCM buffer, volume changes between Advance and Push, and a pushing thread waiting for the producer. With the new tests retained but all three runtime files restored to main
91ed4ce62(audio files byte-identical to759c66564),audio_out2_port_buffersfails; restoring the fix passes. Existing no-Advance buffer, timing, routing and layout checks remain included.Separate game A/B: the same playable integration based on main
5b083445852c3dc2a02231f97b6f2c254c39791b, with identical rendering/memory fixes, differing in this audio fix. Bounded in-memory instrumentation captured 43.69 seconds of generated stereo float input before SDL output per run:The tester confirmed startup/title audio sounds clean. The temporary probes are absent from this PR. These are generated-input measurements, not a host loopback recording or a clean-main title run. Complete gameplay, console semantics, Linux and CI are not claimed.
Checklist
main; no other open PR implements the same functions