Line data Source code
1 : #include "audio/effects/distortion.h"
2 : #include "audio/effects/effect_factory.h"
3 :
4 : namespace Amplitron {
5 :
6 2 : static EffectRegistrar<Distortion> reg("Distortion");
7 :
8 100 : Distortion::Distortion() {
9 225 : params_ = {
10 75 : {"Drive", 2.0f, 1.0f, 20.0f, 2.0f, "x", "Amount of input gain slamming into the hard clippers. Creates aggressive, dense harmonic distortion."},
11 25 : {"Tone", 0.6f, 0.0f, 1.0f, 0.6f, "", "Low-pass filter cutoff to tame the fizzy high-end generated by hard clipping."},
12 25 : {"Level", 0.5f, 0.0f, 1.0f, 0.5f, "", "Master output volume of the pedal. Useful to match volume with the pedal bypassed."},
13 225 : };
14 100 : drive_smoothed_ = params_[0].value;
15 75 : tone_smoothed_ = params_[1].value;
16 75 : level_smoothed_ = params_[2].value;
17 175 : }
18 :
19 27 : void Distortion::process(float* buffer, int num_samples) {
20 27 : if (!enabled_) return;
21 :
22 : // One-pole smoothing: advance states toward raw param targets each block
23 24 : const float alpha = 1.0f - std::exp(-1.0f / (sample_rate_ * 0.010f)); // 10 ms
24 24 : drive_smoothed_ += alpha * (params_[0].value - drive_smoothed_);
25 24 : tone_smoothed_ += alpha * (params_[1].value - tone_smoothed_);
26 24 : level_smoothed_ += alpha * (params_[2].value - level_smoothed_);
27 :
28 24 : float drive = drive_smoothed_;
29 24 : float tone = tone_smoothed_;
30 24 : float level = level_smoothed_;
31 :
32 : // Tone control: simple one-pole LP filter coefficient
33 24 : float lp_coeff = 0.1f + tone * 0.8f;
34 :
35 6168 : for (int i = 0; i < num_samples; ++i) {
36 6144 : float dry = buffer[i];
37 :
38 : // Apply drive gain
39 6144 : float x = buffer[i] * drive;
40 :
41 : // Soft path (tube-like via tanh + soft clip)
42 6144 : float x_soft = soft_clip(fast_tanh(x) * 1.5f);
43 :
44 : // Hard path (hard clip at unity)
45 6144 : float x_hard = hard_clip(x, 1.0f);
46 :
47 : // Blend: more drive → more hard clipping
48 6144 : float hard_amount = (drive - 1.0f) / 19.0f; // 0 at drive=1, 1 at drive=20
49 6144 : x = x_soft * (1.0f - hard_amount) + x_hard * hard_amount;
50 :
51 : // Tone filter (one-pole LP)
52 6144 : x = tone_lp_.lp(x, lp_coeff);
53 :
54 : // Output level
55 6144 : x *= level;
56 :
57 : // Wet/dry mix
58 6144 : buffer[i] = dry * (1.0f - mix_) + x * mix_;
59 2048 : }
60 9 : }
61 :
62 69 : void Distortion::reset() {
63 69 : tone_lp_.reset();
64 69 : }
65 :
66 : } // namespace Amplitron
|