diff --git a/src/ADPCMSoundDecoder.js b/src/ADPCMSoundDecoder.js index 3a29d79..b970d76 100644 --- a/src/ADPCMSoundDecoder.js +++ b/src/ADPCMSoundDecoder.js @@ -9,8 +9,12 @@ const log = require('./log'); * https://github.com/LLK/scratch-flash/blob/master/src/sound/WAVFile.as */ class ADPCMSoundDecoder { - constructor (context) { - this.context = context; + /** + * @param {AudioContext} audioContext - a webAudio context + * @constructor + */ + constructor (audioContext) { + this.audioContext = audioContext; } /** * Data used by the decompression algorithm @@ -79,7 +83,7 @@ class ADPCMSoundDecoder { const samples = this.imaDecompress(this.extractChunk('data', stream), this.adpcmBlockSize); - const buffer = this.context.createBuffer(1, samples.length, this.samplesPerSecond); + const buffer = this.audioContext.createBuffer(1, samples.length, this.samplesPerSecond); // @todo optimize this? e.g. replace the divide by storing 1/32768 and multiply? for (let i = 0; i < samples.length; i++) { diff --git a/src/DrumPlayer.js b/src/DrumPlayer.js index 3d1aaf4..8592321 100644 --- a/src/DrumPlayer.js +++ b/src/DrumPlayer.js @@ -3,11 +3,11 @@ const SoundPlayer = require('./SoundPlayer'); class DrumPlayer { /** * A prototype for the drum sound functionality that can load drum sounds, play, and stop them. - * @param {AudioContext} context - a webAudio context + * @param {AudioContext} audioContext - a webAudio context * @constructor */ - constructor (context) { - this.context = context; + constructor (audioContext) { + this.audioContext = audioContext; const baseUrl = 'https://raw.githubusercontent.com/LLK/scratch-audio/develop/sound-files/drums/'; const fileNames = [ @@ -34,7 +34,7 @@ class DrumPlayer { this.drumSounds = []; for (let i = 0; i < fileNames.length; i++) { - this.drumSounds[i] = new SoundPlayer(this.context); + this.drumSounds[i] = new SoundPlayer(this.audioContext); // download and decode the drum sounds // @todo: use scratch-storage to manage these sound files @@ -44,7 +44,7 @@ class DrumPlayer { request.responseType = 'arraybuffer'; request.onload = () => { const audioData = request.response; - this.context.decodeAudioData(audioData).then(buffer => { + this.audioContext.decodeAudioData(audioData).then(buffer => { this.drumSounds[i].setBuffer(buffer); }); }; diff --git a/src/InstrumentPlayer.js b/src/InstrumentPlayer.js index bb3484d..87c900f 100644 --- a/src/InstrumentPlayer.js +++ b/src/InstrumentPlayer.js @@ -9,11 +9,11 @@ class InstrumentPlayer { * play note or set instrument block runs, causing a delay of a few seconds. * Using this library we don't have a way to set the volume, sustain the note beyond the sample * duration, or run it through the sprite-specific audio effects. - * @param {AudioContext} context - a webAudio context + * @param {AudioContext} audioContext - a webAudio context * @constructor */ - constructor (context) { - this.context = context; + constructor (audioContext) { + this.audioContext = audioContext; this.outputNode = null; // Instrument names used by Musyng Kite soundfont, in order to @@ -42,7 +42,7 @@ class InstrumentPlayer { this.loadInstrument(instrumentNum) .then(() => { this.instruments[instrumentNum].play( - note, this.context.currentTime, { + note, this.audioContext.currentTime, { duration: sec, gain: gain } @@ -59,7 +59,7 @@ class InstrumentPlayer { if (this.instruments[instrumentNum]) { return Promise.resolve(); } - return Soundfont.instrument(this.context, this.instrumentNames[instrumentNum]) + return Soundfont.instrument(this.audioContext, this.instrumentNames[instrumentNum]) .then(inst => { inst.connect(this.outputNode); this.instruments[instrumentNum] = inst; diff --git a/src/SoundPlayer.js b/src/SoundPlayer.js index ed73a78..35e9e67 100644 --- a/src/SoundPlayer.js +++ b/src/SoundPlayer.js @@ -4,8 +4,12 @@ const log = require('./log'); * A SoundPlayer stores an audio buffer, and plays it */ class SoundPlayer { - constructor (context) { - this.context = context; + /** + * @param {AudioContext} audioContext - a webAudio context + * @constructor + */ + constructor (audioContext) { + this.audioContext = audioContext; this.outputNode = null; this.buffer = null; this.bufferSource = null; @@ -60,7 +64,7 @@ class SoundPlayer { return; } - this.bufferSource = this.context.createBufferSource(); + this.bufferSource = this.audioContext.createBufferSource(); this.bufferSource.buffer = this.buffer; this.bufferSource.playbackRate.value = this.playbackRate; this.bufferSource.connect(this.outputNode); diff --git a/src/effects/PanEffect.js b/src/effects/PanEffect.js index 86e55eb..8374243 100644 --- a/src/effects/PanEffect.js +++ b/src/effects/PanEffect.js @@ -5,9 +5,13 @@ * Clamped -100 to 100 */ class PanEffect { - constructor (context) { - this.context = context; - this.panner = this.context.createStereoPanner(); + /** + * @param {AudioContext} audioContext - a webAudio context + * @constructor + */ + constructor (audioContext) { + this.audioContext = audioContext; + this.panner = this.audioContext.createStereoPanner(); this.value = 0; } diff --git a/src/index.js b/src/index.js index ff638ba..49dfdf2 100644 --- a/src/index.js +++ b/src/index.js @@ -26,11 +26,11 @@ class AudioPlayer { // Create the audio effects this.pitchEffect = new PitchEffect(); - this.panEffect = new PanEffect(this.audioEngine.context); + this.panEffect = new PanEffect(this.audioEngine.audioContext); // Chain the audio effects together // effectsNode -> panEffect -> audioEngine.input -> destination (speakers) - this.effectsNode = this.audioEngine.context.createGain(); + this.effectsNode = this.audioEngine.audioContext.createGain(); this.effectsNode.connect(this.panEffect.panner); this.panEffect.connect(this.audioEngine.input); @@ -58,7 +58,7 @@ class AudioPlayer { } // create a new soundplayer to play the sound - const player = new SoundPlayer(this.audioEngine.context); + const player = new SoundPlayer(this.audioEngine.audioContext); player.setBuffer(this.audioEngine.audioBuffers[md5]); player.connect(this.effectsNode); this.pitchEffect.updatePlayer(player); @@ -150,21 +150,21 @@ class AudioPlayer { class AudioEngine { constructor () { const AudioContext = window.AudioContext || window.webkitAudioContext; - this.context = new AudioContext(); + this.audioContext = new AudioContext(); - this.input = this.context.createGain(); - this.input.connect(this.context.destination); + this.input = this.audioContext.createGain(); + this.input.connect(this.audioContext.destination); // global tempo in bpm (beats per minute) this.currentTempo = 60; // instrument player for play note blocks - this.instrumentPlayer = new InstrumentPlayer(this.context); + this.instrumentPlayer = new InstrumentPlayer(this.audioContext); this.instrumentPlayer.outputNode = this.input; this.numInstruments = this.instrumentPlayer.instrumentNames.length; // drum player for play drum blocks - this.drumPlayer = new DrumPlayer(this.context); + this.drumPlayer = new DrumPlayer(this.audioContext); this.numDrums = this.drumPlayer.drumSounds.length; // a map of md5s to audio buffers, holding sounds for all sprites @@ -204,10 +204,10 @@ class AudioEngine { switch (sound.format) { case '': - loaderPromise = this.context.decodeAudioData(bufferCopy); + loaderPromise = this.audioContext.decodeAudioData(bufferCopy); break; case 'adpcm': - loaderPromise = (new ADPCMSoundDecoder(this.context)).decode(bufferCopy); + loaderPromise = (new ADPCMSoundDecoder(this.audioContext)).decode(bufferCopy); break; default: return log.warn('unknown sound format', sound.format); @@ -297,8 +297,8 @@ class AudioEngine { if (!this.mic && !this.connectingToMic) { this.connectingToMic = true; // prevent multiple connection attempts navigator.mediaDevices.getUserMedia({audio: true}).then(stream => { - this.mic = this.context.createMediaStreamSource(stream); - this.analyser = this.context.createAnalyser(); + this.mic = this.audioContext.createMediaStreamSource(stream); + this.analyser = this.audioContext.createAnalyser(); this.mic.connect(this.analyser); this.micDataArray = new Float32Array(this.analyser.fftSize); })