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 }); }
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; }
public SimpleEq() { this._lowFilter = default(IirFilter); this._highFilter = default(IirFilter); this._bassFilter = default(IirFilter); this.initLow(); this.initHigh(); this.initBass(); }
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); }
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()); }
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)); }); }
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>()); }); }
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); }
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>()); }); }
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"); }
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); }
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; }
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); }
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);
/// <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); }