Line data Source code
1 : #pragma once
2 :
3 : // Preamp and tone-stack models for classic guitar amplifier voicings.
4 : // Signal model: y = L * sat(G * H_tone{x}, mix, asymmetry), where H_tone is
5 : // a low-shelf + peaking-mid + high-shelf biquad cascade. The factory models
6 : // cover Clean American / Fender Twin, British Crunch / Marshall JCM800,
7 : // High Gain Modern / Mesa Rectifier, and Jazz Warm / Roland JC-120. Dynamic
8 : // sag follows an envelope e[n] = a*x_abs[n] + (1-a)*e[n-1] and reduces gain
9 : // as the simulated supply is loaded.
10 :
11 : #include "audio/dsp/biquad.h"
12 : #include "audio/effects/core/effect.h"
13 :
14 : namespace Amplitron {
15 :
16 : /**
17 : * @brief Describes the tonal character of an amp model.
18 : *
19 : * Each model packages a characteristic tone-stack EQ curve, saturation
20 : * transfer function, and dynamic response into a single struct that the
21 : * AmpSimulator effect consumes.
22 : */
23 : struct AmpModel {
24 : const char* name; ///< Display name (e.g. "Clean American")
25 : const char* inspiration; ///< Real-world amp inspiration
26 : const char* description; ///< Short tonal description
27 :
28 : // --- Tone stack (3-band biquad EQ) ---
29 : float bass_freq; ///< Low shelf center frequency (Hz)
30 : float bass_gain_db; ///< Low shelf gain (dB)
31 : float bass_q; ///< Low shelf Q factor
32 : float mid_freq; ///< Mid peak center frequency (Hz)
33 : float mid_gain_db; ///< Mid peak gain (dB)
34 : float mid_q; ///< Mid peak Q factor
35 : float treble_freq; ///< High shelf center frequency (Hz)
36 : float treble_gain_db; ///< High shelf gain (dB)
37 : float treble_q; ///< High shelf Q factor
38 :
39 : // --- Saturation ---
40 : float preamp_gain; ///< Pre-saturation drive multiplier
41 : float saturation_mix; ///< Blend of soft vs hard clipping [0=soft, 1=hard]
42 : float asymmetry; ///< Positive-negative clipping ratio (1.0 = symmetric)
43 : float output_level; ///< Post-saturation output scaling
44 :
45 : // --- Dynamic response ---
46 : float attack_coeff; ///< Envelope follower attack speed (0-1, higher = faster)
47 : float release_coeff; ///< Envelope follower release speed (0-1, higher = faster)
48 : float sag_amount; ///< Power-sag simulation depth (0 = none)
49 : };
50 :
51 : /**
52 : * @brief Returns the built-in amp model library.
53 : * @return Vector of AmpModel structs for all factory amp types.
54 : */
55 : const std::vector<AmpModel>& get_amp_models();
56 :
57 : /**
58 : * @brief Preamp simulator effect with selectable amp models.
59 : *
60 : * Implements a complete preamp stage: input gain -> envelope follower ->
61 : * tone-stack EQ (3 biquad filters) -> waveshaping saturation -> output level.
62 : * The tonal character is defined by the selected AmpModel.
63 : */
64 7 : class AmpSimulator : public Effect {
65 : public:
66 : AmpSimulator();
67 : void process(float* buffer, int num_samples) override;
68 : void set_sample_rate(int sample_rate) override;
69 : void reset() override;
70 341 : const char* name() const override { return "Amp Sim"; }
71 3 : const char* type_id() const override { return "Amp Sim"; }
72 144 : std::vector<EffectParam>& params() override { return params_; }
73 0 : const std::vector<EffectParam>& params() const override { return params_; }
74 :
75 : private:
76 : std::vector<EffectParam> params_;
77 :
78 : // 3-band tone-stack biquad filters
79 : Biquad low_shelf_;
80 : Biquad mid_peak_;
81 : Biquad high_shelf_;
82 :
83 : // Envelope follower for dynamic response
84 : float envelope_ = 0.0f;
85 :
86 : // DC blocking high-pass state
87 : OnePole dc_block_;
88 :
89 : // One-pole smoothing states for trim parameters (avoids coefficient click on UI change)
90 : float bass_trim_state_ = 0.0f;
91 : float mid_trim_state_ = 0.0f;
92 : float treble_trim_state_ = 0.0f;
93 : float gain_smoothed_ = 0.5f;
94 : float level_smoothed_ = 0.7f;
95 :
96 : // Cached model index for dirty-check coefficient recomputation
97 : int cached_model_index_ = -1;
98 : float cached_bass_ = -999.0f;
99 : float cached_mid_ = -999.0f;
100 : float cached_treble_ = -999.0f;
101 : float cached_gain_ = -999.0f;
102 :
103 : void recompute_coefficients_if_dirty();
104 : };
105 :
106 : } // namespace Amplitron
|