diff options
author | Damien Zammit <damien@zamaudio.com> | 2020-12-01 20:34:35 +1100 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2020-12-01 20:34:35 +1100 |
commit | f18d83b4f5caba9a846558e9b266629617adc1c2 (patch) | |
tree | 39bcf8017b3753b566d206cb22df2a0769dd84f3 | |
parent | 30ac8e0de1ad650edfa068cde562f6b613dd2fb9 (diff) |
ZamTube: Introduce two modes of operation toggled by the insane switch
-rw-r--r-- | plugins/ZamTube/ZamTubePlugin.cpp | 20 | ||||
-rw-r--r-- | plugins/ZamTube/ZamTubePlugin.hpp | 3 | ||||
-rw-r--r-- | plugins/ZamTube/wdfcircuits.h | 143 |
3 files changed, 137 insertions, 29 deletions
diff --git a/plugins/ZamTube/ZamTubePlugin.cpp b/plugins/ZamTube/ZamTubePlugin.cpp index b47186b..40349c4 100644 --- a/plugins/ZamTube/ZamTubePlugin.cpp +++ b/plugins/ZamTube/ZamTubePlugin.cpp @@ -299,6 +299,7 @@ void ZamTubePlugin::activate() // Passive components /* Original WDF preamp + ci[0] = 100e-9; rg[0] = 20e+3; rk[0] = 1e+3; ck[0] = 10e-6; @@ -309,6 +310,7 @@ void ZamTubePlugin::activate() */ /* Matt's preamp */ + ci[0] = 100e-9; rg[0] = 1e-3; rk[0] = 1200.; // 820 originally ck[0] = 50e-6; @@ -318,6 +320,7 @@ void ZamTubePlugin::activate() ro[0] = 470e+3; /* CLA's preamp + ci[0] = 100e-9; rg[0] = 5.6e+3; rk[0] = 1.5e+3; ck[0] = 4.7e-6; @@ -329,9 +332,7 @@ void ZamTubePlugin::activate() int pre = 0; float volumepot = 800e+3; // 100 good at low gain, 1000 good at high gain - ckt.on = false; - ckt.updateRValues(ck[pre], co[pre], e[pre], er[pre], rg[pre], volumepot, rk[pre], 1e+3, ro[pre], Fs); - ckt.warmup_tubes(); + ckt.updateRValues(ci[pre], ck[pre], co[pre], e[pre], er[pre], rg[pre], volumepot, rk[pre], 1e+3, ro[pre], Fs); fSamplingFreq = Fs; @@ -346,7 +347,6 @@ void ZamTubePlugin::activate() void ZamTubePlugin::deactivate() { - ckt.warmup_tubes(); fRec0[3] = 0.f; fRec0[2] = 0.f; fRec0[1] = 0.f; @@ -407,20 +407,26 @@ void ZamTubePlugin::run(const float** inputs, float** outputs, uint32_t frames) float toneout = 0.f; - float cut = insane ? 0. : 15.; + float cut = 15.; float pregain = from_dB(tubedrive*3.6364 - cut + mastergain); float postgain = from_dB(cut + 42. * (1. - log1p(tubedrive/11.))); + + if (insaneold != (int)insane) { + insaneold = (int)insane; + ckt.set_mode(insane > 0.5 ? ckt.TUBE_MODE_GRIDLEAK : ckt.TUBE_MODE_SIXTIES); + ZamTubePlugin::deactivate(); + } for (uint32_t i = 0; i < frames; ++i) { //Step 1: read input sample as voltage for the source float in = inputs[0][i] * pregain; - //Tone Stack (post tube) + //Tone Stack (pre tube) fRec0[0] = (in - (fSlow31 * (((fSlow30 * fRec0[1]) + (fSlow29 * fRec0[2])) + (fSlow27 * fRec0[3])))) + 1e-20f; toneout = sanitize_denormal((float)(fSlow31 * ((((fSlow46 * fRec0[0]) + (fSlow45 * fRec0[1])) + (fSlow43 * fRec0[2])) + (fSlow41 * fRec0[3])))); - outputs[0][i] = ckt.advanc(toneout) * postgain / 10000.; + outputs[0][i] = ckt.run(toneout) * postgain / 10000.; // update filter states fRec0[3] = fRec0[2]; diff --git a/plugins/ZamTube/ZamTubePlugin.hpp b/plugins/ZamTube/ZamTubePlugin.hpp index 55df704..cf838d1 100644 --- a/plugins/ZamTube/ZamTubePlugin.hpp +++ b/plugins/ZamTube/ZamTubePlugin.hpp @@ -157,7 +157,8 @@ Wave digital filter physical model of a triode tube amplifier stage, with modell // ------------------------------------------------------------------- private: - float tubedrive,bass,middle,treble,tonestack,mastergain,insane,insaneold; //parameters + float tubedrive,bass,middle,treble,tonestack,mastergain,insane; //parameters + int insaneold; float ts[25][7]; diff --git a/plugins/ZamTube/wdfcircuits.h b/plugins/ZamTube/wdfcircuits.h index 5bf2e93..5f99367 100644 --- a/plugins/ZamTube/wdfcircuits.h +++ b/plugins/ZamTube/wdfcircuits.h @@ -3,23 +3,37 @@ #include "glue.h" #include "triode.h" +#define WARMUP_SAMPLES 48000 + class TubeStageCircuit { /*Tube Preamp*/ public: Triode t; bool on; + int mode; + int counter; TubeStageCircuit() { reset_tubes(); + P3_3Gamma1 = 1.; + P0_3Gamma1 = 1.; + S1_3Gamma1 = 1.; + S3_3Gamma1 = 1.; + P1_3Gamma1 = 1.; + S0_3Gamma1 = 1.; + S2_3Gamma1 = 1.; + P2_3Gamma1 = 1.; + E500E = 0.; + ViE = 0.; } + enum tube_mode { + TUBE_MODE_SIXTIES = 0, + TUBE_MODE_GRIDLEAK, + }; + void warmup_tubes(void) { - int i; - on = false; - for (i = 0; i < 5000; i++) { - advanc(0.0); - } - on = true; + counter = WARMUP_SAMPLES; } void reset_tubes(void) { @@ -28,21 +42,12 @@ public: Coa = 0.0; Vg = 0.0; Vk = 0.0; - P3_3Gamma1 = 1.; - P0_3Gamma1 = 1.; - S1_3Gamma1 = 1.; - S3_3Gamma1 = 1.; - P1_3Gamma1 = 1.; - ViE = 0.; - S0_3Gamma1 = 1.; - S2_3Gamma1 = 1.; - P2_3Gamma1 = 1.; - E500E = 0.; } - void updateRValues(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) { - + 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) { + warmup_tubes(); Real ViR = R_Vi; + Real CiR = 1.0 / (2.0*C_Ci*sampleRate); Real RiR = R_Ri; Real RgR = R_Rg; Real RoR = R_Ro; @@ -51,7 +56,10 @@ public: Real E500R = R_E500; E500E = E_E500; Real CoR = 1.0 / (2.0*C_Co*sampleRate); - Real P0_1R = ViR; + 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); @@ -75,7 +83,85 @@ public: Assert(S2_3Gamma1 >= 0.0 && S2_3Gamma1 <= 1.0); } - Real advanc(Real ViE) { + Real advanc_gridleak(Real ViE) { + //Get Bs + //S2_3GetB + //P2_3GetB + //S3_3GetB + Real Cob = Coa; + //S3_1SetA + //RoGetB + //S3_2SetA + Real S3_3b3 = -(Cob); + //P2_1SetA + //E500GetB + //P2_2SetA + Real P2_3b3 = E500E - P2_3Gamma1*(E500E - S3_3b3); + //S2_1SetA + //P1_3GetB + Real Ckb = Cka; + //P1_1SetA + //RkGetB + //P1_2SetA + Real P1_3b3 = P1_3Gamma1*(-Ckb); + //S2_2SetA + Real S2_3b3 = (P2_3b3 + P1_3b3); + //S1_3GetB + //RgGetB + //S1_1SetA + //P0_3GetB + //S0_3GetB + Real Cib = Cia; + //S0_1SetA + //ViGetB + //S0_2SetA + Real S0_3b3 = -(Cib + ViE); + //P0_1SetA + //RiGetB + //P0_2SetA + Real P0_3b3 = -P0_3Gamma1*(-S0_3b3); + //S1_2SetA + Real S1_3b3 = -(P0_3b3); + //P1_3GetB + //P1_1SetA + //RkGetB + //P1_2SetA + //Call tube model + Vg = (S1_3b3); + Real Vd = Vk+Vg; + Real Rd = (Vd > 0.) ? 2.7e+3 : 100e+9; + Real b = t.compute(S2_3b3, S2_3Gamma1, Vg, Vk); + Vk = -(P1_3b3 + Vd * S1_3Gamma1 / Rd); + //Set As + //S2_3SetA + Real S2_3b1 = P2_3b3 - S2_3Gamma1*(P2_3b3 - (Vk+Vg) + b); + //P2_3SetA + Real P2_3b1 = S2_3b1 + E500E - S3_3b3 - P2_3Gamma1*(E500E - S3_3b3); + //S3_3SetA + Real S3_3b1 = Cob - S3_3Gamma1*(Cob + P2_3b1); + Coa = S3_3b1; + Real S3_3b2 = Cob + P2_3b1 - S3_3Gamma1*(Cob + P2_3b1); + //RoSetA + Real Roa = S3_3b2; + Real S2_3b2 = P2_3b3 + b - S2_3Gamma1*(P2_3b3 - (Vk+Vg) + b); + //P1_3SetA + Real P1_3b1 = S2_3b2 - Ckb - P1_3Gamma1*(-Ckb); + Cka = P1_3b1; + //RkSetA + //S1_3SetA + //RgSetA + Real S1_3b2 = Vg - S1_3Gamma1*(P0_3b3 + Vg); + //P0_3SetA + Real P0_3b1 = S1_3b2 - S0_3b3 - P0_3Gamma1*(-S0_3b3); + //S0_3SetA + Real S0_3b1 = Cib - S0_3Gamma1*(Cib + ViE + P0_3b1); + Cia = S0_3b1; + //RiSetA + //printf("Vk=%f Vg=%f Vd=%f in=%f out=%f\n", Vk,Vg,Vd, ViE,Roa); + return -Roa; + } + + Real advanc_sixties(Real ViE) { //Get Bs //S2_3GetB //P2_3GetB @@ -144,7 +230,22 @@ public: //Cia = S0_3b1; //RiSetA //printf("Vk=%f Vg=%f Vpk=%f in=%f out=%f\n", Vk,Vg,S2_3b3, ViE,Roa); - return Roa; + return -Roa; + } + + void set_mode(enum tube_mode newmode) { + warmup_tubes(); + mode = newmode; + } + + Real run(Real input) { + Real output = (mode == TUBE_MODE_SIXTIES) ? advanc_sixties(input) : advanc_gridleak(input); + if (counter > 0) { + counter--; + return 0.; + } else { + return output; + } } private: |