void next_k(int inNumSamples) { float newFreq = in0(1); float newQ = in0(2); float newHPCutoff = in0(3); if (q != newQ) set_q(newQ); if (newHPCutoff != hpCutoff) setFeedbackHPF(newHPCutoff * sampleDur()); double a, a_inv, a2, b, b2, c, g, g0; calcFilterCoefficients(newFreq, a, a2, a_inv, b, b2, c, g, g0); double z0 = z[0]; double z1 = z[1]; double z2 = z[2]; double z3 = z[3]; double z4 = z[4]; const float * inSig = zin(0); float * outSig = zout(0); for (int i = 0; i != inNumSamples; ++i) { double x = ZXP(inSig); ZXP(outSig) = tick(x, a, a2, a_inv, b, b2, c, g, g0, z0, z1, z2, z3, z4); } z[0] = z0; z[1] = z1; z[2] = z2; z[3] = z3; z[4] = z4; }
void calcFilterCoefficients(const double newFreq, double & a, double & a2, double & a_inv, double & b, double & b2, double & c, double & g, double & g0) { double fc = sc_max(10, newFreq) * sampleDur(); fc = sc_min(fc, 0.25); a = M_PI * fc; // PI is Nyquist frequency // a = 2 * tan(0.5*a); // dewarping, not required with 2x oversampling a_inv = 1/a; a2 = a*a; b = 2*a + 1; b2 = b*b; c = 1 / (2*a2*a2 - 4*a2*b2 + b2*b2); g0 = 2*a2*a2*c; g = g0 * bh; }
MySaw2() { // 1. set the calculation function. if (isAudioRateIn(0)) { // if the frequency argument is audio rate set_calc_function<MySaw2,&MySaw2::next_a>(); } else { // if thene frequency argument is control rate (or a scalar). set_calc_function<MySaw2,&MySaw2::next_k>(); } // 2. initialize the unit generator state variables. // initialize a constant for multiplying the frequency mFreqMul = 2.0 * sampleDur(); // get initial phase of oscillator mPhase = in0(1); // 3. calculate one sample of output. if (isAudioRateIn(0)) { next_a(1); } else { next_k(1); } }