Search code examples
web-audio-api

How can I mix multiple stereo signals to one with WebAudio?


I'm writing a web app which needs to combine a number of stereo sounds into one stereo output, so I want an equivalent of gstreamer's audiomixer element, but there doesn't seem to be one in WebAudio. ChannelMerger doesn't do quite the same thing - it combines multiple mono signals into one multi-channel signal.

The documentation for AudioNode.connect says that you can connect an output to multiple inputs of other nodes and that attempts to connect the same output to the same input more than once are ignored. But it doesn't say what will happen if you try to connect multiple different outputs to the same input. Would that act as a simple mixer like I want? I suspect not, because what splitting/merging functionality WebAudio does provide (see ChannelMerger above) seems to mostly be based on converting between multiple mono signals and one multi-channel signal with a one channel to one mono signal mapping.

I could take an arbitrary node (I guess a GainNode would work, and I could take advantage of its gain functionality) and set its channelInterpretation mode to "speakers" to actually mix channels, but it only works for 1, 2, 4 or 6 inputs. I'm unlikely to need more than 6, but I will definitely need to be able to handle 3, and possibly 5. That could be done by using more than one mixer (eg for three channels mix inputs 1 and 2 in one mixer, then mix its output with input 3 in a second mixer), but I think I would have to add more GainNodes to balance the mix correctly. A mixer presumably has to attenuate each input to prevent coincident peaks from clipping out of range, so with chained mixers without compensation I'd end up with 1/4,1/4,1/2 instead of 1/3,1/3,1/3?


Solution

  • You almost got it right. Use a single GainNode and connect each source to the single input to the GainNode. This will sum up all of the different connections and produce a single output. If you know all of the individual sources are stereo, you don't need to change anything about the channelInterpretation, channelCountMode, or channelCount to get what you want.

    You will probably have to adjust the gain value of the GainNode to reduce the output volume so that you don't overdrive the output device.

    Other than, this should all work.