One input or output transformer: band-limit, mild saturation, DC-blocked. More...
#include <diode_bridge_compressor.hpp>
Public Member Functions | |
| void | prepare (double sample_rate) |
| void | reset () |
| void | set_character (double character01) |
| 0..1 colour depth, shared with the bridge. | |
| void | set_adaa (bool on) |
| double | saturate (double u) const |
| u − (a/2)·u·|u| − (a·ε/2)·u². | |
| double | saturate_antiderivative (double u) const |
| ∫sat du. | |
| SampleType | process (SampleType input) |
Static Public Attributes | |
| static constexpr double | kLowCornerHz = 20.0 |
| Low-frequency corner: the transformer's LF droop, and the stage's DC block. | |
| static constexpr double | kHighCornerHz = 28000.0 |
| High-frequency corner: winding bandwidth. | |
| static constexpr double | kSaturationDepth = 0.15 |
| Saturation depth at character = 1. | |
| static constexpr double | kEvenAsymmetry = 0.5 |
| How much of the saturation is asymmetric, i.e. | |
| static constexpr double | kMonotonicMargin = 0.98 |
| Fraction of the 1/(a(1+ε)) monotonicity limit the input clamp uses. | |
| static constexpr double | kAdaaEpsilon = 1e-5 |
| ADAA ill-conditioning guard, as DiodeBridgeGainT::kAdaaEpsilon. | |
| static constexpr double | kPeakGain = 1.0 |
| The peak gain this stage can present, at any frequency and any amplitude. | |
One input or output transformer: band-limit, mild saturation, DC-blocked.
Peak gain is exactly 1.0, and that is load-bearing — it is the Tpeak the compressor's worst-case-gain bound multiplies by, so it has to be a property of the construction rather than a measured approximation. Three stages, each with magnitude ≤ 1 at every frequency and amplitude: a one-pole high-pass, a compressive saturator whose gain is 1 − (a/2)|u| (≤ 1 by inspection, = 1 only at the origin), and a one-pole low-pass.
Why not DcBlocker. The spec composes DcBlocker for the LF corner. Its transfer function (1 − z⁻¹)/(1 − p·z⁻¹) has magnitude 2/(1 + p) at Nyquist — 1.0025 at the default pole. Two brackets would therefore have a peak gain of 1.005, and the Tpeak = 1.0 the worst-case bound cites would be false by construction. The house TPT one-pole's high-pass output is 1 − LP, whose magnitude is ≤ 1 everywhere with equality only at Nyquist, and it is still an exact DC block (H(0) = 0). Same existing primitive family, one that does not void the invariant it is used inside.
Order: saturate, then high-pass. The saturator's even-harmonic term rectifies, so it generates a program-dependent DC offset. Placing the high-pass after it makes one filter do both jobs the spec names — the documented LF droop AND the DC block — and keeps that offset out of the output sum and out of the feedback detector, which would otherwise read it as signal and hold gain down on a silent passage.
The even harmonics are real, and they need an asymmetry to exist. The spec prescribes sat(u) = u − (a/2)·u·|u| and describes it as adding a second harmonic. It does not: u·|u| is an ODD function, so that shaper is odd-symmetric and produces odd harmonics only — which is also the physically right answer for a SYMMETRIC magnetic core. Even harmonics in a transformer come from asymmetry. kEvenAsymmetry is the parameter that supplies it, and at kEvenAsymmetry = 0 this reduces to the spec's formula exactly:
RT contract: as the file doc block. Nothing allocates.
|
inline |
|
inline |
|
inline |
|
inline |
u − (a/2)·u·|u| − (a·ε/2)·u².
Slope 1 at the origin; |sat(u)/u| ≤ 1 everywhere inside the monotonic region.
|
inline |
∫sat du.
Continuous and continuously differentiable at the origin, which is what makes the ADAA quotient valid across a zero crossing.
|
inline |
|
inline |
0..1 colour depth, shared with the bridge.
|
staticconstexpr |
ADAA ill-conditioning guard, as DiodeBridgeGainT::kAdaaEpsilon.
[design parameter] default 1e-5, range 1e-7 .. 1e-4.
|
staticconstexpr |
How much of the saturation is asymmetric, i.e.
how even-harmonic-forward the bracket is. 0 is the spec's odd-only formula; 1 leaves the negative half of the curve untouched entirely. [design parameter] default 0.5, range 0.0 .. 1.0.
|
staticconstexpr |
High-frequency corner: winding bandwidth.
[design parameter] default 28 kHz, range 18 .. 40 kHz.
|
staticconstexpr |
Low-frequency corner: the transformer's LF droop, and the stage's DC block.
[design parameter] default 20 Hz, range 10 .. 40 Hz.
|
staticconstexpr |
Fraction of the 1/(a(1+ε)) monotonicity limit the input clamp uses.
At the default depth that limit is ~4.4 — far outside any real signal, so this is a guard against a caller feeding the bracket something wild, not a shaping stage. [design parameter] default 0.98, range 0.90 .. 0.99.
|
staticconstexpr |
The peak gain this stage can present, at any frequency and any amplitude.
Exactly 1 by construction — see the class doc block. Named rather than written as a literal because the compressor's worst-case bound multiplies two of them.
|
staticconstexpr |
Saturation depth at character = 1.
Small: a line-level bracket runs at far lower flux than a tape head, which is also why hysteresis is out of scope here (see the module's scope notes). [design parameter] default 0.15, range 0.0 .. 0.5.