blob: 44e9ccc058f7cac2d79e764ed8748c3bf561649c (
plain)
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
|
/* global AFRAME */
// Measures how loud a remote person is talking (0..1) from their incoming voice
// stream, for lip-sync and the speaking indicator.
AFRAME.registerComponent('voice-level', {
init() {
this.level = 0;
this.analyser = null;
this.samples = null;
this.onSoundSource = (evt) => {
const source = evt.detail.soundSource;
if (this.analyser) this.analyser.disconnect();
this.analyser = source.context.createAnalyser();
this.analyser.fftSize = 512;
this.samples = new Uint8Array(this.analyser.fftSize);
source.connect(this.analyser);
};
this.el.addEventListener('sound-source-set', this.onSoundSource);
},
remove() {
this.el.removeEventListener('sound-source-set', this.onSoundSource);
if (this.analyser) this.analyser.disconnect();
},
tick() {
if (!this.analyser) return;
this.analyser.getByteTimeDomainData(this.samples);
let sum = 0;
for (let i = 0; i < this.samples.length; i++) {
const v = (this.samples[i] - 128) / 128;
sum += v * v;
}
const rms = Math.sqrt(sum / this.samples.length);
const target = Math.min(1, Math.max(0, (rms - 0.012) * 9));
// Open quickly, close a little slower, so mouths don't chatter.
this.level += (target - this.level) * (target > this.level ? 0.6 : 0.2);
},
});
|