/// <summary> /// Apply filter to entire signal /// </summary> /// <param name="signal"></param> /// <param name="method"></param> /// <returns></returns> public override DiscreteSignal ApplyTo(DiscreteSignal signal, FilteringMethod method = FilteringMethod.Auto) { if (_kernel.Length >= FilterSizeForOptimizedProcessing && method == FilteringMethod.Auto) { method = FilteringMethod.OverlapAdd; } switch (method) { case FilteringMethod.OverlapAdd: { var fftSize = MathUtils.NextPowerOfTwo(4 * Kernel.Length); var blockConvolver = OlaBlockConvolver.FromFilter(this, fftSize); return(blockConvolver.ApplyTo(signal)); } case FilteringMethod.OverlapSave: { var fftSize = MathUtils.NextPowerOfTwo(4 * Kernel.Length); var blockConvolver = OlsBlockConvolver.FromFilter(this, fftSize); return(blockConvolver.ApplyTo(signal)); } case FilteringMethod.Custom: { return(this.ProcessChunks(signal)); } default: { return(ApplyFilterDirectly(signal)); } } }
/// <summary> /// Does block convolution of <paramref name="signal"/> with <paramref name="kernel"/> /// (using either Overlap-Add or Overlap-Save algorithm). /// </summary> /// <param name="signal">Signal</param> /// <param name="kernel">Convolution kernel</param> /// <param name="fftSize">FFT size</param> /// <param name="method">Block convolution method (OverlapAdd / OverlapSave)</param> public static DiscreteSignal BlockConvolve(DiscreteSignal signal, DiscreteSignal kernel, int fftSize, FilteringMethod method = FilteringMethod.OverlapSave) { IFilter blockConvolver; if (method == FilteringMethod.OverlapAdd) { blockConvolver = new OlaBlockConvolver(kernel.Samples, fftSize); } else { blockConvolver = new OlsBlockConvolver(kernel.Samples, fftSize); } return(blockConvolver.ApplyTo(signal)); }
/// <summary> /// Method implements block convolution of signals (using either OLA or OLS algorithm) /// </summary> /// <param name="signal"></param> /// <param name="kernel"></param> /// <param name="fftSize"></param> /// <param name="method"></param> /// <returns></returns> public static DiscreteSignal BlockConvolve(DiscreteSignal signal, DiscreteSignal kernel, int fftSize, FilteringMethod method = FilteringMethod.OverlapSave) { if (kernel.Length > fftSize) { throw new ArgumentException("Kernel length must not exceed the size of FFT!"); } IFilter blockConvolver; if (method == FilteringMethod.OverlapAdd) { blockConvolver = new OlaBlockConvolver(kernel.Samples, fftSize); } else { blockConvolver = new OlsBlockConvolver(kernel.Samples, fftSize); } return(blockConvolver.ApplyTo(signal)); }
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); }