71 const float wetScaleFactor = 3.0f;
72 const float dryScaleFactor = 2.0f;
74 const float wet = newParams.
wetLevel * wetScaleFactor;
75 dryGain.setTargetValue (newParams.
dryLevel * dryScaleFactor);
76 wetGain1.setTargetValue (0.5f * wet * (1.0f + newParams.
width));
77 wetGain2.setTargetValue (0.5f * wet * (1.0f - newParams.
width));
79 gain = isFrozen (newParams.
freezeMode) ? 0.0f : 0.015f;
80 parameters = newParams;
90 jassert (sampleRate > 0);
92 static const short combTunings[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 };
93 static const short allPassTunings[] = { 556, 441, 341, 225 };
94 const int stereoSpread = 23;
95 const int intSampleRate = (int) sampleRate;
97 for (
int i = 0; i < numCombs; ++i)
99 comb[0][i].setSize ((intSampleRate * combTunings[i]) / 44100);
100 comb[1][i].setSize ((intSampleRate * (combTunings[i] + stereoSpread)) / 44100);
103 for (
int i = 0; i < numAllPasses; ++i)
105 allPass[0][i].setSize ((intSampleRate * allPassTunings[i]) / 44100);
106 allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100);
109 const double smoothTime = 0.01;
110 damping .reset (sampleRate, smoothTime);
111 feedback.reset (sampleRate, smoothTime);
112 dryGain .reset (sampleRate, smoothTime);
113 wetGain1.reset (sampleRate, smoothTime);
114 wetGain2.reset (sampleRate, smoothTime);
120 for (
int j = 0; j < numChannels; ++j)
122 for (
int i = 0; i < numCombs; ++i)
125 for (
int i = 0; i < numAllPasses; ++i)
126 allPass[j][i].clear();
132 void processStereo (
float*
const left,
float*
const right,
const int numSamples) noexcept
134 jassert (left !=
nullptr && right !=
nullptr);
136 for (
int i = 0; i < numSamples; ++i)
138 const float input = (left[i] + right[i]) * gain;
139 float outL = 0, outR = 0;
141 const float damp =
damping.getNextValue();
142 const float feedbck = feedback.getNextValue();
144 for (
int j = 0; j < numCombs; ++j)
146 outL += comb[0][j].process (input, damp, feedbck);
147 outR += comb[1][j].process (input, damp, feedbck);
150 for (
int j = 0; j < numAllPasses; ++j)
152 outL = allPass[0][j].process (outL);
153 outR = allPass[1][j].process (outR);
156 const float dry = dryGain.getNextValue();
157 const float wet1 = wetGain1.getNextValue();
158 const float wet2 = wetGain2.getNextValue();
160 left[i] = outL * wet1 + outR * wet2 + left[i] * dry;
161 right[i] = outR * wet1 + outL * wet2 + right[i] * dry;
166 void processMono (
float*
const samples,
const int numSamples) noexcept
168 jassert (samples !=
nullptr);
170 for (
int i = 0; i < numSamples; ++i)
172 const float input = samples[i] * gain;
175 const float damp =
damping.getNextValue();
176 const float feedbck = feedback.getNextValue();
178 for (
int j = 0; j < numCombs; ++j)
179 output += comb[0][j].process (input, damp, feedbck);
181 for (
int j = 0; j < numAllPasses; ++j)
182 output = allPass[0][j].process (output);
184 const float dry = dryGain.getNextValue();
185 const float wet1 = wetGain1.getNextValue();
187 samples[i] = output * wet1 + samples[i] * dry;
193 static bool isFrozen (
const float freezeMode) noexcept {
return freezeMode >= 0.5f; }
195 void updateDamping() noexcept
197 const float roomScaleFactor = 0.28f;
198 const float roomOffset = 0.7f;
199 const float dampScaleFactor = 0.4f;
201 if (isFrozen (parameters.freezeMode))
202 setDamping (0.0f, 1.0f);
204 setDamping (parameters.damping * dampScaleFactor,
205 parameters.roomSize * roomScaleFactor + roomOffset);
208 void setDamping (
const float dampingToUse,
const float roomSizeToUse) noexcept
210 damping.setTargetValue (dampingToUse);
211 feedback.setTargetValue (roomSizeToUse);
218 CombFilter() noexcept {}
220 void setSize (
const int size)
222 if (size != bufferSize)
225 buffer.malloc (size);
232 void clear() noexcept
235 buffer.clear ((
size_t) bufferSize);
238 float process (
const float input,
const float damp,
const float feedbackLevel) noexcept
240 const float output = buffer[bufferIndex];
241 last = (output * (1.0f - damp)) + (last * damp);
242 JUCE_UNDENORMALISE (last);
244 float temp = input + (last * feedbackLevel);
245 JUCE_UNDENORMALISE (temp);
246 buffer[bufferIndex] = temp;
247 bufferIndex = (bufferIndex + 1) % bufferSize;
253 int bufferSize = 0, bufferIndex = 0;
256 JUCE_DECLARE_NON_COPYABLE (CombFilter)
263 AllPassFilter() noexcept {}
265 void setSize (
const int size)
267 if (size != bufferSize)
270 buffer.malloc (size);
277 void clear() noexcept
279 buffer.clear ((
size_t) bufferSize);
282 float process (
const float input) noexcept
284 const float bufferedValue = buffer [bufferIndex];
285 float temp = input + (bufferedValue * 0.5f);
286 JUCE_UNDENORMALISE (temp);
287 buffer [bufferIndex] = temp;
288 bufferIndex = (bufferIndex + 1) % bufferSize;
289 return bufferedValue - input;
294 int bufferSize = 0, bufferIndex = 0;
296 JUCE_DECLARE_NON_COPYABLE (AllPassFilter)
300 enum { numCombs = 8, numAllPasses = 4, numChannels = 2 };
305 CombFilter comb [numChannels][numCombs];
306 AllPassFilter allPass [numChannels][numAllPasses];
310 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
Reverb)
void processStereo(float *const left, float *const right, const int numSamples) noexcept
const Parameters & getParameters() const noexcept
void setSampleRate(const double sampleRate)
void processMono(float *const samples, const int numSamples) noexcept
void setParameters(const Parameters &newParams)