Commit Graph
103 Commits
Author SHA1 Message Date
Adrià 94b2b54e8c Merge pull request #8338 from KernelPanicNT/feat/ngs2-calc-waveform-block-pcm
feat(libSceNgs2): map waveform blocks of linear PCM and float types
2026-10-21 14:17:40 +02:00
Federico Marras c8e99c7f71 Merge remote-tracking branch 'upstream/main' into feat/ngs2-voice-owner
# Conflicts:
#	docs/dev/debt/libSceNgs2.md
2026-10-21 12:56:14 +02:00
Dean 36206a5fd4 Merge pull request #8829 from xdCloudy/split/libSceNgs2.native
feat(prx): add missing libSceNgs2.native exports
2026-10-21 19:35:07 +13:00
Dean 1fd67185b6 Merge pull request #8513 from milescoviello/fix/ngs2-destroy-in-own-render
fix(libSceNgs2): refuse a destroy from inside its own system's render
2026-10-21 17:44:56 +13:00
Dean 141a6a5104 Merge pull request #8322 from MarrasFederico/feat/ngs2-rack-user-data
feat(libSceNgs2): keep caller data on racks with sceNgs2RackSetUserData and sceNgs2RackGetUserData
2026-10-21 16:06:57 +13:00
xdCloudy c8f0d006a0 feat(prx): add missing libSceNgs2.native exports 2026-10-21 02:37:17 +01:00
milescovielloandClaude Opus 5.5 0ff3d32a3d fix(libSceNgs2): count a system's renders to refuse a destroy from a nested render
A render recorded only the innermost system it was rendering, so a
destroy called from the callback of a system rendered inside another
system's callback was let through, and the outer render then used the
destroyed rack. Each system now counts the renders it is in. A destroy
first waits until no other thread holds the exclusive state, so a
non-zero count can only come from the calling thread's own stack.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 19:07:53 +00:00
milescovielloandClaude Opus 5.5 f1cafaca07 fix(libSceNgs2): refuse a destroy from inside its own system's render
A voice callback runs during its system's render. A rack or system
destroyed from that callback was freed while the render still walked
it, which corrupted the heap. sceNgs2RackDestroy and
sceNgs2SystemDestroy now throw when the calling thread is rendering
that system; the console's behaviour there is not measured.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 14:23:07 +00:00
milescovielloandClaude Opus 5.5 741e706b19 fix(libSceNgs2): let a rack or system destroy wait for other threads' rack locks
A destroy waited only for another thread's render, so destroying a rack
that another thread had locked freed it under that lock. Destroys now
wait like renders and rack locks do, and the render owner field that
only those waits read is gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 13:16:13 +00:00
milescovielloandClaude Opus 5.5 850b807cf2 fix(libSceNgs2): let rack locks and renders exclude each other across systems
Rack locks and renders were tracked per system, so a voice callback
that locked a rack of another system could deadlock with that system's
render, or with a thread holding rack locks in both systems. Rack locks
and renders now exclude each other across threads and systems, as the
single internal lock did, while a thread nests them and other calls go
ahead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 12:33:33 +00:00
milescovielloandClaude Opus 5.5 0fdc0e22b3 fix(libSceNgs2): make a rack lock wait for another thread's render
A voice callback runs with the internal lock released, so another
thread could lock the rack being rendered and the render then finished
it under that lock. sceNgs2RackLock now also waits while another thread
renders the rack's system, as it did when the rack lock was the
internal lock.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 11:34:14 +00:00
Federico Marras bd1cbb90de feat(libSceNgs2): report the rack and index that own a voice in sceNgs2VoiceGetOwner 2026-10-20 12:10:02 +02:00
Federico Marras 2b633ab57d feat(libSceNgs2): keep caller data on racks with sceNgs2RackSetUserData and sceNgs2RackGetUserData 2026-10-20 12:03:19 +02:00
KernelPanicNT 7dbe27c8da feat(libSceNgs2): map waveform blocks of linear PCM and float types 2026-10-20 09:44:59 +00:00
milescovielloandClaude Opus 5.5 a5b0685432 fix(libSceNgs2): keep a rack lock and a voice callback from blocking other threads
sceNgs2RackLock took the library's internal recursive mutex and kept it
until sceNgs2RackUnlock, and a render held the same mutex while it called a
voice's block-end or repeat callback. Every NGS2 call from another thread
waited behind either one. A title that takes one of its own locks while it
holds a rack lock (or inside the callback), while another of its threads
holds that lock and calls sceNgs2VoiceGetStateFlags, deadlocks.

A rack lock is now an owner and a depth on the rack, and only a render of
its system waits for another thread's rack lock. The voice callback runs
with the internal lock released (the lock depth is tracked per thread so it
is released fully and taken back after). A rack or system destroy waits
while another thread renders its system, as the callback window would
otherwise let it free what the render still walks.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 05:24:03 +00:00
Adrià ef0eed9b31 Merge pull request #6680 from 011010/feat/libSceNgs2-geom-report
feat(libSceNgs2.native): keep a registry of report handlers
2026-10-20 01:50:58 +02:00
Adrià dfd22c1887 Merge pull request #7428 from mrfelek/fix/ngs2-setup-clears-callback
fix(libSceNgs2): clear the voice callback on sampler and mixer setup
2026-10-19 21:52:05 +02:00
011010 6d72ebe47c feat(libSceNgs2.native): keep a registry of report handlers
sceNgs2ReportRegisterHandler and sceNgs2ReportUnregisterHandler stop
being throwing stubs: they keep a registry of report handlers, so a
title that imports them can register and later drop its handler.

Register rejects a null handler with an invalid argument and returns
INVALID_OUT_ADDRESS for a null out handle, then stores the report
type, handler and user data under a freshly allocated opaque handle.
Unregister removes and frees the matching record and throws for a
handle that is not registered.

The signatures follow SharpProspero and shadPS4's ngs2_report.h, and
the 24-byte Ngs2ReportDataHeader passed to a handler is its
OrbisNgs2ReportDataHeader. No report is produced yet, so no registered
handler is ever invoked.
2026-10-19 10:29:06 -06:00
notaxeltvandCursor 07d9f409a4 fix(libSceNgs2): keep CalcListener basis when front and up are parallel
PPSA15552 passes matching front/up after a listener move; pick a perpendicular up hint instead of throwing so Dead Cells can keep running.

Co-authored-by: Cursor <[email protected]>
2026-10-19 08:29:47 +02:00
Adrià 56ea17e5d7 Merge pull request #6369 from JJenkx/fix/ngs2-voice-handle-errors
fix(ngs2): return PS5 errors for invalid voice handles
2026-10-19 01:48:35 +02:00
mrfelekandClaude Opus 5.5 3f33dcf951 fix(libSceNgs2): clear the voice callback on sampler and mixer setup
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BywPXoZACVi8ALV4JKvuPZ
2026-10-18 08:07:27 +02:00
Dean a2d40a48ba Merge pull request #7072 from mrfelek/fix/ngs2-system-lock-try-render
fix(libSceNgs2): let render skip a grain while another thread holds the system lock
2026-10-18 10:07:14 +13:00
JJenkx b17406a33a fix(ngs2): return PS5 errors for invalid voice handles 2026-10-17 14:07:44 -04:00
Dean 8f8bd8cd09 Merge pull request #6348 from JJenkx/fix/ngs2-ps5-handle-errors
fix(ngs2): use PS5 system and rack handle errors
2026-10-18 02:04:35 +13:00
mrfelekandClaude Opus 5.5 40f4506659 fix(libSceNgs2): let render skip a grain while another thread holds the system lock
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BywPXoZACVi8ALV4JKvuPZ
2026-10-17 12:15:01 +02:00
Adrià 31f02805fc Merge pull request #6029 from Ondra97/codex/fix-ngs2-callback-waveform
fix(ngs2): stop stale rendering after waveform callbacks
2026-10-17 06:10:16 +02:00
JJenkx b4a93cd91b test(ngs2): expect PS5 handle errors in render checks 2026-10-16 16:02:31 -04:00
JJenkx 5637c958c4 fix(ngs2): use PS5 system and rack handle errors 2026-10-16 16:02:31 -04:00
alosta b630e7897b fix(libSceNgs2): implement a minimal sceNgs2GeomApply pass-through
Implement sceNgs2GeomApply, which was previously an unimplemented
throwing stub and was blocking Dead Cells (PPSA15552).

The implementation validates null handles/output addresses and writes a
minimal Ngs2GeomAttribute: pitch_ratio 1.0, source position, source
volume/level maxima, and diagonal channel levels for the source's channel
count. It does not implement source attenuation, distance rolloff, panning
or Doppler.

The export lives in Geom.cpp's internal Ngs2GeomApply and is exposed through
the existing default-visibility wrapper in Voice.cpp. Unimplemented.cpp no
longer defines the stub. A passing test was added to Ngs2Geom.cpp.

Unblocks: PPSA15552 #<Game bring-up discussion number>
Depends on: none
AI assistance: yes
2026-10-16 21:59:08 +02:00
Adrià ea4cc112a0 Merge pull request #5916 from JosepBove/fix/ngs2-rack-voice-index-error
fix(ngs2): return the voice-index error from sceNgs2RackGetVoiceHandle
2026-10-16 21:54:28 +02:00
Adrià FranchandClaude b8b42e61ed test(libSceNgs2): cover custom filter type 0 and unsupported types
Co-Authored-By: Claude <[email protected]>
2026-10-16 20:32:04 +02:00
alosta f888a236bc fix(libSceNgs2): support custom filter type 0 in Ngs2ApplyCustomParam
Allow custom voice filter type 0 to clear the destination filter,
matching the sampler filter convention. Type 1 continues to configure
the biquad frequency, Q and level. Other unsupported filter types
still throw.

This follows the listener-transform support in
fix/libSceNgs2-listener-transform and is needed for Dead Cells
(PPSA15552), which reaches this path after the custom sampler rack.

Depends on: fix(libSceNgs2): support listener transforms in sceNgs2GeomCalcListener- #5810
Unblocks: PPSA15552
AI assistance: yes
2026-10-16 20:31:18 +02:00
alosta 868d8bd24c fix(libSceNgs2): support listener transforms in sceNgs2GeomCalcListener
Restore world-to-listener matrix construction instead of rejecting
non-default orientation, translation or flags.

- Build an orthonormal row-major matrix from position, orient_front
  and orient_up; apply the right-handed axis flip for flag 1.
- Store the negated dotted translation in each matrix row.
- Validate unknown flags, invalid or non-finite input, short
  orientation axes, and unrepresentable translation without changing
  the output.
- Preserve finite velocity and positive finite sound speed.
- Update NGS2 geometry tests and the libSceNgs2 technical debt note.

AI assistance: yes
2026-10-15 15:03:25 +02:00
milescovielloandClaude Opus 5.5 c6e3af3258 fix(ngs2): accept empty waveform blocks and matrix levels on a voice without a format
A sampler voice set up with an all-zero format has no channels. Adding no
waveform blocks to it, or setting a matrix with no levels, threw
std::invalid_argument, which ends the title.

Accept both on such a voice: the empty add only applies RESET and the
CONTINUE state, and the empty matrix clears that matrix, which rendering
already treats as unset. Blocks with data, APPEND, and an empty matrix on
a voice with a format are still refused.

Steins;Gate Re:Boot (PPSA36591) clears a voice this way when a button is
pressed at its title screen.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 13:48:54 +02:00
Adrià 5e7d09aafe Merge pull request #5538 from JJenkx/fix/ngs2-render-capacity
fix(ngs2): limit render writes to the configured grain
2026-10-15 13:29:33 +02:00
Dean a077a88df5 Merge pull request #5139 from Kikoarl/feat/ngs2-custom-module-user-fx
feat(ngs2): support custom submixer rack UserFx module 0x1d
2026-10-15 15:34:22 +13:00
Ondra97 18114a241d fix(ngs2): stop stale rendering after waveform callbacks 2026-10-14 21:31:15 +02:00
JosepBove 5fe4780812 fix(ngs2): return the voice-index error from sceNgs2RackGetVoiceHandle
An index at or beyond the rack's voice count returned through
APS5_INVALID_ARG_EX, which throws and ends the process. Heretic + Hexen
(PPSA26525) creates a one-voice reverb rack, takes voice 0 and asks for
voice 1 at start-up, so it stopped at 1.5 s on
"sceNgs2RackGetVoiceHandle: invalid argument". Return 0x804A8305 and
leave the output handle untouched, after the existing null-output and
rack-handle checks. The value follows prosper's analysis of
libSceNgs2.native.sprx; shadPS4 lists 0x804A0302 for the PS4 library.
Neither is a PS5 measurement, recorded in the technical debt.

ngs2_voiceindex creates one-voice sampler, submixer, mastering and
reverb racks and a default sampler rack, and checks the error, the
untouched output, the null-output and invalid-rack codes and that the
last valid index still resolves afterwards. It aborts on main's library
with the throw above and passes with this change.
2026-10-14 17:29:25 +02:00
Adrià 956269ad1a Merge pull request #5470 from p3n1cillin/claude/ngs2-custom-sampler-state
feat(ngs2): report custom sampler voice state
2026-10-14 14:20:02 +02:00
Kikoarl 40e2019756 feat(ngs2): support custom submixer rack UserFx module 0x1d
Accept SCE_NGS2_CUSTOM_MODULE_ID_USER_FX (0x1d) on custom submixer racks alongside UserFx2 (0x1f). When configuring a custom rack voice, support voice control parameter SCE_NGS2_CUSTOM_VOICE_PARAM_USER_FX (0x40001d00) to install custom submixer UserFx callbacks with user data. Run legacy UserFx callbacks during custom voice rendering and update sample presence flags accordingly.

Fixes runtime abort in Void Terrarium (PPSA03061):
  terminate called after throwing an instance of 'std::runtime_error'
    what(): NGS2: custom module id 0x1d is not implemented
  FATAL: abort() (SIGABRT)

Closes #5055
2026-10-14 10:04:34 +02:00
JJenkx aaa34abc67 Merge commit '30f961266ade83b41d5c9de7dec1393e7fcecfb7' into fix/ngs2-render-capacity 2026-10-13 18:59:57 -04:00
p3nicillinandClaude Opus 5.5 87f2c7de83 feat(ngs2): report custom sampler voice state
Dead Cells (PPSA15552) calls sceNgs2VoiceGetState on custom sampler
voices with a 48-byte buffer and reads the 64-bit value at offset 16 as
a running counter. Fill it with the decoded sample count, keep the
common state flags, and return INVALID_OUT_SIZE for other sizes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 21:20:15 +01:00
MarcZX100 8b0da182a0 fix(ngs2): resolve voice patches to rack handles 2026-10-13 20:02:08 +00:00
MarcZX100 852c808373 test(libSceNgs2): fix custom filter regression expectations 2026-10-14 08:47:31 +13:00
jnbla6 40ebfae70b fix: throw on unsupported filter types and update debt docs 2026-10-14 08:39:32 +13:00
Jnbla6 ef52b16920 feat(libSceNgs2.native): add custom voice filter support and related tests for 0x13 issue case 2026-10-14 08:39:32 +13:00
Jnbla6 855823e85e feat(libSceNgs2.native): implement custom sampler rack id 0x4001 (#4334) 2026-10-14 08:39:32 +13:00
JJenkx d6cd25e123 fix(ngs2): limit render writes to the configured grain 2026-10-12 21:36:12 -04:00
lorkydey dadc23a8c1 fix(libSceNgs2): reject unverified listener transforms 2026-10-12 23:12:40 +02:00
lorkydey 4168cf3bbd feat(libSceNgs2): calculate the listener coordinate transform 2026-10-12 23:10:42 +02:00