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