1 // ----------------------------------------------------------------------- 2 // Copyright (C) 2003-2011 Fons Adriaensen <fons@linuxaudio.org> 3 // 4 // This program is free software; you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation; either version 2 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 // ----------------------------------------------------------------------- 18 19 #ifndef __ZITA_H__ 20 #define __ZITA_H__ 21 22 #include "effects/effect.h" 23 #include <atomic> 24 namespace Ms { 25 26 class EffectGui; 27 28 //--------------------------------------------------------- 29 // Pareq 30 //--------------------------------------------------------- 31 32 class Pareq 33 { 34 enum { BYPASS, STATIC, SMOOTH, MAXCH = 4 }; 35 36 void calcpar1 (int nsamp, float g, float f); 37 void process1 (int nsamp, float*); 38 39 std::atomic<int16_t> _touch0 = { 0 }; 40 std::atomic<int16_t> _touch1 = { 0 }; 41 #if 0 // not yet (?) used 42 bool _bypass; 43 #endif 44 int _state = BYPASS; 45 float _fsamp = 1.f; 46 47 float _g = 0.f; 48 float _g0 = 1.f, _g1 = 1.f; 49 float _f = 0.f; 50 float _f0 = 1e3f, _f1 = 1e3f; 51 float _c1 = 0.f, _dc1 = 0.f; 52 float _c2 = 0.f, _dc2 = 0.f; 53 float _gg = 0.f, _dgg = 0.f; 54 55 float _z1 [MAXCH] = { 0.f, 0.f, 0.f, 0.f }; 56 float _z2 [MAXCH] = { 0.f, 0.f, 0.f, 0.f }; 57 58 public: 59 Pareq(); 60 61 void setfsamp(float fsamp); setparam(float f,float g)62 void setparam(float f, float g) { 63 _f = f; 64 _g = g;//dB 65 _f0 = f; 66 _g0 = powf (10.0f, 0.05f * g); 67 _touch0++; 68 } set_gn(float g)69 void set_gn(float g) { setparam(_f, g); } gn()70 float gn() const { return _g; } set_fr(float f)71 void set_fr(float f) { setparam(f, _g); } fr()72 float fr() const { return _f; } 73 74 void reset(); 75 void prepare(int nsamp); process(int nsamp,float * data)76 void process(int nsamp, float* data) { 77 if (_state != BYPASS) 78 process1(nsamp, data); 79 } 80 }; 81 82 //--------------------------------------------------------- 83 // Diff1 84 //--------------------------------------------------------- 85 86 class Diff1 87 { 88 friend class ZitaReverb; 89 90 int _i = 0; 91 float _c = 0.f; 92 int _size = 0; 93 float* _line = nullptr; 94 Diff1()95 Diff1() {} 96 ~Diff1(); 97 void init(int size, float c); 98 void fini(); 99 process(float x)100 float process(float x) { 101 if (!_line) { 102 return 0.f; 103 } 104 float z = _line [_i]; 105 x -= _c * z; 106 _line [_i] = x; 107 if (++_i == _size) 108 _i = 0; 109 return z + _c * x; 110 } 111 }; 112 113 //--------------------------------------------------------- 114 // Filt1 115 //--------------------------------------------------------- 116 117 class Filt1 118 { 119 friend class ZitaReverb; 120 Filt1()121 Filt1 () : _slo (0), _shi (0) {} ~Filt1()122 ~Filt1 () {} 123 124 void set_params (float del, float tmf, float tlo, float wlo, float thi, float chi); 125 process(float x)126 float process(float x) { 127 _slo += _wlo * (x - _slo) + 1e-10f; 128 x += _glo * _slo; 129 _shi += _whi * (x - _shi); 130 return _gmf * _shi; 131 } 132 float _gmf = 0.f; 133 float _glo = 0.f; 134 float _wlo = 0.f; 135 float _whi = 0.f; 136 float _slo = 0.f; 137 float _shi = 0.f; 138 }; 139 140 //--------------------------------------------------------- 141 // Delay 142 //--------------------------------------------------------- 143 144 class Delay 145 { 146 friend class ZitaReverb; 147 148 Delay(); 149 ~Delay(); 150 151 void init (int size); 152 void fini (); 153 read()154 float read () { 155 if (!_line) { 156 return 0.f; 157 } 158 return _line [_i]; 159 } 160 write(float x)161 void write (float x) { 162 if (!_line) { 163 return; 164 } 165 _line [_i++] = x; 166 if (_i == _size) 167 _i = 0; 168 } 169 int _i = 0; 170 int _size = 0; 171 float *_line = nullptr; 172 }; 173 174 //--------------------------------------------------------- 175 // Vdelay 176 //--------------------------------------------------------- 177 178 class Vdelay 179 { 180 friend class ZitaReverb; 181 182 Vdelay(); 183 ~Vdelay(); 184 185 void init (int size); 186 void fini (); 187 void set_delay (int del); 188 read()189 float read () { 190 if (!_line) { 191 return 0.f; 192 } 193 float x = _line [_ir++]; 194 if (_ir == _size) 195 _ir = 0; 196 return x; 197 } 198 write(float x)199 void write (float x) { 200 if (!_line) { 201 return; 202 } 203 _line [_iw++] = x; 204 if (_iw == _size) 205 _iw = 0; 206 } 207 int _ir = 0; 208 int _iw = 0; 209 int _size = 0; 210 float* _line = nullptr; 211 }; 212 213 //--------------------------------------------------------- 214 // ZitaReverb 215 //--------------------------------------------------------- 216 217 class ZitaReverb : public Effect 218 { 219 Q_OBJECT 220 221 float _fsamp = 1.f; 222 223 Vdelay _vdelay0; 224 Vdelay _vdelay1; 225 Diff1 _diff1[8]; 226 Filt1 _filt1[8]; 227 Delay _delay[8]; 228 229 std::atomic<int> _cntA1 = { 1 }; 230 std::atomic<int> _cntB1 = { 1 }; 231 std::atomic<int> _cntC1 = { 1 }; 232 int _cntA2 = 0; 233 int _cntB2 = 0; 234 int _cntC2 = 0; 235 236 float _ipdel = 0.04f; 237 float _xover = 200.0f; 238 float _rtlow = 1.4f; 239 float _rtmid = 2.0f; 240 float _fdamp = 3e3f; 241 float _opmix = 0.33f; 242 243 float _g0 = 0.f, _d0 = 0.f; 244 float _g1 = 0.f, _d1 = 0.f; 245 246 Pareq _pareq1; 247 Pareq _pareq2; 248 249 static float _tdiff1 [8]; 250 static float _tdelay [8]; 251 252 int _fragm = 0; 253 int _nsamp = 0; 254 255 void prepare(int n); 256 257 public: ZitaReverb()258 ZitaReverb() : Effect() {} 259 ~ZitaReverb(); 260 261 virtual void init(float fsamp); 262 void fini(); 263 264 virtual void process(int n, float* inp, float* out); 265 set_delay(float v)266 void set_delay(float v) { _ipdel = v; _cntA1++; } delay()267 float delay() const { return _ipdel; } 268 set_xover(float v)269 void set_xover(float v) { _xover = v; _cntB1++; } xover()270 float xover() const { return _xover; } 271 set_rtlow(float v)272 void set_rtlow(float v) { _rtlow = v; _cntB1++; } rtlow()273 float rtlow() const { return _rtlow; } 274 set_rtmid(float v)275 void set_rtmid(float v) { _rtmid = v; _cntB1++; _cntC1++; } rtmid()276 float rtmid() const { return _rtmid; } 277 set_fdamp(float v)278 void set_fdamp(float v) { _fdamp = v; _cntB1++; } fdamp()279 float fdamp() const { return _fdamp; } 280 set_eq1fr(float f)281 void set_eq1fr(float f) { _pareq1.set_fr(f); } eq1fr()282 float eq1fr() const { return _pareq1.fr(); } 283 set_eq1gn(float f)284 void set_eq1gn(float f) { _pareq1.set_gn(f); } eq1gn()285 float eq1gn() const { return _pareq1.gn(); } 286 set_eq2fr(float f)287 void set_eq2fr(float f) { _pareq2.set_fr(f); } eq2fr()288 float eq2fr() const { return _pareq2.fr(); } 289 set_eq2gn(float f)290 void set_eq2gn(float f) { _pareq2.set_gn(f); } eq2gn()291 float eq2gn() const { return _pareq2.gn(); } 292 set_opmix(float v)293 void set_opmix(float v) { _opmix = v; _cntC1++; } opmix()294 float opmix() const { return _opmix; } 295 name()296 virtual const char* name() const { return "Zita1"; } 297 virtual EffectGui* gui(); 298 virtual const std::vector<ParDescr>& parDescr() const; 299 300 virtual void setNValue(int parameter, double value); 301 virtual double nvalue(int idx) const; 302 303 virtual SynthesizerGroup state() const; 304 virtual void setState(const SynthesizerGroup&); 305 }; 306 } 307 308 #endif 309 310