Code: Select all
// prewarp for BZT
double wd = 2*pi*m_dFc;
double T = 1/(double)m_nSampleRate;
double wa = (2/T)*tan(wd*T/2);
double g = wa*T/2;
float G = g/(1.0 + g);
// set betas all are in the form of <something>/((1 + g)
m_LPF2.m_fBeta = (m_dK - m_dK*G)/(1.0 + g);
m_HPF1.m_fBeta = -1.0/(1.0 + g);
// set m_dAlpha0 variable
m_dAlpha0 = 1.0/(1.0 - m_dK*G + m_dK*G*G);
Code: Select all
g = tan(cutoff * .4999 * M_PI);
G = g / (1.0 + g);
// adjust K to never be zero and use a cube to help with the fine tuning at hi rez
K = clamp((1.0 - cube(resonance)) * 3.0, .0001, 2.97);
lpf2_beta = (K - K * G) / (1.0 + g);
hpf1_beta = -1.0 / (1.0 + g);
alpha = 1.0 / (1.0 - K * G + K * G * G);
Anyway, the resonance works, although it needs some fine tuning on the upper end. g properly falls into the range of 0..inf (actually, ~3183.1, avoiding the NaN at .5), and G follows a nice tanh curve. All well and good.
However, the cutoff does not work at all. I've checked my code against Pirkle and Surge and it appears correct.
Code: Select all
// i = input sample
// LPF1
double v1 = (i - z1) * G;
double lp1 = v1 + z1;
z1 = v1 + lp1;
double S35 = (lpf2_beta * z2) + (hpf1_beta * z3);
double u = alpha * (z1 + S35);
// Using 2.0 as a temp saturation value until we get cutoff working
u = tanh(u * 2.0);
// LPF2
double v2 = (v1 - z2) * G;
double lp2 = v2 + z2;
z2 = v2 + lp2;
// HPF
double v3 = (v2 - z3) * G;
double hp1 = i - v3 + z3;
z3 = v3 + hp1;
return z3/K;
Can anybody explain this to me ... slowly?
I've glanced over the whole paper, but the math in turning electronic components into formulae still makes my eyes and brain glaze over.