Personal project · 2026

A real-time copilot for live conversations

Adarna listens to a meeting as it happens, transcribes it on your own machine, and — on a pause or a hotkey — drafts the next thing you could say. It arrives in an always-on-top overlay you can glance at without leaving the call.

Built solo, end to end: Windows audio capture, local speech-to-text, a two-process cross-OS architecture, and a Claude session that never leaves the machine unless it has to.

Listening Overlay · opacity 90%
Adarna's always-on-top overlay showing a real streamed suggestion during a mock interview exchange
Adarna — system characteristics Solo build Sheet 01 of 03
01 · Pause to suggestion 5–8 s End of speech to first streamed token
02 · Speech-to-text 100% local faster-whisper on device, no cloud STT
03 · Audio sources 2 streams Mic + WASAPI loopback, merged and labeled
04 · Written to disk Nothing Unless session recording is opted into

Measured on the developer's own hardware across repeated live-call testing, not in a benchmark harness.

02 · The app itself
Adarna's main window: connection status, audio device pickers, session settings, overlay controls, and the merged, labeled live transcript
Main window — device setup, session settings, and the merged "You" / "Them" transcript, live.
Adarna's dedicated Suggestions window showing a full-length suggested response, with a Copy Latest Suggestion button
Suggestions window — pulled out on its own (Day 27) so a full answer has real room to read.
03 · How it works
Step 01

Listen

It hears both sides of the call — your voice and theirs — the moment the call starts.

WASAPI loopback for system audio, a parallel microphone stream, WebRTC VAD segmenting speech from silence.

Step 02

Transcribe

Speech becomes text on your own machine, tagged with who said it.

faster-whisper in a WSL worker; the two source streams are ordered independently, then merged in true spoken order.

Step 03

Suggest

On a natural pause — or when you press the hotkey — Claude drafts what you could say next.

A long-lived Claude CLI session holds the conversation; mode-aware prompting shapes the answer.

Step 04

Glance

The suggestion streams into a small overlay above the call. You read it and keep talking.

Always-on-top PySide6 window: draggable, resizable, adjustable opacity, optional click-through.

04 · Highlights

Nothing leaves the machine unnecessarily

Transcription runs locally and nothing is written to disk unless you explicitly turn on session recording — the default is a system that forgets.

It knows who said what

Microphone and system audio are transcribed separately, then merged in spoken order and labeled "You" and "Them", so suggestions answer the right person.

Two modes, two shapes of answer

Work Meeting mode replies in a sentence or two. Interview mode returns a short narrative plus bullets, branching again by the kind of question asked.

An overlay that stays out of the way

Always-on-top, draggable, resizable, opacity-adjustable, optionally click-through. Suggestions stream token by token so you can start reading immediately.

Defended against hallucinated speech

Filtering on the speech-to-text output catches both failure modes: confident silence transcribed as words, and thin signal that sends the model free-associating.

Proven on real hardware, not just in review

Several rounds of "correct in code, broken in the room": audio-thread and transcription-worker races, device quirks, timing drift — each root-caused on live calls and fixed.

05 · Under the hood

Two processes, two operating systems, one socket

WSL cannot see native Windows system audio, so capture has to live on Windows — but the speech-to-text stack and the Claude CLI session want a Linux home. Feasibility testing ruled out the simpler single-process design, so Adarna is deliberately split: a native Windows GUI and audio process talking to a WSL worker over a local TCP socket.

The socket carries audio segments one way and streamed suggestion tokens the other. The Claude session is long-lived, so conversation context accumulates instead of being re-sent.

Process A · Windows (native)
  • WASAPI loopback capture — system audio
  • Microphone capture, parallel stream
  • WebRTC VAD segmentation
  • PySide6 overlay + hotkey listener
  • Audio thread ↔ worker synchronization
TCP socket
localhost
segments out
tokens back
Process B · WSL2
  • faster-whisper speech-to-text
  • Hallucination-defense filtering
  • Dual-stream merge + speaker labeling
  • Mode-aware prompt construction
  • Long-lived Claude CLI session
Dual-source transcript — merged in spoken order
t+00:41Loopback"…so how are you handling the audio side of it?"
t+00:44Mic"Two streams, actually —"
t+00:46Loopback"Right, and you keep them apart?"

Each source is transcribed and ordered independently, then interleaved by segment start time and relabeled "You" / "Them" before the prompt is built.

06 · Built with
Python PySide6 / Qt faster-whisper WebRTC VAD Claude Code CLI WASAPI loopback WSL2 TCP socket IPC

Want the long version?

The repository carries the architecture notes, the feasibility write-up that killed the single-process design, and the failure log from live testing. Happy to walk through any of it.