This release is a pre-release and may not be stable for production use.
ovos-ww-verifier-plugin-speaker
An OVOS wake word verifier plugin. It accepts voice commands only from enrolled household members.
After a wake word engine detects an activation, this verifier extracts a speaker embedding from the captured audio. It compares the embedding against enrolled profiles. The plugin silently drops activations from unrecognized speakers.
Use case
Alice and Bob live together and use OVOS at home. They enroll their voices once. A guest's "Hey Mycroft" still triggers the wake word detector, but the speaker verifier rejects it before any intent is processed. Commands from Alice and Bob go through normally.
Privacy note
The plugin stores speaker profiles as fixed-length numeric vectors (embeddings) in a local
JSON file at ~/.local/share/ovos_speaker_verifier/profiles.json. It keeps no audio after
embedding extraction. You cannot reverse an embedding back into audio.
Install
pip install ovos-ww-verifier-plugin-speaker
Enroll household members
ovos-speaker-enroll Alice clip1.wav clip2.wav clip3.wav
ovos-speaker-enroll Bob morning_command.wav evening_command.wav
More clips (5 to 30 s total per person) give a more robust profile.
OVOS configuration
ovos-dinkum-listener
(>= 0.6.0) loads wake-word verifiers from listener.ww_verifiers. Each key is
a verifier plugin's entry-point name. Its value is that plugin's config. Add
this to ~/.config/mycroft/mycroft.conf (or the OpenVoiceOS equivalent):
{
"listener": {
"ww_verifiers": {
"ovos-ww-verifier-speaker": {
"model": "wespeaker-resnet34",
"threshold": 0.45,
"fail_open": true
}
}
}
}
Installing the plugin enables it. The listener runs every installed verifier whose config does not set
"enabled": false. With no entry inww_verifiers, the plugin still loads with its defaults. Becausefail_opendefaults totrue, it accepts everything until you enroll at least one profile. Enroll first, then tune the threshold. To install the plugin without activating it, set"enabled": false:{"listener": {"ww_verifiers": {"ovos-ww-verifier-speaker": {"enabled": false}}}}
Configuration keys
| Key | Type | Default | Description |
|---|---|---|---|
model |
str | "wespeaker-resnet34" |
speakeronnx model alias or .onnx path |
threshold |
float | 0.45 |
Cosine similarity acceptance threshold |
fail_open |
bool | true |
Accept all activations when no profiles enrolled |
profiles_path |
str | ~/.local/share/ovos_speaker_verifier/profiles.json |
Override profile storage path |
per_profile_thresholds |
dict | {} |
Per-name threshold overrides, e.g. {"Alice": 0.5} |
sample_rate |
int | 16000 |
PCM sample rate of audio chunks passed to verify() |
sample_width |
int | 2 |
PCM sample width in bytes (2 = 16-bit) |
channels |
int | 1 |
PCM channel count |
Supported models
The model key accepts any alias from
speakeronnx's registry (models are
downloaded from HuggingFace on first use and cached):
| Alias | Architecture |
|---|---|
wespeaker-resnet34 (default) |
WeSpeaker ResNet34 r-vector |
wespeaker-ecapa512 |
WeSpeaker ECAPA-TDNN-512 |
wespeaker-resnet293 |
WeSpeaker ResNet293 (large) |
campplus |
WeSpeaker CAM++ |
campplus-zh-en |
CAM++ (zh/en) |
eres2net |
ERes2Net |
titanet-small |
NVIDIA TitaNet-Small |
titanet-large |
NVIDIA TitaNet-Large |
redimnet-b2 |
ReDimNet-B2 |
Threshold tuning
The acceptance threshold is model-specific. It does not transfer between
models. Cosine-similarity scales differ widely across architectures. In our
tests the same enrolled-vs-guest pair scored ~0.95 / 0.89 on titanet-small, but
~0.17 / 0.14 on campplus. The default 0.45 is calibrated for the default
wespeaker-resnet34. If you change model, you must re-tune threshold.
To pick a value, enroll a speaker. Then compare verify() scores for genuine and
guest clips, and choose a threshold that sits between them
(tests/test_ovoscope_models_e2e.py calibrates this per model automatically). For
a given model, lower the threshold for noisier or distant-microphone setups. Raise
it for stricter security.
Python API
from ovos_ww_verifier_plugin_speaker import SpeakerVerifier
v = SpeakerVerifier(config={"threshold": 0.45, "fail_open": False})
v.enroll("Alice", ["alice1.wav", "alice2.wav"])
# In wake word callback:
accepted = v.verify(pcm_bytes) # True if Alice spoke
Testing
pip install -e ".[test]"
pytest tests/test_unit.py tests/test_ovoscope_e2e.py # fast, offline
test_unit.py: verifier policy logic (enrollment, thresholds, fail-open).test_ovoscope_e2e.py: drives the verifier through a real listener (ovoscope.MiniVoiceLoop) and asserts a rejected speaker suppressesrecognizer_loop:record_beginon the bus. It is fast and needs no model download.test_e2e.py/test_ovoscope_models_e2e.py: real-model tests over everyspeakeronnxmodel. They useedge-ttssynthetic voices to confirm only the enrolled speaker triggers the wake word. These tests neededge-ttsandffmpeg, and they download models. They skip automatically when those are unavailable.
Dependencies
speakeronnx(onnxruntime + numpy + huggingface_hub)ovos-plugin-manager
Credits
Developed by TigreGótico for OpenVoiceOS.
This project was funded through the NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101135429.
Metadata
Release files for ovos-ww-verifier-plugin-speaker 0.0.3a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ovos_ww_verifier_plugin_speaker-0.0.3a1.tar.gz | 18.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ovos_ww_verifier_plugin_speaker-0.0.3a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.0 kB
Release files / ovos_ww_verifier_plugin_speaker-0.0.3a1.tar.gz
| Download URL | ovos_ww_verifier_plugin_speaker-0.0.3a1.tar.gz |
|---|---|
| Size | 18.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12de8b3459fb214a7f78b8810dc3c152b180d282201e5d2166a0030a5b5c75c2
|
|
BLAKE2b-256 checksum How to use checksums |
59cb7b51b7b2d7ed002cb31dd85eac7d9e674538a9066d96c7219279a08048b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / ovos_ww_verifier_plugin_speaker-0.0.3a1-py3-none-any.whl
| Download URL | ovos_ww_verifier_plugin_speaker-0.0.3a1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
60d179cebdb1a5e9488a428a54a61487a2a1ed7249c0382fb3f76fa0a15c1edc
|
|
BLAKE2b-256 checksum How to use checksums |
0e8b35d776f9c91580b2ff63764b150c6a22fb137ce1e0f5aaa10de68b2bf010
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|