Add TAL-Reverb-II plugin to test
[juce-lv2.git] / tal-reverb-2-juce / src / Engine / Reverb.h
bloba70de5e969805ab9964ccc32289e8472ed7f5171
1 /*
2 ==============================================================================
3 This file is part of Tal-Reverb by Patrick Kunz.
5 Copyright(c) 2005-2009 Patrick Kunz, TAL
6 Togu Audio Line, Inc.
7 http://kunz.corrupt.ch
9 This file may be licensed under the terms of of the
10 GNU General Public License Version 2 (the ``GPL'').
12 Software distributed under the License is distributed
13 on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14 express or implied. See the GPL for the specific language
15 governing rights and limitations.
17 You should have received a copy of the GPL along with this
18 program. If not, go to http://www.gnu.org/licenses/gpl.html
19 or write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 ==============================================================================
25 #if !defined(__TalReverb_h)
26 #define __TalReverb_h
28 #include "AllPassFilter.h"
29 #include "CombFilter.h"
30 #include "NoiseGenerator.h"
31 #include "Filter.h"
32 #include "Math.h"
33 #include "AudioUtils.h"
34 #include "TalEq.h"
36 class TalReverb
38 private:
39 static const int DELAY_LINES_COMB = 4;
40 static const int DELAY_LINES_ALLPASS = 5;
42 static const int MAX_PRE_DELAY_MS = 1000;
43 float* reflectionGains;
44 float* reflectionDelays;
46 CombFilter *combFiltersPreDelayL;
47 CombFilter *combFiltersPreDelayR;
49 CombFilter **combFiltersL;
50 CombFilter **combFiltersR;
51 NoiseGenerator **noiseGeneratorAllPassL;
52 NoiseGenerator **noiseGeneratorAllPassR;
53 NoiseGenerator **noiseGeneratorDelayL;
54 NoiseGenerator **noiseGeneratorDelayR;
55 NoiseGenerator **diffusionL;
56 NoiseGenerator **diffusionR;
58 AllPassFilter **allPassFiltersL;
59 AllPassFilter **allPassFiltersR;
61 AllPassFilter *preAllPassFilterL;
62 AllPassFilter *preAllPassFilterR;
64 AllPassFilter *postAllPassFilterL;
65 AllPassFilter *postAllPassFilterR;
67 TalEq* talEqL;
68 TalEq* talEqR;
70 float decayTime;
71 float preDelayTime;
72 bool stereoMode;
73 float modulationIntensity;
75 float outL;
76 float outR;
78 AudioUtils audioUtils;
80 public:
81 TalReverb(int sampleRate)
83 createDelaysAndCoefficients(DELAY_LINES_COMB + DELAY_LINES_ALLPASS, 82.0f);
85 combFiltersPreDelayL = new CombFilter((float)MAX_PRE_DELAY_MS, 0.0f, sampleRate);
86 combFiltersPreDelayR = new CombFilter((float)MAX_PRE_DELAY_MS, 0.0f, sampleRate);
88 combFiltersL = new CombFilter *[DELAY_LINES_COMB];
89 combFiltersR = new CombFilter *[DELAY_LINES_COMB];
90 noiseGeneratorAllPassL = new NoiseGenerator *[DELAY_LINES_COMB];
91 noiseGeneratorAllPassR = new NoiseGenerator *[DELAY_LINES_COMB];
92 noiseGeneratorDelayL = new NoiseGenerator *[DELAY_LINES_COMB];
93 noiseGeneratorDelayR = new NoiseGenerator *[DELAY_LINES_COMB];
94 diffusionL = new NoiseGenerator *[DELAY_LINES_COMB];
95 diffusionR = new NoiseGenerator *[DELAY_LINES_COMB];
97 float stereoSpreadValue = 0.008f;
98 float stereoSpreadSign = 1.0f;
99 for (int i = 0; i < DELAY_LINES_COMB; i++)
101 float stereoSpreadFactor = 1.0f + stereoSpreadValue;
102 if (stereoSpreadSign > 0.0f)
104 combFiltersL[i] = new CombFilter(reflectionDelays[i] * stereoSpreadFactor, reflectionGains[i], sampleRate);
105 combFiltersR[i] = new CombFilter(reflectionDelays[i], reflectionGains[i], sampleRate);
107 else
109 combFiltersL[i] = new CombFilter(reflectionDelays[i], reflectionGains[i], sampleRate);
110 combFiltersR[i] = new CombFilter(reflectionDelays[i] * stereoSpreadFactor, reflectionGains[i], sampleRate);
112 stereoSpreadSign *= -1.0f;
113 noiseGeneratorAllPassL[i] = new NoiseGenerator(sampleRate);
114 noiseGeneratorAllPassR[i] = new NoiseGenerator(sampleRate);
115 noiseGeneratorDelayL[i] = new NoiseGenerator(sampleRate);
116 noiseGeneratorDelayR[i] = new NoiseGenerator(sampleRate);
117 diffusionL[i] = new NoiseGenerator(sampleRate);
118 diffusionR[i] = new NoiseGenerator(sampleRate);
121 preAllPassFilterL = new AllPassFilter(20.0f, 0.68f, sampleRate);
122 preAllPassFilterR = new AllPassFilter(20.0f, 0.68f, sampleRate);
124 postAllPassFilterL = new AllPassFilter(200.0f, 0.68f, sampleRate);
125 postAllPassFilterR = new AllPassFilter(200.0f, 0.68f, sampleRate);
127 allPassFiltersL = new AllPassFilter *[DELAY_LINES_ALLPASS];
128 allPassFiltersR = new AllPassFilter *[DELAY_LINES_ALLPASS];
129 for (int i = 0; i < DELAY_LINES_ALLPASS; i++)
131 allPassFiltersL[i] = new AllPassFilter(reflectionDelays[i + DELAY_LINES_COMB - 1] * 0.105f, 0.68f, sampleRate);
132 allPassFiltersR[i] = new AllPassFilter(reflectionDelays[i + DELAY_LINES_COMB - 1] * 0.1f, 0.68f, sampleRate);
135 talEqL = new TalEq(sampleRate);
136 talEqR = new TalEq(sampleRate);
138 decayTime = 0.5f;
139 preDelayTime = 0.0f;
140 modulationIntensity = 0.12f;
141 stereoMode = false;
143 outL = 0.0f;
144 outR = 0.0f;
147 ~TalReverb()
149 delete[] reflectionGains;
150 delete[] reflectionDelays;
152 delete combFiltersPreDelayL;
153 delete combFiltersPreDelayR;
155 for (int i = 0; i < DELAY_LINES_COMB; i++) delete combFiltersL[i];
156 delete[] combFiltersL;
157 for (int i = 0; i < DELAY_LINES_COMB; i++) delete combFiltersR[i];
158 delete[] combFiltersR;
160 for (int i = 0; i < DELAY_LINES_ALLPASS; i++) delete allPassFiltersL[i];
161 delete[] allPassFiltersL;
162 for (int i = 0; i < DELAY_LINES_ALLPASS; i++) delete allPassFiltersR[i];
163 delete[] allPassFiltersR;
165 for (int i = 0; i < DELAY_LINES_COMB; i++) delete noiseGeneratorAllPassL[i];
166 delete[] noiseGeneratorAllPassL;
167 for (int i = 0; i < DELAY_LINES_COMB; i++) delete noiseGeneratorAllPassR[i];
168 delete[] noiseGeneratorAllPassR;
169 for (int i = 0; i < DELAY_LINES_COMB; i++) delete noiseGeneratorDelayL[i];
170 delete[] noiseGeneratorDelayL;
171 for (int i = 0; i < DELAY_LINES_COMB; i++) delete noiseGeneratorDelayR[i];
172 delete[] noiseGeneratorDelayR;
174 for (int i = 0; i < DELAY_LINES_COMB; i++) delete diffusionL[i];
175 delete[] diffusionL;
176 for (int i = 0; i < DELAY_LINES_COMB; i++) delete diffusionR[i];
177 delete[] diffusionR;
179 delete preAllPassFilterL;
180 delete preAllPassFilterR;
182 delete postAllPassFilterL;
183 delete postAllPassFilterR;
185 delete talEqL;
186 delete talEqR;
190 void setDecayTime(float decayTime)
192 this->decayTime = audioUtils.getLogScaledValueInverted(decayTime) * 0.99f;
195 void setPreDelay(float preDelayTime)
197 this->preDelayTime = audioUtils.getLogScaledValue(preDelayTime);
200 void setStereoMode(bool stereoMode)
202 this->stereoMode = stereoMode;
205 void setLowShelfGain(float lowShelfGain)
207 talEqL->setLowShelfGain(lowShelfGain);
208 talEqR->setLowShelfGain(lowShelfGain);
211 void setHighShelfGain(float highShelfGain)
213 talEqL->setHighShelfGain(highShelfGain);
214 talEqR->setHighShelfGain(highShelfGain);
217 void setLowShelfFrequency(float lowShelfFrequency)
219 talEqL->setLowShelfFrequency(lowShelfFrequency);
220 talEqR->setLowShelfFrequency(lowShelfFrequency);
223 void setHighShelfFrequency(float highShelfFrequency)
225 talEqL->setHighShelfFrequency(highShelfFrequency);
226 talEqR->setHighShelfFrequency(highShelfFrequency);
229 void setPeakFrequency(float peakFrequency)
231 talEqL->setPeakFrequency(peakFrequency);
232 talEqR->setPeakFrequency(peakFrequency);
235 void setPeakGain(float peakGain)
237 talEqL->setPeakGain(peakGain);
238 talEqR->setPeakGain(peakGain);
241 // All input values [0..1]
242 inline void process(float* sampleL, float* sampleR)
244 float revR;
245 float revL;
247 if (!stereoMode)
249 revL = (*sampleL + *sampleR) * 0.25f;
250 revL = combFiltersPreDelayL->process(revL, 0.0f, 0.0f, preDelayTime);
251 talEqL->process(&revL);
252 revR = revL;
254 else
256 revL = combFiltersPreDelayL->process(*sampleL * 0.5f, 0.0f, 0.0f, preDelayTime);
257 revR = combFiltersPreDelayL->process(*sampleR * 0.5f, 0.0f, 0.0f, preDelayTime);
258 talEqL->process(&revL);
259 talEqR->process(&revR);
262 // ----------------- Comb Filter --------------------
263 outL = 0.0f;
264 outR = 0.0f;
266 float scaledRoomSize = decayTime * 0.998f;
267 float sign = 1.0f;
268 for (int i = 0; i < DELAY_LINES_COMB; i++)
270 outL += sign * combFiltersL[i]->processInterpolated(revL, diffusionL[i]->tickFilteredNoiseFast() * 0.2f, scaledRoomSize, scaledRoomSize + 0.012f * noiseGeneratorDelayL[i]->tickFilteredNoise());
271 outR += sign * combFiltersR[i]->processInterpolated(revR, diffusionR[i]->tickFilteredNoiseFast() * 0.2f, scaledRoomSize, scaledRoomSize + 0.012f * noiseGeneratorDelayR[i]->tickFilteredNoise());
272 sign *= -1.0f;
275 // ----------------- Pre AllPass --------------------
276 outL += 0.5f * preAllPassFilterL->processInterpolated(revR, 0.6f + 0.4f * noiseGeneratorAllPassL[0]->tickFilteredNoise(), 0.99f, true);
277 outR += 0.5f * preAllPassFilterR->processInterpolated(revL, 0.6f + 0.4f * noiseGeneratorAllPassR[0]->tickFilteredNoise(), 0.99f, true);
279 //// ----------------- Post AllPass --------------------
280 outL += 0.45f * postAllPassFilterL->processInterpolated(revL, 0.8f + 0.2f * noiseGeneratorAllPassL[1]->tickFilteredNoise(), 0.7f, true);
281 outR += 0.45f * postAllPassFilterR->processInterpolated(revR, 0.8f + 0.2f * noiseGeneratorAllPassR[1]->tickFilteredNoise(), 0.7f, true);
283 // ----------------- AllPass Filter ------------------
284 for (int i = 0; i < DELAY_LINES_ALLPASS; i++)
286 outL = allPassFiltersL[i]->process(outL);
287 outR = allPassFiltersR[i]->process(outR);
290 // ----------------- Write to output / Stereo --------
291 *sampleL = outL;
292 *sampleR = outR;
295 void createDelaysAndCoefficients(int numlines, float delayLength)
297 reflectionDelays = new float[numlines];
298 reflectionGains = new float[numlines];
300 float volumeScale = (float)(-3.0 * delayLength / log10f(0.5f));
301 for (int n = numlines - 1; n >= 0; n--)
303 reflectionDelays[numlines -1 - n] = delayLength / powf(2.0f, (float)n / numlines);
304 reflectionGains[numlines -1 - n] = powf(10.0f, - (3.0f * reflectionDelays[numlines -1 - n]) / volumeScale);
308 #endif