Deterministic randomness for modulation: a counter-free PRNG, a Gaussian draw, a stateless purpose-keyed hash, and the Ornstein-Uhlenbeck walk that every "analog drift" effect in the catalog is built from. More...
#include <algorithm>#include <cmath>#include <cstdint>Go to the source code of this file.
Classes | |
| class | pulp::signal::Xorshift32 |
| Xorshift32 (Marsaglia, "Xorshift RNGs", J. More... | |
| class | pulp::signal::OuWalkT< SampleType > |
| Ornstein-Uhlenbeck walk (Uhlenbeck & Ornstein, Phys. More... | |
| class | pulp::signal::DriftT< SampleType > |
| Two decorrelated OU walks presented as the two things drift is actually wired to: a pitch ratio and a unit fraction. More... | |
Namespaces | |
| namespace | pulp |
| namespace | pulp::signal |
Typedefs | |
| using | pulp::signal::OuWalk = OuWalkT<float> |
| using | pulp::signal::OuWalk64 = OuWalkT<double> |
| using | pulp::signal::Drift = DriftT<float> |
| using | pulp::signal::Drift64 = DriftT<double> |
Functions | |
| constexpr std::uint64_t | pulp::signal::mix64 (std::uint64_t z) |
| splitmix64 finalizer (Steele, Lea & Flood, OOPSLA 2014). | |
| constexpr std::uint64_t | pulp::signal::mix64 (std::uint64_t seed, std::uint64_t index, std::uint64_t field=0u) |
| Purpose-keyed overload used when seed, index, and field are already separate values. | |
| float | pulp::signal::unit_from (std::uint64_t key) |
| Stateless purpose-keyed draw in [0, 1). | |
| template<typename T> | |
| T | pulp::signal::unit_from (std::uint64_t key) |
| template<typename T = float> | |
| T | pulp::signal::bipolar_from (std::uint64_t key) |
| constexpr std::uint64_t | pulp::signal::rng_key (std::uint64_t purpose, std::uint64_t index) |
| Combine a purpose tag and an index into a key for unit_from(). | |
Variables | |
| constexpr std::uint64_t | pulp::signal::kGoldenGamma = 0x9E3779B97F4A7C15ull |
| The 64-bit golden-ratio odd constant that splitmix64 steps its state by. | |
Deterministic randomness for modulation: a counter-free PRNG, a Gaussian draw, a stateless purpose-keyed hash, and the Ornstein-Uhlenbeck walk that every "analog drift" effect in the catalog is built from.
RT contract: every type here is POD scalar state with no owned memory. prepare() recomputes coefficients from a sample rate and is a control-side call; seed(), reset(), next*(), and the accessors allocate nothing and are audio-thread safe.
USE: modulation that must sound alive but replay identically. Randomness in a plugin is only usable when it is reproducible — an A/B comparison, a golden-file test, and an offline bounce all have to agree with the live render. Every generator here is seeded explicitly at reset() and never reads a clock, a device id, or std::random_device. Two instances with the same seed produce bit-identical streams forever.