{ } // io.voice → ∗ ⌁ stdin ◌ stdout
Local-first voice control for AI · zero cloud

Speak to anything on your machine.

voxctrl is a programmable voice broker for Linux and Windows that runs 100% on your device. Whisper transcribes locally, your own models do the processing, and not a single byte of audio leaves your machine. Your words. Your hardware. Your control.

$ chmod +x voxctrl.AppImage && ./voxctrl.AppImage
voxctrl · live RECORDING
◉ MIC  ·  whisper.large-v3  ·  cuda fp16
Hermes Agent
▸ raw input um, schedule a team sync, uh, for thursday at three p m ↳ post-processing  ·  remove_fillers + openai_rewrite ▸ delivered Schedule a team sync for Thursday at 3:00 PM
⊳ injectFocused window
⇉ pipe/tmp/agent.in
∷ execclaude --print
≡ file~/journal.md
evdevwhisper.cpp at-spi2piper-tts fifodbus mcpopenai-api vulkancuda waylandx11 evdevwhisper.cpp at-spi2piper-tts fifodbus mcpopenai-api vulkancuda waylandx11
// positioning

Voice is the missing primitive in your AI stack.

Every modern editor speaks MCP. Every shell speaks pipes. Every desktop speaks DBus. voxctrl is the part you've been writing yourself — the bit that turns vibrations into bytes and routes them to the right place.

Output Targets
9
Delivery Types
2
Inference Backends
280+
Tests Passing
// privacy · first-class

Your words. Your machine. Your control.

voxctrl is built for people who don't want their voice on someone else's server. Audio is captured, transcribed, and processed entirely on your hardware — no telemetry, no cloud round-trip, no API key required.

100% on-deviceWhisper runs against your CPU/GPU. Audio buffers never leave RAM.
Zero telemetryNo analytics, no crash reporters, no phone-home on launch or update.
Offline after setupModels download once, then run locally forever. No network calls during use.
MIT & auditableEvery byte of the pipeline is open source. Read it, fork it, run it.
// pipeline

One utterance. Five stages. Many destinations.

Press a key. Speech becomes text. Text gets shaped. Shaped text goes wherever you tell it. Each leg is configurable per binding.

PROCESS-001 ∗ async, lock-free
◉ INPUTevdev
Holdsuper+space
Togglectrl+super+space
Double-tapalt
Double-tap+holdsuper
Chordctrl+super → z
↯ CAPTUREvad
CPAL16kHz mono
RMS gatesilence ⟶ stop
∇ TRANSCRIBEauto-select
NVIDIAwhisper.cpp + cuda
AMD/Intelwhisper.cpp + vulkan
CPUwhisper.cpp int8
Edge / Pimoonshine
Context primeat-spi2 → 300ch
⌬ PROCESSper-target
Snippets"my email" ⟶ …
Spoken punct"period" ⟶ .
Code modeget_user.name
LLM rewriteOpenAI-compatible API
⊳ ROUTE9 types
injectat-spi2
clipboardwl-copy
execshell=false
pipeFIFO
sockettcp / unix
fileappend
dbussignal
httpPOST
webhookPOST + headers
↺ RESPONDloop
FIFO listenerresponse_pipe
TTS enginepiper / pocket-tts / espeak-ng
// capabilities

A real toolkit, not a transcription widget.

Each subsystem composes with the others. Pick what you need, ignore the rest.

01

Global hotkeys

evdev-based input listener on Linux (Wayland + X11) and Win32 hooks on Windows. Five gesture types — hold, toggle, double-tap, double-tap & hold, and chord — each mapped to a different output.

  • Superset shadowing prevents combo conflicts
  • Bare-key bindings & chord (base-keys + subkey) combos
  • Per-binding gesture settings
02

GPU-accelerated Whisper inference

whisper.cpp runs on CUDA (NVIDIA), Vulkan (AMD/Intel), and CPU. Moonshine (ONNX) is available for streaming and edge devices. The right backend is selected by GPU probe at startup.

  • CUDA fp16 on NVIDIA, Vulkan on AMD/Intel
  • Moonshine: streaming, low-latency on CPU
  • Override anytime in Settings → Engine
03

AT-SPI2 context priming

Reads the surrounding text from the focused widget via the accessibility bus and feeds it to Whisper as an initial prompt — improving continuity with what's already on screen.

  • Surrounding text primes the Whisper initial prompt
  • Auto code-mode for terminals & IDEs
  • Injection fallback chain: wtype → xdotool → clipboard+paste
04

MCP server, built-in

voxctrl ships a Model Context Protocol server. Any MCP-capable agent can drive your mic and speak through your speakers.

  • transcribe_voice · speak_text · get_status
  • One-click Claude Desktop registration
  • Unix socket, JSON-RPC 2.0
05

Neural TTS & loopback

Piper (ONNX neural voices) or Pocket-TTS (Rust voice-cloning) for high-quality on-device speech, with espeak-ng as a lightweight fallback. Per-target response_pipe FIFOs let agents stream answers back as audio.

  • ~11 Piper voices + 5 Pocket-TTS cloned voices, in-app downloads
  • Configurable global stop key
  • "SYSTEM RESPONDING" speaking-pill overlay
06

Eight built-in overlay styles

Ocean Wave, Voice Card, Waveform, Pulse Ring, Mono Bars, Neon Spectrum, Retro Terminal, and Analog VU — rendered by a native Slint helper process. Select in Settings → Visual tab. Active-target indicator included on every style.

  • Ocean Wave (default) — tide-pool waves that rise with the mic level
  • Voice Card — 20×6 LED VU matrix · Waveform — scrolling oscilloscope trace
  • Pulse Ring, Mono Bars, Neon Spectrum, Retro Terminal, Analog VU
// workflow

Same engine. Three different jobs.

Bind a different gesture to each. Switch destinations without switching focus.

IDE-aware code dictation

voxctrl detects when VS Code, Neovim, or any terminal is focused via AT-SPI2 and switches to Code Mode automatically — reformatting speech into valid syntax without touching your global Settings.

  • »"function handle user login" → handleUserLogin()
  • »"constant max retries" → MAX_RETRIES
  • »Reads surrounding text as Whisper initial prompt via AT-SPI2
  • »Delivery via wtype/xdotool keystroke injection, with clipboard+paste fallback
~/.config/voxctrl/targets.toml
# IDE target — code mode + AT-SPI2 context
[[target]]
id       = "editor"
label    = "Code Editor"
delivery = "inject"

[editor.processing]
code_mode    = true
atspi_context = true
remove_fillers = true
spoken_punctuation = false

AI agent voice backend

Pipe your voice into any CLI agent through a named FIFO. The agent's response can stream back through response_pipe and be spoken aloud automatically.

  • »Bidirectional: agent reads from .in, writes to .out
  • »Per-target post-processing — keep agent input clean
  • »Each line in response_pipe = one TTS utterance
  • »Listener auto-reopens FIFO on agent restart
~/.config/voxctrl/targets.toml
# bidirectional voice ⇄ agent
[[target]]
id              = "hermes"
label           = "Hermes Agent"
delivery        = "pipe"
pipe_path       = "/tmp/hermes.in"
response_pipe   = "/tmp/hermes.out"
append_newline  = true

[hermes.processing]
remove_fillers      = true
spoken_punctuation  = false

# shell-side
# mkfifo /tmp/hermes.in /tmp/hermes.out
# cat /tmp/hermes.in | hermes > /tmp/hermes.out

Hands-free desktop control

Three different gestures, three different destinations. Hold to dictate. Double-tap to fire commands at an agent. Press a meta-binding to append to your daily journal. All without touching the mouse.

  • »Routing indicator badge confirms which destination is live
  • »DBus interface — wire it into Waybar & Rofi
  • »Quiet mode & noise suppression for open offices
  • »Persistent searchable transcription history
~/.config/voxctrl/bindings.toml
[[binding]]
id        = "dictate_hold"
label     = "Dictate (Hold)"
keys      = ["KEY_LEFTMETA", "KEY_SPACE"]
gesture   = "hold"
target_ids = ["default"]

[[binding]]
id        = "agent_command"
label     = "Agent (Double-tap)"
keys      = ["KEY_LEFTCTRL"]
gesture   = "double_tap"
target_ids = ["hermes"]
tap_ms    = 250

[[binding]]
id        = "journal_capture"
label     = "Journal (Hold)"
keys      = ["KEY_LEFTMETA", "KEY_J"]
gesture   = "hold"
target_ids = ["journal"]
// per-target processing

Same words. Different shapes.

Each target gets its own post-processing pipeline. The agent gets raw text. Your editor gets polished prose. Your journal gets bullets. From the same utterance.

▣ FAN-OUT
▸ raw whisper uh, i think we should, like, schedule a meeting for friday at three
→ editor remove_fillersopenai_rewrite
Schedule a meeting for Friday at 3:00 PM.
→ agent.in none
schedule a meeting for friday at three
→ journal.md openai_rewrite only
- Schedule meeting · Fri 3pm
// mcp gateway

A voice gateway any MCP agent can call.

voxctrl exposes its full pipeline as JSON-RPC 2.0 tools. Claude Desktop, Cursor, Zed — anything that speaks MCP — can open your mic, get a transcript, and queue a spoken response.

transcribe_voicetool

Opens the microphone, returns a transcript when speech ends.

args: { timeout_seconds: 15 }
"Schedule a sync for Thursday"
speak_texttool

Queues text for playback through the configured TTS voice.

args: { text: "On it." }
"spoken"
get_statustool

Returns whether the mic is open and TTS is playing.

{ recording: false, speaking: true }
~/.config/claude/claude_desktop_config.json
{
  "mcpServers": {
    "voxctrl": {
      "command": "socat",
      "args": [
        "STDIO",
        "UNIX-CONNECT:/tmp/voxctrl-mcp.sock"
      ]
    }
  }
}
// overlays

Eight overlay styles built-in. Switch instantly from Settings.

Every overlay shows an active-target indicator — so you always know where your speech is going, before you say a word.

Voice Card
20×6 LED VU matrix
Waveform
scrolling oscilloscope
Pulse Ring
sonar sweep · target lock
Mono Bars
black & white 5-bar meter
Neon Spectrum
16-band equalizer
Retro Terminal
DOS-blue ASCII meter
Analog VU
vintage needle meter
// hardware

Auto-detect your GPU. Pick the right backend.

On startup voxctrl probes nvidia-smi, /dev/nvidia0, and vulkaninfo to select the fastest Whisper engine for your hardware. Override anytime in Settings → Engine.

Hardware Backend Compute Latency Notes
NVIDIA
CUDA 11+
whisper.cpp CUDA fp16 near-instant Requires a CUDA-enabled build (--features cuda); auto-detected via nvidia-smi
AMD RDNA / GCN
vulkan
whisper.cpp Vulkan high-speed Auto-detected via vulkaninfo
Intel Arc / Iris Xe
vulkan
whisper.cpp Vulkan fast Requires Vulkan ICD drivers
CPU only
x86_64 / arm
whisper.cpp CPU int8 reliable Out of the box, no extra steps
Raspberry Pi / Edge
arm · onnxruntime
Moonshine ONNX int8 streaming Select in Settings → Engine
// backends

Two engines. One voice layer.

whisper.cpp handles most hardware. Moonshine shines on edge devices and streaming. voxctrl selects automatically — or you can lock one in Settings → Engine.

01

whisper.cpp

C++ Whisper port with GGUF model support. Runs on CUDA (NVIDIA), Vulkan (AMD/Intel), and CPU. The default engine — selected automatically at startup by GPU probe.

  • CUDA fp16 on NVIDIA, Vulkan on AMD/Intel
  • CPU int8 fallback, no extra setup
  • Models: tiny → large-v3-turbo (GGUF)
  • Default model: large-v3
Best accuracy (large-v3)
~3.1 GB model · 1.5B params
02

Moonshine

Streaming-first ASR using ONNX runtime. Designed for edge and low-latency use cases. Caches encoder state during live speech for near-instant responses.

  • ONNX int8 weights, CPU-native runtime
  • Streaming mode — flexible input window
  • Best for edge devices and RPi
  • Enable: engine.backend = "moonshine"
Streaming · low-latency
base · tiny models available
Feature whisper.cpp Moonshine ✦
Inference style batch / offline streaming / live
GPU acceleration CUDA + Vulkan none (CPU-first)
Model format GGUF ONNX (.ort)
Edge / RPi impractical excellent ✓
Model sizes tiny → large-v3-turbo base · tiny
Default model large-v3 base
// open source · MIT

Ready when you are.

Install in five minutes. Forks and contributions welcome.