SPU: free rung-out sustain voices + stop same-sample loop stacking - #6
Open
vjravenlight wants to merge 1 commit into
Open
SPU: free rung-out sustain voices + stop same-sample loop stacking#6vjravenlight wants to merge 1 commit into
vjravenlight wants to merge 1 commit into
Conversation
Two fixes for the endless-loop SFX family (wheelchair over load screens, the Nowhere grandfather-clock crescendo, ending SFX pile-ups): - A decreasing ADSR sustain that reaches level 0 now transitions to ENV_OFF. Left in SUSTAIN at 0, the voice read keyed-on forever, so libsd's free-voice scan saw a silent-but-busy channel and every re-strike of the same sample pinned a fresh voice until all 24 drained. - Key-on of a looping voice silences any OTHER non-enveloped voice still looping the same sample address. PSX hardware freed a re-struck loop via its ADSR release; without an engaged envelope the previous instance rang at full static gain on another voice and instances piled into an endless crescendo. Enveloped instances still overlap and ring out naturally. Both are no-ops for one-shot SFX. Pairs with the game-side change that turns ADSR on by default via config (the render-thread deadlock that originally shipped it off was fixed by the audio-thread tick placement). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Targets the looping-SFX bug family from silent-hill-decomp#13: the wheelchair loop that survives load screens, the Nowhere grandfather-clock ring that swells into an endless crescendo (#27 there), and the Good+ ending SFX pile-ups.
Root cause
With ADSR off, a looping voice plays at static gain until an explicit key-off that in these cases never comes — on PSX the sample's own decreasing sustain/release envelope silenced it. And every re-strike of the same sample (each clock chime) key-ons a new voice while the old one still reads busy, so instances stack toward all 24 voices — that stack is the audible crescendo.
Fixes
ENV_OFF. Previously the voice stayed inENV_SUSTAINat level 0 forever: silent, but reading keyed-on, so libsd's free-voice scan couldn't reclaim it and each re-strike pinned another channel.Both changes are no-ops for one-shot SFX (
voice->loopinggating).Relationship to the ADSR gate
The envelope path currently ships default-off (
g_SpuAdsrEnabled = 0) because its original render-thread tick placement deadlocked — but that was already fixed by moving the tick to the audio-timing thread (PsyX_main.cppintrThread), and the game already force-enables it for the endings and Cybil maps. The companion silent-hill-decomp PR adds anadsr_enabledconfig key (default on) so the whole game benefits; with it off, fix 2 here still kills the stacking/crescendo on its own.Builds clean, boots and plays (SH1 port, MSYS2/MinGW64).
🤖 Generated with Claude Code