-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsound-detector.js
88 lines (62 loc) · 1.77 KB
/
sound-detector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const EventEmitter = require('events');
const spawn = require('child_process').spawn;
const os = require('os');
class SoundDetector extends EventEmitter {
constructor() {
super();
this.config = {
PERCENTAGE_START : '10%',
PERCENTAGE_END : '10%'
}
}
start() {
if(this._started) {
return;
}
this._started = true;
this._listen();
}
stop(){
this._started = false;
if(this.recorder) {
this.recorder.kill();
this.recorder = null;
}
}
_listen() {
if(!this._started)
return this.emit("Listener not running");
var args = ({
'Linux' : ['-t', 'alsa', 'hw:1,0'],
'Windows_NT' : ['-t', 'waveaudio', '-d'],
'Darwin' : ['-t', 'coreaudio', 'default']
}) [os.type()];
args.push("-t", "wav", "-n");
args.push("--no-show-progress");
args.push("silence", "1", "0.0001", this.config.PERCENTAGE_START, "1", "0.1", this.config.PERCENTAGE_END);
args.push("stat");
var child = spawn("sox", args), body = "";
this.recorder = child;
child.stderr.on("data", function(buf){ body += buf; });
child.on("exit", () => {
var {max,duration,rms} = this._parse(body);
this.emit("detected", {max,duration,rms});
this._listen();
});
}
_parse(body) {
body = body.replace(new RegExp("[ \\t]+", "g") , " "); //sox use spaces to align output
var split = new RegExp("^(.*):\\s*(.*)$", "mg"), match, dict = {}; //simple key:value
while(match = split.exec(body))
dict[match[1]] = parseFloat(match[2]);
return {
duration: dict['Length (seconds)'],
rms: dict['RMS amplitude'],
max: dict['Maximum amplitude']
};
}
isStarted() {
return this._started;
}
}
module.exports = SoundDetector;