FIR フィルタ。
Inheritance: IFilter
Beispiel #1
0
        public OfflineFilterForLoopVsLinq()
        {
            _signal = new WhiteNoiseBuilder().OfLength(N).Build();

            _filter     = new IirFilter(new[] { 1, 0.2, -0.3, 0.1 }, new[] { 1, -0.7, 0.4 });
            _filterLinq = new IirFilterLinq(new[] { 1, 0.2, -0.3, 0.1 }, new[] { 1, -0.7, 0.4 });
        }
Beispiel #2
0
	public object Clone()
	{
		IirFilter f = new IirFilter(this.a, this.b, this.c);
		for (int i = 0; i < this.buf.Count; ++i)
		{
			f.GetValue(this.buf[i]);
		}
		return f;
	}
Beispiel #3
0
 public SimpleEq()
 {
     this._lowFilter  = default(IirFilter);
     this._highFilter = default(IirFilter);
     this._bassFilter = default(IirFilter);
     this.initLow();
     this.initHigh();
     this.initBass();
 }
Beispiel #4
0
    public object Clone()
    {
        IirFilter f = new IirFilter(this.a, this.b, this.c);

        for (int i = 0; i < this.buf.Count; ++i)
        {
            f.GetValue(this.buf[i]);
        }
        return(f);
    }
Beispiel #5
0
        float[] EstimateSpectrum(int idx)
        {
            var vector = _lpcVectors[idx].Features.ToDoubles();  // make new copy of array of features
            var gain   = Math.Sqrt(vector[0]);

            vector[0] = 1.0;

            var lpcFilter = new IirFilter(new[] { gain }, vector);

            return(lpcFilter.FrequencyResponse().Power.ToFloats());
        }
Beispiel #6
0
        public void TestParallelIirIir()
        {
            var f1 = new IirFilter(new[] { 1, -0.1 }, new[] { 1, 0.2 });
            var f2 = new IirFilter(new[] { 1, 0.4 }, new[] { 1, -0.6 });

            var f = f1 + f2;

            Assert.Multiple(() =>
            {
                Assert.That(f.Tf.Numerator, Is.EqualTo(new[] { 2, -0.1, 0.14 }).Within(1e-7));
                Assert.That(f.Tf.Denominator, Is.EqualTo(new[] { 1, -0.4, -0.12 }).Within(1e-7));
            });
        }
Beispiel #7
0
        public void TestParallelFirIir()
        {
            var f1 = new FirFilter(new[] { 1, -0.1 });
            var f2 = new IirFilter(new[] { 1, 0.4 }, new[] { 1, -0.6 });

            var f = f1 + f2;

            Assert.Multiple(() =>
            {
                Assert.That(f.Tf.Numerator, Is.EqualTo(new[] { 2, -0.3, 0.06 }).Within(1e-10));
                Assert.That(f.Tf.Denominator, Is.EqualTo(new[] { 1, -0.6 }).Within(1e-10));
                Assert.That(f, Is.TypeOf <IirFilter>());
            });
        }
Beispiel #8
0
        public TestOutputConsistency()
        {
            _signal = new WhiteNoiseBuilder().OfLength(N).Build();

            var biquad = new Filters.BiQuad.LowPassFilter(0.1);
            var butter = new Filters.Butterworth.LowPassFilter(0.1, 6);

            _filterV4BiQuad       = new IirFilterV4(biquad.Tf);
            _filterV5BiQuad       = new IirFilter(biquad.Tf);
            _filterZiBiQuad       = new ZiFilter(biquad.Tf);
            _filterV4Butterworth6 = new IirFilterV4(butter.Tf);
            _filterV5Butterworth6 = new IirFilter(butter.Tf);
            _filterZiButterworth6 = new ZiFilter(butter.Tf);
        }
Beispiel #9
0
        public void TestSequentialFirIir()
        {
            var f1 = new FirFilter(new[] { 1, 0.4 });
            var f2 = new IirFilter(new[] { 1, -0.1 }, new[] { 1, 0.2 });

            var f = f1 * f2;

            Assert.Multiple(() =>
            {
                Assert.That(f.Tf.Numerator, Is.EqualTo(new[] { 1, 0.3, -0.04 }).Within(1e-7));
                Assert.That(f.Tf.Denominator, Is.EqualTo(new[] { 1, 0.2 }).Within(1e-7));
                Assert.That(f, Is.TypeOf <IirFilter>());
            });
        }
Beispiel #10
0
 static void Write(StreamWriter writer, string title, IirFilter f)
 {
     writer.Write("{0}\n", title);
     writer.Write("{0}", f.A[0]);
     for (int i = 1; i < f.A.Length; ++i)
     {
         writer.Write(", {0}", f.A[i]);
     }
     writer.Write("\n");
     writer.Write("{0}", f.B[0]);
     for (int i = 1; i < f.B.Length; ++i)
     {
         writer.Write(", {0}", f.B[i]);
     }
     writer.Write("\n");
 }
Beispiel #11
0
        public void Test60HzFilterTaps()
        {
            List <double> input;
            List <double> expectedOutput;

            GetInputAndExpected(out input, out expectedOutput);

            var filter = new IirFilter(A60, B60);


            var actualOutput = filter.Filter(input.ToArray());

            var equal = expectedOutput.ContentsEqual(actualOutput, .000001);

            Assert.IsTrue(equal);
        }
Beispiel #12
0
        public void TestIir()
        {
            var filter = new IirFilter(_a, _b);

            var actual   = filter.Filter(GetInput2().ToArray());
            var expected = GetOutput2();

            var equal = expected.ContentsEqual(actual, .0001);

            if (!equal)
            {
                expected.Print();
                Console.WriteLine();
                actual.Print();
            }

            Assert.IsTrue(equal);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="gain"></param>
        /// <param name="mix"></param>
        /// <param name="q"></param>
        /// <param name="dist"></param>
        /// <param name="rh"></param>
        /// <param name="rl"></param>
        public TubeDistortionEffect(float gain = 20.0f,
                                    float mix  = 0.9f,
                                    float q    = -0.2f,
                                    float dist = 5,
                                    float rh   = 0.995f,
                                    float rl   = 0.5f)
        {
            Gain = gain;
            Mix  = mix;
            Q    = q;
            Dist = dist;
            Rh   = rh;
            Rl   = rl;

            var filter1 = new IirFilter(new[] { 1.0, -2, 1 }, new[] { 1.0, -2 * Rh, Rh * Rh });
            var filter2 = new IirFilter(new[] { 1.0 - Rl }, new[] { 1.0, -Rl });

            _outputFilter = filter1 * filter2;
        }
Beispiel #14
0
        public void TestIirAllZeros()
        {
            var input = Enumerable.Repeat(0.0, 300);

            var filter = new IirFilter(_a, _b);

            var actual   = filter.Filter(input.ToArray());
            var expected = input.ToArray();

            var equal = expected.ContentsEqual(actual, .0001);

            if (!equal)
            {
                expected.Print();
                Console.WriteLine();
                actual.Print();
            }

            Assert.IsTrue(equal);
        }
        public IirFiltersVersion2Vs4Vs5VsZi()
        {
            _signal = new WhiteNoiseBuilder().OfLength(N).Build();

            var biquad = new Filters.BiQuad.LowPassFilter(0.1);
            var butter = new Filters.Butterworth.LowPassFilter(0.1, 6);
            var custom = new TransferFunction(new[] { 1.0, 0.2, -0.4, 0.3 }, new[] { 1.0, -0.5 });

            _filterV2BiQuad       = new IirFilterV2(biquad.Tf);
            _filterV4BiQuad       = new IirFilterV4(biquad.Tf);
            _filterV5BiQuad       = new IirFilter(biquad.Tf);
            _filterZiBiQuad       = new ZiFilter(biquad.Tf);
            _filterV2Butterworth6 = new IirFilterV2(butter.Tf);
            _filterV4Butterworth6 = new IirFilterV4(butter.Tf);
            _filterV5Butterworth6 = new IirFilter(butter.Tf);
            _filterZiButterworth6 = new ZiFilter(butter.Tf);
            _filterV2Custom       = new IirFilterV2(custom);
            _filterV4Custom       = new IirFilterV4(custom);
            _filterV5Custom       = new IirFilter(custom);
            _filterZiCustom       = new ZiFilter(custom);
        }
Beispiel #16
0
        public void Run()
        {
            var output2  = new float[_signal.Length];
            var output4  = new float[_signal.Length];
            var output5  = new float[_signal.Length];
            var outputZi = new float[_signal.Length];

            var samples = _signal.Samples;

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4BiQuad.Process(samples[i]);
                output5[i]  = _filterV5BiQuad.Process(samples[i]);
                outputZi[i] = _filterZiBiQuad.Process(samples[i]);
            }

            var diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            var diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4Butterworth6.Process(samples[i]);
                output5[i]  = _filterV5Butterworth6.Process(samples[i]);
                outputZi[i] = _filterZiButterworth6.Process(samples[i]);
            }

            diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");


            // === MISC ====

            var med  = new MedianFilter();
            var med2 = new MedianFilter2();

            var medOut  = med.ApplyTo(_signal).Samples;
            var medOut2 = med2.ApplyTo(_signal).Samples;

            var diffAverageMed = medOut.Zip(medOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MedianFilter vs. MedianFilter2 : {diffAverageMed}");


            var ma    = new MovingAverageFilter();
            var maRec = new MovingAverageRecursiveFilter();

            var maOut    = ma.ApplyTo(_signal).Samples;
            var maRecOut = maRec.ApplyTo(_signal).Samples;

            var diffAverageMa = maOut.Zip(maRecOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MovingAverageFilter vs. MovingAverageRecursiveFilter : {diffAverageMa}");


            // 32bit vs. 64bit

            var fir32 = new FirFilter(DesignFilter.FirWinLp(7, 0.1));
            var fir64 = new FirFilter64(DesignFilter.FirWinLp(7, 0.1));

            var fir32Out = fir32.ApplyTo(_signal).Samples;
            var fir64Out = fir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageFir = fir64Out.Zip(fir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference FirFilter vs. FirFilter64 : {diffAverageFir}");


            var iir32 = new IirFilter(_filterV5Butterworth6.Tf);
            var iir64 = new IirFilter64(_filterV5Butterworth6.Tf);

            var iir32Out = iir32.ApplyTo(_signal).Samples;
            var iir64Out = iir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageIir = iir64Out.Zip(iir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference IirFilter vs. IirFilter64 : {diffAverageIir}");


            var zi32 = new ZiFilter(_filterV5Butterworth6.Tf);
            var zi64 = new ZiFilter64(_filterV5Butterworth6.Tf);

            var zi32Out = zi32.ApplyTo(_signal).Samples;
            var zi64Out = zi64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageZis = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 : {diffAverageZis}");

            zi32Out = zi32.ZeroPhase(_signal).Samples;
            zi64Out = zi64.ZeroPhase(_signal.Samples.ToDoubles());

            var diffAverageZiZeroPhase = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 (zero-phase): {diffAverageZiZeroPhase}");
        }
 public static extern void SetIirFilter(IntPtr board, IirFilter filter);
 public static extern void SetIirFilter(IntPtr config, IirFilter filter);
Beispiel #19
0
        /// <summary>
        /// Method creates overlapping ERB filters (ported from Malcolm Slaney's MATLAB code).
        /// </summary>
        /// <param name="erbFilterCount">Number of ERB filters</param>
        /// <param name="fftSize">Assumed size of FFT</param>
        /// <param name="samplingRate">Assumed sampling rate</param>
        /// <param name="lowFreq">Lower bound of the frequency range</param>
        /// <param name="highFreq">Upper bound of the frequency range</param>
        /// <param name="normalizeGain">True if gain should be normalized; false if all filters should have same height 1.0</param>
        /// <returns>Array of ERB filters</returns>
        public static float[][] Erb(
            int erbFilterCount, int fftSize, int samplingRate, double lowFreq = 0, double highFreq = 0, bool normalizeGain = true)
        {
            if (lowFreq < 0)
            {
                lowFreq = 0;
            }
            if (highFreq <= lowFreq)
            {
                highFreq = samplingRate / 2.0;
            }

            const double earQ  = 9.26449;
            const double minBw = 24.7;
            const double bw    = earQ * minBw;
            const int    order = 1;

            var t = 1.0 / samplingRate;

            var frequencies = new double[erbFilterCount];

            for (var i = 1; i <= erbFilterCount; i++)
            {
                frequencies[erbFilterCount - i] =
                    -bw + Math.Exp(i * (-Math.Log(highFreq + bw) + Math.Log(lowFreq + bw)) / erbFilterCount) * (highFreq + bw);
            }

            var ucirc = new Complex[fftSize / 2 + 1];

            for (var i = 0; i < ucirc.Length; i++)
            {
                ucirc[i] = Complex.Exp((2 * Complex.ImaginaryOne * i * Math.PI) / fftSize);
            }

            var rootPos = Math.Sqrt(3 + Math.Pow(2, 1.5));
            var rootNeg = Math.Sqrt(3 - Math.Pow(2, 1.5));

            var fft = new Fft(fftSize);

            var erbFilterBank = new float[erbFilterCount][];

            for (var i = 0; i < erbFilterCount; i++)
            {
                var cf  = frequencies[i];
                var erb = Math.Pow(Math.Pow(cf / earQ, order) + Math.Pow(minBw, order), 1.0 / order);
                var b   = 1.019 * 2 * Math.PI * erb;

                var theta  = 2 * cf * Math.PI * t;
                var itheta = Complex.Exp(2 * Complex.ImaginaryOne * theta);

                var a0 = t;
                var a2 = 0.0;
                var b0 = 1.0;
                var b1 = -2 * Math.Cos(theta) / Math.Exp(b * t);
                var b2 = Math.Exp(-2 * b * t);

                var common = -t *Math.Exp(-b *t);

                var k1 = Math.Cos(theta) + rootPos * Math.Sin(theta);
                var k2 = Math.Cos(theta) - rootPos * Math.Sin(theta);
                var k3 = Math.Cos(theta) + rootNeg * Math.Sin(theta);
                var k4 = Math.Cos(theta) - rootNeg * Math.Sin(theta);

                var a11 = common * k1;
                var a12 = common * k2;
                var a13 = common * k3;
                var a14 = common * k4;

                var gainArg = Complex.Exp(Complex.ImaginaryOne * theta - b * t);

                var gain = Complex.Abs(
                    (itheta - gainArg * k1) *
                    (itheta - gainArg * k2) *
                    (itheta - gainArg * k3) *
                    (itheta - gainArg * k4) *
                    Complex.Pow(t * Math.Exp(b * t) / (-1.0 / Math.Exp(b * t) + 1 + itheta * (1 - Math.Exp(b * t))), 4.0));

                var filter1 = new IirFilter(new[] { a0, a11, a2 }, new[] { b0, b1, b2 });
                var filter2 = new IirFilter(new[] { a0, a12, a2 }, new[] { b0, b1, b2 });
                var filter3 = new IirFilter(new[] { a0, a13, a2 }, new[] { b0, b1, b2 });
                var filter4 = new IirFilter(new[] { a0, a14, a2 }, new[] { b0, b1, b2 });

                var ir = new double[fftSize];
                ir[0] = 1.0;

                // for doubles the following code will work ok
                // (however there's a crucial lost of precision in case of floats):

                //var filter = filter1 * filter2 * filter3 * filter4;
                //ir = filter.ApplyTo(ir);

                // this code is ok both for floats and for doubles:

                ir = filter1.ApplyTo(ir);
                ir = filter2.ApplyTo(ir);
                ir = filter3.ApplyTo(ir);
                ir = filter4.ApplyTo(ir);

                var kernel = new DiscreteSignal(1, ir.Select(s => (float)(s / gain)));

                erbFilterBank[i] = fft.PowerSpectrum(kernel, false).Samples;
            }

            // normalize gain (by default)

            if (!normalizeGain)
            {
                return(erbFilterBank);
            }

            foreach (var filter in erbFilterBank)
            {
                var sum = 0.0;
                for (var j = 0; j < filter.Length; j++)
                {
                    sum += Math.Abs(filter[j] * filter[j]);
                }

                var weight = Math.Sqrt(sum * samplingRate / fftSize);

                for (var j = 0; j < filter.Length; j++)
                {
                    filter[j] = (float)(filter[j] / weight);
                }
            }

            return(erbFilterBank);
        }
 public static extern void SetIirFilter(IntPtr config, IirFilter filter);