15class Mutable :
public Base {
16 constexpr static size_t kBufferSize = 32768;
21 ~Mutable()
override =
default;
23 void process(std::span<int32_t> in, std::span<StereoSample> output)
override {
42 FxEngine::ConstructTopology(engine_,
44 &ap1, &ap2, &ap3, &ap4,
45 &dap1a, &dap1b, &del1,
46 &dap2a, &dap2b, &del2,
49 const float kap = diffusion_;
50 const float klp = lp_;
51 const float krt = reverb_time_;
52 const float gain = input_gain_;
54 float lp_1 = lp_decay_1_;
55 float lp_2 = lp_decay_2_;
57 for (
size_t frame = 0; frame < in.size(); frame++) {
67 const float input_sample = in[frame] /
static_cast<float>(std::numeric_limits<int32_t>::max());
83 dap1a.Process(c, -kap);
84 dap1b.Process(c, kap);
87 wet = wet - dsp::OnePole(hp_r_, wet, hp_cutoff_);
89 wet = dsp::OnePole(lp_r_, wet, lp_cutoff_);
92 static_cast<int32_t
>(wet *
static_cast<float>(std::numeric_limits<uint32_t>::max()) * 0xF);
97 dap2a.Process(c, -kap);
98 dap2b.Process(c, kap);
101 wet = wet - dsp::OnePole(hp_l_, wet, hp_cutoff_);
103 wet = dsp::OnePole(lp_l_, wet, lp_cutoff_);
107 static_cast<int32_t
>(wet *
static_cast<float>(std::numeric_limits<uint32_t>::max()) * 0xF);
110 s.l += multiply_32x32_rshift32_rounded(output_left, getPanLeft());
111 s.r += multiply_32x32_rshift32_rounded(output_right, getPanRight());
118 inline void Clear() { engine_.Clear(); }
120 static constexpr float kReverbTimeMin = 0.01f;
121 static constexpr float kReverbTimeMax = 0.98f;
122 static constexpr float kWidthMin = 0.1f;
123 static constexpr float kWidthMax = 0.9f;
126 void setRoomSize(
float value)
override {
127 reverb_time_ = util::map(value, 0.f, 1.f, kReverbTimeMin, kReverbTimeMax);
129 [[nodiscard]]
float getRoomSize()
const override {
130 return util::map(reverb_time_, kReverbTimeMin, kReverbTimeMax, 0.f, 1.f);
133 void setDamping(
float value)
override {
135 lp_ = (value == 0.f) ? 1.f : 1.f - std::clamp((std::log2(((1.f - lp_val_) * 50.f) + 1.f) / 5.7f), 0.f, 1.f);
137 [[nodiscard]]
float getDamping()
const override {
return lp_val_; }
139 void setWidth(
float value)
override { diffusion_ = util::map(value, 0.f, 1.f, kWidthMin, kWidthMax); }
140 [[nodiscard]]
float getWidth()
const override {
return util::map(diffusion_, kWidthMin, kWidthMax, 0.f, 1.f); };
142 void setHPF(
float f)
override {
144 hp_cutoff_ = calcFilterCutoff<FilterType::HighPass>(f);
147 [[nodiscard]]
float getHPF()
const override {
return hp_cutoff_val_; }
149 void setLPF(
float f)
override {
151 lp_cutoff_ = calcFilterCutoff<FilterType::LowPass>(f);
154 [[nodiscard]]
float getLPF()
const override {
return lp_cutoff_val_; }
157 static constexpr float sample_rate = kSampleRate;
159 std::array<float, kBufferSize> buffer_{};
160 FxEngine engine_{buffer_, {0.5f / sample_rate, 0.3f / sample_rate}};
162 float input_gain_ = 0.2;
165 float reverb_time_ = 0.665f;
168 float diffusion_ = 0.625f;
175 float lp_decay_1_{0};
176 float lp_decay_2_{0};
179 float hp_cutoff_val_{0.f};
181 float hp_cutoff_{calcFilterCutoff<FilterType::HighPass>(0)};
186 float lp_cutoff_val_{0.f};
188 float lp_cutoff_{calcFilterCutoff<FilterType::LowPass>(0)};
Definition fx_engine.hpp:81