Search guides and the APICtrl K
  1. API reference
  2. DSP

random.h

Randomness, and the noise a DSP makes out of it.

#include <sonore/random.h>
On this page

Design notes

Why not <random>

std::mt19937 is 2.5 kilobytes of state and its constructor loops 624 times. std::uniform_real_distribution is not specified to give the same numbers on two implementations, so a plugin's dither would differ between a Windows build and a Linux one and the two would not null against each other. And nothing in <random> promises to be free of allocation or locks, which is the one property this needs.

So: xoshiro128+, which is sixteen bytes of state, a dozen instructions, and the same sequence everywhere.

The real-time rule

Every call here runs on the audio thread. No allocation, no locks, no division, no branches on the value. A noise generator that allocated would be a dropout every time somebody turned it up.

Types 5

xoshiro128+, seeded by splitmix64.

Deterministic from its seed, which matters more than it sounds: a plugin whose noise differed between runs cannot be tested by rendering twice and comparing, and cannot be nulled against a reference render at all.

White noise: equal energy per hertz, which sounds bright.

A class rather than a call on Random because a plugin wants one per voice with its own seed, so two voices do not produce identical noise and cancel when summed to mono.

Pink noise: equal energy per OCTAVE, which is what people mean when they say noise sounds natural, and what every acoustic measurement is done with.

Voss-McCartney with sixteen rows: every octave from 20 Hz to 20 kHz within 0.6 dB of the others at 48 kHz (measured; the test allows 1 dB), and pink down to fs/2^17 -- 1.5 Hz even at 192 kHz -- so the level in a low band does not depend on the session's rate. Seven rows, which is what this had, are pink only above fs/128: at 48 kHz everything under 375 Hz was white, the 20-40 Hz octave 8 dB down. A true -3 dB per octave filter is an infinite-order problem; this is still one new random value per sample.

Bounded to +-1 (seventeen sources, each +-1, over seventeen); about 0.14 RMS, -17 dBFS.

TPDF dither: what you add before reducing bit depth.

Triangular rather than rectangular, and that is the entire point. Rectangular dither removes the correlation between the signal and the quantisation error but leaves the NOISE FLOOR modulated by the signal -- audible as a hiss that breathes with the music. Triangular removes both, at the cost of 3 dB more noise, and is what every mastering engineer means by "dither".

Velvet noise: sparse random impulses, one per grid cell, each +1 or -1.

It sounds like white noise and costs almost nothing to convolve with, because it is nearly all zeros -- which is why it is the diffusion element of choice in modern reverbs (Välimäki et al.): a 2000-pulse-per-second velvet convolution is a few thousand adds per second of tail, where a dense noise convolution is millions of multiplies. The grid keeps the pulses evenly spread; the random offset within each cell is what stops the grid's own period from being heard.

Constants 1

↑↓ to move↵ to openEvery public name in the headers, and every guide