Skip to content

Commit 79587fa

Browse files
authored
Trigger (#20) fixes #18
* add trigger event so users can mantually start streaming detection * simple markdown file for documentation. website coming soon(ish) 😄 * fix "unused" eslint error * 0.1.2 * make index and keyword optional paramaters to trigger * using int for hotword trigger remove console.log * 0.1.3
1 parent d119eb6 commit 79587fa

File tree

4 files changed

+180
-3
lines changed

4 files changed

+180
-3
lines changed

docs/API.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
## API Methods
2+
3+
Paramaters marked in **bold** are required
4+
5+
### Require sonus and a cloud speech recognizer in your project:
6+
``` javascript
7+
const Sonus = require('sonus')
8+
const speech = require('@google-cloud/speech')({
9+
projectId: 'streaming-speech-sample',
10+
keyFilename: './keyfile.json'
11+
})
12+
```
13+
For more information about Google Cloud Speech see: https://cloud.google.com/speech/
14+
Note: don't forget to enable billing!
15+
16+
### Custom hotwords
17+
You can train and download custom hotwords for sonus from https://snowboy.kitt.ai
18+
In order to initialize Sonus you need to pass in 1 or more hotwords.
19+
Each hotword supports the following proporties:
20+
**`file`** - The path to your hotword model (either pmdl or umdl)
21+
**`hotword`** - The string that represents your hotword (ex: "sonus")
22+
`sensitivity` - (default `'0.5'`) If you are getting a lot of false positives or are having trouble detecting your hotword adjusting this value shoud help
23+
24+
**Example:** (to be passed into the sonus constructor)
25+
``` javascript
26+
const hotwords = [
27+
{file: '/mymodel.pmdl', hotword: 'sonus'},
28+
{file: 'snowboy.umdl', hotword: 'snowboy'}]
29+
```
30+
31+
### Languages
32+
Sonus lets you customize the lenguage for streaming speech recognition. For details on supported lenguages see the docs for your streaming speech recognizer
33+
34+
**Example:** (to be passed into the sonus constructor)
35+
``` javascript
36+
const lenguage = "en-US"
37+
```
38+
39+
### Initialize Sonus
40+
Sonus's initialization accepts two paramaters:
41+
**`options`** - an options object that contains your hotwords, lenguage, etc
42+
- **`hotwords`** - an array of recognizable hotwords
43+
- `lenguage` - streaming lenguage recognition
44+
- `dictionary` - [TODO] only supported by some streaming recognizers
45+
**`speechRecognizer`** - the speech recognizer of your choice
46+
47+
**Example:**
48+
``` javascript
49+
const sonus = Sonus.init({ hotwords, language }, speech)
50+
```
51+
52+
### Start recognition
53+
Pass your initialized sonus object into `Sonus.start`
54+
**Example:**
55+
``` javascript
56+
Sonus.start(sonus)
57+
```
58+
59+
### Pause recognition
60+
Pass your initialized sonus object into `Sonus.pause`.
61+
Pausing recognition while streaming will not cancel the request, instead it will cause it to simulate the "end" of speech and return final results.
62+
**Example:**
63+
``` javascript
64+
Sonus.pause(sonus)
65+
```
66+
67+
### Resume recognition
68+
Pass your initialized sonus object into `Sonus.resume`
69+
**Example:**
70+
``` javascript
71+
Sonus.resume(sonus)
72+
```
73+
74+
### Stop recognition
75+
If you want to stop recognition enterly you can use `Sonus.stop`
76+
**Example:**
77+
``` javascript
78+
Sonus.stop(sonus)
79+
```
80+
Note that after recognition is stopped it can not be started again without creating an enterly new sonus instance.
81+
82+
### Trigger keyword/hotword manually
83+
You can manuall trigger a hotword by passing your initialized sonus object and an index into `Sonus.trigger`
84+
The indexes of your hotwords are base 1 and are deturmined by the order in which the hotwords are passed into `Sonus.init`
85+
86+
**Exceptions**
87+
- `NOT_STARTED` - will be thrown if you have not started sonus when this is called.
88+
- `INVALID_INDEX` - will be thrown if you pass an invalid index.
89+
90+
**Example:**
91+
``` javascript
92+
Sonus.trigger(sonus, 1)
93+
```
94+
sonus will be triggered with a hotword index of `1`
95+
96+
You can also optionally specify an index of `0` and an arbitrary hotword that will be returned in the `hotword` event
97+
**Example:**
98+
``` javascript
99+
sonus.trigger(sonus, 0, 'some hotword')
100+
```
101+
sonus will be triggered with a hotword index of `1` and a hotword of `some hotword`
102+
103+
Passing a hotword with a valid index will override the hotword name and trigger that hotword
104+
**Example:**
105+
``` javascript
106+
sonus.trigger(sonus, 1, 'override')
107+
```
108+
## Events
109+
hotword
110+
partial-result
111+
final-result
112+
error

examples/trigger-example.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict'
2+
3+
const ROOT_DIR = __dirname + '/../'
4+
const Sonus = require(ROOT_DIR + 'index.js')
5+
const speech = require('@google-cloud/speech')({
6+
projectId: 'streaming-speech-sample',
7+
keyFilename: ROOT_DIR + 'keyfile.json'
8+
})
9+
10+
const hotwords = [{ file: ROOT_DIR + 'resources/sonus.pmdl', hotword: 'sonus' }]
11+
const language = "en-US"
12+
const sonus = Sonus.init({ hotwords, language }, speech)
13+
14+
try{
15+
Sonus.trigger(sonus, 1)
16+
} catch (e) {
17+
console.log('Triggering Sonus before starting it will throw the following exception:', e)
18+
}
19+
20+
Sonus.start(sonus)
21+
22+
sonus.on('hotword', (index, keyword) => console.log("!" + keyword))
23+
24+
sonus.on('partial-result', result => console.log("Partial", result))
25+
26+
sonus.on('error', (error) => console.log(error))
27+
28+
sonus.on('final-result', result => {
29+
console.log("Final", result)
30+
if (result.includes("stop")) {
31+
Sonus.stop()
32+
}
33+
})
34+
35+
try{
36+
Sonus.trigger(sonus, 2)
37+
} catch (e) {
38+
console.log('Triggering Sonus with an invalid index will throw the following error:', e)
39+
}
40+
41+
//Will use index 0 with a hotword of "triggered" and start streaming immedietly
42+
Sonus.trigger(sonus, 0, "some hotword")

index.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ const record = require('node-record-lpcm16')
44
const stream = require('stream')
55
const {Detector, Models} = require('snowboy')
66

7+
const ERROR = {
8+
NOT_STARTED : "NOT_STARTED",
9+
INVALID_INDEX : "INVALID_INDEX"
10+
}
11+
712
const CloudSpeechRecognizer = {}
813
CloudSpeechRecognizer.init = recognizer => {
914
const csr = new stream.Writable()
@@ -56,6 +61,7 @@ Sonus.init = (options, recognizer) => {
5661
sonus = new stream.Writable(),
5762
csr = CloudSpeechRecognizer.init(recognizer)
5863
sonus.mic = {}
64+
sonus.started = false
5965

6066
// If we don't have any hotwords passed in, add the default global model
6167
opts.hotwords = opts.hotwords || [1]
@@ -80,8 +86,7 @@ Sonus.init = (options, recognizer) => {
8086

8187
// When a hotword is detected pipe the audio stream to speech detection
8288
detector.on('hotword', (index, hotword) => {
83-
sonus.emit('hotword', index, hotword)
84-
CloudSpeechRecognizer.startStreaming(opts, sonus.mic, csr)
89+
sonus.trigger(index, hotword)
8590
})
8691

8792
csr.on('error', error => sonus.emit('error', { streamingError: error }))
@@ -97,6 +102,21 @@ Sonus.init = (options, recognizer) => {
97102
}
98103
}
99104
})
105+
106+
sonus.trigger = (index, hotword) => {
107+
if(sonus.started){
108+
try{
109+
let triggerHotword = (index == 0)? hotword : models.lookup(index)
110+
sonus.emit('hotword', index, triggerHotword)
111+
CloudSpeechRecognizer.startStreaming(opts, sonus.mic, csr)
112+
} catch (e) {
113+
throw ERROR.INVALID_INDEX
114+
}
115+
} else {
116+
throw ERROR.NOT_STARTED
117+
}
118+
}
119+
100120
return sonus
101121
}
102122

@@ -107,8 +127,11 @@ Sonus.start = sonus => {
107127
})
108128

109129
sonus.mic.pipe(sonus.detector)
130+
sonus.started = true
110131
}
111132

133+
Sonus.trigger = (sonus, index, hotword) => sonus.trigger(index, hotword)
134+
112135
Sonus.pause = sonus => sonus.mic.pause()
113136

114137
Sonus.resume = sonus => sonus.mic.resume()

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sonus",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "Open source cross platform decentralized always-on speech recognition framework",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)