2019-02-10 15:26:50 +03:00
|
|
|
/**
|
|
|
|
* This file allows to run a separate node to detect the wake word "Leon/Léon"
|
|
|
|
* You can consider to run this file on a different hardware
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* eslint-disable import/no-unresolved */
|
|
|
|
|
|
|
|
const request = require('superagent')
|
|
|
|
const record = require('node-record-lpcm16')
|
2022-01-31 07:09:54 +03:00
|
|
|
const { Detector, Models } = require('@bugsounet/snowboy')
|
2021-03-16 10:04:09 +03:00
|
|
|
const { io } = require('socket.io-client')
|
2019-02-10 15:26:50 +03:00
|
|
|
|
2019-05-25 07:07:11 +03:00
|
|
|
process.env.LEON_HOST = process.env.LEON_HOST || 'http://localhost'
|
|
|
|
process.env.LEON_PORT = process.env.LEON_PORT || 1337
|
|
|
|
const url = `${process.env.LEON_HOST}:${process.env.LEON_PORT}`
|
2019-02-10 15:26:50 +03:00
|
|
|
const socket = io(url)
|
2022-02-12 20:42:29 +03:00
|
|
|
const { argv } = process
|
|
|
|
const lang = argv[2] || 'en'
|
2019-02-10 15:26:50 +03:00
|
|
|
|
|
|
|
socket.on('connect', () => {
|
|
|
|
socket.emit('init', 'hotword-node')
|
2022-02-12 20:42:29 +03:00
|
|
|
console.log('Language:', lang)
|
2019-02-10 15:26:50 +03:00
|
|
|
console.log('Connected to the server')
|
|
|
|
console.log('Waiting for hotword...')
|
|
|
|
})
|
|
|
|
|
2022-01-28 13:34:35 +03:00
|
|
|
request.get(`${url}/api/v1/info`)
|
2019-02-10 15:26:50 +03:00
|
|
|
.end((err, res) => {
|
|
|
|
if (err || !res.ok) {
|
|
|
|
if (!err.response) {
|
|
|
|
console.error(`Failed to reach the server: ${err}`)
|
|
|
|
} else {
|
|
|
|
console.error(err.response.error.message)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const models = new Models()
|
|
|
|
|
|
|
|
models.add({
|
2022-02-12 20:42:29 +03:00
|
|
|
file: `${__dirname}/models/leon-${lang}.pmdl`,
|
2019-02-10 15:26:50 +03:00
|
|
|
sensitivity: '0.5',
|
2022-02-12 20:42:29 +03:00
|
|
|
hotwords: `leon-${lang}`
|
2019-02-10 15:26:50 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
const detector = new Detector({
|
2022-01-31 07:09:54 +03:00
|
|
|
resource: `${__dirname}/node_modules/@bugsounet/snowboy/resources/common.res`,
|
2019-02-10 15:26:50 +03:00
|
|
|
models,
|
|
|
|
audioGain: 2.0,
|
|
|
|
applyFrontend: true
|
|
|
|
})
|
|
|
|
|
|
|
|
detector.on('silence', () => {
|
|
|
|
})
|
|
|
|
|
|
|
|
detector.on('sound', (/* buffer */) => {
|
|
|
|
/**
|
|
|
|
* <buffer> contains the last chunk of the audio that triggers the "sound" event.
|
|
|
|
* It could be written to a wav stream
|
|
|
|
*/
|
|
|
|
})
|
|
|
|
|
|
|
|
detector.on('error', () => {
|
|
|
|
console.error('error')
|
|
|
|
})
|
|
|
|
|
|
|
|
detector.on('hotword', (index, hotword, buffer) => {
|
|
|
|
/**
|
|
|
|
* <buffer> contains the last chunk of the audio that triggers the "hotword" event.
|
|
|
|
* It could be written to a wav stream. You will have to use it
|
|
|
|
* together with the <buffer> in the "sound" event if you want to get audio
|
|
|
|
* data after the hotword
|
|
|
|
*/
|
|
|
|
const obj = { hotword, buffer }
|
|
|
|
|
|
|
|
console.log('Hotword detected', obj)
|
|
|
|
socket.emit('hotword-detected', obj)
|
|
|
|
})
|
|
|
|
|
|
|
|
const mic = record.start({
|
|
|
|
threshold: 0,
|
|
|
|
verbose: false
|
|
|
|
})
|
|
|
|
|
|
|
|
mic.pipe(detector)
|
|
|
|
}
|
|
|
|
})
|