Architecture¶
flowchart LR
NVDA[NVDA or SAPI speech] --> Speakers[Windows default render device]
Speakers --> Loopback[WASAPI loopback capture]
Loopback --> Wav[16 kHz 16-bit mono PCM WAV]
Wav --> Whisper[Local Whisper.net ggml model]
Whisper --> Text[Transcribed text]
Text --> Score[Token Jaccard + ordered Levenshtein assertion]
Expected[Expected text] --> Score
RoundTripService owns orchestration and depends only on IAudioCapture, ISpeechSynth, and ITranscriber. Unit tests mock those seams. Windows-specific adapters live at the edge:
WasapiCapture: NAudio WASAPI loopback capture and WAV conversion.SapiSpeech: System.Speech/SAPI synthesis.WhisperTranscriber: lazy Whisper.net model load and local transcription.
Tool surface¶
graph LR
C[Claude / MCP client] -->|stdio| S[AudioLoopMcp.Server]
S --> T1[speak]
S --> T2[record_loopback]
S --> T3[transcribe]
S --> T4[list_audio_devices]
S --> T5[round_trip_test]
S --> T6[listen_and_transcribe]
T1 --> SAPI[System.Speech SAPI]
T2 --> WAS[NAudio WASAPI loopback]
T3 --> WH[Whisper.net local model]
T5 --> SAPI
T5 --> WAS
T5 --> WH
T6 --> WAS
T6 --> WH