From 073ee84a91a47ee4265ab48a1deada7141391c3e Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Mon, 22 Jan 2018 11:57:06 -0500 Subject: [PATCH] Keep bufferSource refs so onended fires on safari --- src/extensions/scratch3_music/index.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/extensions/scratch3_music/index.js b/src/extensions/scratch3_music/index.js index 6202b2ceb..6d391bb9e 100644 --- a/src/extensions/scratch3_music/index.js +++ b/src/extensions/scratch3_music/index.js @@ -60,6 +60,15 @@ class Scratch3MusicBlocks { */ this._instrumentBufferArrays = []; + /** + * An array of audio bufferSourceNodes. Each time you play an instrument or drum sound, + * a bufferSourceNode is created. We keep references to them to make sure their onended + * events can fire. + * @type {Array} + * @private + */ + this._bufferSources = []; + this._loadAllSounds(); } @@ -555,9 +564,14 @@ class Scratch3MusicBlocks { bufferSource.buffer = this._drumBuffers[drumNum]; bufferSource.connect(outputNode); bufferSource.start(); + + const bufferSourceIndex = this._bufferSources.length; + this._bufferSources.push(bufferSource); + this._concurrencyCounter++; bufferSource.onended = () => { this._concurrencyCounter--; + delete this._bufferSources[bufferSourceIndex]; }; } @@ -638,6 +652,10 @@ class Scratch3MusicBlocks { // Create the audio buffer to play the note, and set its pitch const context = util.runtime.audioEngine.audioContext; const bufferSource = context.createBufferSource(); + + const bufferSourceIndex = this._bufferSources.length; + this._bufferSources.push(bufferSource); + bufferSource.buffer = this._instrumentBufferArrays[inst][sampleIndex]; const sampleNote = sampleArray[sampleIndex]; bufferSource.playbackRate.value = this._ratioForPitchInterval(note - sampleNote); @@ -667,6 +685,7 @@ class Scratch3MusicBlocks { this._concurrencyCounter++; bufferSource.onended = () => { this._concurrencyCounter--; + delete this._bufferSources[bufferSourceIndex]; }; }