diff --git a/src/content/getusermedia/volume/js/soundmeter.js b/src/content/getusermedia/volume/js/soundmeter.js index 20c5ae9c46..b8e5b9743e 100644 --- a/src/content/getusermedia/volume/js/soundmeter.js +++ b/src/content/getusermedia/volume/js/soundmeter.js @@ -18,32 +18,22 @@ function SoundMeter(context) { this.instant = 0.0; this.slow = 0.0; this.clip = 0.0; - this.script = context.createScriptProcessor(2048, 1, 1); - const that = this; - this.script.onaudioprocess = function(event) { - const input = event.inputBuffer.getChannelData(0); - let i; - let sum = 0.0; - let clipcount = 0; - for (i = 0; i < input.length; ++i) { - sum += input[i] * input[i]; - if (Math.abs(input[i]) > 0.99) { - clipcount += 1; - } - } - that.instant = Math.sqrt(sum / input.length); - that.slow = 0.95 * that.slow + 0.05 * that.instant; - that.clip = clipcount / input.length; - }; + this.node = null; } -SoundMeter.prototype.connectToSource = function(stream, callback) { +SoundMeter.prototype.connectToSource = async function(stream, callback) { console.log('SoundMeter connecting'); try { + await this.context.audioWorklet.addModule('js/volume-meter-processor.js'); this.mic = this.context.createMediaStreamSource(stream); - this.mic.connect(this.script); - // necessary to make sample run, but should not be. - this.script.connect(this.context.destination); + this.node = new AudioWorkletNode(this.context, 'volume-meter-processor'); + this.node.port.onmessage = (event) => { + const {instant, clip} = event.data; + this.instant = instant; + this.clip = clip; + this.slow = 0.95 * this.slow + 0.05 * this.instant; + }; + this.mic.connect(this.node); if (typeof callback !== 'undefined') { callback(null); } @@ -58,5 +48,5 @@ SoundMeter.prototype.connectToSource = function(stream, callback) { SoundMeter.prototype.stop = function() { console.log('SoundMeter stopping'); this.mic.disconnect(); - this.script.disconnect(); + this.node.disconnect(); }; diff --git a/src/content/getusermedia/volume/js/volume-meter-processor.js b/src/content/getusermedia/volume/js/volume-meter-processor.js new file mode 100644 index 0000000000..144bafb93e --- /dev/null +++ b/src/content/getusermedia/volume/js/volume-meter-processor.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + +'use strict'; + +// This class is used to compute the volume of the input audio stream. +class VolumeMeterProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this._lastUpdate = Date.now(); + } + process(inputs) { + // This example only supports mono channel. + const input = inputs[0][0]; + if (!input) { + return true; + } + let sum = 0.0; + let clipcount = 0; + for (let i = 0; i < input.length; ++i) { + sum += input[i] * input[i]; + if (Math.abs(input[i]) > 0.99) { + clipcount += 1; + } + } + const instant = Math.sqrt(sum / input.length); + this.port.postMessage({ + instant: instant, + clip: clipcount / input.length, + }); + return true; + } +} + +registerProcessor('volume-meter-processor', VolumeMeterProcessor);