Configuration

~/.config/horchd/config.toml is the source of truth. Hand-editable; horchctl reload re-reads it without dropping the audio thread. horchctl wakeword {threshold,enable,disable,cooldown,add,remove} --save mutate the file in place while preserving comments and formatting.

Full example

[engine]
device = "default"           # cpal device name; "default" = system default mic
sample_rate = 16000          # must be 16000; horchd refuses other rates
log_level = "info"           # trace | debug | info | warn | error

[engine.shared_models]
melspectrogram = "/usr/local/share/horchd/melspectrogram.onnx"
embedding      = "/usr/local/share/horchd/embedding_model.onnx"

[[wakeword]]
name = "alexa"                         # unique id; appears in D-Bus signal
model = "~/.local/share/horchd/models/alexa_v0.1.onnx"
threshold = 0.5                        # score must reach this to fire
cooldown_ms = 1500                     # don't refire within this window
enabled = true                         # toggle without unloading

[[wakeword]]
name = "hey_jarvis"
model = "~/.local/share/horchd/models/hey_jarvis_v0.1.onnx"
threshold = 0.65
cooldown_ms = 1500

Field reference

[engine]

Field Type Default Notes
device string "default" cpal device name. "default" = system default mic.
sample_rate int 16000 Must be 16000. Documented sanity check.
log_level string "info" RUST_LOG env wins if set.

[engine.shared_models]

Field Type Required Notes
melspectrogram path yes Universal openWakeWord melspec model.
embedding path yes Universal openWakeWord embedding model.

Both ship with the upstream Python openwakeword package and are not per-wakeword. install.sh puts them under /usr/local/share/horchd/.

[[wakeword]]

Field Type Default Notes
name string Required. Unique. Appears in the D-Bus Detected signal.
model path Required. .onnx classifier. ~ expansion supported.
threshold float 0.5 Score must rise to this for a fire.
cooldown_ms int 1500 Suppress refire within this window.
enabled bool true Toggle without unloading.

Multiple aliases on the same model

You can have multiple [[wakeword]] entries pointing at the same model = "..." path with different name, threshold, and cooldown_ms values. Each unique model file is loaded into the ONNX runtime exactly once but the detector state machine runs per [[wakeword]] entry — so N detectors against M unique models cost M classifier evaluations per frame, not N.

Found a bug? Improve a section?

These docs live at codeberg.org/NewtTheWolf/docs.horchd.xyz. File an issue or send a pull request — even a typo fix is welcome.

For bugs and feature requests against the daemon itself, head to the horchd issue tracker.