Example #1
0
        /// <devdoc>
        /// Evaluates the transfer function of a Bessel filter. The gain is normalized to 1 for DC.
        /// It returns a complex number that corresponds to the gain and phase of the filter output.
        /// </devdoc>
        private static Complex TransferFunction(double[] besselPolynomialCoefficients, Complex frequency)
        {
            var f = new Polynomials.RationalFraction
            {
                Top    = new double[] { besselPolynomialCoefficients[besselPolynomialCoefficients.Length - 1] }, // to normalize gain at DC
                Bottom = besselPolynomialCoefficients
            };

            return(Polynomials.Evaluate(f, frequency));
        }
 /// <devdoc>
 /// Returns the IIR filter coefficients for a transfer function.
 /// Normalizes the coefficients so that a[0] is 1.
 /// </devdoc>
 private static IirFilterCoefficients ComputeIirFilterCoefficients(Polynomials.RationalFraction tf, double gain)
 {
     // Note that compared to the original C code by Tony Fisher the order of the A/B coefficients
     // is reverse and the A coefficients are negated.
     double scale = tf.Bottom[0];
     var coefficients = new IirFilterCoefficients();
     coefficients.A = tf.Bottom.Select(x => x / scale / gain).ToArray();
     coefficients.A[0] = 1;
     coefficients.B = tf.Top.Select(x => x / scale / gain).ToArray();
     
     return coefficients;
 }
 private static double ComputeGain(Polynomials.RationalFraction tf, FilterKind type, double fcf1, double fcf2)
 {
     switch (type)
     {
         case FilterKind.LowPass:
             return ComputeGainAt(tf, Complex.One); // At DC
         case FilterKind.HighPass:  // At Nyquist
             return ComputeGainAt(tf, new Complex(-1, 0));
         case FilterKind.BandPass: // At center frequency
             return ComputeGainAt(tf, Mathx.Expj(2 * Math.PI * ((fcf1 + fcf2) / 2)));
         case FilterKind.BandStop: // At sqrt( [gain at DC] * [gain at samplingRate/2]
             return Math.Sqrt(ComputeGainAt(tf, Complex.One) * ComputeGainAt(tf, new Complex(-1, 0)));
         default:
             throw new System.ComponentModel.InvalidEnumArgumentException("type", (int)type, typeof(FilterKind));
     }
 }
 private static double ComputeGainAt(Polynomials.RationalFraction tf, Complex w)
 {
     return Complex.Abs(Polynomials.Evaluate(tf, w));
 }