EFFECT_RESONANT_LOWPASS::EFFECT_RESONANT_LOWPASS (CHAIN_OPERATOR::parameter_t co, CHAIN_OPERATOR::parameter_t res, CHAIN_OPERATOR::parameter_t g) : ProtoCoef(2), Coef(2) { cutoff = co; Q = res; gain_orig = gain = g; laskuri = 0.0; pi = 4.0 * atan(1.0); // --- // Setup filter s-domain coefficients // --- ProtoCoef[0].a0 = 1.0; ProtoCoef[0].a1 = 0; ProtoCoef[0].a2 = 0; ProtoCoef[0].b0 = 1.0; ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q ProtoCoef[0].b2 = 1.0; ProtoCoef[1].a0 = 1.0; ProtoCoef[1].a1 = 0; ProtoCoef[1].a2 = 0; ProtoCoef[1].b0 = 1.0; ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q ProtoCoef[1].b2 = 1.0; szxform(0); szxform(1); }
static void initFilter(float fs, float fc, float *icoeff, float Q) { float *coef; double a0, a1, a2, b0, b1, b2; double k = 1.5; // Set overall filter gain factor coef = icoeff + 1; // Skip k, or gain // Section 1 a0 = 1.0; a1 = 0; a2 = 0; b0 = 1.0; b1 = 0.765367 / Q; // Divide by resonance or Q b2 = 1.0; szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef); coef += 4; // Point to next filter section // Section 2 a0 = 1.0; a1 = 0; a2 = 0; b0 = 1.0; b1 = 1.847759 / Q; b2 = 1.0; szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef); icoeff[0] = (float)k; }
void calcCoeff() { /* * Compute z-domain coefficients for each biquad section * for new Cutoff Frequency and Resonance */ unsigned nInd; double a0, a1, a2, b0, b1, b2; k = 1.0; coef = iir.coef + 1; /* Skip k, or gain */ for (nInd = 0; nInd < iir.length; nInd++) { a0 = ProtoCoef[nInd].a0; a1 = ProtoCoef[nInd].a1; a2 = ProtoCoef[nInd].a2; b0 = ProtoCoef[nInd].b0; b1 = ProtoCoef[nInd].b1 / Q; /* Divide by resonance or Q */ b2 = ProtoCoef[nInd].b2; szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef); coef += 4; /* Point to next filter section */ } /* Update overall filter gain in coef array */ iir.coef[0] = k; }
void Filter::GetOutput(int V, Sample &data) { float Cutoff; float Resonance; if (m_FilterBypass || fc<0) return; for (int n=0; n<data.GetLength(); n++) { coef = iir[V].coef + 1; /* Skip k, or gain */ k=0.25; Cutoff = fc; Resonance = Q; Cutoff/=2; if (Resonance>MAX_RES) Resonance=MAX_RES; if (Cutoff>MAX_CUTOFF) Cutoff=MAX_CUTOFF; if (Resonance<MIN_RES) Resonance=MIN_RES; if (Cutoff<MIN_CUTOFF) Cutoff=MIN_CUTOFF; if (n%10==0) { // if different from last time //if (m_LastQ!=Q || m_LastFC!=fc) { for (nInd = 0; nInd < iir[V].length; nInd++) { a2 = ProtoCoef[nInd].a2; a0 = ProtoCoef[nInd].a0; a1 = ProtoCoef[nInd].a1; b0 = ProtoCoef[nInd].b0; b1 = ProtoCoef[nInd].b1 / Resonance; b2 = ProtoCoef[nInd].b2; szxform(&a0, &a1, &a2, &b0, &b1, &b2, Cutoff*(Cutoff/1000.0f), fs, &k, coef); coef += 4; } iir[V].coef[0] = k; m_LastQ=Q; m_LastFC=fc; } } data.Set(n,iir_filter(data[n],&iir[V])); } }
void EFFECT_RESONANT_LOWPASS::refresh_values(void) { if (cutoff == 0.0) cutoff = 0.1; gain = gain_orig; // ProtoCoef[0].a0 = 1.0; ProtoCoef[0].a1 = 0; ProtoCoef[0].a2 = 0; // ProtoCoef[0].b0 = 1.0; ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q ProtoCoef[0].b2 = 1.0; // ProtoCoef[1].a0 = 1.0; ProtoCoef[1].a1 = 0; ProtoCoef[1].a2 = 0; // ProtoCoef[1].b0 = 1.0; ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q ProtoCoef[1].b2 = 1.0; szxform(0); szxform(1); }
void LPF::update(int nframes){ unsigned int j; float *hist1_ptr,*hist2_ptr,*coef_ptr; float output,new_hist,history1,history2; /* allocate history array if different size than last call */ if(!iir.history) { iir.history = (float *) calloc(2*iir.length,sizeof(float)); if(!iir.history) throw Exception("Unable to allocate history array in LPF"); } float *in = ins[0]; float *qmods = ins[1]?ins[1]:floatZeroes; float *fmods = ins[2]?ins[2]:floatZeroes; q2=q+qmod*qmods[0]; fc2=fc+fmod*fmods[0]; ///////////// INIT ///////////////////// float *coef = iir.coef + 1; /* Skip k, or gain */ extern float samprate; double fs= samprate; double k = gain; for(unsigned int i=0;i<iir.length;i++){ double a0 = protoCoef[i].a0; double a1 = protoCoef[i].a1; double a2 = protoCoef[i].a2; double b0 = protoCoef[i].b0; double b1 = protoCoef[i].b1/q2; double b2 = protoCoef[i].b2; szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc2, fs, &k, coef); coef+=4; } iir.coef[0]=k; ///////////// END OF FILTER INIT //////// for(int i=0;i<nframes;i++){ float input = *in++; coef_ptr = iir.coef; /* coefficient pointer */ hist1_ptr = iir.history; /* first history */ hist2_ptr = hist1_ptr + 1; /* next history */ /* 1st number of coefficients array is overall input scale factor, * or filter gain */ output = input * (*coef_ptr++); for(j = 0 ; j < iir.length; j++) { history1 = *hist1_ptr; /* history values */ history2 = *hist2_ptr; output = output - history1 * (*coef_ptr++); new_hist = output - history2 * (*coef_ptr++); /* poles */ output = new_hist + history1 * (*coef_ptr++); output = output + history2 * (*coef_ptr++); /* zeros */ *hist2_ptr++ = *hist1_ptr; *hist1_ptr++ = new_hist; hist1_ptr++; hist2_ptr++; } out[i]=output; } }