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