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
|
#ifndef WDFCIRCUITS_H
#define WDFCIRCUITS_H
#include "glue.h"
#include "triode.h"
class TubeStageCircuit {
/*Tube Preamp*/
public:
Triode t;
bool on;
TubeStageCircuit() {
Cia = 0.0;
Cka = 0.0;
Coa = 0.0;
on = false;
}
TubeStageCircuit(Real C_Ci, Real C_Ck, Real C_Co, Real E_E250, Real R_E250, Real R_Rg, Real R_Ri, Real R_Rk, Real R_Ro, Real R_Vi, Real sampleRate, Triode& tube) {
Cia = 0.0;
Cka = 0.0;
Coa = 0.0;
on = false;
updateRValues(C_Ci, C_Ck, C_Co, E_E250, R_E250, R_Rg, R_Ri, R_Rk, R_Ro, R_Vi, sampleRate, tube);
}
void updateRValues(Real C_Ci, Real C_Ck, Real C_Co, Real E_E250, Real R_E250, Real R_Rg, Real R_Ri, Real R_Rk, Real R_Ro, Real R_Vi, Real sampleRate, Triode& tube) {
t = tube;
Real ViR = R_Vi;
Real CiR = 1.0 / (2.0*C_Ci*sampleRate);
Real CkR = 1.0 / (2.0*C_Ck*sampleRate);
Real CoR = 1.0 / (2.0*C_Co*sampleRate);
Real RoR = R_Ro;
Real RgR = R_Rg;
Real RiR = R_Ri;
Real RkR = R_Rk;
Real E250R = R_E250;
E250E = E_E250;
Real S0_3R = (CiR + ViR);
S0_3Gamma1 = CiR/(CiR + ViR);
Assert(S0_3Gamma1 >= 0.0 && S0_3Gamma1 <= 1.0);
Real P0_1R = S0_3R;
Real P0_2R = RiR;
Real P0_3R = 1.0 /(1.0 / P0_1R + 1.0 / P0_2R);
P0_3Gamma1 = 1.0 / P0_1R/(1.0 / P0_1R + 1.0 / P0_2R);
Assert(P0_3Gamma1 >= 0.0 && P0_3Gamma1 <= 1.0);
S1_3Gamma1 = RgR/(RgR + P0_3R);
Assert(S1_3Gamma1 >= 0.0 && S1_3Gamma1 <= 1.0);
Real I3_1R = CkR;
Real I3_2R = RkR;
I3_3Gamma1 = 1.0 / I3_1R/(1.0 / I3_1R + 1.0 / I3_2R);
Assert(I3_3Gamma1 >= 0.0 && I3_3Gamma1 <= 1.0);
Real S2_3R = (CoR + RoR);
S2_3Gamma1 = CoR/(CoR + RoR);
Assert(S2_3Gamma1 >= 0.0 && S2_3Gamma1 <= 1.0);
Real P2_1R = S2_3R;
Real P2_2R = E250R;
P2_3Gamma1 = 1.0 / P2_1R/(1.0 / P2_1R + 1.0 / P2_2R);
Assert(P2_3Gamma1 >= 0.0 && P2_3Gamma1 <= 1.0);
t.Kr = sanitize_denormal(I3_3Gamma1);
t.Pr = sanitize_denormal(S2_3Gamma1);
t.Gr = sanitize_denormal(S1_3Gamma1);
//printf("Kr = %f Pr = %f Gr = %f\n", t.Kr, t.Pr, t.Gr);
}
void warmup_tubes(void) {
int i;
on = false;
for (i = 0; i < 1000; i++) {
advanc(0.0);
}
on = true;
}
Real advanc(Real VE){
ViE = VE;
Real Ckb = Cka;
Real I3_3b3 = I3_3Gamma1 * Ckb;
Real Cib = Cia;
Real S0_3b3 = Cib + ViE;
Real P0_3b3 = P0_3Gamma1*(S0_3b3);
Real S1_3b3 = P0_3b3;
Real Cob = Coa;
Real S2_3b3 = Cob;
Real P2_3b3 = E250E - P2_3Gamma1*(E250E + S2_3b3);
//Tube: K G P
//printf("K=%f G=%f P=%f\n", I3_3b3,-S1_3b3,P2_3b3);
t.compute(I3_3b3,-S1_3b3,P2_3b3);
Real b1 = t.getC();
Real b2 = t.getG();
Real b3 = t.getP();
//Set As
Real I3_3b1 = (b1 + Ckb - I3_3Gamma1*(Ckb));
Cka = I3_3b1;
Real S1_3b2 = ((-b2) - S1_3Gamma1*(P0_3b3 + (-b2)));
Real P0_3b1 = (S1_3b2 + (S0_3b3) - P0_3Gamma1*(S0_3b3));
Real S0_3b1 = (Cib - S0_3Gamma1*(Cib + ViE + P0_3b1));
Cia = S0_3b1;
Real P2_3b1 = (b3 + E250E + (S2_3b3) - P2_3Gamma1*(E250E + S2_3b3));
Real S2_3b1 = (Cob - S2_3Gamma1*(Cob + P2_3b1));
Coa = S2_3b1;
Real S2_3b2 = (Cob + P2_3b1 - S2_3Gamma1*(Cob + P2_3b1));
Real Roa = S2_3b2;
return -Roa;
}
private:
//State variables
Real Cia;
Real Cka;
Real Coa;
//R values
Real I3_3Gamma1;
Real E250E;
Real ViE;
Real P0_3Gamma1;
Real S0_3Gamma1;
Real S2_3Gamma1;
Real S1_3Gamma1;
Real P2_3Gamma1;
};
#endif
|