I'd like to create hierarchical "channels" where the parents gain will limit the child's gain.
So for example, I'd like sounds played on the child to have 0.1 volume.
var child = context.createGain();
var parent = context.createGain();
parent.gain.value = 0.1;
child.gain.value = 1.0;
child.connect(parent);
                Yes, audio gain is chained hierarchically as described.
It multiplies the input audio signal by the (possibly time-varying) gain attribute, copying the result to the output. By default, it will take the input and pass it through to the output unchanged, which represents a constant gain change of 1.
As with other AudioParams, the gain parameter represents a mapping from time (in the coordinate system of AudioContext.currentTime) to floating-point value. Every PCM audio sample in the input is multiplied by the gain parameter's value for the specific time corresponding to that audio sample. This multiplied value represents the PCM audio sample for the output.
from http://www.w3.org/TR/webaudio/#GainNode
Here is a complete example.
<html>
<body>
<script type="text/javascript">
var AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var parentGain = context.createGain();
var childGain = context.createGain();
parentGain.gain.value = 0.1;
childGain.gain.value = 1.0;
childGain.connect(parentGain);
parentGain.connect(context.destination);
var bufferSize = 4096;
var pinkNoise = (function() {
    var b0, b1, b2, b3, b4, b5, b6;
    b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
    var node = context.createScriptProcessor(bufferSize, 1, 1);
    node.onaudioprocess = function(e) {
        var output = e.outputBuffer.getChannelData(0);
        for (var i = 0; i < bufferSize; i++) {
            var white = Math.random() * 2 - 1;
            b0 = 0.99886 * b0 + white * 0.0555179;
            b1 = 0.99332 * b1 + white * 0.0750759;
            b2 = 0.96900 * b2 + white * 0.1538520;
            b3 = 0.86650 * b3 + white * 0.3104856;
            b4 = 0.55000 * b4 + white * 0.5329522;
            b5 = -0.7616 * b5 - white * 0.0168980;
            output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
            output[i] *= 0.11; // (roughly) compensate for gain
            b6 = white * 0.115926;
        }
    }
    return node;
})();
pinkNoise.connect(childGain);
</script>
</body>
</html>
                        Yes, you can chain gain nodes serially, as you describe. Note that this isn't a "limiting" effect in your example - it's multiplicative. (If parent.gain.value were 2, the end result would be a .2x gain.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With