예제 #1
0
        /// <summary>
        /// Interpolation followed by low-pass filtering
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="factor"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        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 == null)
            {
                var filterSize = factor > MinResamplingFilterOrder / 2 ?
                                 2 * factor + 1 :
                                 MinResamplingFilterOrder;

                lpFilter = DesignFilter.FirLp(filterSize, 0.5f / factor);
            }

            return(lpFilter.ApplyTo(new DiscreteSignal(signal.SamplingRate * factor, output)));
        }
예제 #2
0
        /// <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 = DesignFilter.FirLp(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));
        }
예제 #3
0
        private void ApplySettings()
        {
            _fftSize = int.Parse(fftSizeTextBox.Text);

            chunkTimer.Interval = int.Parse(intervalTextBox.Text);
            var filter = DesignFilter.FirLp(int.Parse(kernelSizeTextBox.Text), 0.2);

            _blockConvolver = OlaBlockConvolver.FromFilter(filter, _fftSize);

            _output = new float[_blockConvolver.HopSize * 5];
        }
예제 #4
0
        /// <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 = DesignFilter.FirLp(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));
        }
예제 #5
0
        /// <summary>
        /// Simple resampling (as the combination of interpolation and decimation).
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="newSamplingRate"></param>
        /// <returns></returns>
        public static DiscreteSignal Resample(DiscreteSignal signal, int newSamplingRate)
        {
            if (newSamplingRate == signal.SamplingRate)
            {
                return(signal.Copy());
            }

            var gcd = MathUtils.Gcd(signal.SamplingRate, newSamplingRate);

            var up   = newSamplingRate / gcd;
            var down = signal.SamplingRate / gcd;

            if (up > 20 && down > 20)
            {
                return(ResampleUpDown(signal, up, down));
            }

            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 factor     = Math.Max(up, down);
            var filterSize = factor > MinResamplingFilterOrder / 2 ?
                             8 * factor + 1 :
                             MinResamplingFilterOrder;

            var lpFilter = DesignFilter.FirLp(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
        /// <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 = DesignFilter.FirLp(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));
        }
예제 #7
0
        /// <summary>
        /// Resampling based on simple interpolation
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="up"></param>
        /// <param name="down"></param>
        /// <returns></returns>
        private static DiscreteSignal ResampleUpDown(DiscreteSignal signal, int up, int down)
        {
            var ratio = (float)up / down;

            var freq     = ratio > 1 ? 0.5f / ratio : 0.5f * ratio;
            var lpFilter = DesignFilter.FirLp(MinResamplingFilterOrder, freq);

            var input  = signal.Samples;
            var output = MathUtils.InterpolateLinear(
                Enumerable.Range(0, input.Length)
                .Select(s => s * ratio)
                .ToArray(),
                input,
                Enumerable.Range(0, (int)(signal.Length * ratio) + 1)
                .Select(s => (float)s)
                .ToArray());

            return(lpFilter.ApplyTo(new DiscreteSignal(signal.SamplingRate * up / down, output)));
        }
예제 #8
0
        private void AnalyzeCustomLpFilter()
        {
            var order = 15;
            var freq  = 0.1;

            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 = DesignFilter.FirLp(order, freq);

            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;
        }