示例#1
0
        static PoleZero BilinearTransform(PoleZero sFilter, double fs)
        {
            // Convert from s-domain to z-domain using the bilinear transform:
            // s = K * (z-1) / (z+1); K = 2 / fs
            // http://en.wikipedia.org/wiki/Bilinear_transform
            var sPoles = sFilter.Poles;
            var sZeros = sFilter.Zeros;
            var poles  = new List <Complex>();
            var zeros  = new List <Complex>();
            var gain   = Complex.One;

            for (int i = 0; i < sPoles.Length; i++)
            {
                zeros.Add(-1);
                poles.Add((2 + sPoles[i] * fs) / (2 - sPoles[i] * fs));
                gain *= fs / (2 - sPoles[i] * fs);
            }

            for (int i = 0; i < sZeros.Length; i++)
            {
                poles.Add(-1);
                zeros.Add((2 + sZeros[i] * fs) / (2 - sZeros[i] * fs));
                gain *= (2 - sZeros[i] * fs) / fs;
            }

            PoleZero zFilter;

            zFilter.Poles = poles.ToArray();
            zFilter.Zeros = zeros.ToArray();
            zFilter.Gain  = (sFilter.Gain * gain).Real;
            return(zFilter);
        }
示例#2
0
        static PoleZero BandPass(PoleZero filter, double fl, double fh, double c)
        {
            // Apply lowpass to bandpass frequency transformation:
            // http://en.wikipedia.org/wiki/Prototype_filter
            var filterPoles = filter.Poles;
            var filterZeros = filter.Zeros;
            var poles       = new List <Complex>();
            var zeros       = new List <Complex>();
            var gain        = Complex.One;

            for (int i = 0; i < filterPoles.Length; i++)
            {
                var b = (filterPoles[i] / c) * (fh - fl) / 2;
                zeros.Add(0);
                poles.Add(b + Complex.Sqrt(b * b - fh * fl));
                poles.Add(b - Complex.Sqrt(b * b - fh * fl));
                gain *= (fh - fl) / c;
            }

            for (int i = 0; i < filterZeros.Length; i++)
            {
                var b = (filterZeros[i] / c) * (fh - fl) / 2;
                poles.Add(0);
                zeros.Add(b + Complex.Sqrt(b * b - fh * fl));
                zeros.Add(b - Complex.Sqrt(b * b - fh * fl));
                gain *= c / (fh - fl);
            }

            PoleZero bandPass;

            bandPass.Poles = poles.ToArray();
            bandPass.Zeros = zeros.ToArray();
            bandPass.Gain  = (filter.Gain * gain).Real;
            return(bandPass);
        }
示例#3
0
        static PoleZero HighPass(PoleZero filter, double fc, double c)
        {
            // Apply lowpass to highpass frequency transformation:
            // http://en.wikipedia.org/wiki/Prototype_filter
            var filterPoles = filter.Poles;
            var filterZeros = filter.Zeros;
            var poles       = new List <Complex>();
            var zeros       = new List <Complex>();
            var gain        = Complex.One;

            for (int i = 0; i < filterPoles.Length; i++)
            {
                zeros.Add(0);
                poles.Add(fc * c / filterPoles[i]);
                gain *= -1 / filterPoles[i];
            }

            for (int i = 0; i < filterZeros.Length; i++)
            {
                poles.Add(0);
                zeros.Add(fc * c / filterZeros[i]);
                gain *= -filterPoles[i];
            }

            PoleZero highPass;

            highPass.Poles = poles.ToArray();
            highPass.Zeros = zeros.ToArray();
            highPass.Gain  = (filter.Gain * gain).Real;
            return(highPass);
        }
示例#4
0
 static void TransferFunction(PoleZero filter, out Complex[] b, out Complex[] a)
 {
     // Conversion from pole-zero specification to transfer function
     b = Coefficients(filter.Zeros);
     a = Coefficients(filter.Poles);
     for (int i = 0; i < b.Length; i++)
     {
         b[i] *= filter.Gain;
     }
 }
示例#5
0
        static PoleZero Reduce(PoleZero filter)
        {
            var poles  = new List <Complex>();
            var zeros  = new List <Complex>();
            var hitMap = new Dictionary <Complex, int>();

            for (int i = 0; i < filter.Poles.Length; i++)
            {
                int hits;
                var pole = filter.Poles[i];
                hitMap.TryGetValue(pole, out hits);
                hitMap[pole] = hits + 1;
                poles.Add(pole);
            }

            for (int i = 0; i < filter.Zeros.Length; i++)
            {
                int hits;
                var zero = filter.Zeros[i];
                hitMap.TryGetValue(zero, out hits);
                if (hits > 0)
                {
                    hitMap[zero]--;
                    poles.Remove(zero);
                }
                else
                {
                    zeros.Add(zero);
                }
            }

            PoleZero result;

            result.Poles = poles.ToArray();
            result.Zeros = zeros.ToArray();
            result.Gain  = filter.Gain;
            return(result);
        }
示例#6
0
        internal static void GetFilterCoefficients(PoleZero sFilter, double[] fs, FilterType ftype, out double[] b, out double[] a)
        {
            // Pre-warp cutoff frequency
            fs = Array.ConvertAll(fs, fc => 2 * Math.Tan(Math.PI * fc));

            // Transform filter frequencies
            switch (ftype)
            {
            case FilterType.LowPass:
                sFilter = LowPass(sFilter, fs[0], 1.0);
                break;

            case FilterType.HighPass:
                sFilter = HighPass(sFilter, fs[0], 1.0);
                break;

            case FilterType.BandPass:
                sFilter = BandPass(sFilter, fs[0], fs[1], 1.0);
                break;

            case FilterType.BandStop:
                sFilter = BandStop(sFilter, fs[0], fs[1], 1.0);
                break;
            }

            // Convert from s-domain to z-domain
            var zFilter = BilinearTransform(sFilter, 1.0);

            zFilter = Reduce(zFilter);

            // Output transfer function coefficients
            Complex[] bz, az;
            TransferFunction(zFilter, out bz, out az);
            b = Array.ConvertAll(bz, c => c.Real);
            a = Array.ConvertAll(az, c => c.Real);
        }