Files
voculinux/README.md
T
Sergey SilaevandGitHub 582d494633 chore(build): uv tooling, a Python 3.11 floor, and verified model downloads (epic #701, phases 2.5 & 5) (#713)
* chore(build): migrate justfile tooling to uv

All recipes now run through 'uv run' against .venv, with a shared
DEV_EXTRAS variable (dev + vad) because uv syncs the environment
exactly and would otherwise uninstall the dev tools between
recipes. 'deps' installs dev+vad; new 'deps-all' covers every
extra. 'build' switches to 'uv build'; 'version' uses --no-sync.

Bump [tool.uv] required-version to >=0.12,<0.13 for uv 0.12.x, and
raise the mypy python_version target to 3.12: mypy 1.19 in the lock
cannot target 3.9 and numpy 2.x stubs need a 3.12 target to parse
(mypy is not run in CI or pre-commit; this only affects 'just
typecheck').

* fix(tests): isolate test runs from real XDG state; fix Arch model-path crash

Local test runs failed en masse (185 failures) while CI stayed
green: tests picked up the developer's real ~/.local/share/vocalinux
models via the default XDG paths and switched IBus/keyboard code
paths through the desktop session env (XDG_CURRENT_DESKTOP/
XDG_SESSION_TYPE on GNOME/Wayland, issue #478 branches). conftest
now points XDG base dirs at a throwaway session-wide directory and
clears session variables at import time, mirroring a fresh CI
runner (paths like MODELS_DIR freeze at first import during
collection, so fixture-time isolation is too late).

Also guard the Arch branch of _get_system_model_paths(): it removed
/usr/local/share/vocalinux/models unconditionally and crashed with
ValueError on Arch hosts when a custom XDG_DATA_DIRS never added
that path. Add regression tests, and make the lock-file test assert
the actual $XDG_DATA_HOME/vocalinux contract instead of the
hardcoded ~/.local/share default.

* fix(tests): keep the IBus engine double a plain class

Python 3.14's unittest.mock re-instantiates a user subclass when it builds
child mocks (klass(name=...)). VocalinuxEngine inherits from whatever
IBus.Engine resolves to, and the test module bound that to the MagicMock
class itself, so every engine instantiation raised

    TypeError: VocalinuxEngine.__init__() got an unexpected keyword argument 'name'

on 3.14 while passing on 3.13. Replace it with a plain stand-in class that
still hands out per-instance MagicMocks for the IBus API surface the engine
touches.

The same pattern remains in test_ibus_engine.py, test_ibus_engine_utils.py,
test_ibus_active_engine_guard.py and test_ibus_xkb_wayland.py; those never
instantiate the engine, so they are unaffected for now.

* fix(install): build the venv from the system Python

install.sh looked up a bare `python3` from PATH. Started from an activated
virtualenv — a shell left in uv's .venv after `just deps` — it built venv/
from that interpreter, where distro PyGObject is invisible even with
--system-site-packages, and the run aborted with

    Distro PyGObject (python3-gi / python3-gobject) is not importable in the venv.

A mismatched venv/ then survived every retry, because the installer reuses
whatever venv it finds.

- drop an inherited VIRTUAL_ENV (and its bin from PATH) before any
  interpreter lookup
- select the interpreter explicitly: $SYSTEM_PYTHON (default
  /usr/bin/python3) or PATH python3, preferring one that can import gi,
  and create the venv with it instead of `python3`
- recreate venv/ when it was built by a different interpreter
- name the interpreter in the PyGObject guard's error

Documents the two environments (uv's .venv for tooling, venv/ for the
installed app) in CONTRIBUTING, the justfile header and AGENTS.md, and adds
the mismatch symptom to the INSTALL troubleshooting section.

* chore(python): raise the supported floor to 3.11

requires-python promised 3.9 while the CI matrix ran 3.9/3.10/3.11/3.13,
the classifiers advertised up to 3.14, mypy targeted 3.12 and install.sh
enforced 3.9 — five different answers to "which Python does this support".

Settle on 3.11 everywhere: pyproject (requires-python, classifiers, black
targets), install.sh's MIN_VERSION, check-system-deps.sh, the distro package
map, the CI matrix (now 3.11-3.14, matching the classifiers), the release and
nightly workflows, and the docs.

mypy now targets the floor instead of 3.12, so type checking covers what we
promise; numpy 2.x ships stubs in 3.12 syntax that a 3.11 target cannot
parse, so its imports are skipped. (mypy has 71 pre-existing errors either
way; no CI job gates on it.)

uv.lock and the requirements/* exports are regenerated — dropping 3.9/3.10
removes most of the version-conditional resolution branches.

tests/test_python_version_policy.py pins the invariant: install.sh's floor,
requires-python, the classifiers and the CI matrix must agree.

* ci: run lint and tests from uv.lock

The lock file and the hash-pinned exports were not enforced anywhere: CI
still built a venv by hand and installed unpinned `PyGObject` plus
`-e ".[dev,vad]"`, so the tool versions it checked against had nothing to do
with the ones `just lint` uses locally.

Both Python jobs now use astral-sh/setup-uv and run through `uv sync
--locked` / `uv run --locked`, which also fails the build when uv.lock drifts
from pyproject.toml.

Partially covers phase 5 of #701 (tests install from the lock, lock freshness
gate); trusted publishing, artifact checksums and action SHA pinning are
still open there.

* ci: lint from a dedicated dependency group

The lint job failed on this branch: `uv run --extra dev` syncs the whole
project, so it tried to build pyaudio from source on a runner that installs
no system dependencies.

    src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: No such file or directory

Move black/isort/flake8 out of the `dev` extra into a `lint` dependency
group. CI runs `uv run --locked --only-group lint`, which installs the three
pure-Python tools and skips the project entirely — no portaudio or
girepository headers needed. `just deps` and DEV_EXTRAS request the group
alongside the dev extras, so the local environment still carries test and
lint tooling at once and `just lint` matches CI version for version.

pre-commit is unaffected: its hooks pin their own tool versions upstream.

* fix(install): never configure an engine the venv cannot import

vosk became an optional extra in #705, but the installer still writes
`"engine": "vosk"` into config.json on the whisper.cpp fallback path even
when installing the extra only produced a warning. config.json also survives
reinstalls — every writer guards on "file does not exist" — so an engine
picked by an earlier attempt outlives the venv that supported it. Either way
Vocalinux dies at startup:

    ModuleNotFoundError: No module named 'vosk'

- the fallback now writes the vosk config only when `import vosk` actually
  succeeds, and otherwise leaves the engine configuration alone
- a new verify_configured_engine() runs near the end of the install: if
  config.json selects vosk and the venv cannot import it, it says so and
  prints both fixes instead of leaving a broken install behind

* feat(models): verify every model download against a pinned digest

Pins a sha256/md5 per downloadable speech model in
src/vocalinux/utils/model_checksums.txt and verifies against it in both
install.sh and the runtime downloaders, before the file is moved into place.
Verification fails closed. Covers phase 2.5 of #701; see the PR for details.

* docs(agents): rebase AGENTS.md onto the #727 rewrite

* fix(install): hash models that are already on disk instead of trusting them

* refactor(models): one download path per engine, and fix Whisper's

* docs(install): drop distros that cannot meet the 3.11 floor

* docs: retire the distros and Python versions the 3.11 floor rules out

* fix(install): abort instead of warning when Python is below the floor

* fix(install): fall back to the system Python, not the one on PATH

* fix(install): match an existing venv by installation, not by X.Y

* fix(install): repair a config naming an engine the venv cannot import

* fix(models): pin VOSK by the sha256 of bytes we fetched, not upstream's md5

* fix(justfile): request the dev set in every recipe that syncs

* test(version): scan the docs and website trees for a stale Python floor

* docs: correct the stale model-checksum and distro claims

* fix(models): stamp the VOSK tree the app extracts, as the installer does

* fix(install): replace an unverified VOSK model only once its successor is ready

* docs(install): align the Fedora floor with the rest of the tree

* test(install): drop an f-string with no placeholders

* test(models): stub the downloader probe the VOSK installer test relies on

* docs: drop the long dashes from two model-checksum comments

* fix(install): gate on the interpreter, not on the distro release label

* fix(justfile): export the lint group into requirements/dev.txt

* fix(models): unpack the VOSK tree into staging and stamp it before the swap

* fix(whisper): adopt a checkpoint an earlier release stored under the catalog name

* docs(settings): state what a stray Whisper copy really means for deletion

* fix(models): hash a whisper.cpp model found on disk before it reaches ctypes

* docs(contributing): stop telling readers to uninstall their linters

* fix(install): stop warning off distros the project documents as supported

* docs(distros): file the supported derivatives under supported
2026-08-24 00:25:06 -07:00

517 lines
22 KiB
Markdown

<div align="center">
<img src="https://github.com/user-attachments/assets/56dabe5c-5c65-44d5-a36a-429c9fea0719" width="50" height="50" alt="Vocalinux">
# Vocalinux
**Voice-to-text for Linux, finally done right!**
<!-- Badge rows ordered narrowest → widest (steps out into the hero) -->
<!-- Values + packaging (narrow) -->
[![Privacy: 100% offline](https://img.shields.io/badge/privacy-100%25%20offline-success)](https://github.com/VocaHQ/vocalinux#features)
[![X11 & Wayland](https://img.shields.io/badge/display-X11%20%7C%20Wayland-lightgrey)](https://github.com/VocaHQ/vocalinux#features)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![Discord](https://img.shields.io/discord/1538633755877580810?logo=discord&logoColor=white&label=Discord)](https://discord.gg/t6muquAJbm)
[![VocaHQ](https://img.shields.io/badge/VocaHQ-vocahq.com-1a7f4e)](https://vocahq.com)
<!-- Identity + quality (medium) -->
[![GitHub release](https://img.shields.io/github/v/release/VocaHQ/vocalinux)](https://github.com/VocaHQ/vocalinux/releases)
[![PyPI](https://img.shields.io/pypi/v/vocalinux)](https://pypi.org/project/vocalinux/)
[![AUR](https://img.shields.io/aur/version/vocalinux)](https://aur.archlinux.org/packages/vocalinux)
[![Vocalinux CI](https://github.com/VocaHQ/vocalinux/actions/workflows/unified-pipeline.yml/badge.svg?branch=main)](https://github.com/VocaHQ/vocalinux/actions/workflows/unified-pipeline.yml?query=branch%3Amain)
[![codecov](https://codecov.io/gh/VocaHQ/vocalinux/branch/main/graph/badge.svg)](https://codecov.io/gh/VocaHQ/vocalinux)
[![Follow on X](https://img.shields.io/badge/Follow%20%40vocahq-000000?style=flat&logo=x&logoColor=white)](https://x.com/vocahq)
<!-- Distros (widest; base plate above the hero) -->
[![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04+-E95420?logo=ubuntu&logoColor=white)](docs/DISTRO_COMPATIBILITY.md)
[![Debian](https://img.shields.io/badge/Debian-12+-A81D33?logo=debian&logoColor=white)](docs/DISTRO_COMPATIBILITY.md)
[![Fedora](https://img.shields.io/badge/Fedora-39+-51A2DA?logo=fedora&logoColor=white)](docs/DISTRO_COMPATIBILITY.md)
[![Arch](https://img.shields.io/badge/Arch-rolling-1793D1?logo=archlinux&logoColor=white)](docs/DISTRO_COMPATIBILITY.md)
[![openSUSE](https://img.shields.io/badge/openSUSE-Tumbleweed-73BA25?logo=opensuse&logoColor=white)](docs/DISTRO_COMPATIBILITY.md)
</div>
Linux has always punched above its weight, except when it comes to voice typing. Vocalinux fixes that.
It's a free, AGPL-3.0-licensed desktop app that lets you dictate text into *any* application, on X11 or Wayland, using fully offline speech recognition. Pick from three engines (whisper.cpp, OpenAI Whisper, or VOSK), get automatic GPU acceleration via Vulkan, and control it all with customizable keyboard shortcuts: toggle or push-to-talk.
No internet required. No data leaves your machine. Just speak and type.
## 📚 What's New in v0.16.0
> **0.16.0** adds an in-app update checker with tray notifications, defaults new installs to hold Right Alt push-to-talk, makes the language list searchable, lets you delete unused downloaded models, and adds a family dictation tone picker. The project license is AGPL-3.0. The installer is hardened (Justfile, uv lockfiles, distro python3-gi). The app icon, tray states, and site favicons use the shared Voca family mic.
### Highlights
| Feature | Description |
|---------|-------------|
| **Update checker** | Settings → About checks stable/nightly channels; tray shows Update Available when GitHub has a newer release (#631, #645) |
| **Right Alt PTT default** | New installs default to hold Right Alt (push-to-talk); existing configs keep their shortcut (#648) |
| **Searchable languages** | Type to filter the Speech Model language list (#672) |
| **Delete unused models** | Remove leftover downloaded speech models from Settings (#671) |
| **AGPL-3.0** | License aligned with other VocaHQ projects (#660) |
| **Family mic icons** | App icon, tray states, and site favicons use the shared Voca family mic (#704) |
| **Tone picker** | Settings → Audio: Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off, plus Preview. New installs default to Voca. Catalog uses family preview WAVs (#707, #708) |
| **Installer** | Justfile, uv lockfiles, distro python3-gi required (no pip sdist of PyGObject). Epic #701 still open (#700, #705, #706) |
### Also in this release
- IBus: safer scoped injection, engine restore after teardown, XKB layout restore on X11 (#623, #643, #665)
- Audio: filter unsafe virtual capture devices; open stereo mics at native channel count; catalog tones are the family preview WAVs, not the synthesized #707 files (#629, #673, #708)
- Clipboard: restore after ydotool paste; text-only reads and safer overlapping restore (#588, #646)
- GPU / AppImage: honor bundled GPU libs and skip software Vulkan; ship transitive GI typelibs (AppImage fix already hotfixed onto the v0.15.0 AppImages) (#674, #637)
- Settings / tray: separate Close from Test Dictation; reuse Settings/Logs windows; prefer Ayatana AppIndicator on KDE; optional missing-tray warning toggle (#670, #669, #621, #628)
- Test Dictation: no longer reports no speech when recognition never started (#702)
- Settings: About page groups this app, the VocaHQ family, and talk-to-us links (#718)
- Installer / downloads / tests: gate `util-linux-extra` to Ubuntu 24.04+; report failed model downloads; stop tests from overwriting real `config.json` (#635, #690, #694)
- Website: vocalinux.com restyled to the Voca family workbench; Discord and X links point at VocaHQ (#728, #729, #722, #717)
See [docs/UPDATE.md](docs/UPDATE.md) and the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.0).
---
## Features
- 🎤 **Toggle or Push-to-Talk** activation modes
- ⚡ **Real-time transcription** with minimal latency
- 🌎 **Universal compatibility** across all Linux applications
- 🔒 **100% Offline operation** for privacy and reliability
- 🤖 **whisper.cpp by default** - High-performance C++ speech recognition
- 🎮 **Universal GPU support** - Vulkan acceleration for AMD, Intel, and NVIDIA
- 🎨 **System tray integration** with visual status indicators
- 🚀 **Start on login support** via XDG autostart (desktop-session startup)
- 🔊 **Pleasant audio feedback** - smooth gliding tones, headphone-friendly
- ⚙️ **Graphical settings** dialog for easy configuration
- 📦 **3 engine choices** - whisper.cpp (default), OpenAI Whisper, or VOSK
## 📸 Screenshots
Vocalinux in action. Settings gallery shots may lag the newest UI. Full gallery on the [website screenshots page](https://vocalinux.com/screenshots/).
### Product
<table>
<tr>
<td align="center" width="50%">
<img src="web/public/screenshots/00-transcription.png" alt="Transcription in Action" width="350"><br>
<em>Real-time voice-to-text transcription</em>
</td>
<td align="center" width="50%">
<img src="web/public/screenshots/02-system-tray.png" alt="System Tray" width="350"><br>
<em>System tray with listening indicator</em>
</td>
</tr>
<tr>
<td align="center">
<img src="web/public/screenshots/05-about-view.png" alt="About View" width="350"><br>
<em>About &amp; Updates in Settings</em>
</td>
<td align="center">
<img src="web/public/screenshots/03-log-viewer.png" alt="Log Viewer" width="350"><br>
<em>Log viewer for debugging</em>
</td>
</tr>
</table>
### Settings
<table>
<tr>
<td align="center" width="33%">
<img src="web/public/screenshots/settings-speech-engine.png" alt="Speech Engine settings" width="260"><br>
<em>Speech Engine</em>
</td>
<td align="center" width="33%">
<img src="web/public/screenshots/settings-recognition.png" alt="Recognition settings" width="260"><br>
<em>Recognition</em>
</td>
<td align="center" width="33%">
<img src="web/public/screenshots/settings-audio.png" alt="Audio settings" width="260"><br>
<em>Audio</em>
</td>
</tr>
<tr>
<td align="center">
<img src="web/public/screenshots/settings-performance.png" alt="Performance settings" width="260"><br>
<em>Performance</em>
</td>
<td align="center">
<img src="web/public/screenshots/settings-general.png" alt="General settings" width="260"><br>
<em>General</em>
</td>
<td align="center">
<img src="web/public/screenshots/settings-advanced.png" alt="Advanced tuning and settings" width="260"><br>
<em>Advanced</em>
</td>
</tr>
</table>
## 🚀 Quick Install
### Interactive Install (Recommended)
Our new interactive installer guides you through setup with intelligent hardware detection:
```bash
curl -fsSL raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh
```
**Choose your engine:**
1. **whisper.cpp** ⭐ (Recommended) - Fast, works with any GPU via Vulkan
2. **Whisper** (OpenAI) - PyTorch-based, NVIDIA GPU only
3. **VOSK** - Lightweight, works on older systems
The installer will:
- **Auto-detect your hardware** (GPU, RAM, Vulkan support)
- **Recommend the best engine** for your system
- **Download the appropriate model** (~74MB for the default whisper.cpp tiny model)
- **Install neural VAD support** when ONNX Runtime is available
- **Install in ~1-2 minutes** (vs 5-10 min with old Whisper)
> **Note**: Always installs the latest release. For a specific version, check [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases).
### Installation Options
**Default (whisper.cpp - recommended):**
```bash
curl -fsSL raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh
```
Fastest installation (~1-2 min), universal GPU support via Vulkan.
**Whisper (OpenAI) - if you prefer PyTorch:**
```bash
curl -fsSL raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh --engine=whisper
```
NVIDIA GPU only (~5-10 min, downloads PyTorch + CUDA).
**VOSK only - for low-RAM systems:**
```bash
curl -fsSL raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh && bash /tmp/vl.sh --engine=vosk
```
Lightweight option (~40MB), works on systems with 4GB RAM.
### Arch Linux (AUR)
```bash
yay -S vocalinux
```
See [docs/AUR.md](docs/AUR.md).
### Flatpak (any distro)
For a sandboxed, distro-independent install (great for NixOS, Fedora Silverblue,
Steam Deck, and anywhere else), build the Flatpak from the bundled manifest:
```bash
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
flatpak-builder --user --install --force-clean build-dir \
packaging/flatpak/com.vocalinux.Vocalinux.yml
flatpak run com.vocalinux.Vocalinux
```
The Flatpak ships the whisper.cpp engine with Vulkan GPU support and runs through
XWayland on Wayland sessions. See [`packaging/flatpak/README.md`](packaging/flatpak/README.md)
for build details, permissions, and Flathub submission notes. Flathub publishing
is in progress.
### Alternative: Install from Source
```bash
# Clone the repository
git clone https://github.com/VocaHQ/vocalinux.git
cd vocalinux
# Run the interactive installer (engine picker + GPU detection)
./install.sh
# Or pick the engine up front
./install.sh --engine=whisper_cpp # whisper.cpp (default, GPU-accelerated)
./install.sh --engine=vosk # lightweight VOSK
```
The installer handles everything: system dependencies, Python environment, speech models, and desktop integration.
### 🌙 Nightly Releases (Bleeding Edge)
For developers and early adopters who want to test the latest features, check out our [GitHub Releases page](https://github.com/VocaHQ/vocalinux/releases) which includes both beta and nightly builds.
> **⚠️ Warning**: Nightly releases contain the absolute latest code and may be unstable. For production use, we recommend using the latest beta release.
Nightly builds are automatically generated from the `main` branch every day. They include all merged changes but haven't undergone the same testing as beta releases.
**Release Channels:**
- **Beta** (Recommended) - Tested pre-releases with known features
- **Nightly** - Untested bleeding edge with latest commits
### After Installation
```bash
# If ~/.local/bin is in your PATH (recommended):
vocalinux
# Or activate the virtual environment first:
source ~/.local/bin/activate-vocalinux.sh
vocalinux
# Or run directly:
~/.local/share/vocalinux/venv/bin/vocalinux
```
Or launch it from your application menu!
## 📋 Requirements
- **OS**: Linux (tested on Ubuntu 24.04+, Debian 12+, Fedora 39+, Arch Linux, openSUSE Tumbleweed)
- **Python**: 3.11 or newer
- **Display**: X11 or Wayland
- **Hardware**: Microphone for voice input
**Note:** See [Distribution Compatibility](docs/DISTRO_COMPATIBILITY.md) for distribution-specific information and experimental support for Gentoo, Alpine, Void, Solus, and more.
## 🎙️ Usage
### Voice Dictation
1. **Push-to-talk (default)**: Hold Right Alt (Option on Mac-layout keyboards) and speak
2. Speak clearly into your microphone
3. **Release** the key to stop, or switch to **Toggle mode** in Settings (double-tap a key to start/stop)
### Voice Commands
| Command | Action |
|---------|--------|
| "new line" | Inserts a line break |
| "period" / "full stop" | Types a period (.) |
| "comma" | Types a comma (,) |
| "question mark" | Types a question mark (?) |
| "exclamation mark" | Types an exclamation mark (!) |
| "delete that" | Deletes the last sentence |
| "capitalize" | Capitalizes the next word |
### Command Line Options
```bash
vocalinux --help # Show all options
vocalinux --debug # Enable debug logging
vocalinux --engine whisper_cpp # Use whisper.cpp engine (default)
vocalinux --engine whisper # Use OpenAI Whisper engine
vocalinux --engine vosk # Use VOSK engine
vocalinux --model medium # Use medium-sized model
vocalinux --model medium.en-q5_0 # Use exact whisper.cpp model variant
vocalinux --model large-v3-turbo # Use large-v3 Turbo with whisper.cpp
vocalinux --wayland # Force Wayland mode
vocalinux --start-minimized # Start without first-run modal prompts
```
### Autostart on Login
Vocalinux uses the Linux desktop standard for autostart:
- **Mechanism**: XDG autostart desktop entry (`vocalinux.desktop`)
- **Path**: `$XDG_CONFIG_HOME/autostart/` or `~/.config/autostart/` (fallback)
- **Launch mode**: Starts as a regular **user desktop app** in your graphical session
- **Not used**: No `systemd` unit/service is created by Vocalinux for autostart
How to enable/disable:
- First-run welcome dialog
- Tray menu: **Start on Login**
- Settings dialog: **Start on Login**
Compatibility notes:
- Works on mainstream desktop environments (GNOME, KDE, Xfce, Cinnamon, MATE, LXQt)
- On minimal/custom window-manager sessions, an autostart handler may be required
(for example DE-specific startup hooks or tools like `dex`)
## ⚙️ Configuration
Configuration is stored in `~/.config/vocalinux/config.json`:
```json
{
"speech_recognition": {
"engine": "whisper_cpp",
"model_size": "tiny",
"vad_sensitivity": 3,
"silence_timeout": 2.0
}
}
```
For whisper.cpp, `model_size` may be a size such as `tiny` or an exact ggml model ID
such as `medium.en-q5_0` or `large-v3-turbo`. You can also configure this through
the graphical Settings dialog, where whisper.cpp models are split into **Model Size**
and **Specialization** controls. Unused leftover downloads can be deleted from
**Unused downloads** on the Speech Model page (expand the section, then delete
one model at a time).
### Neural Voice Activity Detection
Vocalinux ships with a Silero VAD model and uses it automatically when `onnxruntime` is available. The official installer attempts to install this support automatically. Without it, recording falls back to the simpler amplitude-threshold VAD.
For manual or PyPI installs, enable neural VAD with:
```bash
pip install "vocalinux[vad]"
```
Restart Vocalinux after install. The Recognition tab in Settings shows which backend is active. The same `vad_sensitivity` (1-5) works for both -- it's mapped to a Silero probability threshold internally (1 = 0.8, 5 = 0.3).
## 🔧 Development Setup
```bash
# Clone and install in dev mode
git clone https://github.com/VocaHQ/vocalinux.git
cd vocalinux
./install.sh --dev
# Activate environment
source venv/bin/activate
# Run tests
pytest
# Run from source with debug
python -m vocalinux.main --debug
```
## 📁 Project Structure
```
vocalinux/
├── src/vocalinux/ # Main application code
│ ├── speech_recognition/ # Speech recognition engines (VOSK, Whisper, whisper.cpp)
│ │ └── recognition_manager.py # Unified engine interface
│ ├── text_injection/ # Text injection (X11/Wayland)
│ ├── ui/ # GTK UI components
│ └── utils/ # Utility functions
│ ├── whispercpp_model_info.py # whisper.cpp model metadata & hardware detection
│ └── vosk_model_info.py # VOSK model metadata
├── tests/ # Test suite
├── scripts/ # Development utilities
│ └── generate_sounds.py # Sound generation script
├── resources/ # Icons and sounds
├── docs/ # Documentation
└── web/ # Website source
```
## 📖 Documentation
- [Installation Guide](docs/INSTALL.md) - Detailed installation instructions
- [Update Guide](docs/UPDATE.md) - How to update Vocalinux
- [User Guide](docs/USER_GUIDE.md) - Complete user documentation
- [Distribution Compatibility](docs/DISTRO_COMPATIBILITY.md) - Distro/session behavior and caveats
- [Contributing](CONTRIBUTING.md) - Development setup and contribution guidelines
## Repository mirrors
GitHub is the **primary** forge for issues, pull requests, CI, and releases.
| Role | URL |
|------|-----|
| Primary | https://github.com/VocaHQ/vocalinux |
| Read-only mirror (Codeberg) | https://codeberg.org/jatinkrmalik/vocalinux |
The Codeberg copy is a read-only source backup. Open issues and PRs on GitHub only.
## 🔊 Sound Customization
Vocalinux uses smooth, pleasant gliding tones for audio feedback:
- **Start**: Ascending F4→A4 (0.6s) - positive, uplifting
- **Stop**: Descending A4→F4 (0.6s) - resolves completion
- **Error**: Lower descending E4→C4 (0.7s) - gentle but noticeable
All sounds use pure sine waves with smoothstep interpolation for buttery smooth pitch transitions - perfect for headphone use!
### Regenerate Sounds
To modify or regenerate the notification sounds:
```bash
python scripts/generate_sounds.py
```
This script generates all three sounds using the same smooth glide algorithm. You can edit the frequencies, durations, and amplitudes in the script to customize the sounds to your preference.
## 🗺️ Roadmap
- [x] ~~Custom icon design~~ ✅
- [x] ~~Graphical settings dialog~~ ✅
- [x] ~~Whisper AI support~~ ✅
- [x] ~~Multi-language support (FR, DE, RU)~~ ✅
- [x] ~~whisper.cpp integration (default engine)~~ ✅
- [x] ~~Vulkan GPU support~~ ✅
- [x] In-app update mechanism ✅
- [x] ~~Wayland support via IBus~~ ✅
- [x] ~~Flatpak packaging~~ ✅ (Flathub submission in progress)
- [ ] Application-specific commands
- [ ] Debian/Ubuntu package (.deb)
- [ ] Voice command customization
## 🌐 The Voca Ecosystem
Vocalinux is part of [VocaHQ](https://vocahq.com). Same privacy-first, offline voice dictation idea, one app per operating system.
| Platform | Project | Website | GitHub | Status |
|----------|---------|---------|--------|--------|
| 🐧 Linux | **VocaLinux** | [vocalinux.com](https://vocalinux.com) | [VocaHQ/vocalinux](https://github.com/VocaHQ/vocalinux) | ✅ Stable v0.16.0 |
| 🍎 macOS | **VocaMac** | [vocamac.com](https://vocamac.com) | [VocaHQ/vocamac](https://github.com/VocaHQ/vocamac) | 🚀 Beta |
| 🪟 Windows | **VocaWin** | [vocawin.com](https://vocawin.com) | [VocaHQ/vocawin](https://github.com/VocaHQ/vocawin) | 📋 Planned |
> Each platform uses native technologies for the best possible integration, while sharing the same privacy-first philosophy and offline-only architecture.
## 🤝 Contributing
We welcome contributions! Whether it's bug reports, feature requests, or code contributions, please check out our [Contributing Guide](CONTRIBUTING.md).
### Contributors
Thanks to everyone who has contributed to Vocalinux! 🙌
<a href="https://github.com/VocaHQ/vocalinux/graphs/contributors">
<img src="https://contrib.rocks/image?repo=VocaHQ/vocalinux" />
</a>
### Quick Links
- 🐛 [Report a Bug](https://github.com/VocaHQ/vocalinux/issues/new?template=bug_report.md)
- 💡 [Request a Feature](https://github.com/VocaHQ/vocalinux/issues/new?template=feature_request.md)
- 💬 [Discussions](https://github.com/VocaHQ/vocalinux/discussions)
## ⭐ Support
If you find Vocalinux useful, please consider:
- ⭐ Starring this repository
- 🐛 Reporting bugs you encounter
- 📖 Improving documentation
- 🔀 Contributing code
## 📜 License
This project is licensed under the **GNU Affero General Public License v3.0**
([AGPL-3.0](LICENSE)), aligning with the other [VocaHQ](https://github.com/VocaHQ)
distribution projects ([VocaMac](https://github.com/VocaHQ/vocamac),
[VocaPhone](https://github.com/VocaHQ/vocaphone),
[VocaGateway](https://github.com/VocaHQ/vocagateway)).
You may use, study, modify, and redistribute the software under AGPL-3.0. If you
run a modified version as a network service, AGPL also requires that you make the
corresponding source available.
## Star Chart
[![Star History Chart](https://api.star-history.com/chart?repos=VocaHQ/vocalinux&type=date&legend=top-left&sealed_token=ZWyQQLhSORoR4mKf6UXMGFSCBXRxM_yEZgc8MFCH_ysBjaFUm_OCH-bI3TD7OivczEzm-ADRIpF9xCWFOMHvBPW95eQBxzfRMpNksChz7rN_eiqL7AIMDw)](https://www.star-history.com/?type=date&repos=VocaHQ%2Fvocalinux)
---
<p align="center">
Made with ❤️ for the Linux community
</p>