34class Freeverb :
public Base {
37 ~Freeverb()
override =
default;
41 void setRoomSize(
float value)
override {
42 roomsize = (value * scaleroom) + offsetroom;
46 [[nodiscard]]
constexpr float getRoomSize()
const override {
return (roomsize - offsetroom) / scaleroom; }
48 void setDamping(
float value)
override {
49 damp = value * scaledamp;
53 [[nodiscard]]
constexpr float getDamping()
const override {
return damp / scaledamp; }
55 void setWet(
float value) {
56 wet = value * scalewet;
60 [[nodiscard]]
constexpr float getWet()
const {
return wet / scalewet; }
62 void setDry(
float value) { dry = value * scaledry; }
64 [[nodiscard]]
constexpr float getDry()
const {
return dry / scaledry; }
66 void setWidth(
float value)
override {
71 [[nodiscard]]
constexpr float getWidth()
const override {
return width; }
73 [[gnu::always_inline]]
void ProcessOne(int32_t input,
StereoSample& output_sample) {
78 for (int32_t i = 0; i < numcombs; i++) {
79 out_l += combL[i].process(input);
80 out_r += combR[i].process(input);
84 for (int32_t i = 0; i < numallpasses; i++) {
85 out_l = allpassL[i].process(out_l);
86 out_r = allpassR[i].process(out_r);
90 out_l = (out_l + multiply_32x32_rshift32_rounded(out_r, wet2)) << 1;
91 out_r = (out_r + multiply_32x32_rshift32_rounded(out_l, wet2)) << 1;
94 output_sample.l += multiply_32x32_rshift32_rounded(out_l, this->getPanLeft());
95 output_sample.r += multiply_32x32_rshift32_rounded(out_r, this->getPanRight());
98 [[gnu::always_inline]]
void process(std::span<int32_t> input, std::span<StereoSample> output)
override {
100 for (int32_t& reverb_sample : input) {
101 int32_t distance_to_go_l = reverb_sample - reverb_send_post_lpf_;
102 reverb_send_post_lpf_ += distance_to_go_l >> 11;
103 reverb_sample -= reverb_send_post_lpf_;
106 for (
size_t frame = 0; frame < input.size(); frame++) {
107 ProcessOne(input[frame], output[frame]);
128 std::array<freeverb::Comb, numcombs> combL;
129 std::array<freeverb::Comb, numcombs> combR;
132 std::array<freeverb::Allpass, numallpasses> allpassL;
133 std::array<freeverb::Allpass, numallpasses> allpassR;
136 std::array<int32_t, combtuningL1> bufcombL1;
137 std::array<int32_t, combtuningR1> bufcombR1;
138 std::array<int32_t, combtuningL2> bufcombL2;
139 std::array<int32_t, combtuningR2> bufcombR2;
140 std::array<int32_t, combtuningL3> bufcombL3;
141 std::array<int32_t, combtuningR3> bufcombR3;
142 std::array<int32_t, combtuningL4> bufcombL4;
143 std::array<int32_t, combtuningR4> bufcombR4;
144 std::array<int32_t, combtuningL5> bufcombL5;
145 std::array<int32_t, combtuningR5> bufcombR5;
146 std::array<int32_t, combtuningL6> bufcombL6;
147 std::array<int32_t, combtuningR6> bufcombR6;
148 std::array<int32_t, combtuningL7> bufcombL7;
149 std::array<int32_t, combtuningR7> bufcombR7;
150 std::array<int32_t, combtuningL8> bufcombL8;
151 std::array<int32_t, combtuningR8> bufcombR8;
154 std::array<int32_t, allpasstuningL1> bufallpassL1;
155 std::array<int32_t, allpasstuningR1> bufallpassR1;
156 std::array<int32_t, allpasstuningL2> bufallpassL2;
157 std::array<int32_t, allpasstuningR2> bufallpassR2;
158 std::array<int32_t, allpasstuningL3> bufallpassL3;
159 std::array<int32_t, allpasstuningR3> bufallpassR3;
160 std::array<int32_t, allpasstuningL4> bufallpassL4;
161 std::array<int32_t, allpasstuningR4> bufallpassR4;
163 int32_t reverb_send_post_lpf_ = 0;