diff --git a/src/effects/PanEffect.js b/src/effects/PanEffect.js index aeebb2c..b8090e0 100644 --- a/src/effects/PanEffect.js +++ b/src/effects/PanEffect.js @@ -5,11 +5,12 @@ */ class PanEffect { /** - * @param {AudioContext} audioContext - a webAudio context + * @param {AudioEngine} audioEngine - the audio engine. * @constructor */ - constructor (audioContext) { - this.audioContext = audioContext; + constructor (audioEngine) { + this.audioEngine = audioEngine; + this.audioContext = this.audioEngine.audioContext; this.value = 0; this.input = this.audioContext.createGain(); @@ -37,8 +38,11 @@ class PanEffect { // Use trig functions for equal-loudness panning // See e.g. https://docs.cycling74.com/max7/tutorials/13_panningchapter01 - this.leftGain.gain.value = Math.cos(p * Math.PI / 2); - this.rightGain.gain.value = Math.sin(p * Math.PI / 2); + const leftVal = Math.cos(p * Math.PI / 2); + const rightVal = Math.sin(p * Math.PI / 2); + + this.leftGain.gain.setTargetAtTime(leftVal, 0, this.audioEngine.DECAY_TIME); + this.rightGain.gain.setTargetAtTime(rightVal, 0, this.audioEngine.DECAY_TIME); } /** diff --git a/src/index.js b/src/index.js index 6dccf70..501452f 100644 --- a/src/index.js +++ b/src/index.js @@ -28,7 +28,7 @@ class AudioPlayer { // Create the audio effects this.pitchEffect = new PitchEffect(); - this.panEffect = new PanEffect(this.audioEngine.audioContext); + this.panEffect = new PanEffect(this.audioEngine); // Chain the audio effects together // effectsNode -> panEffect -> audioEngine.input @@ -121,7 +121,8 @@ class AudioPlayer { clearEffects () { this.panEffect.set(0); this.pitchEffect.set(0, this.activeSoundPlayers); - this.effectsNode.gain.value = 1; + if (this.audioEngine === null) return; + this.effectsNode.gain.setTargetAtTime(1.0, 0, this.audioEngine.DECAY_TIME); } /** @@ -129,7 +130,8 @@ class AudioPlayer { * @param {number} value - the volume in range 0-100 */ setVolume (value) { - this.effectsNode.gain.value = value / 100; + if (this.audioEngine === null) return; + this.effectsNode.gain.setTargetAtTime(value / 100, 0, this.audioEngine.DECAY_TIME); } } @@ -164,6 +166,16 @@ class AudioEngine { }; } + /** + * A short duration, for use as a time constant for exponential audio parameter transitions. + * See: + * https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime + * @const {number} + */ + get DECAY_TIME () { + return 0.001; + } + /** * Decode a sound, decompressing it into audio samples. * Store a reference to it the sound in the audioBuffers dictionary, indexed by soundId