This works, but depending on the application, it might be inefficient. With a buffer size of 4096, the onaudioprocess callback is being executed around 10 times per second. Not a problem if you’re building an ambient sound generator that only uses a single instance of white noise, but if you’re building, say, a polyphonic synthesizer with noise-modulated filters, this computational overhead will introduce latency.

A more efficient approach is to generate a buffer of white noise and then loop through it:

This code generates two seconds of white noise and then loops through it continuously. The primary disadvantage of this approach is that the same chunk of noise is being reused, over and over. Depending on how large the noise buffer is, this means you might be able to hear the noise repeating. In practice, I’ve found that this is only noticeable when the noise buffer is less than two seconds long.

Pink Noise

The next type of noise we’ll be generating is pink noise. Whereas white noise has equal power across the frequency spectrum, pink noise sounds like it has equal power across the frequency spectrum. Our ears process frequencies logarithmically, and pink noise takes this into account. In terms of ambient noise, I find that pink noise sounds much nicer than white noise, which is too harsh in the upper frequencies.

So the code to generate pink noise is quite a bit more complex than the code to generate white noise. The pinkNoise node is wrapped within a closure because we want the values of b0 through b6 (the filter state) to persist between calls to onaudioprocess. The 0.11 scaling factor is taken from the Csound source code.

Brownian Noise

Let’s move on to Brownian noise (also known as brown noise or red noise). Brownian noise decreases in power by 12dB/octave, and sounds like a waterfall. Here’s how to generate Brownian noise with the Web Audio API: