Defer audio layout detection until a valid command list (#331)

An incomplete startup command list consumed both layout detection and the
one-time DeviceSink scan, leaving valid SDK 4 audio frames permanently
silent. Keep both decisions pending until a supported layout walks the
whole list, as proposed in PR #331.

Extend the reproducer with valid-first and incomplete-startup stereo PCM
checks for SDK 4, 6, 16 and 21, and document the finding.

Co-authored-by: aldomrodriguez <rodriguez.aldo.91@hotmail.com>
This commit is contained in:
seeddsandaldomrodriguez committed 2026-10-27 08:56:25 +08:00
1 parent f388c0bfb7
commit 15805ef525
6 files changed
+118 -6

No files matched your search

+1
View File
@@ -212,6 +212,7 @@ One line per symptom in the [subsystem references](../reference/): what you see
- `CommandListProcessor::Process` crashes now and then (SIGSEGV under `render_main`, once at 60 s and once at 134 s in the shrine); every `RequestUpdate` renders a catch-up frame. → [The render thread's route through the public `ExecuteAudioRendererRendering` (SDK 20)](../reference/audio.md#the-render-threads-route-through-the-public-executeaudiorendererrendering-sdk-20)
- SIGSEGV at address 0x18 in `UpsamplerManager::Allocate` on the render thread. → [A renderer below 48 kHz with no upsampler on the CPU](../reference/audio.md#a-renderer-below-48-khz-with-no-upsampler-on-the-cpu)
- the main thread spins at start-up in a resource wait (a `YieldThread` loop, no crash), right after `OpenAudioRenderer`. → [A sound engine's heap too small for its renderer and players](../reference/audio.md#a-sound-engines-heap-too-small-for-its-renderer-and-players)
- no sound after boot; `audren: no DeviceSink (ID 0x13) in the command list` and a malformed-command error persist even when later command lists are valid. → [Incomplete startup lists must not select the command layout](../reference/audio.md#incomplete-startup-lists-must-not-select-the-command-layout)
- the CPU processor drops the final mix. → [The final mix is taken from the DeviceSink's mix buffers](../reference/audio.md#the-final-mix-is-taken-from-the-devicesinks-mix-buffers)
- no sound: `[RED] audren: no DeviceSink (ID 0x10) in the command list, 0 commands of 0x148 bytes`. → [SDK 4: DeviceSink is command 0xf of 0x130 bytes](../reference/audio.md#sdk-4-devicesink-is-command-0xf-of-0x130-bytes)
- no sound; red `audren: command 1 in the command list is malformed (magic 0 size 0)`. → [SDK 6: the DSP command header layout](../reference/audio.md#sdk-6-the-dsp-command-header-layout)
+8 -1
View File
@@ -84,6 +84,13 @@ For a replaced DSP renderer the size query keeps the service's work-buffer contr
## Command lists by SDK
### Incomplete startup lists must not select the command layout
- **Symptom:** no sound after boot; `audren: no DeviceSink (ID 0x13) in the command list` and a malformed-command error persist even when later command lists are valid.
- **Cause:** the host's render thread can generate commands before the game's first `RequestUpdate`. Mario Kart 8 Deluxe's first list ended in a zeroed third command, so none of the supported header layouts could walk it. `capture` nevertheless latched the default layout and consumed the one-time sink scan. Later SDK 6 headers were read as SDK 8–20 headers, and SDK 4's DeviceSink was never found. Retrying only header detection still leaves the sink scan consumed.
- **Fix:** select the header only when the whole list walks in a supported layout. Until then, return a silent frame before the sink scan; the first valid list can select both the header and its sink. `t_audren_layout` reproduces the failure and checks stereo PCM for SDK 4, 6, 16 and 21, with valid-first, empty and incomplete startup lists and SDK 21's short first list.
- **Found on:** [Mario Kart 8 Deluxe](../../dm/games/0100152000022000/README.md) (SDK 4.4.0; [PR #331](https://github.com/seedds/nxnative/pull/331)).
### The final mix is taken from the DeviceSink's mix buffers
- **Symptom:** the CPU processor drops the final mix.
@@ -102,7 +109,7 @@ For a replaced DSP renderer the size query keeps the service's work-buffer contr
- **Symptom:** no sound; red `audren: command 1 in the command list is malformed (magic 0 size 0)`.
- **Cause:** SDK 6's DSP command header is +0x04 size (s16), +0x06 command ID (s16), +0x10 enabled, where SDK 8–20 have +0x04 enabled, +0x05 ID, +0x06 size (`CommandListProcessor::Process`, `sdk+0xaaa00`); its DeviceSink is ID 0x10.
- **Fix:** `capture` in `hle_audren.c` takes the layout whose walk finds the 0xcafebabe magic on every command of the first full list.
- **Fix:** `capture` in `hle_audren.c` takes the layout whose walk finds the 0xcafebabe magic on every command of the first valid list; [incomplete startup lists](#incomplete-startup-lists-must-not-select-the-command-layout) leave detection open.
- **Found on:** [Fire Emblem: Three Houses](../../dm/games/010055D009F78000/README.md) (SDK 6.5.0).
### SDK 8: command IDs numbered differently