Line data Source code
1 : #pragma once
2 :
3 : // Cascaded all-pass phaser with LFO modulation.
4 : // Each all-pass stage has near-unity magnitude and phase shift A(z); mixing
5 : // dry + wet creates notches where phase cancellation occurs. The LFO modulates
6 : // the all-pass coefficient so notch frequencies sweep over time.
7 :
8 : #include <array>
9 :
10 : #include "audio/effects/core/effect.h"
11 :
12 : namespace Amplitron {
13 :
14 : /**
15 : * Phaser effect — cascaded 1st-order all-pass filters with LFO modulation.
16 : * Supports 4, 6, 8, or 12 stages (classic MXR Phase 90 to studio phasers).
17 : */
18 6 : class Phaser : public Effect {
19 : public:
20 : Phaser();
21 : void process(float* buffer, int num_samples) override;
22 : void process_stereo(float* left, float* right, int num_samples) override;
23 : void set_sample_rate(int sample_rate) override;
24 : void reset() override;
25 65 : const char* name() const override { return "Phaser"; }
26 3 : const char* type_id() const override { return "Phaser"; }
27 97 : std::vector<EffectParam>& params() override { return params_; }
28 0 : const std::vector<EffectParam>& params() const override { return params_; }
29 :
30 : private:
31 : std::vector<EffectParam> params_;
32 :
33 : float lfo_phase_ = 0.0f;
34 : float feedback_state_ = 0.0f;
35 : float feedback_state_r_ = 0.0f; // right-channel APF feedback
36 :
37 : static constexpr int MAX_STAGES = 12;
38 : std::array<float, MAX_STAGES> apf_xprev_{};
39 : std::array<float, MAX_STAGES> apf_yprev_{};
40 : // Right-channel APF state — LFO is 180° out of phase for stereo sweep
41 : std::array<float, MAX_STAGES> apf_xprev_r_{};
42 : std::array<float, MAX_STAGES> apf_yprev_r_{};
43 : };
44 :
45 : } // namespace Amplitron
|