noises.lib
Noises library. Its official prefix is no.
This library provides various noise generators and stochastic signal sources for audio synthesis and testing. It includes white, pink, brown, and blue noise, as well as pseudo-random number generators and utilities for decorrelated signals and random modulation in Faust DSP programs.
The Noises library is organized into 1 section:
References
Functions Reference
(no.)noise
White noise generator (outputs random number between -1 and 1).
noise is a standard Faust function.
Usage
noise : _
Where:
- output: white noise signal in [-1, 1].
Test
no = library("noises.lib");
noise_test = no.noise;
(no.)multirandom
Generates multiple decorrelated random numbers in parallel.
Usage
multirandom(N) : si.bus(N)
Where:
N: the number of decorrelated random numbers in parallel, a constant numerical expression
Test
no = library("noises.lib");
multirandom_test = no.multirandom(3);
(no.)multinoise
Generates multiple decorrelated noises in parallel.
Usage
multinoise(N) : si.bus(N)
Where:
N: the number of decorrelated random numbers in parallel, a constant numerical expression
Test
no = library("noises.lib");
multinoise_test = no.multinoise(3);
(no.)noises
A convenient wrapper around multinoise.
Usage
noises(N,i) : _
Where:
N: the number of decorrelated random numbers in parallel, a constant numerical expressioni: the selected random number (i in [0..N[)
Test
no = library("noises.lib");
noises_test = no.noises(4, 2);
(no.)dnoise
A deterministic noise burst with a dynamically adjustable seed, enabling consistent recall. Useful for noise variation sensitive applications like replicable/recallable percussion sounds and waveguide excitation.
Usage
dnoise(t,sx) : _
Where:
t: is a noise burst triggersx: defines the range of integer seed multipliers.
Test
no = library("noises.lib");
ba = library("basics.lib");
dnoise_test = (trigger, seedRange) : no.dnoise
with {
trigger = 1 : ba.impulsify;
seedRange = 10.0;
};
Example
This expression sx = hslider("seed multiplier",1,1,1000,1) allows 1000 distinct seed variations.
To generate a burst with a fixed length, use ba.spulse(bLength, t) (as trigger for the t parameter), where bLength is the burst duration in samples and t is a trigger.
(no.)randomseed
A random seed based on the foreign function arc4random
(see man arc4random). Used in rnoise, rmultirandom, etc. to
avoid having the same pseudo random sequence at each run.
WARNING: built on the foreign function arc4random, so it compiles only for the backends that
generate C, C++, Rust or LLVM code, not for WebAssembly, the interpreter, Cmajor, Codebox, Julia, C# or Java.
Usage
randomseed : _
Where:
- output: platform-specific random seed value.
Test
no = library("noises.lib");
randomseed_test = no.randomseed;
(no.)rnoise
A randomized white noise generator (outputs random number between -1 and 1).
WARNING: built on the foreign function arc4random, so it compiles only for the backends that
generate C, C++, Rust or LLVM code, not for WebAssembly, the interpreter, Cmajor, Codebox, Julia, C# or Java.
Usage
rnoise : _
Test
no = library("noises.lib");
rnoise_test = no.rnoise;
(no.)rmultirandom
Generates multiple decorrelated random numbers in parallel.
WARNING: built on the foreign function arc4random, so it compiles only for the backends that
generate C, C++, Rust or LLVM code, not for WebAssembly, the interpreter, Cmajor, Codebox, Julia, C# or Java.
Usage
rmultirandom(N) : si.bus(N)
Where:
N: the number of decorrelated random numbers in parallel, a constant numerical expression
Test
no = library("noises.lib");
rmultirandom_test = no.rmultirandom(3);
(no.)rmultinoise
Generates multiple decorrelated noises in parallel.
WARNING: built on the foreign function arc4random, so it compiles only for the backends that
generate C, C++, Rust or LLVM code, not for WebAssembly, the interpreter, Cmajor, Codebox, Julia, C# or Java.
Usage
rmultinoise(N) : si.bus(N)
Where:
N: the number of decorrelated random numbers in parallel, a constant numerical expression
Test
no = library("noises.lib");
rmultinoise_test = no.rmultinoise(3);
(no.)rnoises
A convenient wrapper around rmultinoise.
WARNING: built on the foreign function arc4random, so it compiles only for the backends that
generate C, C++, Rust or LLVM code, not for WebAssembly, the interpreter, Cmajor, Codebox, Julia, C# or Java.
Usage
rnoises(N,i) : _
Where:
N: the number of decorrelated random numbers in paralleli: the selected random number (i in [0..N[)
Test
no = library("noises.lib");
rnoises_test = no.rnoises(4, 1);
(no.)pink_noise, (no.)pink_noise_m
Pink noise (1/f noise) generator (third-order approximation covering the audio band well).
pink_noise is a standard Faust function. pink_noise_m is the same
generator with its loudness equalized to that of no.noise (beware of
clipping).
Usage
pink_noise : _
pink_noise_m : _
Where:
- output: pink (1/f) noise signal.
Test
no = library("noises.lib");
pink_noise_test = no.pink_noise;
pink_noise_m_test = no.pink_noise_m;
Alternatives
Higher-order approximations covering any frequency band can be obtained using
no.noise : fi.spectral_tilt(order,lowerBandLimit,Bandwidth,p)
where p=-0.5 means filter rolloff f^(-1/2) which gives 1/f rolloff in the
power spectral density, and can be changed to other real values.
Example
pink_noise_compare.dsp - compare three pinking filters
process = pink_noises with {
f0 = 35; // Lower bandlimit in Hz
bw3 = 0.7 * ma.SR/2.0 - f0; // Bandwidth in Hz, 3rd order case
bw9 = 0.8 * ma.SR/2.0 - f0; // Bandwidth in Hz, 9th order case
pink_tilt_3 = fi.spectral_tilt(3,f0,bw3,-0.5);
pink_tilt_9 = fi.spectral_tilt(9,f0,bw9,-0.5);
pink_noises = 1-1' <:
no.pink_filter, // original designed by invfreqz in Octave
pink_tilt_3, // newer method using the same filter order
pink_tilt_9; // newer method using a higher filter order
};
Output of Example
faust2octave pink_noise_compare.dsp
Octave:1> semilogx(20*log10(abs(fft(faustout,8192))(1:4096,:)));
...

References
(no.)pink_filter
The pinking filter used by pink_noise: a third-order IIR
approximating a -3 dB/octave spectral rolloff, designed with
invfreqz in Octave (see the pink_noise example, which compares it
against fi.spectral_tilt alternatives).
Usage
_ : pink_filter : _
Test
no = library("noises.lib");
pink_filter_test = no.noise : no.pink_filter;
(no.)pink_noise_vm
Multi pink noise generator.
Usage
pink_noise_vm(N) : _
Where:
N: number of latched white-noise processes to sum, not to exceed sizeof(int) in C++ (typically 32).
Test
no = library("noises.lib");
pink_noise_vm_test = no.pink_noise_vm(4);
References
- http://www.dsprelated.com/showarticle/908.php
- http://www.firstpr.com.au/dsp/pink-noise/#Voss-McCartney
(no.)lfnoise, (no.)lfnoise0, (no.)lfnoiseN
Low-frequency noise generators (Butterworth-filtered downsampled white noise).
Usage
lfnoise0(rate) : _ // new random number every int(ma.SR/rate) samples or so
lfnoiseN(N,rate) : _ // same as "lfnoise0(rate) : fi.lowpass(N,rate)" [see filters.lib]
lfnoise(rate) : _ // same as "lfnoise0(rate) : seq(i,5,fi.lowpass(1,rate))" (no overshoot)
Where:
N: order of the Butterworth lowpass smoothinglfnoiseN, a constant numerical expressionrate: rate of the new random values (Hz), also the cutoff frequency of the smoothing lowpass
Example
(view waveforms in faust2octave):
rate = ma.SR/100.0; // new random value every 100 samples (ma.SR from maths.lib)
process = lfnoise0(rate), // sampled/held noise (piecewise constant)
lfnoiseN(3,rate), // lfnoise0 smoothed by 3rd order Butterworth LPF
lfnoise(rate); // lfnoise0 smoothed with no overshoot
Test
no = library("noises.lib");
lfnoise0_test = no.lfnoise0(10.1);
lfnoiseN_test = no.lfnoiseN(3, 10.1);
lfnoise_test = no.lfnoise(10.1);
(no.)sparse_noise
Sparse noise generator.
Usage
sparse_noise(f0) : _
Where:
f0: average frequency of noise impulses per second
Random impulses in the amplitude range -1 to 1 are generated at an average rate of f0 impulses per second.
Test
no = library("noises.lib");
sparse_noise_test = no.sparse_noise(5.0);
References
- See velvet_noise
(no.)velvet_noise
Velvet noise generator.
Usage
velvet_noise(amp, f0) : _
Where:
amp: amplitude of noise impulses (positive and negative)f0: average frequency of noise impulses per second
Test
no = library("noises.lib");
velvet_noise_test = no.velvet_noise(0.5, 5.0);
References
- Matti Karjalainen and Hanna Jarvelainen, "Reverberation Modeling Using Velvet Noise", in Proc. 30th Int. Conf. Intelligent Audio Environments (AES07), March 2007.
(no.)gnoise, (no.)gnoisem
Approximate zero-mean, unit-variance Gaussian white noise generator.
gnoisem is the same generator with its loudness equalized to that of
no.noise.
Usage
gnoise(N) : _
gnoisem(N) : _
Where:
N: number of uniform random numbers added to approximate Gaussian white noise
Test
no = library("noises.lib");
gnoise_test = no.gnoise(8);
gnoisem_test = no.gnoisem(8);
References
- See Central Limit Theorem
(no.)colored_noise
Generates a colored noise signal with an arbitrary spectral roll-off factor (alpha) over the entire audible frequency range (20-20000 Hz). The output is normalized so that an equal RMS level is maintained for different values of alpha.
Usage
colored_noise(N,alpha) : _
Where:
N: desired integer filter order (constant numerical expression)alpha: slope of roll-off, between -1 and 1. -1 corresponds to brown/red noise, -1/2 pink noise, 0 white noise, 1/2 blue noise, and 1 violet/azure noise.
Test
no = library("noises.lib");
ba = library("basics.lib");
ma = library("maths.lib");
colored_noise_test = no.colored_noise(4, 0.0);
colored_noise_slider_test = no.colored_noise(4, hslider("colored_noise:alpha", 0.0, -1, 1, 0.01));
colored_noise_modulated_test = no.colored_noise(4, 2*tri - 1) with { P = int(ma.SR/10); tri = 1 - abs(2*ba.period(P)/P - 1); };
colored_noise_jump_test = no.colored_noise(4, 2*sq - 1) with { P = int(ma.SR/10); sq = ba.period(2*P) < P; };
Examples
See dm.colored_noise_demo.
(no.)simplex2
Simplex gradient noise (Ken Perlin, 2001), in the 2-D formulation of Stefan
Gustavson ("Simplex noise demystified", 2005) as implemented in Joseph Gentle's
noisejs, which is what Neil Thapen's Pink Trombone uses for its slow random
drift. Unlike filtered white noise, simplex noise is a smooth (C²) deterministic
function of its argument, bounded to [-1,1], zero at the lattice points, with
most of its energy below roughly 2 cycles per unit of the argument.
The seeding scheme (Perlin's permutation table XOR-ed with the seed) and the gradient
set follow Joseph Gentle's noisejs (ISC license, (c) 2013 Joseph Gentle; its
notice is reproduced in the source below simplex2). Gustavson's original code is
public domain.
Usage
simplex2(seed, x, y) : _
Where:
seed: Constant integer in 0..65535; values below 256 are mirrored into the high byte.x: First coordinate signal, in lattice units.y: Second coordinate signal, in lattice units.
Test
import("stdfaust.lib");
simplex2_test = no.simplex2(12345, os.lf_sawpos(1)*10, 0.5);
References
- Stefan Gustavson, "Simplex noise demystified" (2005).
- Joseph Gentle, noisejs: https://github.com/josephg/noisejs.
(no.)simplex1
One-dimensional slice of simplex2 at (1.2x, -0.7x), as used by Pink Trombone.
The seeding scheme (Perlin's permutation table XOR-ed with the seed) and the gradient
set follow Joseph Gentle's noisejs (ISC license, (c) 2013 Joseph Gentle; its
notice is reproduced in the source below simplex2). Gustavson's original code is
public domain.
Usage
simplex1(seed, x) : _
Where:
seed: Constant integer in 0..65535; values below 256 are mirrored into the high byte.x: Coordinate signal, in lattice units.
Test
import("stdfaust.lib");
simplex1_test = no.simplex1(12345, os.lf_sawpos(1)*10);
References
- Stefan Gustavson, "Simplex noise demystified" (2005).
- Joseph Gentle, noisejs: https://github.com/josephg/noisejs.
(no.)simplex1_lf
Smooth seeded simplex modulation: simplex1(seed, x) where the coordinate x
advances by rate/ma.SR per sample (so x = rate*t for a constant rate, to
within a few ppm of the rate). The coordinate is kept in exact fixed point as
a simplex lattice cell (modulo the 256-cell period of the permutation table)
plus an offset inside it, so the output stays as smooth after hours as at
start-up (no float32 precision loss, no sample-counter overflow), is the same
in single and double precision, and a time-varying rate integrates without
phase jumps.
The seeding scheme (Perlin's permutation table XOR-ed with the seed) and the gradient
set follow Joseph Gentle's noisejs (ISC license, (c) 2013 Joseph Gentle; its
notice is reproduced in the source below simplex2). Gustavson's original code is
public domain.
Usage
simplex1_lf(seed, rate) : _
Where:
seed: Constant integer in 0..65535; values below 256 are mirrored into the high byte.rate: Features per second, below about 0.7*ma.SRin magnitude (may vary; negative runs backwards); one coordinate unit is traversed in 1/rate seconds.
Test
no = library("noises.lib");
ba = library("basics.lib");
ma = library("maths.lib");
import("stdfaust.lib");
simplex1_lf_test = no.simplex1_lf(12345, 4.07);
simplex1_lf_slider_test = no.simplex1_lf(12345, hslider("simplex1_lf:rate", 4.07, -100, 100, 0.01));
simplex1_lf_modulated_test = no.simplex1_lf(12345, 20*(2*tri - 1)) with { P = int(ma.SR/10); tri = 1 - abs(2*ba.period(P)/P - 1); };
References
- Stefan Gustavson, "Simplex noise demystified" (2005).
- Joseph Gentle, noisejs: https://github.com/josephg/noisejs.
(no.)sample_pmf
Draw one of N values at random, each with probability proportional to its
weight (sampling a probability mass function). The draw is made at every
sample from the uniform random signal u, and all the inputs may vary over
time.
Usage
sample_pmf(u, values, weights) : _
Where:
u: uniform random signal in [0, 1), for example(no.noise + 1)/2. Draws that must be independent need decorrelated sources, e.g.(no.noises(K, k) + 1)/2values: list ofNvalues (Nknown at compile time)weights: list ofNnon-negative weights, not all 0; they need not sum to 1
Test
ba = library("basics.lib");
ma = library("maths.lib");
no = library("noises.lib");
sample_pmf_test = no.sample_pmf((no.noise + 1)/2, (1, 2, 3), (0.5, 0.2, 0.3));
sample_pmf_slider_test = no.sample_pmf((no.noise + 1)/2, (1, 2, 3), (hslider("sample_pmf:w0", 0.5, 0, 1, 0.01), hslider("sample_pmf:w1", 0.2, 0, 1, 0.01), hslider("sample_pmf:w2", 0.3, 0, 1, 0.01)));
sample_pmf_modulated_test = no.sample_pmf((no.noise + 1)/2, (1, 2, 3), (tri, 0.2, 1 - tri)) with { P = int(ma.SR/10); tri = 1 - abs(2*ba.period(P)/P - 1); };
(no.)markov_step, (no.)markov_chain
A discrete-time Markov chain over the states 0 to N-1. markov_step
draws the next state from the current one, and markov_chain runs the chain,
moving at every sample where trig is nonzero (use a one-sample trigger such
as ba.pulse or os.lf_imptrain) and holding the state in between; it starts
in state 0. Build other rules (accepting or rejecting a draw, resetting) with
markov_step inside your own recursion. The transition weights may vary over
time, for example to change the chain at each step of a sequence, and
si.softmax turns scores into weights with a temperature control.
Usage
markov_step(P, u, state) : _
markov_chain(P, u, trig) : _
Where:
P: list ofN*Ntransition weights (Nknown at compile time), row by row: theNweights from state 0 to states 0 toN-1, then from state 1, and so on. Each row is non-negative and not all 0; it need not sum to 1u: uniform random signal in [0, 1), for example(no.noise + 1)/2(seeno.sample_pmf)state: current state (int, 0 toN-1)trig: transition trigger (a nonzero sample moves the chain one step)
Test
ba = library("basics.lib");
ma = library("maths.lib");
no = library("noises.lib");
markov_step_test = no.markov_step((0.1, 0.9, 0.9, 0.1), (no.noise + 1)/2, 1);
markov_chain_test = no.markov_chain(P, (no.noise + 1)/2, ba.pulse(int(ma.SR/1000)))
with {
P = (0, 1, 0,
0, 0.5, 0.5,
0.8, 0, 0.2);
};
markov_step_slider_test = no.markov_step((hslider("markov_step:p00", 0.1, 0, 1, 0.01), hslider("markov_step:p01", 0.9, 0, 1, 0.01), hslider("markov_step:p10", 0.9, 0, 1, 0.01), hslider("markov_step:p11", 0.1, 0, 1, 0.01)), (no.noise + 1)/2, int(hslider("markov_step:state", 1, 0, 1, 1)));
markov_step_modulated_test = no.markov_step((tri, 1 - tri, 1 - tri, tri), (no.noise + 1)/2, ba.period(2)) with { P = int(ma.SR/10); tri = 1 - abs(2*ba.period(P)/P - 1); };
markov_chain_slider_test = no.markov_chain((0, 1, 0, 0, a, 1 - a, 0.8, 0, 0.2), (no.noise + 1)/2, ba.pulse(int(ma.SR/1000))) with { a = hslider("markov_chain:a", 0.5, 0, 1, 0.01); };
markov_chain_modulated_test = no.markov_chain((0, 1, 0, 0, tri, 1 - tri, 0.8, 0, 0.2), (no.noise + 1)/2, ba.pulse(int(ma.SR/1000))) with { P = int(ma.SR/10); tri = 1 - abs(2*ba.period(P)/P - 1); };