Search code examples
javascriptweb-audio-api

Web Audio: Change gain value before oscillator starts


I just noticed that it seems not possible to change the gain.value of a gainNode with the method setValueAtTime() or setValueCurveAtTime() when there is no oscillator connected or when the oscillator has not started yet.

setValueAtTime after that the oscillator starts

For instance in this case, setValueAtTime will work as expected:

var context = new AudioContext();

var gain = context.createGain();
gain.connect(context.destination);

var osc = context.createOscillator();
osc.frequency.value = 300;
osc.connect(gain);

osc.start();

gain.gain.setValueAtTime(0, context.currentTime + 1);

The oscillator starts and the gain is 1 for 1 second. Then gain.gain.value will move to 0.

setValueAtTime before that the oscillator starts

However if we set the gain with setValueAtTime before the oscillator starts

var context = new AudioContext();

var gain = context.createGain();
gain.connect(context.destination);

var osc = context.createOscillator();
osc.frequency.value = 300;
osc.connect(gain);

osc.start(context.currentTime + 1);

gain.gain.setValueAtTime(0, context.currentTime);

The gain.gain.value will stay to 1.

Set gain.gain.value without setValueAtTime

What is strange is that this behaviour is not seen if we set the gain directly

var context = new AudioContext();

var gain = context.createGain();
gain.connect(context.destination);

var osc = context.createOscillator();
osc.frequency.value = 300;
osc.connect(gain);

osc.start(context.currentTime + 1);

gain.gain.value = 0;

The gain value will always stay to 0.


Solution

  • If you're using Chrome, then this is probably a bug in Chrome. Chrome actually returns the computed value in the getter, but if a node doesn't have an input but is still connected to the destination, the AudioParam automations aren't run. They should be, and the values can be inspected with the .value getter.