-
-
Notifications
You must be signed in to change notification settings - Fork 1
2. Configuration
/* in config/config.js */
{
module: "MMM-Hotword",
position: "bottom_left",
config: {
verbose: true,
hotwords: [
{ hotword: 'JARVIS' },
...
// Everything is defined by default, but if you want to change something, describe the properties here.
},
},
property | default | description |
---|---|---|
verbose |
false | When you set it as true , more detailed information will be logged. |
startOnBoot |
true | Auto-start on the bootup. |
device |
-1 | Mic index or name to use. System default device would have -1 . You can see the device list in the log. |
sensitivity |
0.5 | Default sensitivity of the mic to detect a voice. This value will be applied to all hot word definitions unless you re-define individually in a hot word. |
continuousRecording |
false | Default behaviour when the hot word is detected. This value will be applied to all hot word definitions unless you re-define individually in a hot word. |
restart |
false | After all jobs are done, restart the detector again. This could also be redefinable in each individual hot word. |
restartDelay |
1000 | (ms) delay before restart |
onDetect |
() => {} | CALLBACK Function. You can do your default job when any hot word is detected. (This would be overridable in each hotword definition.) |
languageModel |
null | For English, just leave as null. You may need this for non-English custom hotwords. e.g) 'porcupine_params_ko.pv' for Korean hotword. (Explained below) |
hotwords |
[...hotword objects] | Definitions of hotword. (Explained below) |
recorderFrameLenght |
512 | (For expert) Generally you don't need to care about this. |
recorderBufferedFramesCount |
50 | (For expert) Generally you don't need to care about this. |
tooShortRecording |
1000 | (ms) When continuous recording is shorter than this, it will be ignored. |
tooLongRecording |
60000 | (ms) Max continuous-recording length. |
soundThreshold |
0.1 | 0 ~ 1 available. Ideally, 0 is absolutely silent, and the loudness of your voice will increase this value. This value may vary depending on your devices and environments. You may need many trials to find a proper value. |
silentFrames |
100 | The count of continuous frames below soundThreashold to detect end-of-utterance silence. It may vary depending on your devices and environments. Usually, this 100 value will be around 1.5 sec. |
waitTimeout |
30000 | (ms) Waiting for continuousRecording without voice will be stopped on this timer. |
-
recorderFrameLength
is the length of the audio frames to receive andrecorderBufferedFramesCount
is the internal buffer size. 512 * 50 / 16000 (sample Rate) would be 1.6 sec. If this value is too low, buffer overflows could occur, and audio frames could be dropped. A higher value will increase memory usage. - When
continuousRecording: true
is set, The detector will wait for the following vocal phrase of you until the end of the utterance or somewhat pause. Then the detected hotword and recorded voice would be delivered.
{
hotword: 'COMPUTER',
continuousRecording: false,
},
// The detector will listen to your word, only `COMPUTER`.
{
hotword: 'COMPUTER',
continuousRecording: true,
}
// The detector will listen to `Computer, What time is it now?`,
// then the detected `COMPUTER` and the recorded file which has `What time is it now` will be delivered to onDetect callback function.
hotwords: [
{
hotword: 'JARVIS' // Default config value would be applied to this hotword
},
{
hotword: 'COMPUTER', // Or you can define each hotword separately.
sensitivity: 0.5,
continuousRecording: false,
restart: true,
onDetect: ({ helper, error, result, payload }) => {
console.log("Detected hotword: 'COMPUTER'")
helper.sendNotification('SHOW_ALERT', { message: `${result.hotword} detected.`})
},
},
{
hotword: 'MagicMirror',
file: "MagicMirror.ppn", // For custom hotword, you need custom file name(.ppn)
}
],
These keywords are pre-defined. (When languageModel
is used, these built-in hotwords will not work.)
'ALEXA', 'AMERICANO', 'BLUEBERRY', 'BUMBLEBEE', 'COMPUTER',
'GRAPEFRUIT', 'GRASSHOPPER', 'HEY_GOOGLE', 'HEY_SIRI', 'JARVIS',
'OK_GOOGLE', 'PICOVOICE', 'PORCUPINE', 'TERMINATOR',
You can train your custom hotword on picovoice/Porcupine
homepage.(https://picovoice.ai/platform/porcupine/) After downloading your custom .ppn
file, put it into the resources
directory of this module.
You need to describe the custom .ppn
filename in the config.
hotwords: [
{
hotword: "MagicMirror",
file: "MagicMirror.ppn",
...
},
{
hotword: "TurnOnCamera",
file: "mycustomcommand1.ppn",
...
},
],
You may need an additional model(.pv)
file for your trained hotword(.ppn)
by non-English hotword.
Available language models are here.
You can download it from github
page manually, or,
# For Korean hotword, you need porcupine_params_ko.pv
cd <MagicMirror Directory>/modules/MMM-Hotword2/resources
curl -L -O https://github.com/Picovoice/porcupine/raw/master/lib/common/porcupine_params_ko.pv
Then, you need additional configuration of the module.
{
module: "MMM-Hotword2",
position: "bottom_right",
config: {
languageModel: "porcupine_params_ko.pv",
hotwords: [
{
hotword: "거울아거울아"
file: "korean_mirrormirror.ppn",
...
- You cannot mix multi-language models for hot words at the same time. All custom hotwords used have to belong to one languageModel.
- The default built-in hotwords like
COMPUTER
will not work with the Non-English model.
You can define the job when the hotword is detected as a callback function.
onDetect : async ({ helper, error, result, payload }) => {
//Do your job.
if (error) console.log(error)
helper.sendNotification('SHOW_ALERT', { title: 'Hotword Detected', message: `Hotword ${result.hotword} is detected!` })
...
},
onDetect
callback function is async
function, so MMM-Hotword2 can know when your job is finished.
This callback function can have 4 objects as a parameter object. / error
, result
, payload
and helper
.
If the detector encounters an error, this object will be returned.
onDetect: async ({ error }) => {
console.log(error)
}
Usually, it will carry the hotword found. If you set continuousRecording
, it will also deliver filePath
and fileUrl
.
{
hotword: 'COMPUTER',
continuousRecording: true,
onDetect: ({helper, result}) => {
console.log(result)
/* This will show some info like this.
{
hotword: 'COMPUTER',
filePath: '/somewhere/path/to/storage/something.wav',
fileUrl: 'modules/MMM-Hotword2/storage/something.wav',
}
*/
},
},
It will carry the original config values. You may not need this generally. You can use these values to check which condition this detector works on.
onDetect: ({ payload }) => {
console.log(payload)
/*
hotwords: [ ... ],
device: -1,
continuousRecording: false,
languageModel: null,
...
*/
},
You can use this helper
object to do various jobs with the detected hotword. It has a few methods;
- return value: void
- This method helps send notifications to other modules.
- return value: Array of MagicMirror module instances
- This method helps get other modules to manipulate them.
- return value: MagicMirror module instance
- This method helps get a specific module to manipulate it.
- return value: Promise(string) / async function
- This method helps execute a shell script and return the result of execution.
This example shows that when the hot word is detected, the clock
module goes hidden, and the alert message will be displayed with the shell command date
; then, after 5 seconds, the clock
module will appear again.
onDetect: async ({ helper, error, result, payload }) => {
if (error) return
const clock = helper.getModule('clock')
clock.hide()
const message = await helper.shellExec(`date '+%A %W %Y %X'`)
helper.sendNotification('SHOW_ALERT', { title: `Hotword command - ${result.hotword}`, message: message, timer: 5000 })
setTimeout(() => clock.show(), 5000)
},