Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::nonlin_ambience Namespace Reference

The calibration register: every number this module ships that is not cited to the literature lives here with a default and a range, so a reviewer finds them in one place rather than spread through the code. More...

Classes

struct  VelvetTapDesign
 Pure intermediate for one candidate in a velvet tap grid. More...

Functions

constexpr double allpass_l1_gain (double g)
 The time-domain L1 (peak) gain of one Schroeder allpass with coefficient g: Σ|h| = g + (1−g²)/(1−g) = 1 + 2g.
double worst_case_gain (double diffusion=kDiffusionDefault, bool converter_on=false)
 The shipped worst-case gain as a closed form of the shipped constants: Π_i (1 + 2·g_i) · G_L1, an upper bound on Σ_n |h[n]| of the rendered impulse response by Young's convolution inequality.
double program_envelope (NonlinProgram program, double tau, double gate_hold=kGateHold, double attack=kRevRise)
 The dimensionless program envelope E(τ), τ ∈ [0, 1] (series law 7 — scale invariant, so changing length_ms rescales time without refitting anything).
double pulse_density (double u, double density_pct, double gamma)
 Instantaneous pulse density in pulses/second at normalized time u ∈ [0,1]: Nd(u) = Nd_min + (Nd_max − Nd_min)·u^γ.
VelvetTapDesign design_velvet_tap (NonlinProgram program, double position_samples, double grid_samples, int window_samples, int predelay_samples, double gate_hold, double attack, const VelvetNoiseDrawT< double > &draw) noexcept

Variables

constexpr int kNumAllpass = 2
 Number of pre-diffusion Schroeder allpasses.
constexpr double kAllpassDelaysMs [2] = {4.77, 6.13}
 Allpass delays in ms, rounded to the nearest sample and then nudged to the nearest prime sample count so the two combs never align.
constexpr double kDiffusionDefault = 0.70
 Allpass coefficient, exposed as diffusion.
constexpr double kDiffusionMax = 0.85
constexpr double kNdMin = 800.0
 Instantaneous pulse density at the start and end of the window, in pulses/second.
constexpr double kNdMax = 4000.0
constexpr double kDensityRefPct = 60.0
 The density_pct value at which Nd_min equals kNdMin exactly, so the shipped default reproduces the shipped constant rather than a scaled version of it.
constexpr double kGammaDefault = 2.0
 Density growth exponent γ.
constexpr double kAmbDropDb = 60.0
 Ambience drop across the window, in dB; sets α = A_drop·ln(10)/20.
constexpr double kFadeInFrac = 0.02
 Linear rise over the first fraction of the window, which kills the first-tap click on the programs that would otherwise start at full gain.
constexpr double kGateHold = 0.70
 Gated program: normalized hold point h and fall width w.
constexpr double kGateFall = 0.05
constexpr double kRevRise = 0.85
 Reverse program: normalized rise point r and swell exponent p (p < 1 concave, p > 1 convex).
constexpr double kRevPow = 1.0
constexpr int kNlHumps = 2
 NonLin2 program: number of raised-cosine humps, ripple depth, gate point.
constexpr double kNlDepth = 0.4
constexpr double kNlHold = 0.85
constexpr double kL1Budget = 4.0
 The per-channel L1 budget of the tap-gain vector.
constexpr int kSegments = 8
 Number of time segments the tap range is split into for spectral tilt.
constexpr double kFcBright = 16000.0
 Segment tilt corners.
constexpr double kFcDark = 6000.0
constexpr double kSwapFadeMs = 20.0
 Equal-power crossfade length applied when a topology change swaps tap banks.
constexpr double kParamSmoothMs = 20.0
 Smoothing time for the continuous gain parameters.
constexpr std::uint32_t kSeedRodd = 0x9E3779B9u
 seed_R = seed_L ⊕ kSeedRodd.
constexpr std::uint32_t kDefaultSeed = 0x51EDu
 Default seed_L.
constexpr int kTapGuard = 32
 Headroom above the expected tap count, so the jittered grid can never outgrow the pre-sized table.
constexpr double kConverterFcLo = 80.0
 Converter-character pre-filter corners (§5).
constexpr double kConverterFcHi = 15000.0
constexpr int kConverterBitsMax = 16
 Converter word length at converter_amount = 0 and the depth of the sweep: bits = kConverterBitsMax − round(kConverterBitSweep · amount).
constexpr int kConverterBitSweep = 4
constexpr double kConverterDcPole = 0.995
 DC-blocker pole used by the converter stage.
constexpr double kMinLengthMs = 20.0
 Largest window and pre-delay prepare() sizes storage for, in ms.
constexpr double kMaxLengthMs = 2000.0
constexpr double kMaxPredelayMs = 200.0
constexpr double kMinDensityPct = 10.0
 Lower bound of the density control's documented 10 .. 100 % range.
constexpr double kNormFloor = 1e-20
 Floor below which the normalization sum is treated as empty, so a program whose taps all land in a zeroed region produces silence rather than a division by a denormal.
constexpr double kDcBlockerL1Gain = 2.0
 The time-domain L1 gain of the DC blocker, which is exactly 2 for any pole p < 1: h[0] = 1, h[n] = −(1−p)p^{n−1}, so Σ|h| = 1 + (1−p)/(1−p).

Detailed Description

The calibration register: every number this module ships that is not cited to the literature lives here with a default and a range, so a reviewer finds them in one place rather than spread through the code.

Function Documentation

◆ allpass_l1_gain()

double pulp::signal::nonlin_ambience::allpass_l1_gain ( double g)
constexpr

The time-domain L1 (peak) gain of one Schroeder allpass with coefficient g: Σ|h| = g + (1−g²)/(1−g) = 1 + 2g.

Exact, not an approximation.

◆ design_velvet_tap()

VelvetTapDesign pulp::signal::nonlin_ambience::design_velvet_tap ( NonlinProgram program,
double position_samples,
double grid_samples,
int window_samples,
int predelay_samples,
double gate_hold,
double attack,
const VelvetNoiseDrawT< double > & draw )
inlinenoexcept

◆ program_envelope()

double pulp::signal::nonlin_ambience::program_envelope ( NonlinProgram program,
double tau,
double gate_hold = kGateHold,
double attack = kRevRise )
inline

The dimensionless program envelope E(τ), τ ∈ [0, 1] (series law 7 — scale invariant, so changing length_ms rescales time without refitting anything).

gate_hold is the Gated program's h; attack is the Reverse program's r and the NonLin2 program's h. Both are normalized fractions, not percents. Neither is read by Ambience.

◆ pulse_density()

double pulp::signal::nonlin_ambience::pulse_density ( double u,
double density_pct,
double gamma )
inline

Instantaneous pulse density in pulses/second at normalized time u ∈ [0,1]: Nd(u) = Nd_min + (Nd_max − Nd_min)·u^γ.

The u^γ law is the geometric- acoustics t² density growth (Moorer 1979) with γ exposed, because the gated and reverse programs deliberately break that physics.

◆ worst_case_gain()

double pulp::signal::nonlin_ambience::worst_case_gain ( double diffusion = kDiffusionDefault,
bool converter_on = false )
inline

The shipped worst-case gain as a closed form of the shipped constants: Π_i (1 + 2·g_i) · G_L1, an upper bound on Σ_n |h[n]| of the rendered impulse response by Young's convolution inequality.

converter_on adds the converter stage's DC blocker. This is the value the registry cites and the value the test suite asserts the rendered response stays under.

Variable Documentation

◆ kAllpassDelaysMs

double pulp::signal::nonlin_ambience::kAllpassDelaysMs[2] = {4.77, 6.13}
inlineconstexpr

Allpass delays in ms, rounded to the nearest sample and then nudged to the nearest prime sample count so the two combs never align.

[design parameter] default {4.77, 6.13}, range 1 .. 30 ms each.

◆ kAmbDropDb

double pulp::signal::nonlin_ambience::kAmbDropDb = 60.0
inlineconstexpr

Ambience drop across the window, in dB; sets α = A_drop·ln(10)/20.

[design parameter] default 60 dB, range 20 .. 80 dB.

◆ kConverterBitsMax

int pulp::signal::nonlin_ambience::kConverterBitsMax = 16
inlineconstexpr

Converter word length at converter_amount = 0 and the depth of the sweep: bits = kConverterBitsMax − round(kConverterBitSweep · amount).

[design parameter] defaults 16 / 4, ranges 8 .. 24 / 0 .. 8.

◆ kConverterBitSweep

int pulp::signal::nonlin_ambience::kConverterBitSweep = 4
inlineconstexpr

◆ kConverterDcPole

double pulp::signal::nonlin_ambience::kConverterDcPole = 0.995
inlineconstexpr

DC-blocker pole used by the converter stage.

[design parameter] default 0.995 (≈3.5 Hz at 44.1 kHz), range 0.9 .. 0.9999.

◆ kConverterFcHi

double pulp::signal::nonlin_ambience::kConverterFcHi = 15000.0
inlineconstexpr

◆ kConverterFcLo

double pulp::signal::nonlin_ambience::kConverterFcLo = 80.0
inlineconstexpr

Converter-character pre-filter corners (§5).

No verifiable public converter spec exists for any hardware, so these are ours. [design parameter] defaults 80 / 15000 Hz, ranges 20 .. 200 / 10k .. 20k Hz.

◆ kDcBlockerL1Gain

double pulp::signal::nonlin_ambience::kDcBlockerL1Gain = 2.0
inlineconstexpr

The time-domain L1 gain of the DC blocker, which is exactly 2 for any pole p < 1: h[0] = 1, h[n] = −(1−p)p^{n−1}, so Σ|h| = 1 + (1−p)/(1−p).

◆ kDefaultSeed

std::uint32_t pulp::signal::nonlin_ambience::kDefaultSeed = 0x51EDu
inlineconstexpr

Default seed_L.

Seeds are a preset choice, never automated (series law 2). [design parameter] default 0x51ED, range 0 .. 2³¹−1.

◆ kDensityRefPct

double pulp::signal::nonlin_ambience::kDensityRefPct = 60.0
inlineconstexpr

The density_pct value at which Nd_min equals kNdMin exactly, so the shipped default reproduces the shipped constant rather than a scaled version of it.

[design parameter] default 60 %, range 10 .. 100 %.

◆ kDiffusionDefault

double pulp::signal::nonlin_ambience::kDiffusionDefault = 0.70
inlineconstexpr

Allpass coefficient, exposed as diffusion.

|g| < 1 guarantees stability. [design parameter] default 0.70, range 0 .. 0.85.

◆ kDiffusionMax

double pulp::signal::nonlin_ambience::kDiffusionMax = 0.85
inlineconstexpr

◆ kFadeInFrac

double pulp::signal::nonlin_ambience::kFadeInFrac = 0.02
inlineconstexpr

Linear rise over the first fraction of the window, which kills the first-tap click on the programs that would otherwise start at full gain.

[design parameter] default 0.02, range 0 .. 0.1.

◆ kFcBright

double pulp::signal::nonlin_ambience::kFcBright = 16000.0
inlineconstexpr

Segment tilt corners.

kFcDark is the default of the hf_damp_hz parameter. [design parameter] defaults 16000 / 6000 Hz, ranges 4k .. 20k / 1k .. 18k.

◆ kFcDark

double pulp::signal::nonlin_ambience::kFcDark = 6000.0
inlineconstexpr

◆ kGammaDefault

double pulp::signal::nonlin_ambience::kGammaDefault = 2.0
inlineconstexpr

Density growth exponent γ.

2.0 is the physical t² reflection-density growth of geometric acoustics (Moorer 1979); 0 is flat density, which is how the gated and reverse programs deliberately break physics. [design parameter] default 2.0, range 0 .. 2.

◆ kGateFall

double pulp::signal::nonlin_ambience::kGateFall = 0.05
inlineconstexpr

◆ kGateHold

double pulp::signal::nonlin_ambience::kGateHold = 0.70
inlineconstexpr

Gated program: normalized hold point h and fall width w.

[design parameter] defaults 0.70 / 0.05, ranges 0.1 .. 0.95 / 0.01 .. 0.2.

◆ kL1Budget

double pulp::signal::nonlin_ambience::kL1Budget = 4.0
inlineconstexpr

The per-channel L1 budget of the tap-gain vector.

This sets both the loudness and the peak-gain bound: Σ_k |g_k| = G_L1 exactly, by construction. [design parameter] default 4.0, range 1.0 .. 8.0.

◆ kMaxLengthMs

double pulp::signal::nonlin_ambience::kMaxLengthMs = 2000.0
inlineconstexpr

◆ kMaxPredelayMs

double pulp::signal::nonlin_ambience::kMaxPredelayMs = 200.0
inlineconstexpr

◆ kMinDensityPct

double pulp::signal::nonlin_ambience::kMinDensityPct = 10.0
inlineconstexpr

Lower bound of the density control's documented 10 .. 100 % range.

◆ kMinLengthMs

double pulp::signal::nonlin_ambience::kMinLengthMs = 20.0
inlineconstexpr

Largest window and pre-delay prepare() sizes storage for, in ms.

These are the maxima of the corresponding parameter-table rows. [design parameter] defaults 2000 / 200 ms, ranges 100 .. 8000 / 0 .. 1000 ms.

◆ kNdMax

double pulp::signal::nonlin_ambience::kNdMax = 4000.0
inlineconstexpr

◆ kNdMin

double pulp::signal::nonlin_ambience::kNdMin = 800.0
inlineconstexpr

Instantaneous pulse density at the start and end of the window, in pulses/second.

Velvet noise is subjectively smooth by ≈2000 pulses/s and fully smooth by ≈4000 (Karjalainen & Järveläinen 2007; Välimäki et al. 2017), so the upper value is what guarantees a smooth late field. [design parameter] defaults 800 / 4000, ranges 200 .. 2000 / 2000 .. 6000.

◆ kNlDepth

double pulp::signal::nonlin_ambience::kNlDepth = 0.4
inlineconstexpr

◆ kNlHold

double pulp::signal::nonlin_ambience::kNlHold = 0.85
inlineconstexpr

◆ kNlHumps

int pulp::signal::nonlin_ambience::kNlHumps = 2
inlineconstexpr

NonLin2 program: number of raised-cosine humps, ripple depth, gate point.

[design parameter] defaults 2 / 0.4 / 0.85, ranges 1 .. 4 / 0 .. 0.8 / 0.05 .. 0.98.

◆ kNormFloor

double pulp::signal::nonlin_ambience::kNormFloor = 1e-20
inlineconstexpr

Floor below which the normalization sum is treated as empty, so a program whose taps all land in a zeroed region produces silence rather than a division by a denormal.

Guards a divide; any value far below the smallest meaningful L1 sum works. Range 1e-30 .. 1e-9.

◆ kNumAllpass

int pulp::signal::nonlin_ambience::kNumAllpass = 2
inlineconstexpr

Number of pre-diffusion Schroeder allpasses.

[design parameter] default 2, range 0 .. 4.

◆ kParamSmoothMs

double pulp::signal::nonlin_ambience::kParamSmoothMs = 20.0
inlineconstexpr

Smoothing time for the continuous gain parameters.

[design parameter] default 20 ms, range 1 .. 200 ms.

◆ kRevPow

double pulp::signal::nonlin_ambience::kRevPow = 1.0
inlineconstexpr

◆ kRevRise

double pulp::signal::nonlin_ambience::kRevRise = 0.85
inlineconstexpr

Reverse program: normalized rise point r and swell exponent p (p < 1 concave, p > 1 convex).

[design parameter] defaults 0.85 / 1.0, ranges 0.5 .. 0.98 / 0.5 .. 2.0.

◆ kSeedRodd

std::uint32_t pulp::signal::nonlin_ambience::kSeedRodd = 0x9E3779B9u
inlineconstexpr

seed_R = seed_L ⊕ kSeedRodd.

Honest gap: no citable literature exists for this exact 32-bit constant's adoption here. It is the conventional golden-ratio-derived (2³²/φ) multiplicative-hash odd constant, used only because it disperses bits well; any odd 32-bit constant with good dispersion would decorrelate the two seeds equally. A fixed algorithmic constant with a numerical rationale, not a musical design parameter — no range applies.

◆ kSegments

int pulp::signal::nonlin_ambience::kSegments = 8
inlineconstexpr

Number of time segments the tap range is split into for spectral tilt.

Per-tap filtering would be O(taps × filter); this is O(taps + S). [design parameter] default 8, range 4 .. 16.

◆ kSwapFadeMs

double pulp::signal::nonlin_ambience::kSwapFadeMs = 20.0
inlineconstexpr

Equal-power crossfade length applied when a topology change swaps tap banks.

[design parameter] default 20 ms, range 5 .. 100 ms.

◆ kTapGuard

int pulp::signal::nonlin_ambience::kTapGuard = 32
inlineconstexpr

Headroom above the expected tap count, so the jittered grid can never outgrow the pre-sized table.

[design parameter] default 32 taps, range 0 .. 128.