fix(windows): real native exclude + self-echo removal for screen audio

"All apps except selected" previously captured the complement of a frozen
app snapshot in INCLUDE mode (missed late-launched apps and system sounds,
wasted captures on silent windows). It now opens a single ProcessLoopbackCapture
in EXCLUDE mode (AUDIOCLIENT_PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE)
of the one chosen app — true system-mix-minus-one, dynamic so apps launched
after sharing starts are included. The picker enforces single-selection in
exclude mode (the activation params take one target PID).

Adds an "Exclude VoiceCat's own audio (prevents echo)" checkbox (default on,
entire-desktop only) that routes the desktop capture through the same EXCLUDE
path targeting our own process id, killing the whole-device self-echo loop.

No C++/ABI changes. Updates voice.md and PROGRESS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 12:28:53 +02:00
parent fb73b694d0
commit 5e18dfa1c9
6 changed files with 131 additions and 34 deletions

View File

@@ -148,6 +148,21 @@ up instantly. Newest status at the top.
SUCCEEDED (sim slice still arm64-only → simulator run N/A). Next: on-device check of the
drill-down + compose box + unified timeline.
- **Done (2026-06-22):** **Windows exclude mode is now a real native exclude + self-echo
removal.** The "All apps except selected" mode previously captured the *complement of a frozen
app snapshot* in INCLUDE mode (missed late-launched apps, system sounds; wasted captures on
silent windows). It now opens a **single `ProcessLoopbackCapture` in EXCLUDE mode**
(`AUDIOCLIENT_PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE`) of the one chosen app — true
system-mix-minus-one, dynamic. `AppAudioPickerDialog` enforces single-selection in exclude
mode (the API takes one target PID). Added an **"Exclude VoiceCat's own audio (prevents echo)"**
checkbox (default on, entire-desktop only) that routes the desktop capture through the same
EXCLUDE path targeting `Environment.ProcessId`, killing the whole-device self-echo loop.
Touched `ProcessAudioMixer.cs` (`ResolveCaptures`), `AppAudioPickerDialog.cs`, `MainForm.cs`,
`AudioSessionEnumerator.cs` (`EntireDesktop(bool ExcludeSelf)`); docs in voice.md §9. No C++ /
ABI changes. `dotnet build` clean. **Still to verify on-device:** exclude actually silences
the chosen app while the rest plays, late-launched apps appear without restart, and the
self-exclude checkbox removes the echo.
- **Done (2026-06-21):** **Screen-audio sharing on macOS + iOS.** macOS uses ScreenCaptureKit
(`ScreenAudioCapture.swift`) → `vc_stream_feed_pcm`; iOS uses a ReplayKit Broadcast Upload
Extension (`VoiceCatBroadcast`) that forwards captured `.audioApp` PCM through a shared App