/// <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;
 }
Ejemplo n.º 2
0
        public IirFilter(IirFilterCoefficients coefficients)
        {
            Debug.Assert(coefficients != null);
            Debug.Assert(coefficients.A.Length > 0 && coefficients.B.Length > 0 && coefficients.A[0] == 1.0);

            IsEnabled = true;

            _a    = coefficients.A;
            _b    = coefficients.B;
            _nb   = _b.Length - 1;
            _na   = _a.Length - 1;
            _buf1 = new double[_nb];
            _buf2 = new double[_na];
        }
Ejemplo n.º 3
0
        public BiquadFilter(IirFilterCoefficients coefficients)
        {
            Debug.Assert(coefficients != null);
            Debug.Assert(coefficients.B != null && coefficients.B.Length == 3);
            Debug.Assert(coefficients.A != null && coefficients.A.Length == 3);

            IsEnabled = true;

            // From http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt:
            //
            //            b0 + b1*z^-1 + b2*z^-2
            //    H(z) = ------------------------                                  (Eq 1)
            //            a0 + a1*z^-1 + a2*z^-2
            //
            // This shows 6 coefficients instead of 5 so, depending on your architechture,
            // you will likely normalize a0 to be 1 and perhaps also b0 to 1 (and collect
            // that into an overall gain coefficient).  Then your transfer function would
            // look like:
            //
            //            (b0/a0) + (b1/a0)*z^-1 + (b2/a0)*z^-2
            //    H(z) = ---------------------------------------                   (Eq 2)
            //               1 + (a1/a0)*z^-1 + (a2/a0)*z^-2
            //
            // or

            //                      1 + (b1/b0)*z^-1 + (b2/b0)*z^-2
            //    H(z) = (b0/a0) * ---------------------------------               (Eq 3)
            //                      1 + (a1/a0)*z^-1 + (a2/a0)*z^-2
            //
            //
            // The most straight forward implementation would be the "Direct Form 1"
            // (Eq 2):

            //    y[n] = (b0/a0)*x[n] + (b1/a0)*x[n-1] + (b2/a0)*x[n-2]
            //                        - (a1/a0)*y[n-1] - (a2/a0)*y[n-2]            (Eq 4)

            _b0 = coefficients.B[0] / coefficients.A[0];
            _b1 = coefficients.B[1] / coefficients.A[0];
            _b2 = coefficients.B[2] / coefficients.A[0];
            _a1 = coefficients.A[1] / coefficients.A[0];
            _a2 = coefficients.A[2] / coefficients.A[0];
        }
 private static IOnlineFilter Create(IirFilterCoefficients coefficients)
 {
     return new IirFilter(coefficients);
 }
Ejemplo n.º 5
0
 private static IOnlineFilter CreateCascade(int order, IirFilterCoefficients coefficients)
 {
     return(new FilterCascade(Enumerable.Range(0, order).Select(_ => new BiquadFilter(coefficients)).ToArray()));
 }