/* apply filter to an array of values, adding result to output array */ public void Apply( float[] XinVector, int XinVectorOffset, float[] YoutVector, int YoutVectorOffset, int VectorLength, float OutputScaling, SynthParamRec SynthParams) { SecondOrderResonRec Filter = this; float Ym1 = Filter.Ym1; float Ym2 = Filter.Ym2; float A0 = Filter.A0; float B1 = Filter.B1; float B2 = Filter.B2; for (int i = 0; i < VectorLength; i += 1) { float Xin = XinVector[i + XinVectorOffset]; float OrigYOut = YoutVector[i + YoutVectorOffset]; float Y = A0 * Xin - B1 * Ym1 - B2 * Ym2; Ym2 = Ym1; Ym1 = Y; YoutVector[i + YoutVectorOffset] = OrigYOut + Y * OutputScaling; } Filter.Ym1 = Ym1; Filter.Ym2 = Ym2; }
public static void SetSecondOrderResonCoefficients( SecondOrderResonRec Filter, double Cutoff, double Bandwidth, FilterScalings Scaling, double SamplingRate) { double B1; double B2; double OneOverSamplingRate; double HalfSamplingRateMinusEpsilon; OneOverSamplingRate = 1 / SamplingRate; HalfSamplingRateMinusEpsilon = SamplingRate * 0.5 - FILTER_FREQ_EPSILON; if (Bandwidth < FILTER_FREQ_EPSILON) { Bandwidth = FILTER_FREQ_EPSILON; } if (Bandwidth > HalfSamplingRateMinusEpsilon) { Bandwidth = HalfSamplingRateMinusEpsilon; } if (Cutoff < FILTER_FREQ_EPSILON) { Cutoff = FILTER_FREQ_EPSILON; } if (Cutoff > HalfSamplingRateMinusEpsilon) { Cutoff = HalfSamplingRateMinusEpsilon; } B2 = Math.Exp(NEGTWOPI * Bandwidth * OneOverSamplingRate); Filter.B2 = (float)B2; B1 = ((-4 * B2) / (1 + B2)) * Math.Cos(TWOPI * Cutoff * OneOverSamplingRate); Filter.B1 = (float)B1; switch (Scaling) { default: Debug.Assert(false); throw new ArgumentException(); case FilterScalings.eFilterDefaultScaling: Filter.A0 = 1; break; case FilterScalings.eFilterResonMidbandGain1: Filter.A0 = (float)((1 - B2) * Math.Sqrt(1 - B1 * B1 / (4 * B2))); break; case FilterScalings.eFilterResonNoiseGain1: double X = 1 + B2; double Y = 1 - B2; Filter.A0 = (float)(Math.Sqrt((X * X - B1 * B1) * Y / X)); break; } }