1 /**
2 * Simple FDN Reverb based on zita-rev1
3 *
4 * Copyright (C) 2003-2010 Fons Adriaensen <fons@linuxaudio.org>
5 * Copyright (C) 2006-2018 Teru Kamogashira
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "freeverb/zrev2.hpp"
23 #include "freeverb/fv3_type_float.h"
24 #include "freeverb/fv3_ns_start.h"
25
26 // Fs = 34.125 kHz
27 const long FV3_(zrev2)::iAllpassLCo[] = {617, 535, 434, 347, 218, 162, 144, 122, 109, 74,};
28 const long FV3_(zrev2)::iAllpassRCo[] = {603, 547, 416, 364, 236, 162, 140, 131, 111, 79,};
29 const long FV3_(zrev2)::allpM_EXCURSION = 32;
30
FV3_(zrev2)31 FV3_(zrev2)::FV3_(zrev2)()
32 throw(std::bad_alloc)
33 {
34 rt60 = 2.0;
35 rt60_f_low = 1.3;
36 rt60_f_high = 0.3;
37 rt60_xo_low = 500;
38 rt60_xo_high = 3600;
39 idiff1 = 0.78;
40 wander_ms = 22;
41 spin_fq = 2.4;
42 spin_factor = 0.3;
43
44 setFsFactors();
45 }
46
FV3_(zrev2)47 void FV3_(zrev2)::mute()
48 {
49 FV3_(zrev)::mute();
50 for(long i = 0;i < FV3_ZREV_NUM_DELAYS;i ++){ _lsf0[i].mute(); _hsf0[i].mute(); }
51 for(long i = 0;i < FV3_ZREV2_NUM_IALLPASS;i ++){ iAllpassL[i].mute(); iAllpassR[i].mute(); }
52 spin1_lfo.mute(); spin1_lpf.mute(); spincombl.mute(); spincombr.mute();
53 }
54
FV3_(zrev2)55 void FV3_(zrev2)::processreplace(fv3_float_t *inputL, fv3_float_t *inputR, fv3_float_t *outputL, fv3_float_t *outputR, long numsamples)
56 throw(std::bad_alloc)
57 {
58 switch(reverbType)
59 {
60 case FV3_REVTYPE_ZREV:
61 FV3_(zrev)::processreplace(inputL, inputR, outputL, outputR, numsamples);
62 return;
63 case FV3_REVTYPE_SELF:
64 case FV3_REVTYPE_ZREV2:
65 default:
66 ;
67 }
68
69 if(numsamples <= 0) return;
70 long count = numsamples;
71
72 fv3_float_t outL, outR;
73
74 while(count-- > 0)
75 {
76 fv3_float_t lfo1q = lfo1_lpf(lfo1()*lfofactor);
77 fv3_float_t lfo2q = lfo2_lpf(lfo2()*lfofactor);
78 // if(lfo1q < -1.) lfo1q = -1.; if(lfo1q > 1.) lfo1q = 1.;
79 // if(lfo2q < -1.) lfo2q = -1.; if(lfo2q > 1.) lfo2q = 1.;
80 fv3_float_t lfo1p = -1 * lfo1q;
81 fv3_float_t lfo2p = -1 * lfo2q;
82
83 outL = dccutL(*inputL); outR = dccutR(*inputR);
84
85 // input diffusion
86 fv3_float_t i_sign = -1;
87 for(long i = 0;i < FV3_ZREV2_NUM_IALLPASS;i ++)
88 {
89 outL = iAllpassL[i]._process(outL, lfo1q*i_sign);
90 outR = iAllpassR[i]._process(outR, lfo2p*i_sign);
91 i_sign *= -1;
92 }
93
94 fv3_float_t t, x0, x1, x2, x3, x4, x5, x6, x7;
95 t = outL;
96 x0 = _diff1[0]._process(_lsf0[0](_hsf0[0](_delay[0]._getlast() + t)), lfo1q);
97 x1 = _diff1[1]._process(_lsf0[1](_hsf0[1](_delay[1]._getlast() + t)), lfo1p);
98 x2 = _diff1[2]._process(_lsf0[2](_hsf0[2](_delay[2]._getlast() - t)), lfo1q);
99 x3 = _diff1[3]._process(_lsf0[3](_hsf0[3](_delay[3]._getlast() - t)), lfo1p);
100 t = outR;
101 x4 = _diff1[4]._process(_lsf0[4](_hsf0[4](_delay[4]._getlast() + t)), lfo2p);
102 x5 = _diff1[5]._process(_lsf0[5](_hsf0[5](_delay[5]._getlast() + t)), lfo2q);
103 x6 = _diff1[6]._process(_lsf0[6](_hsf0[6](_delay[6]._getlast() - t)), lfo2p);
104 x7 = _diff1[7]._process(_lsf0[7](_hsf0[7](_delay[7]._getlast() - t)), lfo2q);
105
106 t = x0 - x1; x0 += x1; x1 = t;
107 t = x2 - x3; x2 += x3; x3 = t;
108 t = x4 - x5; x4 += x5; x5 = t;
109 t = x6 - x7; x6 += x7; x7 = t;
110 t = x0 - x2; x0 += x2; x2 = t;
111 t = x1 - x3; x1 += x3; x3 = t;
112 t = x4 - x6; x4 += x6; x6 = t;
113 t = x5 - x7; x5 += x7; x7 = t;
114 t = x0 - x4; x0 += x4; x4 = t;
115 t = x1 - x5; x1 += x5; x5 = t;
116 t = x2 - x6; x2 += x6; x6 = t;
117 t = x3 - x7; x3 += x7; x7 = t;
118
119 _delay[0]._process(x0, lfo2q);
120 _delay[1]._process(x1, lfo1q);
121 _delay[2]._process(x2, lfo2p);
122 _delay[3]._process(x3, lfo1p);
123 _delay[4]._process(x4, lfo1p);
124 _delay[5]._process(x5, lfo2q);
125 _delay[6]._process(x6, lfo1p);
126 _delay[7]._process(x7, lfo2q);
127
128 outL = .2*(x0 - x1 + x2 - x3);
129 outR = .2*(x4 + x5 - x6 - x7);
130
131 fv3_float_t spinlfo = spin1_lpf(spin1_lfo()*spin_factor);
132 outL = spincombl._process_ff(outL, spinlfo);
133 outR = spincombr._process_ff(outR, spinlfo*-1);
134
135 fv3_float_t fpL = delayWL(out1_lpf(out1_hpf(outL)));
136 fv3_float_t fpR = delayWR(out2_lpf(out2_hpf(outR)));
137 *outputL = fpL*wet1 + fpR*wet2 + delayL(*inputL)*dry;
138 *outputR = fpR*wet1 + fpL*wet2 + delayR(*inputR)*dry;
139 UNDENORMAL(*outputL); UNDENORMAL(*outputR);
140 inputL ++; inputR ++; outputL ++; outputR ++;
141 }
142 }
143
FV3_(zrev2)144 void FV3_(zrev2)::setrt60(fv3_float_t value)
145 {
146 rt60 = value;
147 fv3_float_t gain = std::sqrt(1./(fv3_float_t)FV3_ZREV_NUM_DELAYS);
148 fv3_float_t back = rt60 * getTotalSampleRate();
149 if(rt60 <= 0){ gain = 0; back = 1; }
150 for(long i = 0;i < FV3_ZREV_NUM_DELAYS;i ++)
151 {
152 _delay[i].setfeedback(gain*std::pow((fv3_float_t)10, (fv3_float_t)-3. * (fv3_float_t)(_delay[i].getsize() + _diff1[i].getsize()) / back));
153 _lsf0[i].setLSF_RBJ(rt60_xo_low,
154 FV3_(utils)::R2dB(std::pow((fv3_float_t)10, (fv3_float_t)-3. * (fv3_float_t)(_delay[i].getsize() + _diff1[i].getsize())
155 / back / rt60_f_low * (1 - rt60_f_low))),
156 1, getTotalSampleRate());
157 _hsf0[i].setHSF_RBJ(rt60_xo_high,
158 FV3_(utils)::R2dB(std::pow((fv3_float_t)10, (fv3_float_t)-3. * (fv3_float_t)(_delay[i].getsize() + _diff1[i].getsize())
159 / back / rt60_f_high * (1 - rt60_f_high))),
160 1, getTotalSampleRate());
161 }
162 }
163
FV3_(zrev2)164 void FV3_(zrev2)::setrt60_factor_low(fv3_float_t gain)
165 {
166 rt60_f_low = gain;
167 setrt60(getrt60());
168 }
169
FV3_(zrev2)170 fv3_float_t FV3_(zrev2)::getrt60_factor_low() const
171 {
172 return rt60_f_low;
173 }
174
FV3_(zrev2)175 void FV3_(zrev2)::setrt60_factor_high(fv3_float_t gain)
176 {
177 rt60_f_high = gain;
178 setrt60(getrt60());
179 }
180
FV3_(zrev2)181 fv3_float_t FV3_(zrev2)::getrt60_factor_high() const
182 {
183 return rt60_f_high;
184 }
185
FV3_(zrev2)186 void FV3_(zrev2)::setloopdamp(fv3_float_t value)
187 {
188 setxover_high(value);
189 }
190
FV3_(zrev2)191 void FV3_(zrev2)::setxover_low(fv3_float_t fc)
192 {
193 rt60_xo_low = limFs2(fc);
194 setrt60(getrt60());
195 }
196
FV3_(zrev2)197 fv3_float_t FV3_(zrev2)::getxover_low() const
198 {
199 return rt60_xo_low;
200 }
201
FV3_(zrev2)202 void FV3_(zrev2)::setxover_high(fv3_float_t fc)
203 {
204 FV3_(zrev)::setloopdamp(fc);
205 rt60_xo_high = limFs2(fc);
206 setrt60(getrt60());
207 }
208
FV3_(zrev2)209 fv3_float_t FV3_(zrev2)::getxover_high() const
210 {
211 return rt60_xo_high;
212 }
213
FV3_(zrev2)214 void FV3_(zrev2)::setidiffusion1(fv3_float_t value)
215 {
216 idiff1 = value;
217 for(long i = 0;i < FV3_ZREV2_NUM_IALLPASS;i ++)
218 {
219 iAllpassL[i].setfeedback(-1.*idiff1);
220 iAllpassR[i].setfeedback(-1.*idiff1);
221 }
222 }
223
FV3_(zrev2)224 fv3_float_t FV3_(zrev2)::getidiffusion1() const
225 {
226 return idiff1;
227 }
228
FV3_(zrev2)229 void FV3_(zrev2)::setwander(fv3_float_t ms)
230 {
231 if(ms < 0) ms = 0;
232 wander_ms = ms;
233 spincombl.setsize(p_(wander_ms, getTotalSampleRate()*0.001));
234 spincombr.setsize(p_(wander_ms, getTotalSampleRate()*0.001));
235 }
236
FV3_(zrev2)237 fv3_float_t FV3_(zrev2)::getwander() const
238 {
239 return wander_ms;
240 }
241
FV3_(zrev2)242 void FV3_(zrev2)::setspin(fv3_float_t fq)
243 {
244 spin1_lfo.setFreq((spin_fq = limFs2(fq)), getTotalSampleRate());
245 spin1_lpf.setLPF_BW(spin_fq, getTotalSampleRate());
246 }
247
FV3_(zrev2)248 fv3_float_t FV3_(zrev2)::getspin() const { return spin_fq; }
249
FV3_(zrev2)250 void FV3_(zrev2)::setspinfactor(fv3_float_t value){ spin_factor = value; }
251
FV3_(zrev2)252 fv3_float_t FV3_(zrev2)::getspinfactor(){ return spin_factor; }
253
FV3_(zrev2)254 void FV3_(zrev2)::setFsFactors()
255 {
256 FV3_(zrev)::setFsFactors();
257 fv3_float_t totalFactor = getTotalFactorFs()/(fv3_float_t)FV3_ZREV2_ALLPASS_FS;
258 fv3_float_t excurFactor = getTotalSampleRate()/(fv3_float_t)FV3_ZREV2_ALLPASS_FS;
259
260 for(long i = 0;i < FV3_ZREV2_NUM_IALLPASS;i ++)
261 {
262 iAllpassL[i].setsize(p_(iAllpassLCo[i],totalFactor), p_(allpM_EXCURSION/3,excurFactor));
263 iAllpassR[i].setsize(p_(iAllpassRCo[i],totalFactor), p_(allpM_EXCURSION/3,excurFactor));
264 }
265
266 setrt60(getrt60());
267 setxover_low(getxover_low());
268 setxover_high(getxover_high());
269 setidiffusion1(getidiffusion1());
270 setwander(getwander());
271 setspin(getspin());
272 }
273
274 #include "freeverb/fv3_ns_end.h"
275