docs: record remaining verification checks for the audio render-hook
List the human/full-setup checks that producer-side capture can't prove on its own: hooked audio over RPT end-to-end, the mix-format assumption for streams that predate injection, and multi-stream games. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
37
README.md
37
README.md
@@ -66,15 +66,34 @@ All phases below are implemented and verified.
|
||||
- **Phase 2 — audio mirror. ✅** The host captures the game's audio by PID via
|
||||
WASAPI process loopback and re-renders it on the default endpoint, so RPT
|
||||
carries game audio to guests.
|
||||
- **Audio render-hook (echo fix). ✅ (pending manual end-to-end)** The injected
|
||||
hook intercepts the game's WASAPI render path (`IAudioRenderClient`), copies
|
||||
the frames into a shared audio ring for the host to re-render, and releases the
|
||||
game's buffer silenced — so the operator no longer hears the audio twice. The
|
||||
host owns an enable flag and re-renders the game's format via `AUTOCONVERTPCM`;
|
||||
if the hook doesn't publish a format in time it reverts to process loopback.
|
||||
The Audio panel shows the active source and a render-stream-count debug table.
|
||||
Validated in-process by `audio_hook_test`; the real-game pass is the remaining
|
||||
manual step.
|
||||
- **Audio render-hook (echo fix). ✅ (capture proven on a real game; full RPT
|
||||
pass pending)** The injected hook intercepts the game's WASAPI render path
|
||||
(`IAudioRenderClient`), copies the frames into a shared audio ring for the host
|
||||
to re-render, and releases the game's buffer silenced — so the operator no
|
||||
longer hears the audio twice. It hooks the render vtables *proactively* so a
|
||||
game that's already playing when injected is still captured. The host owns an
|
||||
enable flag and re-renders the game's format via `AUTOCONVERTPCM`; if the hook
|
||||
doesn't publish a format in time it reverts to process loopback. The Audio panel
|
||||
shows the active source and a render-stream-count debug table. Validated
|
||||
in-process by `audio_hook_test` and against a real already-playing game
|
||||
(Phantom Brave) with `coop_audio_probe`: the pre-existing render client is
|
||||
detected and real, non-silent audio reaches the ring with zero overruns.
|
||||
|
||||
### Remaining verification
|
||||
|
||||
Producer-side capture is proven; these still need a human / full setup to confirm:
|
||||
|
||||
- **Hooked audio over RPT, end-to-end.** Run the host, inject, tick **Mirror game
|
||||
audio**, and confirm **Source: Hooked (no echo)**, the game goes locally silent,
|
||||
and a guest on Remote Play Together still hears it.
|
||||
- **Format guess for non-mix-format games.** For a stream that already exists at
|
||||
injection time the hook can't see the game's `Initialize`, so it assumes the
|
||||
device **mix format**. Phantom Brave matched it exactly (48 kHz/2ch/float). A
|
||||
game that initialized shared mode with a different format would come out
|
||||
wrong-pitched/garbled and needs per-stream format detection — not yet handled.
|
||||
- **Multi-stream games.** v1 captures only the first ("primary") render stream;
|
||||
confirm the Audio panel's render-stream table makes a multi-stream game obvious
|
||||
(secondary streams stay local until per-stream mixing is added).
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
||||
Reference in New Issue
Block a user