From 05d152183a5432813dd4a73fc77393a1a85d1c96 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Mon, 14 Jan 2019 21:34:07 +1100 Subject: Improvement, less squeal - just smoother, insane now no-op --- plugins/ZamTube/Makefile | 4 +-- plugins/ZamTube/ZamTubePlugin.cpp | 50 +++++++++++++++---------------------- plugins/ZamTube/ZamTubePlugin.hpp | 2 +- plugins/ZamTube/lut_current.m | 30 ++++++++++++++++++++++ plugins/ZamTube/triode.cpp | 52 ++++++++++++++++++--------------------- plugins/ZamTube/triode.h | 20 +++------------ plugins/ZamTube/wdfcircuits.h | 18 ++++++++------ 7 files changed, 92 insertions(+), 84 deletions(-) create mode 100644 plugins/ZamTube/lut_current.m diff --git a/plugins/ZamTube/Makefile b/plugins/ZamTube/Makefile index c440694..4f2ed3f 100644 --- a/plugins/ZamTube/Makefile +++ b/plugins/ZamTube/Makefile @@ -14,8 +14,8 @@ NAME = ZamTube FILES_DSP = \ ZamTubePlugin.cpp \ - triode.cpp \ - tonestacks.cpp + tonestacks.cpp \ + triode.cpp FILES_UI = \ ZamTubeArtwork.cpp \ diff --git a/plugins/ZamTube/ZamTubePlugin.cpp b/plugins/ZamTube/ZamTubePlugin.cpp index 01cf557..1eb1328 100644 --- a/plugins/ZamTube/ZamTubePlugin.cpp +++ b/plugins/ZamTube/ZamTubePlugin.cpp @@ -225,6 +225,7 @@ void ZamTubePlugin::loadProgram(uint32_t index) tonestack = 0.0f; mastergain = 0.0f; insane = 1.0f; + insaneold = 1.0f; /* Default variable values */ @@ -250,8 +251,8 @@ void ZamTubePlugin::activate() co[0] = 10e-9; ro[0] = 1e+6; - /* Matt's preamp */ - ci[1] = 1.0e-7; + /* Matt's preamp + ci[1] = 100e-9; rg[1] = 1.; rk[1] = 820.; ck[1] = 50e-6; @@ -259,6 +260,7 @@ void ZamTubePlugin::activate() er[1] = 120e+3; co[1] = 4.7e-9; ro[1] = 470e+3; + */ /* CLA's preamp (not good with all tonestacks) ci[1] = 1.0e-7; @@ -271,28 +273,9 @@ void ZamTubePlugin::activate() ro[1] = 220e+3; */ - // 12AX7 triode model RSD-1 - v.g = 2.242e-3; - v.mu = 103.2; - v.gamma = 1.26; - v.c = 3.4; - v.gg = 6.177e-4; - v.e = 1.314; - v.cg = 9.901; - v.ig0 = 8.025e-8; - - // 12AX7 triode model EHX-1 - v.g2 = 1.371e-3; - v.mu2 = 86.9; - v.gamma2 = 1.349; - v.c2 = 4.56; - v.gg2 = 3.263e-4; - v.e2 = 1.156; - v.cg2 = 11.99; - v.ig02 = 3.917e-8; - - int pre = insane < 0.5 ? 0 : 1; + int pre = 0; ckt.updateRValues(ci[pre], ck[pre], co[pre], e[pre], er[pre], rg[pre], 0., rk[pre], 136e+3, ro[pre], Fs, v); + ckt.t.insane = insane; ckt.warmup_tubes(); fSamplingFreq = Fs; @@ -356,29 +339,36 @@ void ZamTubePlugin::run(const float** inputs, float** outputs, uint32_t frames) float fSlow46 = (fSlow44 - (fConst1 * (fSlow36 + fSlow38))); float tubeout = 0.f; - int pre = insane < 0.5 ? 0 : 1; + + if (insaneold != insane) { + ckt.t.insane = insane; + insaneold = insane; + } + int pre = 0; 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); + double pregain = from_dB(tubedrive*3.6364 + 15.); + double postgain = from_dB(mastergain*3.) / e[pre]; + for (uint32_t i = 0; i < frames; ++i) { //Step 1: read input sample as voltage for the source - double in = sanitize_denormal(inputs[0][i]); + double in = inputs[0][i] * pregain; // protect against overflowing circuit in = fabs(in) < DANGER ? in : 0.f; - double pregain = from_dB(tubedrive*3.6364 + 15.); // 0 to +40dB with -15dBFS in - double postgain = from_dB(mastergain); - - tubeout = ckt.advanc(in*pregain) * postgain / e[pre]; + tubeout = ckt.advanc(in) * postgain; //Tone Stack (post tube) fRec0[0] = ((float)tubeout - (fSlow31 * (((fSlow30 * fRec0[1]) + (fSlow29 * fRec0[2])) + (fSlow27 * fRec0[3])))); outputs[0][i] = sanitize_denormal((float)(fSlow31 * ((((fSlow46 * fRec0[0]) + (fSlow45 * fRec0[1])) + (fSlow43 * fRec0[2])) + (fSlow41 * fRec0[3])))); // update filter states - for (int i=3; i>0; i--) fRec0[i] = fRec0[i-1]; + fRec0[3] = fRec0[2]; + fRec0[2] = fRec0[1]; + fRec0[1] = fRec0[0]; } } diff --git a/plugins/ZamTube/ZamTubePlugin.hpp b/plugins/ZamTube/ZamTubePlugin.hpp index a77d3d1..1a39810 100644 --- a/plugins/ZamTube/ZamTubePlugin.hpp +++ b/plugins/ZamTube/ZamTubePlugin.hpp @@ -157,7 +157,7 @@ Wave digital filter physical model of a triode tube amplifier stage, with modell // ------------------------------------------------------------------- private: - float tubedrive,bass,middle,treble,tonestack,mastergain,insane; //parameters + float tubedrive,bass,middle,treble,tonestack,mastergain,insane,insaneold; //parameters float ts[25][7]; diff --git a/plugins/ZamTube/lut_current.m b/plugins/ZamTube/lut_current.m new file mode 100644 index 0000000..3d42d6e --- /dev/null +++ b/plugins/ZamTube/lut_current.m @@ -0,0 +1,30 @@ +1; + +function I = ip (vgk, vpk) + mu=103.2 + kx=1.26 + kg1=446.0 + kp=3.4 + kvb=300.0 + e1=vpk .* log(1. + exp(kp .* (1.0/mu + vgk ./ (kvb + vpk .* vpk) .^ 0.5))) / kp + if e1 < 0 + I = 0 + return + endif + I = double((e1 .^ kx)/kg1) +endfunction + +gridsizeg = 2001 +gridsizep = 2001 +vgk = linspace(-20, 20, gridsizeg) +vpk = linspace(0, 500, gridsizep) +[vg, vp] = ndgrid(double(vgk), double(vpk)) +cur = 1e+6*ip(double(vg), double(vp)) +surf(vg,vp,cur) + +more off +for i=1:gridsizeg + for j=1:gridsizep + fprintf("%f,\n", cur(i,j)) + endfor +endfor diff --git a/plugins/ZamTube/triode.cpp b/plugins/ZamTube/triode.cpp index a32bbf3..35e0b35 100644 --- a/plugins/ZamTube/triode.cpp +++ b/plugins/ZamTube/triode.cpp @@ -5,24 +5,17 @@ using std::abs; #define DUMP(x) x -T Triode::compute(T a, T R, T Vgate, T Vk) { +T Triode::compute(T a, T R, T Vg, T Vk) { T VakGuess = 100.; - - T Vgk = Vgate - Vk; - - T Vak = VakGuess; // initial guess + T Vgk = Vg - Vk; + T Vak = VakGuess; int iteration = 0; T err = 1e6; - while (fabs(err)/fabs(Vak) > 1e-9){ - VakGuess = iterateNewtonRaphson(Vak, 1e-6, Vgk, a, R); + + for (iteration = 0; (fabs(err)/fabs(Vak) > EPSILON) && (iteration <= ITER); iteration++){ + VakGuess = iterateNewtonRaphson(Vak, TOLERANCE, Vgk, a, R); err = Vak - VakGuess; Vak = VakGuess; - - if (iteration > 100){ - printf("Convergence failure!"); - break; - } - ++iteration; } T b = Vak - R*getIa(Vgk, Vak); @@ -30,25 +23,23 @@ T Triode::compute(T a, T R, T Vgate, T Vk) { return b; } -T Triode::getIa(T Vgk, T Vak) { - if (Vak < 0.0) { - printf("Less than zero!\n"); - Vak = 0.0; +T Triode::getIa(T Vgk, T Vpk) { + if (Vpk < 0.0) { + //printf("Less than zero!\n"); + Vpk = 0.0; } if (Vgk > 0.0) { Vgk = 0.0; } - T mu = 100.; - T kx = 1.4; - T kg1 = 3.981e-8; - T kp = 600.; - T kvb = 300.; - T e1 = Vak*log(1.+exp(kp*(1./mu+Vgk/pow(kvb+Vak*Vak, 0.5))))/kp; + T e1 = Vpk*log1p(exp(kp*(1./mu+Vgk/pow(kvb+Vpk*Vpk, 0.5))))/kp; if (e1 < 0) { return 0.; } - return (pow(e1, kx) / kg1); + 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; + } T Triode::evaluateImplicitEquation(T Vak, T Vgk, T a, T R){ @@ -64,8 +55,13 @@ T Triode::iterateNewtonRaphson(T x, T dx, T Vgk, T a, T R){ Triode::Triode() { - vg = 0.0; - vk = 0.0; - vp = 0.0; - insane = false; + insane = true; + + //12AX7 EHX-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 36e1036..5a4e3d3 100644 --- a/plugins/ZamTube/triode.h +++ b/plugins/ZamTube/triode.h @@ -21,14 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include -#define BIG 1e12 -#define SMALL 1e-14 #define EPSILON 1e-9 #define ITER 50 -#define SWAP_PP(x,y) {T tmp=y; y=x; x=tmp;} -#define SWAP_PN(x,y) {T tmp=y; y=-x; x=tmp;} -#define SWAP_NP(x,y) {T tmp=y; y=x; x=-tmp;} -#define SWAP_NN(x,y) {T tmp=y; y=-x; x=-tmp;} #define TOLERANCE 1e-6 #define MAX(x, y) (( (x) > (y) ) ? x : y ) @@ -45,21 +39,15 @@ sanitize_denormal(float v) { class Triode { public: - T Kb, Gb, Pb; - T Kr, Gr, Pr; + T mu, kp, kvb, kg1, kx; - T vg, vk, vp; - T g, mu, gamma, c, gg, e, cg, ig0; - T g1, mu1, gamma1, c1, gg1, e1, cg1, ig01; - T g2, mu2, gamma2, c2, gg2, e2, cg2, ig02; - - bool insane; - Triode(); - T compute(T Kbb, T Gbb, T Pbb, T R); + T compute(T a, T R, T Vg, T Vk); 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; }; #endif diff --git a/plugins/ZamTube/wdfcircuits.h b/plugins/ZamTube/wdfcircuits.h index e2b9547..02dfee8 100644 --- a/plugins/ZamTube/wdfcircuits.h +++ b/plugins/ZamTube/wdfcircuits.h @@ -10,23 +10,27 @@ public: bool on; TubeStageCircuit() { - Cia = 0.0; - Cka = 0.0; - Coa = 0.0; - Vk = 0.0; - Vg = 0.0; on = false; + reset_tubes(); } void warmup_tubes(void) { int i; on = false; - for (i = 0; i < 8000; i++) { + for (i = 0; i < 100; i++) { advanc(0.0); } on = true; } + void reset_tubes(void) { + Cia = 0.0; + Cka = 0.0; + 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) { @@ -124,7 +128,7 @@ public: Real Roa = S3_3b2; Vk = -P1_3b3; //printf("Vk=%f Vg=%f Vpk(b)=%f(%f) in=%f out=%f\n", Vk,Vg,P2_3b3,b, ViE,Roa); - return (Roa); + return Roa; } private: -- cgit v1.2.3