Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
forge_distortion_catalog.hpp
Go to the documentation of this file.
1#pragma once
2
3// Distortion — bake-layer catalog node.
4//
5// Composes the circuit-modelled clipper family into one node:
6//
7// input trim → pre-tone → drive → CLIPPER → post-tone → output trim
8//
9// with the clipper (and only the clipper) running inside the house
10// oversampling wrapper. The tone stages ride at the oversampled rate too, but
11// only because they sit between the rails of one prepare/process pair — they are
12// linear and carry no antialiasing requirement of their own.
13//
14// TOPOLOGY IS A REGISTRATION-TIME REALIZATION, like the saturator's curve and
15// unlike the compressor's detector mode. `to_ground` and `in_loop` are different
16// circuits, not different coefficients: one clips a fixed voltage after a gain
17// stage, the other clips inside a feedback loop whose capacitor makes the clip
18// frequency-dependent. A baked build authored as an overdrive should stay an
19// overdrive.
20//
21// THE OVERSAMPLING TIER IS ALSO A REALIZATION, and for the harder reason: it
22// determines `latency_samples()`. A node whose reported latency moves under the
23// audio thread breaks the host's delay compensation. ×1 is the zero-latency
24// no antialiasing; ×2/×4/×8 report the composed oversampler's own exact group delay.
25//
26// MONO, one port in and one out. Every stage here is per-sample with no
27// cross-channel state, so a stereo instrument would be two independent copies —
28// which is what instancing two nodes already gives.
29
32
35#include <pulp/signal/units.hpp>
36
37#include <cstddef>
38#include <cstdint>
39#include <string>
40
42
45
48enum class OversampleTier : std::uint8_t { x1, x2, x4, x8 };
49
50// ── Stable type ids ───────────────────────────────────────────────────────
51// One id per (topology, tier) pair, because both are frozen at registration.
52inline constexpr const char* kToGroundX1TypeId = "distortion.to_ground.x1";
53inline constexpr const char* kToGroundX2TypeId = "distortion.to_ground.x2";
54inline constexpr const char* kToGroundX4TypeId = "distortion.to_ground.x4";
55inline constexpr const char* kToGroundX8TypeId = "distortion.to_ground.x8";
56inline constexpr const char* kInLoopX1TypeId = "distortion.in_loop.x1";
57inline constexpr const char* kInLoopX2TypeId = "distortion.in_loop.x2";
58inline constexpr const char* kInLoopX4TypeId = "distortion.in_loop.x4";
59inline constexpr const char* kInLoopX8TypeId = "distortion.in_loop.x8";
60
61// ── Injectable param ids ──────────────────────────────────────────────────
62inline constexpr state::ParamID kDriveDb = 1; // dB
63inline constexpr state::ParamID kSymmetry = 2; // −1..+1
64inline constexpr state::ParamID kDiodeModel = 3; // stepped 0=Si, 1=Ge, 2=LED
65inline constexpr state::ParamID kPreToneHz = 4; // Hz
66inline constexpr state::ParamID kPostToneHz = 5; // Hz
67inline constexpr state::ParamID kToneMix = 6; // 0..1
68inline constexpr state::ParamID kOutputDb = 7; // dB
69// Added after the original seven IDs shipped on the feature branch. Keep it at
70// 8 so saved graphs retain the meaning of every existing parameter ID.
71inline constexpr state::ParamID kPreGainDb = 8; // dB
72
75inline constexpr float kDriveDbMin = 0.0f;
76inline constexpr float kDriveDbMax = 40.0f;
77inline constexpr float kDriveDbDefault = 12.0f;
78
80inline constexpr float kOutputDbMin = -24.0f;
81inline constexpr float kOutputDbMax = 12.0f;
82
84 // Two clipper realizations, one selected per registration.
85 //
86 // `to_ground` uses DiodeClipperT DIRECTLY rather than FeedbackClipperT's
87 // to-ground mode, because that mode bundles the op-amp's own Rf/Rin gain —
88 // 10.85× at the defaults. Bundling it here would double-count against the
89 // node's `drive_db`: the minimum drive setting would already be 20.7 dB of
90 // gain, so the node would arrive fully clipped at drive 0 and the knob
91 // would do nothing but change how square the result is. The spec's chain is
92 // `drive → clipper`, and this is that chain.
97 float drive = 1.0f;
98 float output = 1.0f;
99 int latency = 0;
100};
101
104
106const char* distortion_type_id(Topology topology, OversampleTier tier);
107
109const char* distortion_default_name(Topology topology);
110
113
116
119
121int distortion_latency_samples(OversampleTier tier, double sample_rate);
122
123} // namespace pulp::host::distortion
Definition oversampling.hpp:78
The circuit-modelled clipper family: diode-to-ground and diode-in-the-loop, solved as ODEs with memor...
Definition forge_distortion_catalog.hpp:41
constexpr state::ParamID kSymmetry
Definition forge_distortion_catalog.hpp:63
signal::ClipperTopology Topology
Definition forge_distortion_catalog.hpp:44
constexpr state::ParamID kToneMix
Definition forge_distortion_catalog.hpp:67
OversampleTier
Oversampling tiers this node registers.
Definition forge_distortion_catalog.hpp:48
@ x1
Definition forge_distortion_catalog.hpp:48
@ x2
Definition forge_distortion_catalog.hpp:48
@ x4
Definition forge_distortion_catalog.hpp:48
@ x8
Definition forge_distortion_catalog.hpp:48
signal::DiodeModel DiodeModel
Definition forge_distortion_catalog.hpp:43
constexpr const char * kToGroundX1TypeId
Definition forge_distortion_catalog.hpp:52
constexpr float kOutputDbMin
Output trim. [design parameter] default 0 dB, range −24 .. +12 dB.
Definition forge_distortion_catalog.hpp:80
float distortion_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
ForgeNodeDescriptor distortion_descriptor()
Descriptor for the distortion family and its registered realizations.
constexpr float kDriveDbMax
Definition forge_distortion_catalog.hpp:76
constexpr float kOutputDbMax
Definition forge_distortion_catalog.hpp:81
int oversample_factor(OversampleTier tier)
Returns the integer oversampling factor for a registered tier.
constexpr const char * kInLoopX8TypeId
Definition forge_distortion_catalog.hpp:59
const char * distortion_type_id(Topology topology, OversampleTier tier)
Stable type id for a topology/tier realization.
constexpr float kDriveDbDefault
Definition forge_distortion_catalog.hpp:77
constexpr const char * kToGroundX4TypeId
Definition forge_distortion_catalog.hpp:54
constexpr const char * kToGroundX8TypeId
Definition forge_distortion_catalog.hpp:55
CustomNodeType make_distortion_node(Topology topology, OversampleTier tier=OversampleTier::x4)
One factory, eight registered realizations (2 topologies x 4 tiers).
constexpr state::ParamID kPreGainDb
Definition forge_distortion_catalog.hpp:71
int distortion_latency_samples(OversampleTier tier, double sample_rate)
Reported latency for a tier at the supplied sample rate.
constexpr const char * kToGroundX2TypeId
Definition forge_distortion_catalog.hpp:53
constexpr state::ParamID kDriveDb
Definition forge_distortion_catalog.hpp:62
const char * distortion_default_name(Topology topology)
Default display name for a topology.
constexpr state::ParamID kPostToneHz
Definition forge_distortion_catalog.hpp:66
constexpr state::ParamID kPreToneHz
Definition forge_distortion_catalog.hpp:65
constexpr float kDriveDbMin
Drive range.
Definition forge_distortion_catalog.hpp:75
constexpr const char * kInLoopX1TypeId
Definition forge_distortion_catalog.hpp:56
constexpr const char * kInLoopX4TypeId
Definition forge_distortion_catalog.hpp:58
constexpr const char * kInLoopX2TypeId
Definition forge_distortion_catalog.hpp:57
constexpr state::ParamID kOutputDb
Definition forge_distortion_catalog.hpp:68
constexpr state::ParamID kDiodeModel
Definition forge_distortion_catalog.hpp:64
FeedbackClipperT< float > FeedbackClipper
Definition distortion.hpp:681
ToneStackT< float > ToneStack
Definition distortion.hpp:790
DiodeClipperT< float > DiodeClipper
Definition distortion.hpp:515
DiodeModel
Diode device families. The members differ only in (Is, n).
Definition distortion.hpp:112
ClipperTopology
Where the diode pair sits relative to the gain stage.
Definition distortion.hpp:119
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55
Definition custom_node_type.hpp:90
Definition forge_param_descriptor.hpp:127
Definition forge_distortion_catalog.hpp:83
signal::ToneStack tone
Definition forge_distortion_catalog.hpp:95
int latency
Definition forge_distortion_catalog.hpp:99
signal::FeedbackClipper loop_clipper
Definition forge_distortion_catalog.hpp:94
signal::DiodeClipper ground_clipper
Definition forge_distortion_catalog.hpp:93
signal::OversamplerT< float > oversampler
Definition forge_distortion_catalog.hpp:96
float output
Definition forge_distortion_catalog.hpp:98
float drive
Definition forge_distortion_catalog.hpp:97
The real-unit vocabulary shared by every DSP block in the catalog.