1 /**
2  *  Stereo Enhancer
3  *
4  *  Copyright (C) 2006-2018 Teru Kamogashira
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include "freeverb/stenh.hpp"
22 #include "freeverb/fv3_type_float.h"
23 #include "freeverb/fv3_ns_start.h"
24 
FV3_(stenh)25 FV3_(stenh)::FV3_(stenh)()
26 	    throw(std::bad_alloc)
27 {
28   currentfs = FV3_REVBASE_DEFAULT_FS;
29   RMS = Attack = Release = 0; Ratio = 3; SoftKnee = 10;
30   DepthBPF = 7; DepthBRF = 4; DepthOA = 7;
31   setRatio(3);
32   setSoftKnee(10);
33   setThreshold(0);
34   setChValL(1); setChValR(1);  setDiffusion(0.9);
35   setWidth(1); setDry(1);
36   setBPF_LPF(0.5); setBPF_HPF(0.5);
37   setBRF_LPF(0.5); setBRF_HPF(0.5);
38   updateNRT();
39   update();
40 }
41 
FV3_(stenh)42 fv3_float_t FV3_(stenh)::getSampleRate()
43 {
44   return currentfs;
45 }
46 
FV3_(stenh)47 void FV3_(stenh)::setSampleRate(fv3_float_t fs)
48 {
49   currentfs = fs;
50   updateNRT();
51   update();
52 }
53 
FV3_(stenh)54 void FV3_(stenh)::mute()
55 {
56   bpf.mute(); lpf.mute(); hpf.mute();
57   delayBPF.mute(); delayBRF.mute(); delayOA.mute();
58   compS.mute(); compD.mute();
59 }
60 
FV3_(stenh)61 void FV3_(stenh)::processreplace(fv3_float_t *inputL, fv3_float_t *inputR, fv3_float_t *outputL, fv3_float_t *outputR, long numsamples)
62 {
63   for(long i = 0;i < numsamples;i ++)
64     {
65       fv3_float_t iL = inputL[i], iR = inputR[i], diff, directS, delayS, sumS, gainS, gainD, vcaFactor;
66 
67       diff = chvL*iL - chvR*iR;
68       directS = delayBPF.process(bpf.processL(diff));
69       delayS = diffusion * delayBRF.process(lpf.processL(diff) + hpf.processL(diff));
70 
71       sumS = directS + delayS;
72       gainS = compS.process(iL+iR);
73       gainD = compD.process(sumS);
74       if(gainS < gainD)	vcaFactor = gainS*width;
75       else vcaFactor = gainD*width;
76       sumS = delayOA.process(sumS);
77 
78       outputL[i] = dry*iL - vcaFactor*sumS;
79       outputR[i] = dry*iR + vcaFactor*sumS;
80     }
81 }
82 
FV3_(stenh)83 void FV3_(stenh)::setChValL(fv3_float_t value){ chvL = value; }
84 
FV3_(stenh)85 void FV3_(stenh)::setChValR(fv3_float_t value){ chvR = value; }
86 
FV3_(stenh)87 fv3_float_t FV3_(stenh)::getChValL(){ return chvL; }
88 
FV3_(stenh)89 fv3_float_t FV3_(stenh)::getChValR(){ return chvR; }
90 
FV3_(stenh)91 void FV3_(stenh)::setBPF_LPF(fv3_float_t value){ bpf.setLPF(value); }
92 
FV3_(stenh)93 void FV3_(stenh)::setBPF_HPF(fv3_float_t value){ bpf.setHPF(value); }
94 
FV3_(stenh)95 void FV3_(stenh)::setBRF_LPF(fv3_float_t value){ lpf.setLPF(value); lpf.setHPF(0);}
96 
FV3_(stenh)97 void FV3_(stenh)::setBRF_HPF(fv3_float_t value){ hpf.setLPF(0); hpf.setHPF(value);}
98 
FV3_(stenh)99 void FV3_(stenh)::setBPFDepth(fv3_float_t msec){ DepthBPF = msec; updateNRT(); }
100 
FV3_(stenh)101 void FV3_(stenh)::setBRFDepth(fv3_float_t msec){ DepthBRF = msec; updateNRT(); }
102 
FV3_(stenh)103 fv3_float_t FV3_(stenh)::getBPF_LPF(){ return bpf.getLPF(); }
104 
FV3_(stenh)105 fv3_float_t FV3_(stenh)::getBPF_HPF(){ return bpf.getHPF(); }
106 
FV3_(stenh)107 fv3_float_t FV3_(stenh)::getBRF_LPF(){ return lpf.getLPF(); }
108 
FV3_(stenh)109 fv3_float_t FV3_(stenh)::getBRF_HPF(){ return hpf.getHPF(); }
110 
FV3_(stenh)111 fv3_float_t FV3_(stenh)::getBPFDepth(){ return DepthBPF; }
112 
FV3_(stenh)113 fv3_float_t FV3_(stenh)::getBRFDepth(){ return DepthBRF; }
114 
FV3_(stenh)115 void FV3_(stenh)::setOverallDepth(fv3_float_t msec){ DepthOA = msec; updateNRT(); }
116 
FV3_(stenh)117 void FV3_(stenh)::setDiffusion(fv3_float_t value){ diffusion = value; }
118 
FV3_(stenh)119 void FV3_(stenh)::setWidth(fv3_float_t value){ width = value; }
120 
FV3_(stenh)121 void FV3_(stenh)::setDry(fv3_float_t value){ dry = value; }
122 
FV3_(stenh)123 fv3_float_t FV3_(stenh)::getOverallDepth(){ return DepthOA; }
124 
FV3_(stenh)125 fv3_float_t FV3_(stenh)::getDiffusion(){ return diffusion; }
126 
FV3_(stenh)127 fv3_float_t FV3_(stenh)::getWidth(){ return width; }
128 
FV3_(stenh)129 fv3_float_t FV3_(stenh)::getDry(){ return dry; }
130 
FV3_(stenh)131 void FV3_(stenh)::setThreshold(fv3_float_t dB)
132 { thres_dB = dB; compS.setThreshold(FV3_(utils)::dB2R(thres_dB)); compD.setThreshold(FV3_(utils)::dB2R(thres_dB)); }
133 
FV3_(stenh)134 fv3_float_t FV3_(stenh)::getThreshold(){ return thres_dB; }
135 
FV3_(stenh)136 void FV3_(stenh)::setRMS(fv3_float_t msec){ RMS = msec; updateNRT(); }
137 
FV3_(stenh)138 void FV3_(stenh)::setAttack(fv3_float_t msec){ Attack = msec; update(); }
139 
FV3_(stenh)140 void FV3_(stenh)::setRelease(fv3_float_t msec){ Release = msec; update(); }
141 
FV3_(stenh)142 fv3_float_t FV3_(stenh)::getRMS(){ return RMS; }
143 
FV3_(stenh)144 fv3_float_t FV3_(stenh)::getAttack(){ return Attack; }
145 
FV3_(stenh)146 fv3_float_t FV3_(stenh)::getRelease(){ return Release; }
147 
FV3_(stenh)148 void FV3_(stenh)::setRatio(fv3_float_t value){ Ratio = value; compS.setRatio(Ratio); compD.setRatio(Ratio); }
149 
FV3_(stenh)150 void FV3_(stenh)::setSoftKnee(fv3_float_t dB){ SoftKnee = dB; compS.setSoftKnee(SoftKnee); compD.setSoftKnee(SoftKnee); }
151 
FV3_(stenh)152 fv3_float_t FV3_(stenh)::getSoftKnee(){ return SoftKnee; }
153 
FV3_(stenh)154 fv3_float_t FV3_(stenh)::getRatio(){ return Ratio; }
155 
FV3_(stenh)156 void FV3_(stenh)::updateNRT()
157 {
158   compS.setRMS(FV3_(utils)::ms2sample(RMS,currentfs));
159   compD.setRMS(FV3_(utils)::ms2sample(RMS,currentfs));
160   delayBPF.setsize(FV3_(utils)::ms2sample(DepthBPF,currentfs));
161   delayBRF.setsize(FV3_(utils)::ms2sample(DepthBRF,currentfs));
162   delayOA.setsize(FV3_(utils)::ms2sample(DepthOA,currentfs));
163 }
164 
FV3_(stenh)165 void FV3_(stenh)::update()
166 {
167   compS.setAttack(FV3_(utils)::ms2sample(Attack,currentfs));
168   compD.setAttack(FV3_(utils)::ms2sample(Attack,currentfs));
169   compS.setRelease(FV3_(utils)::ms2sample(Release,currentfs));
170   compD.setRelease(FV3_(utils)::ms2sample(Release,currentfs));
171 }
172 
173 
FV3_(stenh)174 long FV3_(stenh)::getLatency()
175 {
176   return 0;
177 }
178 
179 #include "freeverb/fv3_ns_end.h"
180