PiVocal is a small speech-to-text tool for Linux, built to make the microphone button on a bluetooth remote useful on a desktop system.
On Android, that button usually opens voice input. On Linux, in my case, it did nothing useful. PiVocal gives it a simple behavior: press the microphone button, a small floating window appears, speak, press the microphone button again, and the recognized text is typed into the application that currently has keyboard focus.
Speech recognition runs locally with Vosk.
The project is split into two scripts:
trigger.py # runs as root and listens for the hardware key press
frontend.py # runs as the normal user and handles GUI, microphone, STT and text input
This split is intentional.
trigger.py runs as root because it needs to read Linux input events.
frontend.py runs as the normal desktop user because it handles the window, microphone, speech recognition and text insertion.
The two processes communicate through a Unix socket:
/tmp/stt_trigger.sock
Text insertion is performed directly through wtype on Wayland or xdotool on X11; the clipboard is not used.
PiVocal was developed and tested on the following environment:
Operating systems: LMDE 7, Raspberry Pi OS Full (released on 21 April 2026, based on Debian 13 "Trixie")
Python version: 3.13
It should work on other Linux desktop environments too, but it has not been widely tested.
The remote used during development is a G10S Pro bluetooth remote.
On my system, the microphone button is exposed with these values:
DEVICE_NAME = "SG.Ltd SG Control Mic Consumer Control"
KEY_CODE = 582These values may be different on your system, even with a very similar remote.
The remote parameters are defined in trigger.py:
DEVICE_NAME = "SG.Ltd SG Control Mic Consumer Control"
KEY_CODE = 582If PiVocal does not detect your remote, you need to find the correct device name and key code.
You can list input devices with:
cat /proc/bus/input/devicesA more compact view can be obtained with:
grep -E 'Name=|Handlers=' /proc/bus/input/devicesLook for entries related to your remote. Many remotes expose multiple input interfaces, such as keyboard, mouse and consumer-control/media-control devices.
Each device entry usually contains a Name line and a Handlers line.
Example:
N: Name="SG.Ltd SG Control Mic Consumer Control"
H: Handlers=kbd event5
The value inside Name="..." is the value to use as DEVICE_NAME.
The eventX value in the Handlers line is the event device that can be used to inspect key presses.
In this example:
event5
corresponds to:
/dev/input/event5
Once you have found the correct eventX device, you can inspect key press events directly from /dev/input/eventX.
Replace event5 with your actual event device:
sudo stdbuf -oL od -An -tu2 -w24 /dev/input/event5 | awk '$9 == 1 { print "type="$9, "code="$10, "value="$11 }'Now press the microphone button on the remote.
You should see output similar to:
type=1 code=582 value=1
The important values are:
type=1 EV_KEY event
code=582 key code
value=1 key press
The number after code= is the value to use as KEY_CODE.
For example:
DEVICE_NAME = "SG.Ltd SG Control Mic Consumer Control"
KEY_CODE = 582If pressing the microphone button produces no output, try another eventX device exposed by the remote.
You can also check the /dev/input/by-id/ directory, when available:
ls -l /dev/input/by-id/This can make it easier to identify which /dev/input/eventX file belongs to the remote.
The current setup uses the Italian Vosk model:
vosk-model-small-it-0.22
The model directory must be named:
model
and must be placed inside the project directory before installation.
You can replace it with another Vosk model from:
https://alphacephei.com/vosk/models
Download and extract the model, then rename the extracted folder to:
model
Expected project structure:
pivocal/
├── frontend.py
├── trigger.py
├── install.sh
├── uninstall.sh
├── requirements.txt
└── model/
Before installing, make sure the model directory exists inside the project directory.
Then run:
sudo ./install.shThe installer will install system dependencies, create /opt/pivocal, create a Python virtual environment, install Python dependencies, register the hardware trigger as a systemd service, and configure the frontend to start automatically for the desktop user.
After installation, reboot the system:
sudo rebootAfter reboot, press the configured microphone button on the remote. The PiVocal window should appear.
To remove PiVocal:
sudo ./uninstall.shThe uninstaller stops and disables the systemd service, removes /opt/pivocal, removes the user autostart entry, removes the temporary socket and stops any remaining PiVocal processes.
Python dependencies are listed in requirements.txt:
vosk
sounddevice
evdev
The installer also installs the required system packages, including Tkinter, audio-related libraries, wtype for Wayland, and xdotool for X11.
This project is licensed under the MIT License.