Version 2.0 (July 2026)
Voluble is a GNOME Shell extension plus a companion helper script that turns desktop notifications, mouse‑selection, or pieces of highlighted text into natural‑sounding speech. It now ships with multilingual support, on‑the‑fly language switching, local LLM summarization/translation/explanation, and a proofreading mode.
- Features
- Quick‑Start Installation
- Configuration – USER BLOCK
- How It Works (Overview)
- Screencasts & Example Media
- Advanced Usage (LLM, FastText, Sox, Speech‑Dispatcher)
- Tips & Tricks
- Uninstall / Reset
- Credits
| Feature | Description | NEW? |
|---|---|---|
| Human‑like voice for GNOME notifications | Uses the lightweight neural TTS engine Piper for good-quality (for the purpose) speech. | |
| Read mouse selection | Highlight any text on the screen → Voluble reads it aloud, handling mixed language text that may make larger models stumble. | |
| Mute / Unmute | Toggle voice output without disabling the extension. | |
| Do‑Not‑Disturb awareness | Automatically silences speech when the system DND switch is on. | |
| Multilingual, on‑the‑fly language detection | When fasttext is installed, Voluble detects the language of intelligently chunked text and automatically switches to the appropriate Piper model. |
YES |
Summarise selected text (voluble -s) |
Sends the highlighted text to a local LLM (Gemma 4‑E4B, Gemma 3‑4B, etc.) and reads back a concise summary. | YES |
Translate selected text (voluble -t) |
Same pipeline as summarise, but the LLM returns a translation into a configurable target language of your choice. | YES |
Explain / “teach‑back” (voluble -e) |
LLM produces a short expert‑style explanation of the selected passage. | YES |
Proofread and replace (voluble -p) |
LLM returns a JSON object with { "correction": "...", "brief": "..." }. The corrected text is copied to the clipboard, and the brief is spoken. |
YES |
Local server to CLI fallback e.g. llama‑completion |
If a server is running on localhost:8080 the script prefers it; otherwise it falls back to the CLI. |
YES |
Optional use of sox or spd‑say |
Choose your audio backend (aplay, play, sox, or Speech‑Dispatcher). |
|
| Anounce Joplin tasks | (Optional) Summarise today’s Joplin tasks at session start. | |
| Extensible “commitments” | Random, friendly “I’m on it…” messages spoken before the LLM runs. | YES |
"Practice what you preach: A demo of Voluble's features, narrated by Voluble."
To transition smoothly from the previous section, this short clip demonstrates Voluble’s capabilities by using one of its core features to explain the project itself (please, turn the sound ON):
voluble_code_explain.mp4
| Feature | Description | Screencast |
|---|---|---|
| Multilingual Read-Aloud on‑the‑fly | A fictional scene in the Italian Alps – an Italian clerk, a Chinese tourist, a French traveler, an American, and a Russian speak over each other. Voluble detects and switches languages instantly. | voluble_Alps_autolanguage.mp4 |
| Summarise Chinese newspaper | Select a paragraph from a Chinese newspaper, press Voluble → Summarise. The LLM returns an English summary which is spoken. |
voluble_summarize_cn_en.mp4 |
| Translate to French | Highlight a Spanish paragraph, press Voluble → Translate. The result is spoken in French. |
🎞️ Translate Spanish → French |
| Explain a technical excerpt | Select complex text or a snippet of code, press Voluble → Elucidate. The LLM explains it in plain language. |
🎞️ Explain Code Snippet (see above) |
| Proofread edited text | Highlight a badly‑written paragraph, press Voluble → Proofread. The corrected text lands in the clipboard, and a brief “I fixed punctuation and grammar...” is spoken. |
voluble_proofread2.mp4 |
| Joplin‑Today integration | At login, the script reads a summary of today’s Joplin tasks. | 🎞️ (video below in Advanced Usage, sec. 7) |
NOTE – The steps below assume a zsh environment (the main script ships with a zsh shebang). If you prefer bash, you will have to rewrite any (many) Zsh‑specific syntax fields accordingly.
-
Install required system packages
sudo apt install sox fasttext jq wl-clipboard xsel aplay # Debian/Ubuntu # or the equivalent for your distro
-
Install the GNOME extension
Manual:
git clone https://github.com/QuantiusBenignus/voluble cd voluble unzip voluble@quantiusbenignus.local.zip -d "$HOME/.local/share/gnome-shell/extensions/" gnome-extensions enable voluble@quantiusbenignus.local
-
Download the helper script
mkdir -p "$HOME/.local/bin" cd "$HOME/.local/bin" wget https://raw.githubusercontent.com/QuantiusBenignus/voluble/main/voluble chmod +x voluble
-
Download Piper and Piper models
Download Piper and the desired voice files (a .onnx and a json file per each voice) for the languages of choice. As of this writing, 40+ languages are supported. You can listen to samples and download files here. Once downloaded, make sure that each .json file is named exactly like its corresponding .onnx model file.
# Download the compiled binary (extract and create a symbolic link to `piper`) , e.g.: wget https://github.com/rhasspy/piper/releases/download/2023.11.14-2/piper_linux_x86_64.tar.gz ln -s $HOME/Apps/github/piper/piper $HOME/.local/bin/piper # Check https://rhasspy.github.io/piper-samples/ for language samples. # Example – Choose and download a few models into $HOME/AI/Models/Piper mkdir -p "$HOME/AI/Models/Piper" cd "$HOME/AI/Models/Piper" wget https://huggingface.co/rhasspy/piper-voices/blob/main/da/da_DK/talesyntese/medium/da_DK-talesyntese-medium.onnx wget https://huggingface.co/rhasspy/piper-voices/resolve/main/da/da_DK/talesyntese/medium/da_DK-talesyntese-medium.onnx.json # or use your browser, e.g.: https://huggingface.co/rhasspy/piper-voices/tree/main/es/es_ES/davefx/medium/ # …add any other models you like to support voluble's multilingual capabilities.
-
Set up a local LLM to use the AI features: Download llama.cpp (or any other inference engine that exposes a OpenAI-compatible API, or can be run in a single-shot mode from the command line - e.g. llamafile )
-
Edit the USER CONFIGURATION BLOCK (see next section).
-
Run the extension script (no arguments) from the command line to verify dependencies:
$>voluble -
Restart GNOME (log out/in or press
Alt+F2, typer, press Enter) and test the extension by clicking “Read Aloud” in the Voluble menu.
Open ~/.local/bin/voluble in your favourite editor and locate the USER CONFIGURATION BLOCK (around line 130). Adjust the variables to match your environment:
| Variable | What to set | Example |
|---|---|---|
use_sox |
1 to use sox (play) instead of aplay. |
use_sox=0 |
use_spd |
1 to route audio through Speech‑Dispatcher (spd-say - no auto LID). |
use_spd=0 |
use_fasttext |
1 enables automatic language detection (LID). |
use_fasttext=1 |
MODELDIR |
Base directory where you keep all models. | MODELDIR="$HOME/AI/Models" |
PIPERDIR |
Sub‑directory that contains the Piper .onnx files. | PIPERDIR="$MODELDIR/Piper" |
TTSM (assoc. array) |
Map language → model file. Add or remove entries for any language you want. | See the script; e.g. add "Italian"="it_IT-paola-medium.onnx" |
LCLANG (assoc. array) |
Reverse map ISO‑639‑1 → display name (used by fasttext). | "it"="Italian" |
lang |
Primary UI language (fallback when detection fails). | lang="English" |
trans_lang |
Target language for the -t (translate) mode. |
trans_lang='French' |
LLModel |
Full path to the GGUF model you want the LLM to use. | LLModel="$MODELDIR/gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf" |
lid_model |
Path to the fasttext language‑identification model. | lid_model="${FASTTEXT_MODEL:-$MODELDIR/Piper/lid.176.bin}" |
llam |
Executable name for the LLM CLI (default llama-completion). |
llam="llama-completion" |
llamargs |
CLI arguments for your LLM. Adjust for your engine if needed. | (-t 7 --temp 0.6 …) |
LLM_SERVER |
URL of a local OpenAI‑compatible server (e.g. http://localhost:8080). |
LLM_SERVER="http://localhost:8080" |
commitments |
Friendly “I’m on it…” strings spoken when the LLM runs. | add any you like |
Tip – After you finish editing the block, run
volubleonce with no arguments. It will print “All dependencies are satisfied.” if everything is in place.
At its core, Voluble enhances desktop notifications by reading them aloud, in the absence of (or in addition to) any sound that might accompany the notification. This way, the user will be properly alerted and will not risk missing even the most transient of notifications, clearly hearing what the computer has to say, even when not looking. Creating an intelligent auditory route for text in PRIMARY SELECTION, further expands its capabilities.
-
Voluble GNOME extension intercepts a notification or a mouse‑selection and writes the text to
$XDG_RUNTIME_DIR/voluble.tmp. -
The helper script (
voluble) is invoked by the extension. -
If fasttext is enabled, the script splits the text into sentences, runs each through
fasttext predict, and selects the appropriate Piper model on‑the‑fly. -
If a LLM is requested (
-s,-t,-e,-p):- The script first tries a local server (
$LLM_SERVER). - If the server is unavailable, it falls back to the
llama‑completionCLI with the model you configured. - The LLM returns either a plain summary/translation/explanation or a JSON object (proofread mode).
- The script first tries a local server (
-
The final text (or the proofreading
briefJSON field) is sent to Piper and spoken. -
In proofread mode the corrected text is also copied to the clipboard (
wl-copyon Wayland,xselon X11) and can be pasted directly over the selected text.
# Use Sox/Play (better for large files)
use_sox=1
# Use Speech‑Dispatcher (integrates with Orca etc. - In the context of LID, this has become less desirable and more of an extraneous setup.)
use_spd=1#Use the command line to supply textual payload (questions, program outputs, other text) for voluble's tools (e.g. Elucidate - will explain the recent ):
journalctl -p err --since "yesterday" | fx -p
The zsh function fx (-p loads the PRIMARY SELECTION), along with its mirror xf and other tools, is available as part of the zshelf repository (a zsh-centric local LLM interaction suite ).
-
Download the model (e.g.
nl_NL‑mls-medium.onnx). -
Add entries to the two associative arrays:
TTSM["Dutch"]="nl_NL-mls-medium.onnx" LCLANG["nl"]="Dutch"
-
Because the extension has not changed you do not need to restart the extension (
gnome-extensions restart voluble).
If you run a local llama.cpp server, or vLLM that speaks the OpenAI Chat Completion API, just set:
LLM_SERVER="http://localhost:11434"The script will generally work with any OpenAI compatible API.
- The LLM must return pure JSON (no markdown fences).
- The script strips any surrounding
jsonfences automatically. - Example system prompt (built‑in) forces the model to obey the schema.
- The corrected text is placed on the clipboard; you can paste it anywhere (
Ctrl+VorSuper+V), incl. directly over the selection.
If fasttext is not installed, Voluble falls back to the primary configured language ($lang).
To install fasttext and the language‑identification model:
sudo apt install fasttext
mkdir -p "$HOME/AI/Models/Piper"
wget -O "$HOME/AI/Models/Piper/lid.176.bin" \
https://dl.fbaipublicfiles.com/fasttext/supervised-models/lid.176.binThe script automatically picks up $FASTTEXT_MODEL if you set that environment variable.
7. For users of Joplin. Spoken summary at startup of the tasks due soon. Uses the optional python script joplintoday.py.
One of the many reasons for creating this extension was the need to hear the contents of notifications for appointments and to-do's from the Joplin note-taking app. A video demonstration.
| Notification - Tasks in the next 12 hrs | Notification Audio |
|---|---|
![]() |
joplin-today.mp4 |
You can simply invoke the python script by adding it to you startup applications. On most Linux desktops, placing a .desktop file in ~/.config/autostart/ will do the trick. Here is a sample ~/.config/autostart/joplintoday.desktop file:
[Desktop Entry]
Type=Application
Exec=/home/YourUsername/.local/bin/joplintoday.py
Hidden=false
NoDisplay=true
X-GNOME-Autostart-enabled=true
Name=JoplinToday
(Linux only, will not work with encrypted database).
| Tip | Command |
|---|---|
| Stop a runaway read | pkill -SIGINT voluble && pkill play || pkill aplay (or pkill -SIGINT spd-say) |
| Create an alias | alias shutup='pkill -SIGINT voluble && pkill play || pkill aplay' |
| Add a custom commitment | Edit the commitments array – any line will be spoken before the LLM runs. Only registered languages. |
| Debug dependencies | Run voluble (no flags) from a terminal; you’ll catch any dependency issues. |
| Disable dependency check | After setup is complete, comment out the depends function call at the beginning of main() to avoid the check on each run. |
| Change sample rate (for custom low‑quality models) | Should be handled automatically by the script |
| Use Wayland clipboard | The script automatically picks wl-copy when $XDG_SESSION_TYPE is wayland. |
| Log all processed texts | The helper appends each raw selection to $XDG_RUNTIME_DIR/promf. You can tail it: tail -f $XDG_RUNTIME_DIR/promf. Persistent for the session. |
| Testing voluble from CLI | To test voluble [-s -e -t -p] meaningfully from the command line, $XDG_RUNTIME_DIR/voluble.tmp (which is emptied on exit), must be repopulated. |
# 1. Remove the GNOME extension
gnome-extensions disable voluble@quantiusbenignus.local
gnome-extensions uninstall voluble@quantiusbenignus.local
# 2. Delete the helper script and model folder (optional)
rm -f "$HOME/.local/bin/voluble"
rm -rf "$HOME/AI/Models/Piper"
# 3. Clean up the temporary file
rm -f "$XDG_RUNTIME_DIR/voluble.tmp"If you want to keep the models but start fresh, simply delete the helper script and re‑install it.
Details
Speech Dispatcher is a core accessibility tool designed to facilitate speech synthesis for people with visual impairments. It acts as a bridge between client applications (programs that produce spoken text) and software speech synthesizers (programs that convert text into speech). Speech Dispatcher would typically come preinstalled in many Linux distributions with the espeak-ng TTS engine as the default. The result does not sound good at all when compared with the quality of the new neural TTS engines. Here is a comparison, justifying the integration of Piper with speech dispatcher:
| With espeak-ng | With Piper |
|---|---|
v-espeak.mp4 |
v-lessac.mp4 |
-
Configuration files (speechd.conf) are located in /etc/speech-dispatcher/ for system-wide settings and ~/.config/speech-dispatcher/ for per-user preferences.
-
The
spd-conftool allows one to modify configuration options interactively or create per-user speech dispatcher configuration. -
Integration with synthesizers (TTS engines) is done via module configuration, but unfortunately, the supplied preconfigured modules sound unnatural, robotic and not quite intelligible.
-
It is possible, with some work, to configure Piper as a TTS module for Speech Dispatcher.
- First create a generic local (per user) speech-dispatcher setup with the
spd-conftool, usingsd_genericas the default module. - Then register Piper as a valid TTS module by editing the just-created
~/.config/speech-dispatcher/speechd.conf. Most stuff can be left as is (all is well commented). An excerpt of the relevant parameters in my case shown here:
# The Default language with which to speak # Note that the spd-say client in particular always sets the language to its # current locale language, so this particular client will never pick this configuration. DefaultLanguage en-US # Pulse audio is the default and recommended sound server. OSS and ALSA # are only provided for compatibility with architectures that do not # include Pulse Audio. AudioOutputMethod alsa # The next ones are instrumental, find them in their respective sections AddModule "piper" "sd_generic" "piper.conf" DefaultModule piper LanguageDefaultModule "en" "piper" LanguageDefaultModule "fr" "piper"- Then create a suitable
piper.conffile in~/.config/speech-dispatcher/modules/. Here is an examplepiper.confadapted for my case from here:
Debug 0 GenericExecuteSynth "printf %s \'$DATA\' | piper --length_scale 1 --sentence_silence 0 --model ~/AI/Models/piper/$VOICE --output-raw | aplay -r 16000 -f S16_LE -t raw -" # Using low quality voices to respect the 16000 rate for aplay in the command above is perfectly fine. GenericCmdDependency "piper" GenericCmdDependency "aplay" GenericCmdDependency "printf" GenericSoundIconFolder "/usr/share/sounds/sound-icons/" GenericPunctNone "" GenericPunctSome "--punct=\"()<>[]{}\"" GenericPunctMost "--punct=\"()[]{};:\"" GenericPunctAll "--punct" #GenericStripPunctChars "" GenericLanguage "en" "en_US" "utf-8" GenericLanguage "en" "en_GB" "utf-8" GenericLanguage "fr" "fr_FR" "utf-8" AddVoice "en" "MALE1" "en_US-lessac-low.onnx" AddVoice "en" "FEMALE1" "en_US-amy-low.onnx" AddVoice "fr" "MALE1" "fr_FR-gilles-low.onnx" AddVoice "en" "MALE2" "en_GB-alan-low.onnx" DefaultVoice "en_US-lessac-low.onnx"-
The newly created setup can then be tested with
spd-say, for example:$ spd-say "Your computer can now speak to you nicely"
- First create a generic local (per user) speech-dispatcher setup with the
-
Now all you have to do is set the option
use_spd=1in the CONFIG block of thevolublehelper script to use speech-dispatcher instead of calling piper directly.
- Add automatic translation for the extension GUI
- Implement a blacklist for "must be silent" notifications
- Create an automatic LID preprocessor/router
- Make aware of system-wide "Do not Disturb"
- Add extension code for ver. 45+ of the GNOME shell
- Michael Hansen – Piper author (low‑resource neural TTS)
- GGML‑org – llama.cpp / LLM inference engine
- FastText – language identification model
Happy listening! 🎧

