Skip to main content
Version: Next

Noise generation

Noise is one of the most basic and common tools in digital audio processing, in this guide, we will go through most common noise types and how to implement them using the Web Audio API.

White noise

The most used type of noise. White is a random signal having equal intensity at different frequencies, giving it a constant power spectral density. (Wikipedia).

To produce white noise, we simply create an AudioBuffer containing random samples in range of [-1; 1] (in which the Web Audio API operates), which can be used by AudioBufferSourceNode for playback, further filtering or modification. We write samples directly into the buffer using getChannelData, which returns a modifiable Float32Array view of a given channel's PCM data.

import { AudioContext } from 'react-native-audio-api';

const createWhiteNoise = () => {
const audioContext = new AudioContext();
const bufferSize = 2 * audioContext.sampleRate;

const noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
const channelData = noiseBuffer.getChannelData(0);

for (let i = 0; i < bufferSize; i += 1) {
channelData[i] = Math.random() * 2 - 1;
}

return noiseBuffer;
};

Usually we want the noise to be able to be played constantly. To achieve this we are generating 2 seconds of the noise sound, which we will later play with an AudioBufferSourceNode by assigning the generated data to its buffer property and enabling continuous playback with loop. See the AudioBufferSourceNode documentation for other playback options. In audio processing sampleRate means number of samples that will be played during one second, thus we simply multiply this value by 2 to achieve desired length of the buffer.

Loading...

Pink noise

Pink noise, also known as 1f\frac{1}{f} noise (where ff stands for frequency), is a type of signal or sound that has equal energy per octave. This means that the power spectral density (PSD) decreases inversely with frequency. In simpler terms, pink noise has more energy at lower frequencies and less energy at higher frequencies, which makes it sound softer and more balanced to the human ear than white noise.

To generate pink noise, we will use the effects of a 3dBoctave\frac{-3dB}{octave} filter using the Paul Kellet's refined method

import { AudioContext } from 'react-native-audio-api';

const createPinkNoise = () => {
const audioContext = new AudioContext();

const bufferSize = 2 * audioContext.sampleRate;
const noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
const channelData = noiseBuffer.getChannelData(0);

let b0, b1, b2, b3, b4, b5, b6;
b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;

for (let i = 0; i < bufferSize; i += 1) {
const white = Math.random() * 2 - 1;

b0 = 0.99886 * b0 + white * 0.0555179;
b1 = 0.99332 * b1 + white * 0.0750759;
b2 = 0.969 * b2 + white * 0.153852;
b3 = 0.8665 * b3 + white * 0.3104856;
b4 = 0.55 * b4 + white * 0.5329522;
b5 = -0.7616 * b5 - white * 0.016898;

channelData[i] = 0.11 * (b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362);
b6 = white * 0.115926;
}

return noiseBuffer;
};

You can find more information about pink noise generation here.

Loading...

Brownian noise

The last noise type we would like to describe is brownian noise (also known as Brown or red noise). Brownian noise is named after the Brownian motion phenomenon, where particles inside a fluid move randomly due to collisions with other particles. It relates to its sonic counterpart in that Brownian noise is characterized by a significant presence of low frequencies, with energy decreasing as the frequency increases. Brownian noise is believed to sound like waterfall.

Brownian noise, similarly to pink one, decreases in power by 12dBoctave\frac{12dB}{octave} and sounds similar to waterfall. The implementation is taken from an article by Zach Denton:

import { AudioContext } from 'react-native-audio-api';

const createBrownianNoise = () => {
const audioContext = new AudioContext();

const bufferSize = 2 * audioContext.sampleRate;
const noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
const channelData = noiseBuffer.getChannelData(0);
let lastOut = 0.0;

for (let i = 0; i < bufferSize; i += 1) {
const white = Math.random() * 2 - 1;
channelData[i] = (lastOut + 0.02 * white) / 1.02;
lastOut = channelData[i];
channelData[i] *= 3.5;
}

return noiseBuffer;
};
Loading...

What's next?

In the next section, we will explore how to capture audio data, visualize this data effectively, and utilize it to create basic animations.