Specify which wake-words activate Rhasspy
All wake-words are listened for (including logging filter info for debug) but only a those specified in `config.yaml` `model_names` activate Rhasspy.
This commit is contained in:
parent
f16e03347b
commit
2d3f33331c
3 changed files with 32 additions and 9 deletions
13
README.md
13
README.md
|
@ -115,10 +115,18 @@ On each Rhasspy, in Rhasspy - Settings - Wake Word, set `Hermes MQTT`, like
|
||||||
|
|
||||||
### openWakeWord
|
### openWakeWord
|
||||||
|
|
||||||
openWakeWord listens for all wake-words like "alexa", "hey mycroft", "hey jarvis", and [others](https://github.com/dscripka/openWakeWord#pre-trained-models). These settings ensure Rhasspy is only activated once per wake-word, and help reduce false activations.
|
openWakeWord listens for wake-words like "alexa", "hey mycroft", "hey jarvis", and [others](https://github.com/dscripka/openWakeWord#pre-trained-models). Use `model_names` to specify which wake-words to listen for. (See [Pre-Trained Models](https://github.com/dscripka/openWakeWord#pre-trained-models) documentation, and which [`model_names`](https://github.com/dscripka/openWakeWord/blob/main/openwakeword/__init__.py) to use.)
|
||||||
|
|
||||||
|
Delete any wake-words that you don't want to activate on. Or remove the entire `model_names` section to use all pre-trained models.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
oww:
|
oww:
|
||||||
|
model_names: # From https://github.com/dscripka/openWakeWord/blob/main/openwakeword/__init__.py
|
||||||
|
- alexa # Delete to ignore this wake-word
|
||||||
|
- hey_mycroft
|
||||||
|
- hey_jarvis
|
||||||
|
- timer
|
||||||
|
- weather
|
||||||
activation_samples: 3 # Number of samples in moving average
|
activation_samples: 3 # Number of samples in moving average
|
||||||
activation_threshold: 0.7 # Trigger wakeword when average above this threshold
|
activation_threshold: 0.7 # Trigger wakeword when average above this threshold
|
||||||
deactivation_threshold: 0.2 # Do not trigger again until average falls below this threshold
|
deactivation_threshold: 0.2 # Do not trigger again until average falls below this threshold
|
||||||
|
@ -126,10 +134,11 @@ oww:
|
||||||
vad_threshold: 0.5
|
vad_threshold: 0.5
|
||||||
enable_speex_noise_suppression: false
|
enable_speex_noise_suppression: false
|
||||||
```
|
```
|
||||||
|
The other `oww` settings ensure Rhasspy is only activated once per wake-word, and help reduce false activations.
|
||||||
|
|
||||||
In the example above, the latest 3 audio samples received over UDP are averaged together, and if the average confidence that a wake-word has been spoken is above 0.7 (70%), then Rhasspy is notified. Rhasspy will not be notified again until the average confidence drops below 0.2 (20%), i.e. the wake-word has ended.
|
In the example above, the latest 3 audio samples received over UDP are averaged together, and if the average confidence that a wake-word has been spoken is above 0.7 (70%), then Rhasspy is notified. Rhasspy will not be notified again until the average confidence drops below 0.2 (20%), i.e. the wake-word has ended.
|
||||||
|
|
||||||
Settings for voice activity detection (VAD) and noise suppression are also provided. See openWakeWord's [Recommendations for Usage](https://github.com/dscripka/openWakeWord#recommendations-for-usage).
|
Settings for voice activity detection (VAD) and noise suppression are also provided. (See openWakeWord's [Recommendations for Usage](https://github.com/dscripka/openWakeWord#recommendations-for-usage).)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Feel free to open an Issue if you have a problem, need help or have an idea. PRs always welcome.
|
Feel free to open an Issue if you have a problem, need help or have an idea. PRs always welcome.
|
||||||
|
|
|
@ -11,6 +11,12 @@ mqtt:
|
||||||
|
|
||||||
# Open Wake Word config
|
# Open Wake Word config
|
||||||
oww:
|
oww:
|
||||||
|
model_names: # From https://github.com/dscripka/openWakeWord/blob/main/openwakeword/__init__.py
|
||||||
|
- alexa # Delete to ignore this wake-word
|
||||||
|
- hey_mycroft
|
||||||
|
- hey_jarvis
|
||||||
|
- timer
|
||||||
|
- weather
|
||||||
activation_samples: 3 # Number of samples in moving average
|
activation_samples: 3 # Number of samples in moving average
|
||||||
activation_threshold: 0.7 # Trigger wakeword when average above this threshold
|
activation_threshold: 0.7 # Trigger wakeword when average above this threshold
|
||||||
deactivation_threshold: 0.2 # Do not trigger again until average falls below this threshold
|
deactivation_threshold: 0.2 # Do not trigger again until average falls below this threshold
|
||||||
|
|
22
detect.py
22
detect.py
|
@ -50,6 +50,7 @@ def load_config(config_file):
|
||||||
"password": None,
|
"password": None,
|
||||||
},
|
},
|
||||||
"oww": {
|
"oww": {
|
||||||
|
"model_names": ["alexa", "hey_mycroft", "hey_jarvis", "timer", "weather"],
|
||||||
"activation_threshold": 0.7,
|
"activation_threshold": 0.7,
|
||||||
"deactivation_threshold": 0.2,
|
"deactivation_threshold": 0.2,
|
||||||
"activation_samples": 3,
|
"activation_samples": 3,
|
||||||
|
@ -125,17 +126,21 @@ class Prediction(threading.Thread):
|
||||||
)
|
)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Wake word detection thread."""
|
"""
|
||||||
|
Wake word detection thread.
|
||||||
|
|
||||||
|
Detect and filter all wake-words, but only publish to MQTT if wake-word model name is listed
|
||||||
|
in config.yaml.
|
||||||
|
"""
|
||||||
while True:
|
while True:
|
||||||
roomname, timestamp, audio = self.queue.get()
|
roomname, timestamp, audio = self.queue.get()
|
||||||
prediction = self.oww.predict(audio)
|
prediction = self.oww.predict(audio)
|
||||||
for wakeword in prediction.keys():
|
for wakeword in prediction.keys():
|
||||||
confidence = prediction[wakeword]
|
confidence = prediction[wakeword]
|
||||||
if self.__filter(wakeword, confidence):
|
if (
|
||||||
print(
|
self.__filter(wakeword, confidence)
|
||||||
f"Detected wakeword {wakeword} in {roomname}",
|
and wakeword in config["oww"]["model_names"]
|
||||||
flush=True,
|
):
|
||||||
)
|
|
||||||
self.__publish(wakeword, roomname)
|
self.__publish(wakeword, roomname)
|
||||||
|
|
||||||
def __filter(self, wakeword, confidence):
|
def __filter(self, wakeword, confidence):
|
||||||
|
@ -188,7 +193,10 @@ class Prediction(threading.Thread):
|
||||||
"customEntities": None,
|
"customEntities": None,
|
||||||
}
|
}
|
||||||
self.mqtt.publish(f"hermes/hotword/{wakeword}/detected", dumps(payload))
|
self.mqtt.publish(f"hermes/hotword/{wakeword}/detected", dumps(payload))
|
||||||
print("MQTT: Published to Rhasspy", flush=True)
|
print(
|
||||||
|
"MQTT: Published wakeword {wakeword}, siteId {roomname} to Rhasspy",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Add table
Reference in a new issue