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

noise — response plots

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 expression
  • i: 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 trigger
  • sx: 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 parallel
  • i: 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 — response plots

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,:)));
...

pink_noise_demo figure

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


(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 smoothing lfnoiseN, a constant numerical expression
  • rate: 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

colored_noise — response plots

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


(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


(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.SR in 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


(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)/2
  • values: list of N values (N known at compile time)
  • weights: list of N non-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 of N*N transition weights (N known at compile time), row by row: the N weights from state 0 to states 0 to N-1, then from state 1, and so on. Each row is non-negative and not all 0; it need not sum to 1
  • u: uniform random signal in [0, 1), for example (no.noise + 1)/2 (see no.sample_pmf)
  • state: current state (int, 0 to N-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); };