fcitx5-voice-input is a Fcitx5 addon for voice input. Captures audio via PulseAudio (or PipeWire fallback), detects speech segments with Silero ONNX VAD, and transcribes via OpenAI-compatible API, Volcengine Doubao streaming ASR, or Mistral Realtime streaming transcription.
- Voice input (OpenAI Whisper API / compatible services, Volcengine Doubao streaming ASR, or Mistral Realtime streaming)
- Silero ONNX VAD for automatic speech segmentation (no push-to-talk required)
- Real-time partial transcript update during speech (Volcengine / Mistral Realtime / OpenAI Realtime backends)
- Queue-based pipeline: Audio Capture → VAD → ASR → EventDispatcher → commit
- Graphical configuration via
fcitx5-configtool - Smart delayed stop on window switching
yay -S fcitx5-voice-input
# or
paru -S fcitx5-voice-input
# or build manually
git clone https://aur.archlinux.org/fcitx5-voice-input.git
cd fcitx5-voice-input
makepkg -siSee Build below.
After installation, open fcitx5-configtool, find Voice Input in the Input Method list and add it.
Then open the Addon config for VoiceInput:
| Option | Description | Default |
|---|---|---|
ActiveBackend |
ASR backend | openai |
VADThreshold |
VAD sensitivity (0-100), higher = less sensitive | 20 |
SilenceThresholdMs |
Silence duration to end utterance (ms) | 800 |
StartFrames |
Consecutive speech frames to trigger onset | 2 |
PreRollMs |
Audio before onset to include (ms) | 300 |
MinSpeechMs |
Minimum utterance duration (ms) | 300 |
MaxSpeechMs |
Maximum utterance duration (ms) | 30000 |
Select your backend from the ActiveBackend dropdown, then click the gear button ⚙ to open that backend's config page.
| Option | Description | Default |
|---|---|---|
BaseUrl |
API base URL | https://api.openai.com/v1 |
ApiKey |
API Key | (required) |
Model |
Model name | whisper-1 |
Language |
Output language | auto (English/中文) |
ApiMode |
API mode: whisper (standard Whisper API), chat (OpenAI-compatible Chat Completions audio, e.g. DashScope/Xiaomi MiMo) or realtime (GPT Realtime streaming transcription) |
whisper |
EnableItn |
Send DashScope-specific asr_options.enable_itn; recommended off for Xiaomi MiMo (its API only defines language; true was also accepted in testing, but relies on undocumented behavior) |
true |
CommitIntervalMs |
Periodic commit interval (ms) in realtime mode; keeps emitting partials for long speech with no pauses | 5000 |
LLMEnabled |
LLM post-processing | false |
LLMModel |
Post-processing LLM model | (empty) |
LLMSystemPrompt |
Post-processing system prompt | (empty) |
LLMStream |
LLM streaming output | true |
AutoCommit |
Auto-commit when no LLM | true |
Set ActiveBackend=openai, click the gear button, and fill in your API Key. Compatible with any OpenAI-format service:
-
OpenAI —
https://api.openai.com/v1 -
Groq —
https://api.groq.com/openai/v1 -
SiliconFlow —
https://api.siliconflow.com/v1 -
Xiaomi MiMo —
https://api.xiaomimimo.com/v1 -
Alibaba Cloud DashScope —
https://dashscope.aliyuncs.com/compatible-mode/v1Chat mode (OpenAI-compatible Chat Completions): DashScope's
qwen3-asr-flashand Xiaomi MiMo'smimo-v2.5-asrare batch endpoints that use the Chat Completions API instead of the standard Whisper API: the addon uploads one WAV segment per utterance and gets the transcript back in a single response (no realtime streaming). SetApiMode=chatfor both; for MiMo also setEnableItn=false(itsasr_optionsonly defineslanguage;truewas also accepted in testing, but relies on undocumented behavior).# DashScope BaseUrl=https://dashscope.aliyuncs.com/compatible-mode/v1 ApiKey=your_dashscope_api_key Model=qwen3-asr-flash ApiMode=chat Language=zh# Xiaomi MiMo BaseUrl=https://api.xiaomimimo.com/v1 ApiKey=your_mimo_api_key Model=mimo-v2.5-asr ApiMode=chat Language=zh EnableItn=falseGPT Realtime streaming (optional): Set
ApiMode=realtimeto transcribe incrementally (partials update the preedit live, final commits on speech end) via the OpenAI Realtime transcription session. With an OpenAI account, usegpt-live-transcribe(recommended, true continuous deltas) orgpt-realtime-whisper(compatible alternative).BaseUrl=https://api.openai.com/v1 ApiKey=your_openai_api_key Model=gpt-live-transcribe ApiMode=realtime Language=zhNote: Realtime mode requires a WebSocket-capable endpoint, and
gpt-live-transcribe/gpt-realtime-whisperneed a paid-tier account (Free is not supported). Audio is sent at 24kHz (the addon automatically upsamples the captured 16kHz).
Set ActiveBackend=volcengine, click the gear button to open the Volcengine config page.
| Option | Description | Default |
|---|---|---|
Endpoint |
WebSocket endpoint | wss://openspeech.bytedance.com/api/v3/sauc/bigmodel_async |
AuthMode |
Auth mode: api_key or app_access_key |
api_key |
ApiKey |
API Key (new console) | (required for api_key mode) |
AppKey |
App Key (legacy console) | (required for app_access_key mode) |
AccessKey |
Access Token (legacy console) | (required for app_access_key mode) |
ResourceId |
Resource ID | volc.seedasr.sauc.duration |
ChunkMs |
Audio chunk size per packet (ms) | 200 |
EnableITN |
Enable ITN text normalization | true |
EnablePunc |
Enable punctuation | true |
EnableDDC |
Enable DDC smoothing | false |
EnableNonstream |
Enable second-pass recognition | true |
EndWindowMs |
Server-side end-of-speech window (ms) | 800 |
Volcengine authentication requires a resource purchased from the Volcengine console. The Resource ID depends on your model and purchase plan:
- Model 2.0 hourly:
volc.seedasr.sauc.duration - Model 2.0 concurrency:
volc.seedasr.sauc.concurrent - Model 1.0 hourly:
volc.bigasr.sauc.duration - Model 1.0 concurrency:
volc.bigasr.sauc.concurrent
Troubleshooting: If recognition fails, check the addon log for X-Tt-Logid and provide it to Volcengine support.
Set ActiveBackend=mistral, click the gear button to open the Mistral config page.
| Option | Description | Default |
|---|---|---|
BaseUrl |
API base URL | https://api.mistral.ai/v1 |
ApiKey |
API Key | (required) |
Model |
Model name | voxtral-mini-transcribe-realtime-2602 |
CommitIntervalMs |
Periodic commit interval (ms); keeps emitting partials for long speech | 5000 |
TargetStreamingDelayMs |
Target streaming delay (ms, 0-1000); higher = lower latency but more aggressive partials | 0 |
This backend uses the Mistral Realtime transcription API over WebSocket. Audio is sent as 16kHz PCM directly (no resampling needed). Partial transcription.text.delta events update the preedit live; the final transcription.done commits on speech end. Connection drops are handled with automatic reconnection keeping the same session.
- Switch to Voice Input IME
- Start speaking — VAD automatically detects speech and records
- With the Volcengine, Mistral Realtime or OpenAI Realtime backend, partial recognition text appears in the preedit area in real-time as you speak
- Stop speaking (default 800ms silence timeout) — final recognition result is committed
- Stay in Voice Input mode and continue speaking for consecutive recognition
When switching windows, the plugin delays stop by 200ms. Quick switch-back cancels the stop, avoiding unnecessary restarts.
fcitx5— Input method frameworklibpulse-simple— PulseAudio capture (preferred)libpipewire-0.3— PipeWire capture (fallback)jsoncpp— JSON parsinglibcurl— HTTP/WebSocket client (>= 7.86.0, required for ASR)zlib— Gzip compression (required for Volcengine backend)onnxruntime— Silero VAD ONNX Runtime
Arch Linux:
sudo pacman -S fcitx5 pulseaudio pipewire jsoncpp curl onnxruntime-cpu zlibDebian/Ubuntu:
sudo apt install fcitx5 libpulse-dev libpipewire-0.3-dev libjsoncpp-dev libcurl4-openssl-dev libonnxruntime-dev zlib1g-dev
# Clone and init submodules (for Silero VAD model)
git clone https://github.com/devcxl/fcitx5-voice-input.git
cd fcitx5-voice-input
git submodule update --init --recursive
# Configure
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
# Build
cmake --build build -j"$(nproc)"
# Install
sudo cmake --install build --prefix /usr| Option | Default | Description |
|---|---|---|
BUILD_TESTS |
OFF |
Build tests |
ONNXRUNTIME_ROOT |
— | Custom ONNX Runtime install path |
- API Key Security: API keys are stored in plain text in
~/.config/fcitx5/conf/voiceinput-openai.conf,voiceinput-volcengine.confandvoiceinput-mistral.conf. Ensure proper file permissions - Network Required: OpenAI / Volcengine / Mistral backends require internet. Local ASR can be added via the
AsrEngine/AsrSessioninterfaces - Audio Device: The input device is auto-selected at startup (prefers
alsa_input.*microphones; Monitor and echo-cancel sources are skipped). Manual device selection is not supported yet - VAD Model: The Silero VAD model is distributed via git submodule (
third_party/silero-vad/) and copied to the install directory at build time. Rungit submodule update --init --recursivebefore building - PipeWire Users: The PulseAudio backend works fine under pipewire-pulse. Native PipeWire is only used as fallback when PulseAudio is completely unavailable
- Local ASR: Not yet implemented. The codebase provides
AsrEngine(session factory) /AsrSessionabstract interfaces for future local ASR integration - Window Switching: A 200ms delayed stop prevents unnecessary restarts on quick window switches. Long inactivity will stop the pipeline
Audio Capture Thread → FrameQueue → VAD Worker → SpeechEventQueue → ASR Dispatcher → AsrSession workers
→ ResultCoordinator (ordering + optional LLM post-processing) → ResultQueue → EventDispatcher → commitString
SpeechEvent types: Begin (speech onset) → Audio (32ms frames, batched to 200ms by Pipeline) → End (silence) / Cancel (too short)
Main thread + capture thread + VAD worker + per-session ASR workers, connected by ThreadSafeQueue. Every utterance is an AsrSession (factory: AsrEngine::StartSession); finished sessions are reaped by SessionReaper with timeout, and concurrent results are delivered in creation order. See ARCHITECTURE.md for details.
GNU Lesser General Public License v3.0

