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/effects/effect.h"
12 : #include "audio/dsp/biquad.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 :
74 : private:
75 : std::vector<EffectParam> params_;
76 :
77 : // 3-band tone-stack biquad filters
78 : Biquad low_shelf_;
79 : Biquad mid_peak_;
80 : Biquad high_shelf_;
81 :
82 : // Envelope follower for dynamic response
83 : float envelope_ = 0.0f;
84 :
85 : // DC blocking high-pass state
86 : OnePole dc_block_;
87 :
88 : // One-pole smoothing states for trim parameters (avoids coefficient click on UI change)
89 : float bass_trim_state_ = 0.0f;
90 : float mid_trim_state_ = 0.0f;
91 : float treble_trim_state_ = 0.0f;
92 : float gain_smoothed_ = 0.5f;
93 : float level_smoothed_ = 0.7f;
94 :
95 : // Cached model index for dirty-check coefficient recomputation
96 : int cached_model_index_ = -1;
97 : float cached_bass_ = -999.0f;
98 : float cached_mid_ = -999.0f;
99 : float cached_treble_ = -999.0f;
100 : float cached_gain_ = -999.0f;
101 :
102 : void recompute_coefficients_if_dirty();
103 : };
104 :
105 : } // namespace Amplitron
|