Merge pull request #911 from ericrosenbaum/bugfix/music-ext-safari-onended

Keep playing notes and drums forever on Safari
This commit is contained in:
Eric Rosenbaum 2018-01-26 13:00:56 -05:00 committed by GitHub
commit 229cd7a50c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -60,6 +60,15 @@ class Scratch3MusicBlocks {
*/ */
this._instrumentBufferArrays = []; 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(); this._loadAllSounds();
} }
@ -555,9 +564,14 @@ class Scratch3MusicBlocks {
bufferSource.buffer = this._drumBuffers[drumNum]; bufferSource.buffer = this._drumBuffers[drumNum];
bufferSource.connect(outputNode); bufferSource.connect(outputNode);
bufferSource.start(); bufferSource.start();
const bufferSourceIndex = this._bufferSources.length;
this._bufferSources.push(bufferSource);
this._concurrencyCounter++; this._concurrencyCounter++;
bufferSource.onended = () => { bufferSource.onended = () => {
this._concurrencyCounter--; this._concurrencyCounter--;
delete this._bufferSources[bufferSourceIndex];
}; };
} }
@ -638,6 +652,10 @@ class Scratch3MusicBlocks {
// Create the audio buffer to play the note, and set its pitch // Create the audio buffer to play the note, and set its pitch
const context = util.runtime.audioEngine.audioContext; const context = util.runtime.audioEngine.audioContext;
const bufferSource = context.createBufferSource(); const bufferSource = context.createBufferSource();
const bufferSourceIndex = this._bufferSources.length;
this._bufferSources.push(bufferSource);
bufferSource.buffer = this._instrumentBufferArrays[inst][sampleIndex]; bufferSource.buffer = this._instrumentBufferArrays[inst][sampleIndex];
const sampleNote = sampleArray[sampleIndex]; const sampleNote = sampleArray[sampleIndex];
bufferSource.playbackRate.value = this._ratioForPitchInterval(note - sampleNote); bufferSource.playbackRate.value = this._ratioForPitchInterval(note - sampleNote);
@ -667,6 +685,7 @@ class Scratch3MusicBlocks {
this._concurrencyCounter++; this._concurrencyCounter++;
bufferSource.onended = () => { bufferSource.onended = () => {
this._concurrencyCounter--; this._concurrencyCounter--;
delete this._bufferSources[bufferSourceIndex];
}; };
} }