LMMS
Loading...
Searching...
No Matches
juce_Reverb.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
38class Reverb
39{
40public:
41 //==============================================================================
43 {
45 setSampleRate (44100.0);
46 }
47
48 //==============================================================================
51 {
52 float roomSize = 0.5f;
53 float damping = 0.5f;
54 float wetLevel = 0.33f;
55 float dryLevel = 0.4f;
56 float width = 1.0f;
57 float freezeMode = 0.0f;
59 };
60
61 //==============================================================================
64
69 void setParameters (const Parameters& newParams)
70 {
71 const float wetScaleFactor = 3.0f;
72 const float dryScaleFactor = 2.0f;
73
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));
78
79 gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f;
80 parameters = newParams;
82 }
83
84 //==============================================================================
88 void setSampleRate (const double sampleRate)
89 {
90 jassert (sampleRate > 0);
91
92 static const short combTunings[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }; // (at 44100Hz)
93 static const short allPassTunings[] = { 556, 441, 341, 225 };
94 const int stereoSpread = 23;
95 const int intSampleRate = (int) sampleRate;
96
97 for (int i = 0; i < numCombs; ++i)
98 {
99 comb[0][i].setSize ((intSampleRate * combTunings[i]) / 44100);
100 comb[1][i].setSize ((intSampleRate * (combTunings[i] + stereoSpread)) / 44100);
101 }
102
103 for (int i = 0; i < numAllPasses; ++i)
104 {
105 allPass[0][i].setSize ((intSampleRate * allPassTunings[i]) / 44100);
106 allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100);
107 }
108
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);
115 }
116
118 void reset()
119 {
120 for (int j = 0; j < numChannels; ++j)
121 {
122 for (int i = 0; i < numCombs; ++i)
123 comb[j][i].clear();
124
125 for (int i = 0; i < numAllPasses; ++i)
126 allPass[j][i].clear();
127 }
128 }
129
130 //==============================================================================
132 void processStereo (float* const left, float* const right, const int numSamples) noexcept
133 {
135 jassert (left != nullptr && right != nullptr);
136
137 for (int i = 0; i < numSamples; ++i)
138 {
139 const float input = (left[i] + right[i]) * gain;
140 float outL = 0, outR = 0;
141
142 const float damp = damping.getNextValue();
143 const float feedbck = feedback.getNextValue();
144
145 for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel
146 {
147 outL += comb[0][j].process (input, damp, feedbck);
148 outR += comb[1][j].process (input, damp, feedbck);
149 }
150
151 for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
152 {
153 outL = allPass[0][j].process (outL);
154 outR = allPass[1][j].process (outR);
155 }
156
157 const float dry = dryGain.getNextValue();
158 const float wet1 = wetGain1.getNextValue();
159 const float wet2 = wetGain2.getNextValue();
160
161 left[i] = outL * wet1 + outR * wet2 + left[i] * dry;
162 right[i] = outR * wet1 + outL * wet2 + right[i] * dry;
163 }
165 }
166
168 void processMono (float* const samples, const int numSamples) noexcept
169 {
171 jassert (samples != nullptr);
172
173 for (int i = 0; i < numSamples; ++i)
174 {
175 const float input = samples[i] * gain;
176 float output = 0;
177
178 const float damp = damping.getNextValue();
179 const float feedbck = feedback.getNextValue();
180
181 for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel
182 output += comb[0][j].process (input, damp, feedbck);
183
184 for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
185 output = allPass[0][j].process (output);
186
187 const float dry = dryGain.getNextValue();
188 const float wet1 = wetGain1.getNextValue();
189
190 samples[i] = output * wet1 + samples[i] * dry;
191 }
193 }
194
195private:
196 //==============================================================================
197 static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; }
198
200 {
201 const float roomScaleFactor = 0.28f;
202 const float roomOffset = 0.7f;
203 const float dampScaleFactor = 0.4f;
204
205 if (isFrozen (parameters.freezeMode))
206 setDamping (0.0f, 1.0f);
207 else
208 setDamping (parameters.damping * dampScaleFactor,
209 parameters.roomSize * roomScaleFactor + roomOffset);
210 }
211
212 void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept
213 {
214 damping.setTargetValue (dampingToUse);
215 feedback.setTargetValue (roomSizeToUse);
216 }
217
218 //==============================================================================
220 {
221 public:
223
224 void setSize (const int size)
225 {
226 if (size != bufferSize)
227 {
228 bufferIndex = 0;
229 buffer.malloc (size);
231 }
232
233 clear();
234 }
235
237 {
238 last = 0;
239 buffer.clear ((size_t) bufferSize);
240 }
241
242 float process (const float input, const float damp, const float feedbackLevel) noexcept
243 {
244 const float output = buffer[bufferIndex];
245 last = (output * (1.0f - damp)) + (last * damp);
247
248 float temp = input + (last * feedbackLevel);
249 JUCE_UNDENORMALISE (temp);
250 buffer[bufferIndex] = temp;
252 return output;
253 }
254
255 private:
258 float last = 0.0f;
259
261 };
262
263 //==============================================================================
265 {
266 public:
268
269 void setSize (const int size)
270 {
271 if (size != bufferSize)
272 {
273 bufferIndex = 0;
274 buffer.malloc (size);
276 }
277
278 clear();
279 }
280
282 {
283 buffer.clear ((size_t) bufferSize);
284 }
285
286 float process (const float input) noexcept
287 {
288 const float bufferedValue = buffer [bufferIndex];
289 float temp = input + (bufferedValue * 0.5f);
290 JUCE_UNDENORMALISE (temp);
291 buffer [bufferIndex] = temp;
293 return bufferedValue - input;
294 }
295
296 private:
299
301 };
302
303 //==============================================================================
304 enum { numCombs = 8, numAllPasses = 4, numChannels = 2 };
305
307 float gain;
308
311
313
315};
316
317} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
void process(Alg_seq_ptr seq, bool tempo_flag, double tempo, bool flatten_flag)
Definition allegroconvert.cpp:42
Definition juce_HeapBlock.h:87
Definition juce_Reverb.h:265
void clear() noexcept
Definition juce_Reverb.h:281
void setSize(const int size)
Definition juce_Reverb.h:269
AllPassFilter() noexcept
Definition juce_Reverb.h:267
float process(const float input) noexcept
Definition juce_Reverb.h:286
int bufferSize
Definition juce_Reverb.h:298
HeapBlock< float > buffer
Definition juce_Reverb.h:297
int bufferIndex
Definition juce_Reverb.h:298
Definition juce_Reverb.h:220
float last
Definition juce_Reverb.h:258
float process(const float input, const float damp, const float feedbackLevel) noexcept
Definition juce_Reverb.h:242
int bufferIndex
Definition juce_Reverb.h:257
CombFilter() noexcept
Definition juce_Reverb.h:222
HeapBlock< float > buffer
Definition juce_Reverb.h:256
int bufferSize
Definition juce_Reverb.h:257
void setSize(const int size)
Definition juce_Reverb.h:224
void clear() noexcept
Definition juce_Reverb.h:236
void processMono(float *const samples, const int numSamples) noexcept
Definition juce_Reverb.h:168
void reset()
Definition juce_Reverb.h:118
SmoothedValue< float > wetGain2
Definition juce_Reverb.h:312
SmoothedValue< float > dryGain
Definition juce_Reverb.h:312
void processStereo(float *const left, float *const right, const int numSamples) noexcept
Definition juce_Reverb.h:132
SmoothedValue< float > damping
Definition juce_Reverb.h:312
float gain
Definition juce_Reverb.h:307
void setParameters(const Parameters &newParams)
Definition juce_Reverb.h:69
SmoothedValue< float > wetGain1
Definition juce_Reverb.h:312
static bool isFrozen(const float freezeMode) noexcept
Definition juce_Reverb.h:197
Reverb()
Definition juce_Reverb.h:42
const Parameters & getParameters() const noexcept
Definition juce_Reverb.h:63
@ numChannels
Definition juce_Reverb.h:304
@ numAllPasses
Definition juce_Reverb.h:304
@ numCombs
Definition juce_Reverb.h:304
void setSampleRate(const double sampleRate)
Definition juce_Reverb.h:88
SmoothedValue< float > feedback
Definition juce_Reverb.h:312
void updateDamping() noexcept
Definition juce_Reverb.h:199
void setDamping(const float dampingToUse, const float roomSizeToUse) noexcept
Definition juce_Reverb.h:212
Parameters parameters
Definition juce_Reverb.h:306
CombFilter comb[numChannels][numCombs]
Definition juce_Reverb.h:309
AllPassFilter allPass[numChannels][numAllPasses]
Definition juce_Reverb.h:310
Definition juce_SmoothedValue.h:227
register unsigned j
Definition inflate.c:1576
register unsigned i
Definition inflate.c:1575
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 left
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 right
virtual ASIOError setSampleRate(ASIOSampleRate sampleRate)=0
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define JUCE_UNDENORMALISE(x)
Definition juce_MathsFunctions.h:613
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
Definition carla_juce.cpp:31
Definition juce_Reverb.h:51
float roomSize
Definition juce_Reverb.h:52
float width
Definition juce_Reverb.h:56
float dryLevel
Definition juce_Reverb.h:55
float wetLevel
Definition juce_Reverb.h:54
float freezeMode
Definition juce_Reverb.h:57
float damping
Definition juce_Reverb.h:53
ulg size
Definition extract.c:2350
typedef int(UZ_EXP MsgFn)()
#define const
Definition zconf.h:137