|
| double | retain_finite (double candidate, double current) noexcept |
| | Control setters retain their last valid value when automation supplies a non-finite sample.
|
| double | amplitude_db (double amplitude, double epsilon) |
| | An amplitude → dB, floored by an ADDEND rather than a max().
|
| double | power_db (double mean_square, double epsilon) |
| | A mean square → dB, floored by an addend.
|
| double | one_pole_retain (double tau_seconds, double sample_rate) |
| | α = exp(−1/(τ·fs)) — the RETAIN coefficient (see the file doc block).
|
| double | knee_term_db (double over_db, double knee_db, double slope) |
| | The knee branch's quadratic term: the dB the characteristic bends away from unity inside the knee, (slope − 1)·(over + W/2)² / (2W).
|
| double | soft_knee_output_db (double input_db, double threshold_db, double knee_db, double ratio) |
| | The characteristic in the OUTPUT-LEVEL domain: input dB → output dB.
|
| double | soft_knee_reduction_db (double over_db, double knee_db, double slope) |
| | The same characteristic in the GAIN-REDUCTION domain: dB over threshold → reduction in dB, SIGNED and ≤ 0 for a compressing slope.
|
| double pulp::signal::dynamics::amplitude_db |
( |
double | amplitude, |
|
|
double | epsilon ) |
|
inline |
An amplitude → dB, floored by an ADDEND rather than a max().
20·log10, because the argument is an amplitude. The addend form is chosen over max() here because a detector reading a peak wants a continuous function of its input near silence — a max() puts a corner in the curve at the floor, which a smoother downstream then has to ride over.
| double pulp::signal::dynamics::knee_term_db |
( |
double | over_db, |
|
|
double | knee_db, |
|
|
double | slope ) |
|
inline |
The knee branch's quadratic term: the dB the characteristic bends away from unity inside the knee, (slope − 1)·(over + W/2)² / (2W).
This is the shared kernel — it is bit-identical in both domain forms below and in all four lineages, which is what makes it the thing worth owning here. slope is 1/R; pass 0 for a limiter's infinite ratio and a negative value for an over-unity ("infinity+") curve. Caller guarantees W > 0.
| double pulp::signal::dynamics::power_db |
( |
double | mean_square, |
|
|
double | epsilon ) |
|
inline |
A mean square → dB, floored by an addend.
10·log10, NOT 20, because the integrator already holds a squared quantity. Getting this wrong doubles every level the detector reports, which reads as a compressor with twice the ratio it was set to and no obvious symptom otherwise — so the two conversions are named separately rather than left to a factor at each call site.
| double pulp::signal::dynamics::soft_knee_output_db |
( |
double | input_db, |
|
|
double | threshold_db, |
|
|
double | knee_db, |
|
|
double | ratio ) |
|
inline |
The characteristic in the OUTPUT-LEVEL domain: input dB → output dB.
y(x) = x 2(x−T) < −W
= x + (1/R − 1)(x − T + W/2)² / (2W) 2|x−T| ≤ W
= T + (x−T)/R otherwise
ratio may be negative (an "infinity+" curve that keeps pushing output down as input rises); the equation is continuous through that and the caller owns any floor.
Preconditions, which every module enforced with its own clamp before this was shared code and which are therefore not re-checked here: knee_db >= 0 and ratio != 0. There is deliberately no guard — a compressor whose ratio reached zero has a bug upstream, and swallowing it here would hide that while costing a branch per sample. A module whose top-of-range ratio means "limit" should resolve the slope itself and use soft_knee_reduction_db, which takes slope = 0 for an infinite ratio without any division.