Repository navigation
feat(libSceNgs2.native): reverb rack following the PS4 libSceNgs2 reverb - #2336
Merged
Merged
Conversation
Rack 0x2001 is created with its option layout and KytyPS5's defaults, takes the setup (0x20010000) and I3DL2 (0x20010001) voice params and reports the common voice state. The voice mixes its inputs and runs a Freeverb-style approximation driven by the I3DL2 parameters: room and room HF, early reflections and their delay, late reverb and its pre-delay, decay time and HF ratio, and diffusion. Out-of-range params throw, param changes keep the tail, a stop or kill clears it, and the tail ends once it decays below 1e-20. The console's algorithm is unknown; the approximation is recorded in TechnicalDebt. The test context buffer pool grows to 64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reverb was a Freeverb-style approximation. It now follows the PS4 firmware 11.00 libSceNgs2.sprx, read and checked against its output: the input mixed to mono with the library's fixed gains, a 14400-sample buffer with four reflection taps from the reflection pattern tables and a late feed, sixteen damped comb filters with a pre-emphasis stage, a signed selection of combs and four allpasses per output channel, a two-pole room HF filter, and the library's parameter clamps, crossfades and setup defaults. The test values are the PS4 library's own output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/ngs2-reverb-rack
…/ngs2-reverb-rack
…he reverb does not handle A reverb_size other than the default was accepted and ignored, and below about 7.5 kHz an allpass length went negative and wrapped to a 16 GB buffer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 9, 2026
Contributor
|
Tested on Linux (CachyOS x86_64, Intel RPL-S iGPU / Mesa 26.3.0-devel / Vulkan 1.4.363, GCC 16.2.1) at
LGTM! |
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.
What
sceNgs2RackCreatethrows for rack id0x2001(reverb). This adds the rack, with the reverb the console library renders.SceNgs2ReverbRackOption(rack option,max_channels,reverb_size). The defaults come from KytyPS5: 8 channels andreverb_size1.0x20010000setup takes input and output channel counts and flags. It accepts 1, 2, 6 or 8 channels; other counts are invalid arguments. Non-zero flags and differing input and output counts throw.0x20010001takesSceNgs2ReverbI3DL2Param(88 bytes). The layout of both params, and of the voice state, matches shadPS4'sngs2_reverb.h. Values are clamped to the library's ranges, as it does; NaN throws.sceNgs2VoiceGetStatereturns the common voice state.density.diffusion.hf_reference, then the wet and dry levels. The LFE channel passes dry.densityandreflection_patternare used.reverb_sizeof 1 is handled, with its 14400-sample buffer; other sizes throw.Reference
libSceNgs2.sprx, dumped and decrypted from a console. It was loaded on Windows with a small test loader and called directly; neither the loader nor the library is part of this PR. The reverb was read from its disassembly, and the test values are its output.libSceNgs2.sprx(the module titles import aslibSceNgs2): its readable ELF headers match the PS4 library: the same.eh_frame_hdrsize (3,460 bytes, 431 functions) and code plus read-only data within 1% (321,328 bytes against 323,432). A decrypted PS5 SELF was not used; anyone with a decrypted PS5libSceNgs2.sprxcan help confirm this.Tested
Windows 11, WinLibs GCC 15.2.0 r7, Release.
ngs2_renderTestReverbuses 8 cases with the PS4 library's output, to 2e-7 + 1e-5 of each value:Channel 3 is skipped: the PS4 mastering voice low-passes the LFE channel, and AnyPS5's doesn't yet.
TestReverbSetup: 3, 4, 5 and 7 channels are rejected; channel conversion, flags and NaN throw; the setup defaults render a non-zero level below 1e-8; rendering at 7000 Hz throws, and rack options withreverb_size0 or 2 throw.On
mainthe tests fail, because rack 0x2001 throws. 25 mutations ofReverb.cpp, and removing either new throw, each make them fail.Full ctest merged with
maind70b899, together with feat(libSceNgs2.native): implement sceNgs2PanInit and sceNgs2PanGetVolumeMatrix #959, fix(libSceNgs2.native): mix ports without set levels through the default channel map #964 and fix(libSceNgs2.native): clamp matrix levels to -4..4 as the PS4 libSceNgs2 does #2337: 507/507.Seen in PPSA22520 (Animal Well): it creates the rack with default options, sets up a 2-in, 2-out voice, loads I3DL2 preset 9 ("cave" in the standard preset order) and patches it to its mastering voice. Played with feat(libSceNgs2.native): implement sceNgs2PanInit and sceNgs2PanGetVolumeMatrix #959 and fix(libSceNgs2.native): mix ports without set levels through the default channel map #964 on
main: the jump reverb is the one compared with the PS5 recording above, the game runs at 59 FPS, and there are no NGS2 errors.Linux not tested.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code