In audio, to mix two audio stream (here, buffers) into one, you can simply add each sample value together. Practically, here is we can do this, building on your snippet:
/* `buffers` is a javascript array containing all the buffers you want
* to mix. */
function mix(buffers) {
/* Get the maximum length and maximum number of channels accros all buffers, so we can
* allocate an AudioBuffer of the right size. */
var maxChannels = 0;
var maxDuration = 0;
for (var i = 0; i < buffers.length; i++) {
if (buffers[i].numberOfChannels > maxChannels) {
maxChannels = buffers[i].numberOfChannels;
}
if (buffers[i].duration > maxDuration) {
maxDuration = buffers[i].duration;
}
}
var out = context.createBuffer(maxChannels,
context.sampleRate * maxDuration,
context.sampleRate);
for (var j = 0; j < buffers.length; j++) {
for (var srcChannel = 0; srcChannel < buffers[j].numberOfChannels; srcChannel++) {
/* get the channel we will mix into */
var out = mixed.getChanneData(srcChannel);
/* Get the channel we want to mix in */
var in = buffers[i].getChanneData(srcChannel);
for (var i = 0; i < in.length; i++) {
out[i] += in[i];
}
}
}
return out;
}
Then, simply affect the return from this function to a new AudioBufferSourceNode.buffer
, and play it like usual.
A couple notes: my snippet assumes, for simplicity, that:
- If you have a mono buffer and a stereo buffer, you will only hear the mono buffer in the left channel of the mixed buffer. If you want it copied to the left and right, you will have to do we is called up-mixing ;
- If you want a buffer to be quieter or louder than another buffer (like if you moved a volume fader on a mixing console), simply multiply the
toMix[i]
value by a number lesser than 1.0 to make it quiter, greater than 1.0 to make it louder.
Then again, the Web Audio API does all that for you, so I wonder why you need to do it yourself, but at least now you know how :-).