Line data Source code
1 : #include "audio/effects/compressor.h"
2 : #include "audio/effects/effect_factory.h"
3 :
4 : namespace Amplitron {
5 :
6 2 : static EffectRegistrar<Compressor> reg("Compressor");
7 :
8 88 : Compressor::Compressor() {
9 286 : params_ = {
10 66 : {"Threshold", -20.0f, -60.0f, 0.0f, -20.0f, "dB", "Signal level at which compression begins. Signals above this level will be reduced in volume."},
11 22 : {"Ratio", 4.0f, 1.0f, 20.0f, 4.0f, ":1", "How strongly to reduce peaks that exceed the threshold. Higher values create a more squashed sound."},
12 22 : {"Attack", 5.0f, 0.1f, 50.0f, 5.0f, "ms", "How quickly the compressor reacts to peaks. Fast attack clamps down immediately, slow allows pick transients through."},
13 22 : {"Release", 100.0f, 10.0f, 500.0f, 100.0f, "ms", "How quickly the compressor stops reducing volume after the signal drops below threshold."},
14 22 : {"Makeup", 0.0f, 0.0f, 30.0f, 0.0f, "dB", "Gain boost applied after compression to compensate for the volume lost during peak reduction."},
15 286 : };
16 132 : }
17 :
18 36 : void Compressor::process(float* buffer, int num_samples) {
19 36 : if (!enabled_) return;
20 :
21 36 : float threshold_db = params_[0].value;
22 36 : float ratio = params_[1].value;
23 36 : float attack_ms = params_[2].value;
24 36 : float release_ms = params_[3].value;
25 36 : float makeup = db_to_linear(params_[4].value);
26 :
27 : // Parameter smoothing (anti-zipper) — keep short enough to reduce zipper noise
28 : // while limiting lag in fast attack/release settings.
29 36 : const float alpha = 1.0f - std::exp(-1.0f / (sample_rate_ * 0.002f)); // 2 ms
30 36 : smoothed_attack_ms_ += alpha * (attack_ms - smoothed_attack_ms_);
31 36 : smoothed_release_ms_ += alpha * (release_ms - smoothed_release_ms_);
32 :
33 36 : float attack_coeff = EnvelopeFollower::time_to_coeff(smoothed_attack_ms_, sample_rate_);
34 36 : float release_coeff = EnvelopeFollower::time_to_coeff(smoothed_release_ms_, sample_rate_);
35 :
36 35364 : for (int i = 0; i < num_samples; ++i) {
37 35328 : float envelope = env_.process_additive(buffer[i], attack_coeff, release_coeff);
38 :
39 35328 : float env_db = linear_to_db(envelope);
40 35328 : float gain_db = 0.0f;
41 35328 : if (env_db > threshold_db) {
42 33759 : gain_db = (threshold_db - env_db) * (1.0f - 1.0f / ratio);
43 11253 : }
44 :
45 35328 : float gain = db_to_linear(gain_db) * makeup;
46 35328 : buffer[i] *= gain;
47 11776 : }
48 12 : }
49 :
50 57 : void Compressor::reset() {
51 57 : env_.reset();
52 57 : }
53 :
54 : } // namespace Amplitron
|