From 1c8a545a8a45d121995a965a6375a4419f405299 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Wed, 20 Dec 2017 12:07:53 -0500 Subject: [PATCH 1/2] Set gain using setTargetAtTime --- src/effects/PanEffect.js | 14 +++++++++----- src/index.js | 20 +++++++++++++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/effects/PanEffect.js b/src/effects/PanEffect.js index aeebb2c..a31890b 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.ONE_THIRD_FRAME); + this.rightGain.gain.setTargetAtTime(rightVal, 0, this.audioEngine.ONE_THIRD_FRAME); } /** diff --git a/src/index.js b/src/index.js index 6dccf70..3cab5d8 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.ONE_THIRD_FRAME); } /** @@ -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.ONE_THIRD_FRAME); } } @@ -164,6 +166,18 @@ class AudioEngine { }; } + /** + * The duration in seconds of one third of one frame, at 30 frames per second. + * This is useful for setting web audio time constants. For example, in order for + * a gain to reach 95% of its target value in one frame, use this time constant. + * See: + * https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime + * @const {number} + */ + get ONE_THIRD_FRAME () { + return (1 / 30) / 3; + } + /** * Decode a sound, decompressing it into audio samples. * Store a reference to it the sound in the audioBuffers dictionary, indexed by soundId From 734f97658555b88d76709333d7879c55b851ab24 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Wed, 20 Dec 2017 15:17:26 -0500 Subject: [PATCH 2/2] New name and value for DECAY_TIME --- src/effects/PanEffect.js | 4 ++-- src/index.js | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/effects/PanEffect.js b/src/effects/PanEffect.js index a31890b..b8090e0 100644 --- a/src/effects/PanEffect.js +++ b/src/effects/PanEffect.js @@ -41,8 +41,8 @@ class PanEffect { const leftVal = Math.cos(p * Math.PI / 2); const rightVal = Math.sin(p * Math.PI / 2); - this.leftGain.gain.setTargetAtTime(leftVal, 0, this.audioEngine.ONE_THIRD_FRAME); - this.rightGain.gain.setTargetAtTime(rightVal, 0, this.audioEngine.ONE_THIRD_FRAME); + 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 3cab5d8..501452f 100644 --- a/src/index.js +++ b/src/index.js @@ -122,7 +122,7 @@ class AudioPlayer { this.panEffect.set(0); this.pitchEffect.set(0, this.activeSoundPlayers); if (this.audioEngine === null) return; - this.effectsNode.gain.setTargetAtTime(1.0, 0, this.audioEngine.ONE_THIRD_FRAME); + this.effectsNode.gain.setTargetAtTime(1.0, 0, this.audioEngine.DECAY_TIME); } /** @@ -131,7 +131,7 @@ class AudioPlayer { */ setVolume (value) { if (this.audioEngine === null) return; - this.effectsNode.gain.setTargetAtTime(value / 100, 0, this.audioEngine.ONE_THIRD_FRAME); + this.effectsNode.gain.setTargetAtTime(value / 100, 0, this.audioEngine.DECAY_TIME); } } @@ -167,15 +167,13 @@ class AudioEngine { } /** - * The duration in seconds of one third of one frame, at 30 frames per second. - * This is useful for setting web audio time constants. For example, in order for - * a gain to reach 95% of its target value in one frame, use this time constant. + * 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 ONE_THIRD_FRAME () { - return (1 / 30) / 3; + get DECAY_TIME () { + return 0.001; } /**