docs: condense implementation comments
Some checks failed
Build Linux Binaries / linux/amd64 (push) Has been cancelled
Build Linux Binaries / linux/arm64 (push) Has been cancelled

This commit is contained in:
2026-07-23 13:37:05 +02:00
parent 575e2907d0
commit 4f71b784fe
22 changed files with 102 additions and 507 deletions

View File

@@ -1,18 +1,7 @@
using System.Runtime.InteropServices;
// WASAPI shared-mode capture from a real hardware INPUT device (a microphone / line-in / aux
// device), plus enumeration of capture endpoints for the aux-stream picker.
//
// This is the input-device analogue of ProcessLoopbackCapture (which captures *render* loopback
// via the process-loopback activation hack). Here the source is an ordinary capture endpoint, so
// we use the standard IMMDevice.Activate(IAudioClient) path with RCW interfaces — no vtable
// gymnastics needed (a normal device's COM objects honour QueryInterface).
//
// Why client-side capture at all? The core already owns ONE capture device (the mic). It can't
// open a second arbitrary input device, so for the aux stream the client captures the device and
// feeds 48 kHz / 20 ms int16 frames into the core via vc_stream_feed_pcm — the same external-feed
// pipeline screen-audio sharing uses. The device ids here are WASAPI endpoint ids and are NOT the
// core's miniaudio ids, so the aux picker is populated independently of vc_list_devices.
// Captures a second hardware input for AUX_DEVICE and feeds it through vc_stream_feed_pcm.
// Endpoint identifiers are WASAPI-specific and cannot be exchanged with the core's miniaudio ids.
namespace VoiceCat.App.Audio;
/// <summary>An audio input (capture) endpoint for the aux-stream device picker. <see cref="Id"/>

View File

@@ -1,17 +1,8 @@
using System.Runtime.InteropServices;
// Single-process WASAPI loopback capture via AUDIOCLIENT_ACTIVATION_PARAMS
// (Windows 10 2004+ / Build 19041+).
//
// Threading: ALL WASAPI init runs on the capture thread (MTA). If called from the
// WinForms UI thread (STA), ActivateAudioInterfaceAsync fires ActivateCompleted on
// an MTA pool thread; COM marshals that back to the STA pump — but the STA thread is
// blocked on CompletionEvent.Wait → deadlock. MTA capture thread avoids this.
//
// COM QI policy: the COM objects returned by the process-loopback activation path
// reject QueryInterface for their own IIDs under .NET's RCW mechanism. Every call
// to IAudioClient and IAudioCaptureClient is therefore dispatched via raw vtable
// pointer arithmetic, bypassing .NET COM interop entirely.
// Process loopback requires MTA activation; blocking activation from the WinForms STA
// deadlocks COM completion. The returned interfaces also reject RCW QueryInterface, so audio
// calls use explicitly owned raw pointers and vtable dispatch.
namespace VoiceCat.App.Audio;
public sealed class ProcessLoopbackCapture : IDisposable