Line data Source code
1 : #pragma once
2 :
3 : // Algorithmic reverb for adding room and tail reflections.
4 : // Uses a Schroeder-style network: parallel feedback combs y_i[n]=x[n]+g_i*y_i[n-d_i]
5 : // build the decay tail, followed by all-pass filters that diffuse echoes while
6 : // keeping magnitude roughly flat.
7 :
8 : #include "audio/effects/effect.h"
9 :
10 : namespace Amplitron {
11 :
12 : class Reverb : public Effect {
13 : public:
14 : Reverb();
15 : void process(float* buffer, int num_samples) override;
16 : void process_stereo(float* left, float* right, int num_samples) override;
17 : void set_sample_rate(int sample_rate) override;
18 : void reset() override;
19 320 : const char* name() const override { return "Reverb"; }
20 3 : const char* type_id() const override { return "Reverb"; }
21 212 : std::vector<EffectParam>& params() override { return params_; }
22 :
23 : private:
24 : std::vector<EffectParam> params_;
25 :
26 : // Schroeder reverb: 4 comb filters + 2 allpass filters
27 : static constexpr int NUM_COMBS = 4;
28 : static constexpr int NUM_ALLPASS = 2;
29 :
30 392 : struct CombFilter {
31 : std::vector<float> buffer;
32 392 : int write_pos = 0;
33 392 : float feedback = 0.0f;
34 392 : float lp_state = 0.0f;
35 392 : float damp = 0.5f;
36 : };
37 :
38 196 : struct AllpassFilter {
39 : std::vector<float> buffer;
40 196 : int write_pos = 0;
41 196 : float feedback = 0.5f;
42 : };
43 :
44 : std::array<CombFilter, NUM_COMBS> combs_;
45 : std::array<AllpassFilter, NUM_ALLPASS> allpasses_;
46 : // Right-channel filter banks — slightly longer delays for decorrelation
47 : std::array<CombFilter, NUM_COMBS> combs_r_;
48 : std::array<AllpassFilter, NUM_ALLPASS> allpasses_r_;
49 :
50 : void init_filters();
51 : };
52 :
53 : } // namespace Amplitron
|