コード例 #1
0
        private void AnalyzeCustomLpFilter()
        {
            var order = 23;
            var freq  = 0.22;

            if (filterParamsDataGrid.RowCount > 0)
            {
                order = Convert.ToInt32(filterParamsDataGrid.Rows[0].Cells[1].Value);
                freq  = Convert.ToDouble(filterParamsDataGrid.Rows[1].Cells[1].Value);
            }

            orderNumeratorTextBox.Text   = (order - 1).ToString();
            orderDenominatorTextBox.Text = (order - 1).ToString();

            _filter = new FirFilter(DesignFilter.FirWinLp(order, freq));

            // for double precision and FDA:

            //var tf = new TransferFunction(DesignFilter.FirWinLp(order, freq));
            //_filter = new FirFilter(tf);

            filterParamsDataGrid.RowCount = 2;
            filterParamsDataGrid.Rows[0].Cells[0].Value = "order";
            filterParamsDataGrid.Rows[0].Cells[1].Value = order;
            filterParamsDataGrid.Rows[1].Cells[0].Value = "freq";
            filterParamsDataGrid.Rows[1].Cells[1].Value = freq;
        }
コード例 #2
0
ファイル: Resampler.cs プロジェクト: artemiusgreat/Waves
        /// <summary>
        /// Does interpolation of <paramref name="signal"/> followed by lowpass filtering.
        /// </summary>
        /// <param name="signal">Signal</param>
        /// <param name="factor">Interpolation factor (e.g. factor=2 if 8000 Hz -> 16000 Hz)</param>
        /// <param name="filter">Lowpass anti-aliasing filter</param>
        public DiscreteSignal Interpolate(DiscreteSignal signal, int factor, FirFilter filter = null)
        {
            if (factor == 1)
            {
                return(signal.Copy());
            }

            var output = new float[signal.Length * factor];

            var pos = 0;

            for (var i = 0; i < signal.Length; i++)
            {
                output[pos] = factor * signal[i];
                pos        += factor;
            }

            var lpFilter = filter;

            if (filter is null)
            {
                var filterSize = factor > MinResamplingFilterOrder / 2 ?
                                 2 * factor + 1 :
                                 MinResamplingFilterOrder;

                lpFilter = new FirFilter(DesignFilter.FirWinLp(filterSize, 0.5f / factor));
            }

            return(lpFilter.ApplyTo(new DiscreteSignal(signal.SamplingRate * factor, output)));
        }
コード例 #3
0
ファイル: Resampler.cs プロジェクト: zlwind/NWaves
        /// <summary>
        /// Decimation preceded by low-pass filtering
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="factor"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public DiscreteSignal Decimate(DiscreteSignal signal, int factor, FirFilter filter = null)
        {
            if (factor == 1)
            {
                return(signal.Copy());
            }

            var filterSize = factor > MinResamplingFilterOrder / 2 ?
                             2 * factor + 1 :
                             MinResamplingFilterOrder;

            var lpFilter = filter;

            if (filter == null)
            {
                lpFilter = new FirFilter(DesignFilter.FirWinLp(filterSize, 0.5f / factor));

                signal = lpFilter.ApplyTo(signal);
            }

            var output = new float[signal.Length / factor];

            var pos = 0;

            for (var i = 0; i < output.Length; i++)
            {
                output[i] = signal[pos];
                pos      += factor;
            }

            return(new DiscreteSignal(signal.SamplingRate / factor, output));
        }
コード例 #4
0
        public FirFiltersVersion2Vs5VsZi()
        {
            _signal = new WhiteNoiseBuilder().OfLength(N).Build();

            _filterV5Kernel5  = new FirFilter(DesignFilter.FirWinLp(5, 0.1));
            _filterV2Kernel5  = new FirFilterV2(DesignFilter.FirWinLp(5, 0.1));
            _filterZiKernel5  = new ZiFilter(DesignFilter.FirWinLp(5, 0.1), new[] { 1.0 });
            _filterV5Kernel35 = new FirFilter(DesignFilter.FirWinLp(35, 0.1));
            _filterV2Kernel35 = new FirFilterV2(DesignFilter.FirWinLp(35, 0.1));
            _filterZiKernel35 = new ZiFilter(DesignFilter.FirWinLp(35, 0.1), new[] { 1.0 });
        }
コード例 #5
0
ファイル: Resampler.cs プロジェクト: zlwind/NWaves
        /// <summary>
        /// Simple resampling as the combination of interpolation and decimation.
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="up"></param>
        /// <param name="down"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public DiscreteSignal ResampleUpDown(DiscreteSignal signal, int up, int down, FirFilter filter = null)
        {
            if (up == down)
            {
                return(signal.Copy());
            }

            var newSamplingRate = signal.SamplingRate * up / down;

            if (up > 20 && down > 20)
            {
                return(Resample(signal, newSamplingRate, filter));
            }

            var output = new float[signal.Length * up];

            var pos = 0;

            for (var i = 0; i < signal.Length; i++)
            {
                output[pos] = up * signal[i];
                pos        += up;
            }

            var lpFilter = filter;

            if (filter == null)
            {
                var factor     = Math.Max(up, down);
                var filterSize = factor > MinResamplingFilterOrder / 2 ?
                                 8 * factor + 1 :
                                 MinResamplingFilterOrder;

                lpFilter = new FirFilter(DesignFilter.FirWinLp(filterSize, 0.5f / factor));
            }

            var upsampled = lpFilter.ApplyTo(new DiscreteSignal(signal.SamplingRate * up, output));

            output = new float[upsampled.Length / down];

            pos = 0;
            for (var i = 0; i < output.Length; i++)
            {
                output[i] = upsampled[pos];
                pos      += down;
            }

            return(new DiscreteSignal(newSamplingRate, output));
        }
コード例 #6
0
        private void ApplySettings()
        {
            _fftSize = int.Parse(fftSizeTextBox.Text);

            chunkTimer.Interval = int.Parse(intervalTextBox.Text);

            var kernel = DesignFilter.FirWinLp(int.Parse(kernelSizeTextBox.Text), 0.2);

            _blockConvolver = new OlaBlockConvolver(kernel, _fftSize);

            // or equivalently:
            //_blockConvolver = OlaBlockConvolver.FromFilter(new FirFilter(kernel), _fftSize);

            _output = new float[_blockConvolver.HopSize * 5];
        }
コード例 #7
0
ファイル: Resampler.cs プロジェクト: zlwind/NWaves
        /// <summary>
        /// Band-limited resampling
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="newSamplingRate"></param>
        /// <param name="filter"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public DiscreteSignal Resample(DiscreteSignal signal,
                                       int newSamplingRate,
                                       FirFilter filter = null,
                                       int order        = 15)
        {
            if (signal.SamplingRate == newSamplingRate)
            {
                return(signal.Copy());
            }

            var g = (float)newSamplingRate / signal.SamplingRate;

            var input  = signal.Samples;
            var output = new float[(int)(input.Length * g)];

            if (g < 1 && filter == null)
            {
                filter = new FirFilter(DesignFilter.FirWinLp(MinResamplingFilterOrder, g / 2));

                input = filter.ApplyTo(signal).Samples;
            }

            var step = 1 / g;

            for (var n = 0; n < output.Length; n++)
            {
                var x = n * step;

                for (var i = -order; i < order; i++)
                {
                    var j = (int)Math.Floor(x) - i;

                    if (j < 0 || j >= input.Length)
                    {
                        continue;
                    }

                    var   t    = x - j;
                    float w    = (float)(0.5 * (1.0 + Math.Cos(t / order * Math.PI)));  // Hann window
                    float sinc = (float)MathUtils.Sinc(t);                              // Sinc function
                    output[n] += w * sinc * input[j];
                }
            }

            return(new DiscreteSignal(newSamplingRate, output));
        }
コード例 #8
0
        public FirFiltersVsBlockConvolvers()
        {
            _signal = new WhiteNoiseBuilder().OfLength(N).Build();

            var kernel21 = DesignFilter.FirWinLp(21, 0.1);

            _filter21 = new FirFilter(kernel21);
            _ola21    = new OlaBlockConvolver(kernel21, 128);
            _ols21    = new OlsBlockConvolver(kernel21, 128);

            var kernel101 = DesignFilter.FirWinLp(101, 0.1);

            _filter101 = new FirFilter(kernel101);
            _filter101.KernelSizeForBlockConvolution = 2048;
            _ola101 = new OlaBlockConvolver(kernel101, 512);
            _ols101 = new OlsBlockConvolver(kernel101, 512);

            var kernel315 = DesignFilter.FirWinLp(315, 0.1);

            _filter315 = new FirFilter(kernel315);
            _filter315.KernelSizeForBlockConvolution = 2048;
            _ola315 = new OlaBlockConvolver(kernel315, 2048);
            _ols315 = new OlsBlockConvolver(kernel315, 2048);
        }
コード例 #9
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}");
        }