diff --git a/platform/web/js/libs/audio.position.worklet.js b/platform/web/js/libs/audio.position.worklet.js index 155d4e6e876..1237e843f9a 100644 --- a/platform/web/js/libs/audio.position.worklet.js +++ b/platform/web/js/libs/audio.position.worklet.js @@ -28,40 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -const POST_THRESHOLD_S = 0.1; - class GodotPositionReportingProcessor extends AudioWorkletProcessor { constructor(...args) { super(...args); - this.lastPostTime = currentTime; this.position = 0; - this.ended = false; this.port.onmessage = (event) => { - if (event?.data?.type === 'ended') { - this.ended = true; + switch (event?.data?.type) { + case 'reset': + this.position = 0; + break; + default: + // Do nothing. } }; } process(inputs, _outputs, _parameters) { - if (this.ended) { - return false; - } - if (inputs.length > 0) { const input = inputs[0]; if (input.length > 0) { this.position += input[0].length; + this.port.postMessage({ type: 'position', data: this.position }); } } - // Posting messages is expensive. Let's limit the number of posts. - if (currentTime - this.lastPostTime > POST_THRESHOLD_S) { - this.lastPostTime = currentTime; - this.port.postMessage({ type: 'position', data: this.position }); - } - return true; } } diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 759d893fd94..7f8ddb0aa68 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -635,10 +635,14 @@ class SampleNode { if (this._positionWorklet != null) { return this._positionWorklet; } - this._positionWorklet = new AudioWorkletNode( - GodotAudio.ctx, - 'godot-position-reporting-processor' - ); + if (GodotAudio.audioPositionWorkletNodes.length > 0) { + this._positionWorklet = GodotAudio.audioPositionWorkletNodes.pop(); + } else { + this._positionWorklet = new AudioWorkletNode( + GodotAudio.ctx, + 'godot-position-reporting-processor' + ); + } this._positionWorklet.port.onmessage = (event) => { switch (event.data['type']) { case 'position': @@ -648,6 +652,7 @@ class SampleNode { // Do nothing. } }; + this._positionWorklet.port.postMessage('reset'); return this._positionWorklet; } @@ -678,7 +683,7 @@ class SampleNode { if (this._positionWorklet) { this._positionWorklet.disconnect(); this._positionWorklet.port.onmessage = null; - this._positionWorklet.port.postMessage({ type: 'ended' }); + GodotAudio.audioPositionWorkletNodes.push(this._positionWorklet); this._positionWorklet = null; } @@ -1198,6 +1203,8 @@ const _GodotAudio = { /** @type {Promise} */ audioPositionWorkletPromise: null, + /** @type {Array} */ + audioPositionWorkletNodes: null, /** * Converts linear volume to Db. @@ -1224,6 +1231,7 @@ const _GodotAudio = { GodotAudio.sampleNodes = new Map(); GodotAudio.buses = []; GodotAudio.busSolo = null; + GodotAudio.audioPositionWorkletNodes = []; const opts = {}; // If mix_rate is 0, let the browser choose.