27template <std::
floating_po
int FloatType,
size_t MaximumChannels,
size_t MaximumSampleRate>
30 static_assert (! std::is_const<FloatType>::value,
"FloatType is must NOT be const.");
33 explicit Freeverb (FloatType sampleRate)
44 void setRoomSize (FloatType roomSize, FloatType damp)
noexcept
46 static constexpr FloatType roomScaleFactor = 0.28f;
47 static constexpr FloatType roomOffset = 0.7f;
48 static constexpr FloatType dampScaleFactor = 0.4f;
49 damping = damp * dampScaleFactor;
50 feedback = roomSize * roomScaleFactor + roomOffset;
58 assert (0 < sampleRate);
59 assert (sampleRate <= MaximumSampleRate);
61 static constexpr int_fast16_t combTunings[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 };
62 static constexpr int_fast16_t allPassTunings[] = { 556, 441, 341, 225 };
63 static const FloatType sampleRateRatio = sampleRate / 44100.0f;
65 for (
int i = 0; i < numCombs; ++i)
67 comb[0][i].setSize (std::round (combTunings[i] * sampleRateRatio));
68 comb[1][i].setSize (std::round ((combTunings[i] + stereoSpread) * sampleRateRatio));
71 for (
int i = 0; i < numAllPasses; ++i)
73 allPass[0][i].setSize (std::round (allPassTunings[i] * sampleRateRatio));
74 allPass[1][i].setSize (std::round ((allPassTunings[i] + stereoSpread) * sampleRateRatio));
77 const int_fast16_t smoothSteps =
static_cast<int_fast16_t
> (sampleRate * 0.01f);
78 dryWet.setRampLength (smoothSteps);
86 dryWet.setTargetValue (mix);
92 for (
int ch = 0; ch < MaximumChannels; ++ch)
94 for (
int i = 0; i < numCombs; ++i)
99 for (
int i = 0; i < numAllPasses; ++i)
101 allPass[ch][i].clear();
113 assert (numChannels <= MaximumChannels);
118 for (uint_fast32_t samp = 0; samp < bufferSize; ++samp)
120 const FloatType mix = dryWet.getNextValue();
121 for (uint_fast32_t ch = 0; ch < numChannels; ++ch)
123 const FloatType input = block.view[i];
124 FloatType output = 0.0f;
126 for (
int cmb = 0; cmb < numCombs; ++cmb)
128 output += comb[ch][cmb].process (input, damping, feedback);
131 for (
int ap = 0; ap < numAllPasses; ++ap)
133 output = allPass[ch][ap].process (output);
135 block.view[i] = std::lerp (input, output, mix);
142 static constexpr int stereoSpread = 23;
143 static constexpr FloatType inputGain = 0.06f;
144 static constexpr int numCombs = 8;
145 static constexpr int numAllPasses = 4;
150 CombFilter() noexcept {}
152 void setSize (
const int size)
154 assert (size <= buffer.size());
155 bufferIndex.changeLength (size);
160 void clear() noexcept
166 FloatType
process (FloatType input, FloatType damp, FloatType feedbackLevel)
noexcept
168 const auto ind = bufferIndex.get();
169 const FloatType output = buffer[ind];
170 last = (output * (1.0f - damp)) + (last * damp);
171 buffer[ind] = input + (last * feedbackLevel);
177 static constexpr int bufferAllocatedSize = (1617 + stereoSpread) * (MaximumSampleRate / 44100.0f);
178 std::array<FloatType, bufferAllocatedSize> buffer {};
187 AllPassFilter() noexcept {}
189 void setSize (
const int size)
196 void clear() noexcept
201 FloatType
process (FloatType input)
noexcept
203 const auto ind = bufferIndex.get();
204 const FloatType bufferedValue = buffer[ind];
205 buffer[ind] = input + (bufferedValue * 0.5f);
207 return bufferedValue - input;
211 static constexpr int bufferAllocatedSize = (556 + stereoSpread) * (MaximumSampleRate / 44100.0f);
212 std::array<FloatType, bufferAllocatedSize> buffer;
216 CombFilter comb[MaximumChannels][numCombs] {};
217 AllPassFilter allPass[MaximumChannels][numAllPasses] {};
218 LinearSmoothedValue<FloatType> dryWet { 0.5f, 100 };
219 FloatType damping {};
220 FloatType feedback {};
Some utilities functions.
A lightweight data structure that stores a pointer to an audio buffer.
Definition: ame_AudioBuffer.hpp:32
uint_fast32_t getNumChannels() const noexcept
Returns the number of channels.
Definition: ame_AudioBuffer.hpp:49
void applyGain(const float gain)
Applies a gain multiple to all the audio data.
Definition: ame_AudioBuffer.hpp:91
uint_fast32_t getNumSamplesPerChannel() const noexcept
Returns the number of samples per channel.
Definition: ame_AudioBuffer.hpp:55
A number to wrap between 0~length.
Definition: ame_Util.hpp:254
void changeLength(T newLength) noexcept
The number to automatically wrap in the range [0, length-1].
Definition: ame_Util.hpp:308
Reverb.
Definition: ame_Reverb.hpp:29
void setSampleRate(FloatType sampleRate)
Sets the sample rate that will be used for the reverb.
Definition: ame_Reverb.hpp:56
void process(AudioBlockView< FloatType, N > block)
Applies the reverb to two stereo channels of audio data.
Definition: ame_Reverb.hpp:109
void setDryWet(FloatType mix)
Dry/Wet balance.
Definition: ame_Reverb.hpp:84
void setRoomSize(FloatType roomSize, FloatType damp) noexcept
Room size and damping.
Definition: ame_Reverb.hpp:44
void reset()
Clears the reverb's buffers.
Definition: ame_Reverb.hpp:90