-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathf670l_LevelTimeConstant.hpp
137 lines (132 loc) · 5.93 KB
/
f670l_LevelTimeConstant.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//==============================================================================
/**
Wavechild 670
-------------
Wave digital filter based emulation of a famous 1950's tube stereo limiter
WDF++ based source code by Maxime Coorevits (Nord, France) in 2013
Some part are inspired by the Peter Raffensperger project: Wavechild670,
a command line with python WDF generator that produce C++ code of the circuit.
Major restructuration:
----------------------
* WDF++ based project (single WDF++.hpp file)
* full C++, zero-dependencies except JUCE (core API, AudioProcessor).
* JUCE Plugin wrapper processor (VST, AU ...)
* Photo-Realistic GUI
Reference:
----------
Toward a Wave Digital Filter Model of the Fairchild 670 Limiter,
Raffensperger, P. A., (2012).
Proc. of the 15th International Conference on Digital Audio Effects (DAFx-12),
York, UK, September 17-21, 2012.
Note:
-----
Fairchild (R) a registered trademark of Avid Technology, Inc.,
which is in no way associated or affiliated with the author.
**/
//==============================================================================
#ifndef __F670L_LEVELTIMECONSTANT_HPP_E666EC81__
#define __F670L_LEVELTIMECONSTANT_HPP_E666EC81__
//==============================================================================
#include "WDF++.hpp"
//==============================================================================
namespace Wavechild670 {
//==============================================================================
//----------------------------------------------------------------------
// Level Time Constant 6-way switch parameters (time from 10dB limiting)
//----------------------------------------------------------------------
static const double ltc[6][6] =
{
//------------------------------------------------------------------
// CT CU CV RT RU RV | Release Time
//------------------------------------------------------------------
{ 2e-6, 8e-6, 20e-6, 51.9e3, 10e9, 10e9 }, // 0.3s
{ 2e-6, 8e-6, 20e-6, 149.9e3, 10e9, 10e9 }, // 0.8s
{ 4e-6, 8e-6, 20e-6, 220e3, 10e9, 10e9 }, // 2.0s
{ 8e-6, 8e-6, 20e-6, 220e3, 10e9, 10e9 }, // 5.0s
{ 4e-6, 8e-6, 20e-6, 220e3, 100e3, 10e9 }, // 2.0s / 10.0s
{ 2e-6, 8e-6, 20e-6, 220e3, 100e3, 100e3 } // 0.3s / 5.0s / 25.0s
//------------------------------------------------------------------
};
//==============================================================================
template <typename T>
class LevelTimeConstant
{
public:
LevelTimeConstant (T Fs)
: //----------------------------------------------------------------
R1 (220e3, "RT"),
R2 ( 1e9, "RU"),
R3 ( 1e9, "RV"),
//----------------------------------------------------------------
C1 ( 2e-6, Fs, "CT"),
C2 ( 8e-6, Fs, "CU"),
C3 (20e-6, Fs, "CV"),
//----------------------------------------------------------------
{
wiring ();
}
//----------------------------------------------------------------------
void parameters (T Fs, const int index)
{
jassert(index >= 0 && index < 6);
update (Fs, ltc[index][0], ltc[index][1], ltc[index][2],
ltc[index][3], ltc[index][4], ltc[index][5]);
}
//----------------------------------------------------------------------
T process (T Iin) // Iin == current (current law apply)
{
root.incident (root.reflected() - (2.0*(Iin * root.R())));
return C1.voltage();
}
//----------------------------------------------------------------------
protected:
WDF::Resistor<T> R1, R2, R3;
WDF::Capacitor<T> C1, C2, C3;
//----------------------------------------------------------------------
WDF::Serie<T> serie_A;
WDF::Serie<T> serie_B;
WDF::Parallel<T> paral_A;
WDF::Parallel<T> paral_B;
WDF::Parallel<T> root;
//----------------------------------------------------------------------
/**
--------------------------
| | | | |
| | | R2 R3
root R1 C1 | |
| | | C2 C3
| | | | |
--------------------------
**/
//----------------------------------------------------------------------
inline void wiring ()
{
paral_A.connect (&R1, &C1);
serie_A.connect (&R2, &C2);
serie_B.connect (&R3, &C3);
paral_B.connect (&serie_A, &serie_B);
root.connect (¶l_A, ¶l_B);
}
//----------------------------------------------------------------------
void update (T Fs, T CT = 2e-6, T CU = 8e-6, T CV = 20e-6,
T RT = 220e3, T RU = 1e9, T RV = 1e9)
{
T hFs = FS*.5;
//------------------------------------------------------------------
C1.Rp = hFs*CT;
C2.Rp = hFs*CU;
C3.Rp = hFs*CV;
//------------------------------------------------------------------
R1.Rp = RT;
R2.Rp = RU;
R3.Rp = RV;
//------------------------------------------------------------------
wiring ();
}
//----------------------------------------------------------------------
};
//==============================================================================
} // namespace Wavechild670
//==============================================================================
#endif // __F670L_LEVELTIMECONSTANT_HPP_E666EC81__
//==============================================================================