summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2019-01-14 23:56:10 +1100
committerDamien Zammit <damien@zamaudio.com>2019-01-14 23:56:10 +1100
commit54bc96b04622c6c85bebd1e6af1fcd2f7eb748c9 (patch)
tree09a1126317d8e8543294e1c1713e5f95d7b9f7f2
parent05d152183a5432813dd4a73fc77393a1a85d1c96 (diff)
Introduce taylor expansion to reduce load by > 300x
-rw-r--r--plugins/ZamTube/ZamTubePlugin.cpp13
-rw-r--r--plugins/ZamTube/triode.cpp33
-rw-r--r--plugins/ZamTube/triode.h8
-rw-r--r--plugins/ZamTube/wdfcircuits.h3
4 files changed, 30 insertions, 27 deletions
diff --git a/plugins/ZamTube/ZamTubePlugin.cpp b/plugins/ZamTube/ZamTubePlugin.cpp
index 1eb1328..719a2ae 100644
--- a/plugins/ZamTube/ZamTubePlugin.cpp
+++ b/plugins/ZamTube/ZamTubePlugin.cpp
@@ -251,7 +251,7 @@ void ZamTubePlugin::activate()
co[0] = 10e-9;
ro[0] = 1e+6;
- /* Matt's preamp
+ /* Matt's preamp */
ci[1] = 100e-9;
rg[1] = 1.;
rk[1] = 820.;
@@ -260,9 +260,8 @@ void ZamTubePlugin::activate()
er[1] = 120e+3;
co[1] = 4.7e-9;
ro[1] = 470e+3;
- */
- /* CLA's preamp (not good with all tonestacks)
+ /* CLA's preamp
ci[1] = 1.0e-7;
rg[1] = 5.6e+3;
rk[1] = 1.5e+3;
@@ -340,11 +339,13 @@ void ZamTubePlugin::run(const float** inputs, float** outputs, uint32_t frames)
float tubeout = 0.f;
- if (insaneold != insane) {
- ckt.t.insane = insane;
+ if (insane != insaneold) {
+ ckt.reset_tubes();
+ ckt.warmup_tubes();
+ fRec0[3] = fRec0[2] = fRec0[1] = fRec0[0] = 0.f;
insaneold = insane;
}
- int pre = 0;
+ int pre = insane < 0.5 ? 0 : 1;
float volumepot = tubedrive / 11. * 1e+6;
ckt.updateRValues(ci[pre], ck[pre], co[pre], e[pre], er[pre], rg[pre], volumepot, rk[pre], 136e+3, ro[pre], getSampleRate(), v);
diff --git a/plugins/ZamTube/triode.cpp b/plugins/ZamTube/triode.cpp
index 35e0b35..dfa2505 100644
--- a/plugins/ZamTube/triode.cpp
+++ b/plugins/ZamTube/triode.cpp
@@ -24,6 +24,18 @@ T Triode::compute(T a, T R, T Vg, T Vk) {
}
T Triode::getIa(T Vgk, T Vpk) {
+ static bool prepared = false;
+ static double coeff[3];
+
+ if (!prepared) {
+ const double L2 = log(2.0);
+ const double scale = 2e+9*pow(L2, kx-2.0)/(8.0*pow(kp, kx));
+ coeff[0] = 8.0*L2*L2*scale;
+ coeff[1] = kx*kp*L2*4.0*scale;
+ coeff[2] = (kp*kp*kx*kx + L2*kp*kp*kx - kp*kp*kx) * scale;
+ prepared = true;
+ }
+
if (Vpk < 0.0) {
//printf("Less than zero!\n");
Vpk = 0.0;
@@ -32,14 +44,16 @@ T Triode::getIa(T Vgk, T Vpk) {
Vgk = 0.0;
}
- T e1 = Vpk*log1p(exp(kp*(1./mu+Vgk/pow(kvb+Vpk*Vpk, 0.5))))/kp;
- if (e1 < 0) {
- return 0.;
- }
- T test = 1e+6*pow(e1, kx) / kg1;
- //printf("XXX Ip=%f lut=%f diff=%f vgk=%f vpk=%f\n", test, test2, test2-test, Vgk, Vpk);
- return test;
+ double A = 1./mu + Vgk / sqrt(kvb + Vpk*Vpk);
+ return (coeff[0] + coeff[1]*A + coeff[2]*A*A) / kg1;
+ /* exact solution (takes > 300x longer)
+ e1 = Vpk*log1p(exp(kp*(1./mu+Vgk/sqrt(kvb+Vpk*Vpk))))/kp;
+ if (e1 < 0) {
+ return 0.;
+ }
+ return 1e+6*pow(e1, kx) / kg1;
+ */
}
T Triode::evaluateImplicitEquation(T Vak, T Vgk, T a, T R){
@@ -55,13 +69,10 @@ T Triode::iterateNewtonRaphson(T x, T dx, T Vgk, T a, T R){
Triode::Triode()
{
- insane = true;
-
- //12AX7 EHX-1
+ //12AX7 RSD-1
kvb = 300.;
mu = 103.2;
kx = 1.26;
kg1 = 446.0;
kp = 3.4;
}
-
diff --git a/plugins/ZamTube/triode.h b/plugins/ZamTube/triode.h
index 5a4e3d3..ae552fe 100644
--- a/plugins/ZamTube/triode.h
+++ b/plugins/ZamTube/triode.h
@@ -30,13 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
typedef double T;
-static inline float
-sanitize_denormal(float v) {
- if(!std::isnormal(v) || !std::isfinite(v))
- return 0.f;
- return v;
-}
-
class Triode {
public:
T mu, kp, kvb, kg1, kx;
@@ -46,7 +39,6 @@ public:
T getIa(T Vgk, T Vak);
T evaluateImplicitEquation(T Vak, T Vgk, T a, T R);
T iterateNewtonRaphson(T x, T dx, T Vgk, T a, T R);
- const float *lut_ip;
bool insane;
};
diff --git a/plugins/ZamTube/wdfcircuits.h b/plugins/ZamTube/wdfcircuits.h
index 02dfee8..37203a1 100644
--- a/plugins/ZamTube/wdfcircuits.h
+++ b/plugins/ZamTube/wdfcircuits.h
@@ -12,6 +12,7 @@ public:
TubeStageCircuit() {
on = false;
reset_tubes();
+ warmup_tubes();
}
void warmup_tubes(void) {
@@ -29,10 +30,8 @@ public:
Coa = 0.0;
Vg = 0.0;
Vk = 0.0;
- warmup_tubes();
}
-
void updateRValues(Real C_Ci, Real C_Ck, Real C_Co, Real E_E500, Real R_E500, Real R_Rg, Real R_Ri, Real R_Rk, Real R_Vi, Real R_Ro, Real sampleRate, Triode& tube) {
t = tube;
Real ViR = R_Vi;