75 const float wetScaleFactor = 3.0f;
76 const float dryScaleFactor = 2.0f;
78 const float wet = newParams.
wetLevel * wetScaleFactor;
79 dryGain.setTargetValue (newParams.
dryLevel * dryScaleFactor);
80 wetGain1.setTargetValue (0.5f * wet * (1.0f + newParams.
width));
81 wetGain2.setTargetValue (0.5f * wet * (1.0f - newParams.
width));
83 gain = isFrozen (newParams.
freezeMode) ? 0.0f : 0.015f;
84 parameters = newParams;
94 jassert (sampleRate > 0);
96 static const short combTunings[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 };
97 static const short allPassTunings[] = { 556, 441, 341, 225 };
98 const int stereoSpread = 23;
99 const int intSampleRate = (int) sampleRate;
101 for (
int i = 0; i < numCombs; ++i)
103 comb[0][i].setSize ((intSampleRate * combTunings[i]) / 44100);
104 comb[1][i].setSize ((intSampleRate * (combTunings[i] + stereoSpread)) / 44100);
107 for (
int i = 0; i < numAllPasses; ++i)
109 allPass[0][i].setSize ((intSampleRate * allPassTunings[i]) / 44100);
110 allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100);
113 const double smoothTime = 0.01;
114 damping .reset (sampleRate, smoothTime);
115 feedback.reset (sampleRate, smoothTime);
116 dryGain .reset (sampleRate, smoothTime);
117 wetGain1.reset (sampleRate, smoothTime);
118 wetGain2.reset (sampleRate, smoothTime);
124 for (
int j = 0; j < numChannels; ++j)
126 for (
int i = 0; i < numCombs; ++i)
129 for (
int i = 0; i < numAllPasses; ++i)
130 allPass[j][i].clear();
136 void processStereo (
float*
const left,
float*
const right,
const int numSamples) noexcept
138 jassert (left !=
nullptr && right !=
nullptr);
140 for (
int i = 0; i < numSamples; ++i)
142 const float input = (left[i] + right[i]) * gain;
143 float outL = 0, outR = 0;
145 const float damp =
damping.getNextValue();
146 const float feedbck = feedback.getNextValue();
148 for (
int j = 0; j < numCombs; ++j)
150 outL += comb[0][j].process (input, damp, feedbck);
151 outR += comb[1][j].process (input, damp, feedbck);
154 for (
int j = 0; j < numAllPasses; ++j)
156 outL = allPass[0][j].process (outL);
157 outR = allPass[1][j].process (outR);
160 const float dry = dryGain.getNextValue();
161 const float wet1 = wetGain1.getNextValue();
162 const float wet2 = wetGain2.getNextValue();
164 left[i] = outL * wet1 + outR * wet2 + left[i] * dry;
165 right[i] = outR * wet1 + outL * wet2 + right[i] * dry;
170 void processMono (
float*
const samples,
const int numSamples) noexcept
172 jassert (samples !=
nullptr);
174 for (
int i = 0; i < numSamples; ++i)
176 const float input = samples[i] * gain;
179 const float damp =
damping.getNextValue();
180 const float feedbck = feedback.getNextValue();
182 for (
int j = 0; j < numCombs; ++j)
183 output += comb[0][j].process (input, damp, feedbck);
185 for (
int j = 0; j < numAllPasses; ++j)
186 output = allPass[0][j].process (output);
188 const float dry = dryGain.getNextValue();
189 const float wet1 = wetGain1.getNextValue();
191 samples[i] = output * wet1 + samples[i] * dry;
197 static bool isFrozen (
const float freezeMode) noexcept {
return freezeMode >= 0.5f; }
199 void updateDamping() noexcept
201 const float roomScaleFactor = 0.28f;
202 const float roomOffset = 0.7f;
203 const float dampScaleFactor = 0.4f;
205 if (isFrozen (parameters.freezeMode))
206 setDamping (0.0f, 1.0f);
208 setDamping (parameters.damping * dampScaleFactor,
209 parameters.roomSize * roomScaleFactor + roomOffset);
212 void setDamping (
const float dampingToUse,
const float roomSizeToUse) noexcept
214 damping.setTargetValue (dampingToUse);
215 feedback.setTargetValue (roomSizeToUse);
222 CombFilter() noexcept {}
224 void setSize (
const int size)
226 if (size != bufferSize)
229 buffer.malloc (size);
236 void clear() noexcept
239 buffer.clear ((
size_t) bufferSize);
242 float process (
const float input,
const float damp,
const float feedbackLevel) noexcept
244 const float output = buffer[bufferIndex];
245 last = (output * (1.0f - damp)) + (last * damp);
246 JUCE_UNDENORMALISE (last);
248 float temp = input + (last * feedbackLevel);
249 JUCE_UNDENORMALISE (temp);
250 buffer[bufferIndex] = temp;
251 bufferIndex = (bufferIndex + 1) % bufferSize;
257 int bufferSize = 0, bufferIndex = 0;
260 JUCE_DECLARE_NON_COPYABLE (CombFilter)
267 AllPassFilter() noexcept {}
269 void setSize (
const int size)
271 if (size != bufferSize)
274 buffer.malloc (size);
281 void clear() noexcept
283 buffer.clear ((
size_t) bufferSize);
286 float process (
const float input) noexcept
288 const float bufferedValue = buffer [bufferIndex];
289 float temp = input + (bufferedValue * 0.5f);
290 JUCE_UNDENORMALISE (temp);
291 buffer [bufferIndex] = temp;
292 bufferIndex = (bufferIndex + 1) % bufferSize;
293 return bufferedValue - input;
298 int bufferSize = 0, bufferIndex = 0;
300 JUCE_DECLARE_NON_COPYABLE (AllPassFilter)
304 enum { numCombs = 8, numAllPasses = 4, numChannels = 2 };
309 CombFilter comb [numChannels][numCombs];
310 AllPassFilter allPass [numChannels][numAllPasses];
314 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
Reverb)
float roomSize
Room size, 0 to 1.0, where 1.0 is big, 0 is small.
void processStereo(float *const left, float *const right, const int numSamples) noexcept
Applies the reverb to two stereo channels of audio data.
const Parameters & getParameters() const noexcept
Returns the reverb's current parameters.
float width
Reverb width, 0 to 1.0, where 1.0 is very wide.
float freezeMode
Freeze mode - values < 0.5 are "normal" mode, values > 0.5 put the reverb into a continuous feedback ...
void setSampleRate(const double sampleRate)
Sets the sample rate that will be used for the reverb.
float damping
Damping, 0 to 1.0, where 0 is not damped, 1.0 is fully damped.
float dryLevel
Dry level, 0 to 1.0.
Performs a simple reverb effect on a stream of audio data.
void processMono(float *const samples, const int numSamples) noexcept
Applies the reverb to a single mono channel of audio data.
void reset()
Clears the reverb's buffers.
void setParameters(const Parameters &newParams)
Applies a new set of parameters to the reverb.
float wetLevel
Wet level, 0 to 1.0.
Holds the parameters being used by a Reverb object.