forked from ChelseaKR/olive-bark-logger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdetector.js
More file actions
73 lines (67 loc) · 1.83 KB
/
Copy pathdetector.js
File metadata and controls
73 lines (67 loc) · 1.83 KB
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
// Streaming event detector — a faithful port of monitor/detector.py.
// Threshold + minimum-duration + debounce, peak/avg over loud readings only.
// Numbers and timestamps only; no audio is involved here.
export class Detector {
constructor(thresholdDbfs, minDurationS, debounceS) {
if (minDurationS < 0 || debounceS < 0) {
throw new Error("minDurationS and debounceS must be non-negative");
}
this.threshold = thresholdDbfs;
this.minDuration = minDurationS;
this.debounce = debounceS;
this._active = false;
this._start = 0;
this._lastAbove = 0;
this._peak = 0;
this._sum = 0;
this._n = 0;
}
// Feed one (t, level) reading. Returns an event object if one just closed, else null.
push(t, level) {
const above = level >= this.threshold;
if (!this._active) {
if (above) this._open(t, level);
return null;
}
if (above) {
this._lastAbove = t;
this._accumulate(level);
return null;
}
if (t - this._lastAbove >= this.debounce) return this._close();
return null;
}
// Close any open event at end of stream.
flush() {
return this._active ? this._close() : null;
}
_open(t, level) {
this._active = true;
this._start = t;
this._lastAbove = t;
this._peak = level;
this._sum = level;
this._n = 1;
}
_accumulate(level) {
if (level > this._peak) this._peak = level;
this._sum += level;
this._n += 1;
}
_close() {
const duration = this._lastAbove - this._start;
let event = null;
if (duration >= this.minDuration) {
event = {
start: this._start,
end: this._lastAbove,
duration,
peak_level: this._peak,
avg_level: this._n ? this._sum / this._n : this.threshold,
coarse_tag: null,
};
}
this._active = false;
return event;
}
}