mirror of
https://github.com/scratchfoundation/scratch-audio.git
synced 2025-01-05 04:11:55 -05:00
Re-implement loudness block
This commit is contained in:
parent
03034dd2f7
commit
2974a5e65b
1 changed files with 37 additions and 10 deletions
47
src/index.js
47
src/index.js
|
@ -289,20 +289,47 @@ class AudioEngine {
|
||||||
/**
|
/**
|
||||||
* Get the current loudness of sound received by the microphone.
|
* Get the current loudness of sound received by the microphone.
|
||||||
* Sound is measured in RMS and smoothed.
|
* Sound is measured in RMS and smoothed.
|
||||||
|
* Some code adapted from Tone.js: https://github.com/Tonejs/Tone.js
|
||||||
* @return {number} loudness scaled 0 to 100
|
* @return {number} loudness scaled 0 to 100
|
||||||
*/
|
*/
|
||||||
getLoudness () {
|
getLoudness () {
|
||||||
// if (!this.mic) {
|
// the microphone has not been set up, try to connect to it
|
||||||
// this.mic = new Tone.UserMedia();
|
if (!this.mic && !this.connectingToMic) {
|
||||||
// this.micMeter = new Tone.Meter('level', 0.5);
|
this.connectingToMic = true; // prevent multiple connection attempts
|
||||||
// this.mic.open();
|
navigator.mediaDevices.getUserMedia({audio : true}).then(stream => {
|
||||||
// this.mic.connect(this.micMeter);
|
this.mic = this.context.createMediaStreamSource(stream);
|
||||||
// }
|
this.analyser = this.context.createAnalyser();
|
||||||
// if (this.mic && this.mic.state === 'started') {
|
this.mic.connect(this.analyser);
|
||||||
// return this.micMeter.value * 100;
|
this.micDataArray = new Float32Array(this.analyser.fftSize);
|
||||||
// }
|
}).catch(err => {
|
||||||
return -1;
|
log.warn(err)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the microphone is set up and active, measure the loudness
|
||||||
|
if (this.mic && this.mic.mediaStream.active) {
|
||||||
|
this.analyser.getFloatTimeDomainData(this.micDataArray);
|
||||||
|
let sum = 0;
|
||||||
|
// compute the RMS of the sound
|
||||||
|
for (let i = 0; i < this.micDataArray.length; i++){
|
||||||
|
sum += Math.pow(this.micDataArray[i], 2);
|
||||||
|
}
|
||||||
|
let rms = Math.sqrt(sum / this.micDataArray.length);
|
||||||
|
// smooth the value, if it is descending
|
||||||
|
if (this._lastValue) {
|
||||||
|
rms = Math.max(rms, this._lastValue * 0.5);
|
||||||
|
}
|
||||||
|
this._lastValue = rms;
|
||||||
|
|
||||||
|
// scale it
|
||||||
|
// @todo figure out why this magic number is needed and remove it!
|
||||||
|
rms *= 1.63;
|
||||||
|
// scale and round the output
|
||||||
|
return Math.round(Math.sqrt(rms) * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is no microphone input, return -1
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue