Goal
Clean the other side's audio, not your mic. Capture the incoming call/guest audio from a loopback/aggregate input device the user selects, run it through the same DeepFilterNet engine, and play the de-noised/de-reverbed result to the user's speakers/headphones so the user hears the guest clean (Phase 1). Then optionally route that cleaned incoming audio into a second virtual sink so a recording/streaming app (OBS, Riverside) records the guest cleaned too (Phase 2 — design sketch).
Architecture
A new IncomingCleanupEngine — a second, fully independent capture→DSP→playback pipeline whose shape mirrors the CLI (input device → DeepFilterNetDSP → output device). It owns its own AVCaptureSession, ring buffer, DeepFilterNetDSP instance (DFN only — no VoiceChain), and AVAudioEngine, decoupled from AudioModel. It is held by AudioModel as an OPTIONAL and created only while enabled (a stored let would allocate ML buffers + load the model at launch). Device classification lives in pure, headless-testable predicates on VirtualMicRouting (real-output-only monitor predicate; UID-or-name NoNoise self-loop guard). One capture detail is gated behind an early spike (Task S): that AVCaptureDevice(uniqueID:) can capture a loopback device DiscoverySession never lists.
Plan
docs/plans/2026-06-15-incoming-guest-cleanup.md (Codex-reviewed, approved — Phase 1 executable; Phase 2 is a design sketch)
Goal
Clean the other side's audio, not your mic. Capture the incoming call/guest audio from a loopback/aggregate input device the user selects, run it through the same DeepFilterNet engine, and play the de-noised/de-reverbed result to the user's speakers/headphones so the user hears the guest clean (Phase 1). Then optionally route that cleaned incoming audio into a second virtual sink so a recording/streaming app (OBS, Riverside) records the guest cleaned too (Phase 2 — design sketch).
Architecture
A new
IncomingCleanupEngine— a second, fully independent capture→DSP→playback pipeline whose shape mirrors the CLI (input device →DeepFilterNetDSP→ output device). It owns its ownAVCaptureSession, ring buffer,DeepFilterNetDSPinstance (DFN only — noVoiceChain), andAVAudioEngine, decoupled fromAudioModel. It is held byAudioModelas an OPTIONAL and created only while enabled (a storedletwould allocate ML buffers + load the model at launch). Device classification lives in pure, headless-testable predicates onVirtualMicRouting(real-output-only monitor predicate; UID-or-name NoNoise self-loop guard). One capture detail is gated behind an early spike (Task S): thatAVCaptureDevice(uniqueID:)can capture a loopback deviceDiscoverySessionnever lists.Plan
docs/plans/2026-06-15-incoming-guest-cleanup.md(Codex-reviewed, approved — Phase 1 executable; Phase 2 is a design sketch)