Last active
June 3, 2022 18:07
-
-
Save mwmwmw/d0942149a5a9d94b43d629c4c92f01b9 to your computer and use it in GitHub Desktop.
VU Meter Audio Worklet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class VUMeterNode extends AudioWorkletNode { | |
constructor(context, updateIntervalInMS = 16.67) { | |
super(context, "vumeter", { | |
numberOfInputs: 1, | |
numberOfOutputs: 0, | |
channelCount: 1, | |
processorOptions: { | |
updateIntervalInMS | |
} | |
}); | |
this._updateIntervalInMS = updateIntervalInMS; | |
this._volume = 0; | |
this._volumeDelta = 0; | |
this._hit = 0; | |
this._overage = 0; | |
this.port.onmessage = (event) => { | |
const { volume, volumeDelta, hit, overage } = event.data; | |
this._volume = volume; | |
this._volumeDelta = volumeDelta; | |
this._hit = hit; | |
this._overage = overage; | |
}; | |
this.port.start(); | |
} | |
get updateInterval() { | |
return this._updateIntervalInMS; | |
} | |
get volume() { | |
return this._volume; | |
} | |
get volumeDelta() { | |
return this._volumeDelta; | |
} | |
get hit() { | |
return this._hit; | |
} | |
get overage() { | |
return this._overage; | |
} | |
set updateInterval(updateIntervalInMS) { | |
this._updateIntervalInMS = updateIntervalInMS; | |
this.port.postMessage({ updateIntervalInMS: updateIntervalInMS }); | |
} | |
set sensitivity(value) { | |
const sense = this.parameters.get("sensitivity"); | |
sense.setValueAtTime(value, this.context.currentTime); | |
} | |
set smooth(value) { | |
const sense = this.parameters.get("smooth"); | |
sense.setValueAtTime(value, this.context.currentTime); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const SMOOTHING_FACTOR = 0.99; | |
const MINIMUM_VALUE = 0.000001; | |
registerProcessor('vumeter', class extends AudioWorkletProcessor { | |
static get parameterDescriptors() { | |
return [{ | |
name: 'threshold', | |
defaultValue: 0.2, | |
minValue: 0, | |
maxValue: 1, | |
automationRate: 'k-rate' | |
}, { | |
name: 'sensitivity', | |
defaultValue: 0.1, | |
minValue: 0, | |
maxValue: 1, | |
automationRate: 'k-rate' | |
}, { | |
name: 'smooth', | |
defaultValue: 0.996, | |
minValue: 0, | |
maxValue: 1, | |
automationRate: 'k-rate' | |
}]; | |
} | |
constructor(options) { | |
super(); | |
this._volume = 0; | |
this._lastVolume = 0; | |
this.pack = { | |
volume:0, volumeDelta:0, hit:0, overage:0 | |
} | |
this._updateIntervalInMS = options.processorOptions.updateIntervalInMS | 16.67; | |
this._nextUpdateFrame = this._updateIntervalInMS; | |
this.port.onmessage = event => { | |
if (event.data.updateIntervalInMS) | |
this._updateIntervalInMS = event.data.updateIntervalInMS; | |
} | |
} | |
get intervalInFrames() { | |
return this._updateIntervalInMS / 1000 * sampleRate; | |
} | |
process(inputs, outputs, parameters) { | |
const input = inputs[0]; | |
if (input.length > 0) { | |
let sum = 0; | |
// Calculated the squared-sum. | |
for (let i = 0; i < input[0].length; ++i) | |
sum += input[0][i] * input[0][i]; | |
// Calculate the RMS level and update the volume. | |
this._volume = Math.max(Math.sqrt(sum / input[0].length), this._volume * parameters['smooth'][0]); | |
// Update and sync the volume property with the main thread. | |
this._nextUpdateFrame -= inputs[0][0].length; | |
if (this._nextUpdateFrame < 0) { | |
const delta = this._volume - this._lastVolume; | |
this._nextUpdateFrame += this.intervalInFrames; | |
this.pack.volume = this._volume; | |
this.pack.volumeDelta = delta; | |
this.pack.hit = delta > parameters['sensitivity'][0]; | |
this.port.postMessage(this.pack); | |
this._lastVolume = this._volume; | |
} | |
} | |
return true; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment