Search code examples
javascriptaudio-streamingweb-audio-apivolume

Web Audio API - Automatic Gain Control?


Is there a way to create automatic gain control with the web-audio api? In my case, I'm building a web-based video chat app that takes multiple audio streams (people talking) and plays them. Is there a way to adjust their relative volume-levels such that everyone has roughly the same loudness? I don't want one person to sound very quiet while another person sounds very loud.

GainNodes appear to be very manually; they expect you to figure out what the .gain.value should be. I suppose I could run every audio track through an analyserNode, compute a volume level, and then manually adjust each person's individual gain-node based on that, but I'm wondering if there's an easier way to do automatic gain control? Thanks.


Solution

  • If you're making a web-based chat app, automatic gain control is actually easily handled when you capture microphone audio in the first place:

    const stream = await navigator.mediaDevices.getUserMedia({
      audio: {
        autoGainControl: true
      },
      video: true
    });
    

    (Note that autoGainControl is actually on by default. You don't need to manually enable it.)

    However, if you still want to reduce the dynamics range on playback, what you're looking for is a DynamicsCompressorNode. This will squash variances between the loud and quiet parts. After that node, you can add a fixed GainNode to make up for the losses in the compressor.

    The specific compression settings you use are a matter of taste, and there is a great deal of debate on this. You might start with a 2ms attack time, 10ms release time, 3:1 ratio, -20 dB threshold, and perhaps 6 dB of makeup gain, and tweak from there.