fix(audio): add per-5s live-loop telemetry to name the silent-recording stage
The recorded audio is full-length silent AAC (−91dB, 1124 frames/23.95s) —
the named pipe carried ~9.1MB of zeros the entire take. The mixer's loop
ran, the pipe connected, ffmpeg read it, and the file is full-length
silence. Sources started fine ('Audio: using system default mic...' logged),
no failure callbacks fired, and the existing integration test
(Mix_WithFiltersDuckAndGain_Lands_On_AudioPipe) proves the loop→pipe path
carries real audio when fed — the fault is capture-side.
Added permanent per-5s live-loop telemetry to startup.log so the next take
names the exact stage without new code:
Audio live: pipe connected= dropped writes= micLevel= loopLevel= drained
N/N samples peakMix N (per 5s)
- AudioMixer.FillAndMix now returns (MicRms, MicDrained, LoopDrained) for
the accumulation; StartLive/StopLive log start/stop lines.
- NamedPipeAudioWriter.DroppedWrites: nonzero = audio dropped before ffmpeg
connected (names 'pipe never connected' stage).
Likely root cause: WASAPI loopback captures the default render endpoint —
if audio plays on a non-default device the recording is silently silent.
The fix requires device enumeration + selection (slice 13 candidate).
Suite 290/291 — same sole pre-existing compositor pixel failure.
This commit is contained in:
@@ -896,9 +896,21 @@ seam:** `Func<Scene?>`, `Func<SceneElement, VideoFrame?>` resolver, `Func<Compos
|
||||
(4) **capture-cost telemetry**: first 30 captures per session log elapsed ms to startup.log —
|
||||
PNG-encode+decode cost decides whether ~30Hz stays or drops to ~20Hz; the FramePump drops frames
|
||||
(never time-lapses, slice 10) if UI-thread GC churn starves it, so the cost is observable.
|
||||
Full suite 290/291 passing, the sole failure the pre-existing compositor pixel test. The web-overlay
|
||||
transparency verification (the first-capture diagnostic bound to about:blank) and the audio-silence
|
||||
item remain open push-gate items — both untouched by this slice.
|
||||
Full suite 290/291 passing, the sole failure the pre-existing compositor pixel test. The web-overlay
|
||||
transparency verification (the first-capture diagnostic bound to about:blank) and the audio-silence
|
||||
item remain open push-gate items — both untouched by this slice.
|
||||
- **Slice 12 (audio diagnostics, 2026-09-10):** the recorded audio is full-length silent AAC
|
||||
(−91dB, 1124 frames / 23.95s in the latest take) — the named-pipe delivered ~9.1MB of zeros to
|
||||
ffmpeg for the entire recording, so the loop ran and connected, but both WASAPI capture sources
|
||||
delivered nothing. Sources started fine (`Audio: using system default mic...` logged), no failure
|
||||
callbacks fired, and the mixer's existing integration test (`Mix_WithFiltersDuckAndGain_Lands_On_AudioPipe`)
|
||||
proves the loop→pipe math is sound. The fault is capture-side: either the default render endpoint
|
||||
carried nothing (audio played on a non-default device — common), or both endpoints were held
|
||||
exclusive, or genuinely nothing played. Added permanent per-5s live-loop telemetry to startup.log
|
||||
(`Audio live: pipe connected=, dropped writes=, micLevel=, loopLevel=, drained, peakMix`) and
|
||||
`NamedPipeAudioWriter.DroppedWrites` — names the exact stage on the next take without new
|
||||
code. `AudioMixer.FillAndMix` now returns `(MicRms, MicDrained, LoopDrained)` for the telemetry
|
||||
accumulation. Full suite 290/291, same pre-existing sole failure.
|
||||
- **Stop ordering matters:** `StopAsync` stops the encoder — since slice 10 it FLUSHES the pending
|
||||
queue (`Channel.TryComplete` → drain writes the leftovers, closes stdin → EOF → ffmpeg finalizes+exits;
|
||||
an accepted frame is never lost) — **before** awaiting the loop. The old reverse-order deadlock was
|
||||
|
||||
Reference in New Issue
Block a user