summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2019-01-14 21:34:07 +1100
committerDamien Zammit <damien@zamaudio.com>2019-01-14 21:38:42 +1100
commit05d152183a5432813dd4a73fc77393a1a85d1c96 (patch)
treee0f2165b52a677e8bbe1fbc59d7fd8b5cf2caa2f
parenta76f0fba442bad95bab835cc23c29bfd02cead86 (diff)
Improvement, less squeal - just smoother, insane now no-op
-rw-r--r--plugins/ZamTube/Makefile4
-rw-r--r--plugins/ZamTube/ZamTubePlugin.cpp50
-rw-r--r--plugins/ZamTube/ZamTubePlugin.hpp2
-rw-r--r--plugins/ZamTube/lut_current.m30
-rw-r--r--plugins/ZamTube/triode.cpp52
-rw-r--r--plugins/ZamTube/triode.h20
-rw-r--r--plugins/ZamTube/wdfcircuits.h18
7 files changed, 92 insertions, 84 deletions
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 <math.h>
-#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: