From 92e4133abca72c909c308c4db2e058579f32d146 Mon Sep 17 00:00:00 2001 From: ar1st0crat Date: Thu, 30 Sep 2021 14:39:12 +0300 Subject: [PATCH] refactor IIR filters; update XML comments --- NWaves/Filters/Bessel/BandPassFilter.cs | 47 ++++-- NWaves/Filters/Bessel/BandStopFilter.cs | 47 ++++-- NWaves/Filters/Bessel/HighPassFilter.cs | 34 ++-- NWaves/Filters/Bessel/LowPassFilter.cs | 34 ++-- NWaves/Filters/BiQuad/AllPassFilter.cs | 24 +-- NWaves/Filters/BiQuad/BandPassFilter.cs | 24 +-- NWaves/Filters/BiQuad/HighPassFilter.cs | 24 +-- NWaves/Filters/BiQuad/HighShelfFilter.cs | 22 +-- NWaves/Filters/BiQuad/LowPassFilter.cs | 22 +-- NWaves/Filters/BiQuad/LowShelfFilter.cs | 22 +-- NWaves/Filters/BiQuad/NotchFilter.cs | 22 +-- NWaves/Filters/BiQuad/PeakFilter.cs | 22 +-- NWaves/Filters/Butterworth/BandPassFilter.cs | 57 +++++-- NWaves/Filters/Butterworth/BandStopFilter.cs | 57 +++++-- NWaves/Filters/Butterworth/HighPassFilter.cs | 43 +++-- NWaves/Filters/Butterworth/LowPassFilter.cs | 30 ++-- NWaves/Filters/ChebyshevI/BandPassFilter.cs | 69 +++++--- NWaves/Filters/ChebyshevI/BandStopFilter.cs | 69 +++++--- NWaves/Filters/ChebyshevI/HighPassFilter.cs | 55 +++++-- NWaves/Filters/ChebyshevI/LowPassFilter.cs | 41 +++-- NWaves/Filters/ChebyshevII/BandPassFilter.cs | 70 +++++--- NWaves/Filters/ChebyshevII/BandStopFilter.cs | 70 +++++--- NWaves/Filters/ChebyshevII/HighPassFilter.cs | 57 ++++--- NWaves/Filters/ChebyshevII/LowPassFilter.cs | 43 +++-- NWaves/Filters/Elliptic/BandPassFilter.cs | 63 ++++++-- NWaves/Filters/Elliptic/BandStopFilter.cs | 63 ++++++-- NWaves/Filters/Elliptic/HighPassFilter.cs | 49 ++++-- NWaves/Filters/Elliptic/LowPassFilter.cs | 49 ++++-- NWaves/Filters/Fda/DesignFirFilter.cs | 159 +++++++++---------- NWaves/Filters/Fda/DesignIirFilter.cs | 86 +++++----- NWaves/Filters/Fda/Remez.cs | 26 +-- NWaves/Filters/Fda/VtlnWarper.cs | 30 ++-- NWaves/Filters/OnePole/HighPassFilter.cs | 6 +- NWaves/Filters/OnePole/LowPassFilter.cs | 6 +- NWaves/Windows/Window.cs | 30 ++-- NWaves/Windows/WindowExtensions.cs | 22 +-- 36 files changed, 1040 insertions(+), 554 deletions(-) diff --git a/NWaves/Filters/Bessel/BandPassFilter.cs b/NWaves/Filters/Bessel/BandPassFilter.cs index 8e27b23..ffee6ce 100644 --- a/NWaves/Filters/Bessel/BandPassFilter.cs +++ b/NWaves/Filters/Bessel/BandPassFilter.cs @@ -4,37 +4,60 @@ namespace NWaves.Filters.Bessel { /// - /// Represents band-pass Bessel filter. + /// Represents bandpass Bessel filter. /// public class BandPassFilter : ZiFilter { + /// + /// Gets low cutoff frequency. + /// + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + /// /// Constructs of given - /// with given cutoff frequencies and . + /// with given cutoff frequencies and . /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order - public BandPassFilter(double f1, double f2, int order) : base(MakeTf(f1, f2, order)) + public BandPassFilter(double frequencyLow, double frequencyHigh, int order) : base(MakeTf(frequencyLow, frequencyHigh, order)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; } /// /// Generates transfer function. /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order - private static TransferFunction MakeTf(double f1, double f2, int order) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order) { - return DesignFilter.IirBpTf(f1, f2, PrototypeBessel.Poles(order)); + return DesignFilter.IirBpTf(frequencyLow, frequencyHigh, PrototypeBessel.Poles(order)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// First cutoff frequency - /// Second cutoff frequency - public void Change(double f1, double f2) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + public void Change(double frequencyLow, double frequencyHigh) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2)); + } } } diff --git a/NWaves/Filters/Bessel/BandStopFilter.cs b/NWaves/Filters/Bessel/BandStopFilter.cs index 083ea8b..14a59f7 100644 --- a/NWaves/Filters/Bessel/BandStopFilter.cs +++ b/NWaves/Filters/Bessel/BandStopFilter.cs @@ -4,37 +4,60 @@ namespace NWaves.Filters.Bessel { /// - /// Represents band-stop Bessel filter. + /// Represents bandstop Bessel filter. /// public class BandStopFilter : ZiFilter { + /// + /// Gets low cutoff frequency. + /// + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + /// /// Constructs of given - /// with given cutoff frequencies and . + /// with given cutoff frequencies and . /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order - public BandStopFilter(double f1, double f2, int order) : base(MakeTf(f1, f2, order)) + public BandStopFilter(double frequencyLow, double frequencyHigh, int order) : base(MakeTf(frequencyLow, frequencyHigh, order)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; } /// /// Generates transfer function. /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order - private static TransferFunction MakeTf(double f1, double f2, int order) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order) { - return DesignFilter.IirBsTf(f1, f2, PrototypeBessel.Poles(order)); + return DesignFilter.IirBsTf(frequencyLow, frequencyHigh, PrototypeBessel.Poles(order)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// First cutoff frequency - /// Second cutoff frequency - public void Change(double f1, double f2) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + public void Change(double frequencyLow, double frequencyHigh) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2)); + } } } diff --git a/NWaves/Filters/Bessel/HighPassFilter.cs b/NWaves/Filters/Bessel/HighPassFilter.cs index 0196e7b..4027345 100644 --- a/NWaves/Filters/Bessel/HighPassFilter.cs +++ b/NWaves/Filters/Bessel/HighPassFilter.cs @@ -4,33 +4,49 @@ namespace NWaves.Filters.Bessel { /// - /// Represents high-pass Bessel filter. + /// Represents highpass Bessel filter. /// public class HighPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - public HighPassFilter(double freq, int order) : base(MakeTf(freq, order)) + public HighPassFilter(double frequency, int order) : base(MakeTf(frequency, order)) { + Frequency = frequency; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - private static TransferFunction MakeTf(double freq, int order) + private static TransferFunction MakeTf(double frequency, int order) { - return DesignFilter.IirHpTf(freq, PrototypeBessel.Poles(order)); + return DesignFilter.IirHpTf(frequency, PrototypeBessel.Poles(order)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency - public void Change(double freq) => Change(MakeTf(freq, _a.Length - 1)); + /// Normalized cutoff frequency in range [0..0.5] + public void Change(double frequency) + { + Frequency = frequency; + + Change(MakeTf(frequency, _a.Length - 1)); + } } } diff --git a/NWaves/Filters/Bessel/LowPassFilter.cs b/NWaves/Filters/Bessel/LowPassFilter.cs index 9a90cf1..751ef1f 100644 --- a/NWaves/Filters/Bessel/LowPassFilter.cs +++ b/NWaves/Filters/Bessel/LowPassFilter.cs @@ -4,33 +4,49 @@ namespace NWaves.Filters.Bessel { /// - /// Represents low-pass Bessel filter. + /// Represents lowpass Bessel filter. /// public class LowPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - public LowPassFilter(double freq, int order) : base(MakeTf(freq, order)) + public LowPassFilter(double frequency, int order) : base(MakeTf(frequency, order)) { + Frequency = frequency; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - private static TransferFunction MakeTf(double freq, int order) + private static TransferFunction MakeTf(double frequency, int order) { - return DesignFilter.IirLpTf(freq, PrototypeBessel.Poles(order)); + return DesignFilter.IirLpTf(frequency, PrototypeBessel.Poles(order)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency - public void Change(double freq) => Change(MakeTf(freq, _a.Length - 1)); + /// Normalized cutoff frequency in range [0..0.5] + public void Change(double frequency) + { + Frequency = frequency; + + Change(MakeTf(frequency, _a.Length - 1)); + } } } diff --git a/NWaves/Filters/BiQuad/AllPassFilter.cs b/NWaves/Filters/BiQuad/AllPassFilter.cs index fed0266..413e1b9 100644 --- a/NWaves/Filters/BiQuad/AllPassFilter.cs +++ b/NWaves/Filters/BiQuad/AllPassFilter.cs @@ -3,14 +3,14 @@ namespace NWaves.Filters.BiQuad { /// - /// Represents BiQuad all-pass filter. + /// Represents BiQuad allpass filter. /// public class AllPassFilter : BiQuadFilter { /// /// Gets center frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -20,27 +20,27 @@ public class AllPassFilter : BiQuadFilter /// /// Constructs . /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public AllPassFilter(double freq, double q = 1) + public AllPassFilter(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } /// /// Sets filter coefficients. /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - private void SetCoefficients(double freq, double q) + private void SetCoefficients(double frequency, double q) { // The coefficients are calculated according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -58,11 +58,11 @@ private void SetCoefficients(double freq, double q) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public void Change(double freq, double q = 1) + public void Change(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } } } diff --git a/NWaves/Filters/BiQuad/BandPassFilter.cs b/NWaves/Filters/BiQuad/BandPassFilter.cs index 12b444c..0cbca1d 100644 --- a/NWaves/Filters/BiQuad/BandPassFilter.cs +++ b/NWaves/Filters/BiQuad/BandPassFilter.cs @@ -3,14 +3,14 @@ namespace NWaves.Filters.BiQuad { /// - /// Represents BiQuad band-pass filter. + /// Represents BiQuad bandpass filter. /// public class BandPassFilter : BiQuadFilter { /// /// Gets center frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -20,27 +20,27 @@ public class BandPassFilter : BiQuadFilter /// /// Constructs . /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public BandPassFilter(double freq, double q = 1) + public BandPassFilter(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } /// /// Sets filter coefficients. /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - private void SetCoefficients(double freq, double q) + private void SetCoefficients(double frequency, double q) { // The coefficients are calculated according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -58,11 +58,11 @@ private void SetCoefficients(double freq, double q) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public void Change(double freq, double q = 1) + public void Change(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } } } \ No newline at end of file diff --git a/NWaves/Filters/BiQuad/HighPassFilter.cs b/NWaves/Filters/BiQuad/HighPassFilter.cs index e0e9bf8..8acd124 100644 --- a/NWaves/Filters/BiQuad/HighPassFilter.cs +++ b/NWaves/Filters/BiQuad/HighPassFilter.cs @@ -3,14 +3,14 @@ namespace NWaves.Filters.BiQuad { /// - /// Represents BiQuad high-pass filter. + /// Represents BiQuad highpass filter. /// public class HighPassFilter : BiQuadFilter { /// /// Gets cutoff frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -20,27 +20,27 @@ public class HighPassFilter : BiQuadFilter /// /// Constructs . /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - public HighPassFilter(double freq, double q = 1) + public HighPassFilter(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } /// /// Sets filter coefficients. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - private void SetCoefficients(double freq, double q) + private void SetCoefficients(double frequency, double q) { // The coefficients are calculated according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -58,11 +58,11 @@ private void SetCoefficients(double freq, double q) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - public void Change(double freq, double q = 1) + public void Change(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } } } diff --git a/NWaves/Filters/BiQuad/HighShelfFilter.cs b/NWaves/Filters/BiQuad/HighShelfFilter.cs index b4a3d66..4b2fe39 100644 --- a/NWaves/Filters/BiQuad/HighShelfFilter.cs +++ b/NWaves/Filters/BiQuad/HighShelfFilter.cs @@ -10,7 +10,7 @@ public class HighShelfFilter : BiQuadFilter /// /// Gets shelf midpoint frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -25,32 +25,32 @@ public class HighShelfFilter : BiQuadFilter /// /// Constructs . /// - /// Shelf midpoint frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public HighShelfFilter(double freq, double q = 1, double gain = 1.0) + public HighShelfFilter(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } /// /// Sets filter coefficients. /// - /// Cutoff frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - private void SetCoefficients(double freq, double q, double gain) + private void SetCoefficients(double frequency, double q, double gain) { // The coefficients are calculated according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; Gain = gain; var ga = Math.Pow(10, gain / 40); var asqrt = Math.Sqrt(ga); - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / 2 * Math.Sqrt((ga + 1 / ga) * (1 / q - 1) + 2); var cosw = Math.Cos(omega); @@ -68,12 +68,12 @@ private void SetCoefficients(double freq, double q, double gain) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public void Change(double freq, double q = 1, double gain = 1.0) + public void Change(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } } } diff --git a/NWaves/Filters/BiQuad/LowPassFilter.cs b/NWaves/Filters/BiQuad/LowPassFilter.cs index 190bae4..c6dca74 100644 --- a/NWaves/Filters/BiQuad/LowPassFilter.cs +++ b/NWaves/Filters/BiQuad/LowPassFilter.cs @@ -10,7 +10,7 @@ public class LowPassFilter : BiQuadFilter /// /// Gets cutoff frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -20,27 +20,27 @@ public class LowPassFilter : BiQuadFilter /// /// Constructs . /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - public LowPassFilter(double freq, double q = 1) + public LowPassFilter(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } /// /// Sets filter coefficients. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - private void SetCoefficients(double freq, double q) + private void SetCoefficients(double frequency, double q) { // The coefficients are calculated automatically according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -58,11 +58,11 @@ private void SetCoefficients(double freq, double q) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Q factor - public void Change(double freq, double q = 1) + public void Change(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } } } diff --git a/NWaves/Filters/BiQuad/LowShelfFilter.cs b/NWaves/Filters/BiQuad/LowShelfFilter.cs index d04d43a..140f848 100644 --- a/NWaves/Filters/BiQuad/LowShelfFilter.cs +++ b/NWaves/Filters/BiQuad/LowShelfFilter.cs @@ -10,7 +10,7 @@ public class LowShelfFilter : BiQuadFilter /// /// Gets shelf midpoint frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -25,32 +25,32 @@ public class LowShelfFilter : BiQuadFilter /// /// Constructs . /// - /// Shelf midpoint frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public LowShelfFilter(double freq, double q = 1, double gain = 1.0) + public LowShelfFilter(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } /// /// Sets filter coefficients. /// - /// Cutoff frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - private void SetCoefficients(double freq, double q, double gain) + private void SetCoefficients(double frequency, double q, double gain) { // The coefficients are calculated according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; Gain = gain; var ga = Math.Pow(10, gain / 40); var asqrt = Math.Sqrt(ga); - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / 2 * Math.Sqrt((ga + 1 / ga) * (1 / q - 1) + 2); var cosw = Math.Cos(omega); @@ -68,12 +68,12 @@ private void SetCoefficients(double freq, double q, double gain) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized shelf midpoint frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public void Change(double freq, double q = 1, double gain = 1.0) + public void Change(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } } } \ No newline at end of file diff --git a/NWaves/Filters/BiQuad/NotchFilter.cs b/NWaves/Filters/BiQuad/NotchFilter.cs index 22be2df..ee7aa7a 100644 --- a/NWaves/Filters/BiQuad/NotchFilter.cs +++ b/NWaves/Filters/BiQuad/NotchFilter.cs @@ -10,7 +10,7 @@ public class NotchFilter : BiQuadFilter /// /// Gets center frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -20,27 +20,27 @@ public class NotchFilter : BiQuadFilter /// /// Constructs . /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public NotchFilter(double freq, double q = 1) + public NotchFilter(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } /// /// Sets filter coefficients. /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - private void SetCoefficients(double freq, double q) + private void SetCoefficients(double frequency, double q) { // The coefficients are calculated automatically according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -58,11 +58,11 @@ private void SetCoefficients(double freq, double q) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor - public void Change(double freq, double q = 1) + public void Change(double frequency, double q = 1) { - SetCoefficients(freq, q); + SetCoefficients(frequency, q); } } } diff --git a/NWaves/Filters/BiQuad/PeakFilter.cs b/NWaves/Filters/BiQuad/PeakFilter.cs index 5b4991b..82cdac5 100644 --- a/NWaves/Filters/BiQuad/PeakFilter.cs +++ b/NWaves/Filters/BiQuad/PeakFilter.cs @@ -10,7 +10,7 @@ public class PeakFilter : BiQuadFilter /// /// Gets center frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Gets Q factor. @@ -25,31 +25,31 @@ public class PeakFilter : BiQuadFilter /// /// Constructs . /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public PeakFilter(double freq, double q = 1, double gain = 1.0) + public PeakFilter(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } /// /// Sets filter coefficients. /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor /// Gain (in dB) - private void SetCoefficients(double freq, double q, double gain) + private void SetCoefficients(double frequency, double q, double gain) { // The coefficients are calculated automatically according to // audio-eq-cookbook by R.Bristow-Johnson and WebAudio API. - Freq = freq; + Frequency = frequency; Q = q; Gain = gain; var ga = Math.Pow(10, gain / 40); - var omega = 2 * Math.PI * freq; + var omega = 2 * Math.PI * frequency; var alpha = Math.Sin(omega) / (2 * q); var cosw = Math.Cos(omega); @@ -67,12 +67,12 @@ private void SetCoefficients(double freq, double q, double gain) /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Center frequency + /// Normalized center frequency in range [0..0.5] /// Q factor /// Gain (in dB) - public void Change(double freq, double q = 1, double gain = 1.0) + public void Change(double frequency, double q = 1, double gain = 1.0) { - SetCoefficients(freq, q, gain); + SetCoefficients(frequency, q, gain); } } } diff --git a/NWaves/Filters/Butterworth/BandPassFilter.cs b/NWaves/Filters/Butterworth/BandPassFilter.cs index 5e05a16..d542219 100644 --- a/NWaves/Filters/Butterworth/BandPassFilter.cs +++ b/NWaves/Filters/Butterworth/BandPassFilter.cs @@ -4,37 +4,60 @@ namespace NWaves.Filters.Butterworth { /// - /// Class for Butterworth IIR BP filter. + /// Represents bandpass Butterworth filter. /// public class BandPassFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandPassFilter(double f1, double f2, int order) : base(MakeTf(f1, f2, order)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + public BandPassFilter(double frequencyLow, double frequencyHigh, int order) : base(MakeTf(frequencyLow, frequencyHigh, order)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double f1, double f2, int order) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order) { - return DesignFilter.IirBpTf(f1, f2, PrototypeButterworth.Poles(order)); + return DesignFilter.IirBpTf(frequencyLow, frequencyHigh, PrototypeButterworth.Poles(order)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - public void Change(double f1, double f2) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + public void Change(double frequencyLow, double frequencyHigh) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2)); + } } } diff --git a/NWaves/Filters/Butterworth/BandStopFilter.cs b/NWaves/Filters/Butterworth/BandStopFilter.cs index 50ef091..3b52ac5 100644 --- a/NWaves/Filters/Butterworth/BandStopFilter.cs +++ b/NWaves/Filters/Butterworth/BandStopFilter.cs @@ -4,37 +4,60 @@ namespace NWaves.Filters.Butterworth { /// - /// Class for Butterworth IIR BS filter. + /// Represents bandstop Butterworth filter. /// public class BandStopFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandStopFilter(double f1, double f2, int order) : base(MakeTf(f1, f2, order)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + public BandStopFilter(double frequencyLow, double frequencyHigh, int order) : base(MakeTf(frequencyLow, frequencyHigh, order)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double f1, double f2, int order) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order) { - return DesignFilter.IirBsTf(f1, f2, PrototypeButterworth.Poles(order)); + return DesignFilter.IirBsTf(frequencyLow, frequencyHigh, PrototypeButterworth.Poles(order)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - public void Change(double f1, double f2) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + public void Change(double frequencyLow, double frequencyHigh) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2)); + } } } diff --git a/NWaves/Filters/Butterworth/HighPassFilter.cs b/NWaves/Filters/Butterworth/HighPassFilter.cs index 8f0e88f..d92b449 100644 --- a/NWaves/Filters/Butterworth/HighPassFilter.cs +++ b/NWaves/Filters/Butterworth/HighPassFilter.cs @@ -4,34 +4,49 @@ namespace NWaves.Filters.Butterworth { /// - /// Class for Butterworth IIR HP filter. + /// Represents highpass Butterworth filter. /// public class HighPassFilter : ZiFilter { /// - /// Constructor + /// Gets cutoff frequency. /// - /// - /// - public HighPassFilter(double freq, int order) : base(MakeTf(freq, order)) + public double Frequency { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + public HighPassFilter(double frequency, int order) : base(MakeTf(frequency, order)) { + Frequency = frequency; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - private static TransferFunction MakeTf(double freq, int order) + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + private static TransferFunction MakeTf(double frequency, int order) { - return DesignFilter.IirHpTf(freq, PrototypeButterworth.Poles(order)); + return DesignFilter.IirHpTf(frequency, PrototypeButterworth.Poles(order)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - public void Change(double freq) => Change(MakeTf(freq, _a.Length - 1)); + /// Normalized cutoff frequency in range [0..0.5] + public void Change(double frequency) + { + Frequency = frequency; + + Change(MakeTf(frequency, _a.Length - 1)); + } } } diff --git a/NWaves/Filters/Butterworth/LowPassFilter.cs b/NWaves/Filters/Butterworth/LowPassFilter.cs index cc24b9f..3b26e49 100644 --- a/NWaves/Filters/Butterworth/LowPassFilter.cs +++ b/NWaves/Filters/Butterworth/LowPassFilter.cs @@ -4,45 +4,49 @@ namespace NWaves.Filters.Butterworth { /// - /// Represents low-pass Butterworth filter. + /// Represents lowpass Butterworth filter. /// public class LowPassFilter : ZiFilter { /// /// Gets cutoff frequency. /// - public double Freq { get; private set; } + public double Frequency { get; private set; } /// /// Gets filter order. /// - public int Order { get; private set; } + public int Order => _a.Length - 1; /// - /// Constructs of given with given cutoff . + /// Constructs of given with given cutoff . /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - public LowPassFilter(double freq, int order) : base(MakeTf(freq, order)) + public LowPassFilter(double frequency, int order) : base(MakeTf(frequency, order)) { - Freq = freq; - Order = order; + Frequency = frequency; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order - private static TransferFunction MakeTf(double freq, int order) + private static TransferFunction MakeTf(double frequency, int order) { - return DesignFilter.IirLpTf(freq, PrototypeButterworth.Poles(order)); + return DesignFilter.IirLpTf(frequency, PrototypeButterworth.Poles(order)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency - public void Change(double freq) => Change(MakeTf(freq, _a.Length - 1)); + /// Normalized cutoff frequency in range [0..0.5] + public void Change(double frequency) + { + Frequency = frequency; + + Change(MakeTf(frequency, _a.Length - 1)); + } } } diff --git a/NWaves/Filters/ChebyshevI/BandPassFilter.cs b/NWaves/Filters/ChebyshevI/BandPassFilter.cs index f38c0d1..04db763 100644 --- a/NWaves/Filters/ChebyshevI/BandPassFilter.cs +++ b/NWaves/Filters/ChebyshevI/BandPassFilter.cs @@ -4,38 +4,71 @@ namespace NWaves.Filters.ChebyshevI { /// - /// Band-pass Chebyshev-I filter + /// Represents bandpass Chebyshev-I filter. /// public class BandPassFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandPassFilter(double f1, double f2, int order, double ripple = 0.1) : base(MakeTf(f1, f2, order, ripple)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public BandPassFilter(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripple)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double f1, double f2, int order, double ripple = 0.1) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) { - return DesignFilter.IirBpTf(f1, f2, PrototypeChebyshevI.Poles(order, ripple)); + return DesignFilter.IirBpTf(frequencyLow, frequencyHigh, PrototypeChebyshevI.Poles(order, ripple)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - /// - public void Change(double f1, double f2, double ripple = 0.1) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2, ripple)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequencyLow, double frequencyHigh, double ripple = 0.1) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevI/BandStopFilter.cs b/NWaves/Filters/ChebyshevI/BandStopFilter.cs index 181e69c..2fb1dd0 100644 --- a/NWaves/Filters/ChebyshevI/BandStopFilter.cs +++ b/NWaves/Filters/ChebyshevI/BandStopFilter.cs @@ -4,38 +4,71 @@ namespace NWaves.Filters.ChebyshevI { /// - /// Band-stop Chebyshev-I filter + /// Represents bandstop Chebyshev-I filter. /// public class BandStopFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandStopFilter(double f1, double f2, int order, double ripple = 0.1) : base(MakeTf(f1, f2, order, ripple)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public BandStopFilter(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripple)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double f1, double f2, int order, double ripple = 0.1) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) { - return DesignFilter.IirBsTf(f1, f2, PrototypeChebyshevI.Poles(order, ripple)); + return DesignFilter.IirBsTf(frequencyLow, frequencyHigh, PrototypeChebyshevI.Poles(order, ripple)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - /// - public void Change(double f1, double f2, double ripple = 0.1) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2, ripple)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequencyLow, double frequencyHigh, double ripple = 0.1) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevI/HighPassFilter.cs b/NWaves/Filters/ChebyshevI/HighPassFilter.cs index 8dc7e29..1057d42 100644 --- a/NWaves/Filters/ChebyshevI/HighPassFilter.cs +++ b/NWaves/Filters/ChebyshevI/HighPassFilter.cs @@ -4,36 +4,59 @@ namespace NWaves.Filters.ChebyshevI { /// - /// High-pass Chebyshev-I filter + /// Represents highpass Chebyshev-I filter. /// public class HighPassFilter : ZiFilter { /// - /// Constructor + /// Gets cutoff frequency. /// - /// - /// - /// - public HighPassFilter(double freq, int order, double ripple = 0.1) : base(MakeTf(freq, order, ripple)) + public double Frequency { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public HighPassFilter(double frequency, int order, double ripple = 0.1) : base(MakeTf(frequency, order, ripple)) { + Frequency = frequency; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - private static TransferFunction MakeTf(double freq, int order, double ripple = 0.1) + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequency, int order, double ripple = 0.1) { - return DesignFilter.IirHpTf(freq, PrototypeChebyshevI.Poles(order, ripple)); + return DesignFilter.IirHpTf(frequency, PrototypeChebyshevI.Poles(order, ripple)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - public void Change(double freq, double ripple = 0.1) => Change(MakeTf(freq, _a.Length - 1, ripple)); + /// Normalized cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequency, double ripple = 0.1) + { + Frequency = frequency; + Ripple = ripple; + + Change(MakeTf(frequency, _a.Length - 1, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevI/LowPassFilter.cs b/NWaves/Filters/ChebyshevI/LowPassFilter.cs index 73d84fd..3232b1d 100644 --- a/NWaves/Filters/ChebyshevI/LowPassFilter.cs +++ b/NWaves/Filters/ChebyshevI/LowPassFilter.cs @@ -4,36 +4,59 @@ namespace NWaves.Filters.ChebyshevI { /// - /// Represents low-pass Chebyshev-I filter. + /// Represents lowpass Chebyshev-I filter. /// public class LowPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Ripple (in dB) - public LowPassFilter(double freq, int order, double ripple = 0.1) : base(MakeTf(freq, order, ripple)) + public LowPassFilter(double frequency, int order, double ripple = 0.1) : base(MakeTf(frequency, order, ripple)) { + Frequency = frequency; + Ripple = ripple; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Ripple (in dB) - private static TransferFunction MakeTf(double freq, int order, double ripple = 0.1) + private static TransferFunction MakeTf(double frequency, int order, double ripple = 0.1) { - return DesignFilter.IirLpTf(freq, PrototypeChebyshevI.Poles(order, ripple)); + return DesignFilter.IirLpTf(frequency, PrototypeChebyshevI.Poles(order, ripple)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Ripple (in dB) - public void Change(double freq, double ripple = 0.1) => Change(MakeTf(freq, _a.Length - 1, ripple)); + public void Change(double frequency, double ripple = 0.1) + { + Frequency = frequency; + Ripple = ripple; + + Change(MakeTf(frequency, _a.Length - 1, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevII/BandPassFilter.cs b/NWaves/Filters/ChebyshevII/BandPassFilter.cs index 7759cc1..3b79c45 100644 --- a/NWaves/Filters/ChebyshevII/BandPassFilter.cs +++ b/NWaves/Filters/ChebyshevII/BandPassFilter.cs @@ -4,40 +4,74 @@ namespace NWaves.Filters.ChebyshevII { /// - /// Band-pass Chebyshev-II filter + /// Represents bandpass Chebyshev-II filter. /// public class BandPassFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandPassFilter(double f1, double f2, int order, double ripple = 0.1) : base(MakeTf(f1, f2, order, ripple)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public BandPassFilter(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripple)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double freq1, double freq2, int order, double ripple = 0.1) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) { - return DesignFilter.IirBpTf(freq1, freq2, + return DesignFilter.IirBpTf(frequencyLow, + frequencyHigh, PrototypeChebyshevII.Poles(order, ripple), PrototypeChebyshevII.Zeros(order)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - /// - public void Change(double f1, double f2, double ripple = 0.1) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2, ripple)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequencyLow, double frequencyHigh, double ripple = 0.1) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevII/BandStopFilter.cs b/NWaves/Filters/ChebyshevII/BandStopFilter.cs index 849ebb7..b5778ce 100644 --- a/NWaves/Filters/ChebyshevII/BandStopFilter.cs +++ b/NWaves/Filters/ChebyshevII/BandStopFilter.cs @@ -4,40 +4,74 @@ namespace NWaves.Filters.ChebyshevII { /// - /// Band-stop Chebyshev-II filter + /// Represents bandstop Chebyshev-II filter. /// public class BandStopFilter : ZiFilter { /// - /// Constructor + /// Gets low cutoff frequency. /// - /// - /// - /// - public BandStopFilter(double f1, double f2, int order, double ripple = 0.1) : base(MakeTf(f1, f2, order, ripple)) + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + + /// + /// Constructs of given + /// with given cutoff frequencies and . + /// + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public BandStopFilter(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripple)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - /// - private static TransferFunction MakeTf(double freq1, double freq2, int order, double ripple = 0.1) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripple = 0.1) { - return DesignFilter.IirBsTf(freq1, freq2, + return DesignFilter.IirBsTf(frequencyLow, + frequencyHigh, PrototypeChebyshevII.Poles(order, ripple), PrototypeChebyshevII.Zeros(order)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - /// - public void Change(double f1, double f2, double ripple = 0.1) => Change(MakeTf(f1, f2, (_a.Length - 1) / 2, ripple)); + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequencyLow, double frequencyHigh, double ripple = 0.1) + { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + Ripple = ripple; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevII/HighPassFilter.cs b/NWaves/Filters/ChebyshevII/HighPassFilter.cs index 91528bf..5b2bf24 100644 --- a/NWaves/Filters/ChebyshevII/HighPassFilter.cs +++ b/NWaves/Filters/ChebyshevII/HighPassFilter.cs @@ -4,38 +4,59 @@ namespace NWaves.Filters.ChebyshevII { /// - /// High-pass Chebyshev-II filter + /// Represents highpass Chebyshev-II filter. /// public class HighPassFilter : ZiFilter { /// - /// Constructor + /// Gets cutoff frequency. /// - /// - /// - /// - public HighPassFilter(double freq, int order, double ripple = 0.1) : base(MakeTf(freq, order, ripple)) + public double Frequency { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + public HighPassFilter(double frequency, int order, double ripple = 0.1) : base(MakeTf(frequency, order, ripple)) { + Frequency = frequency; + Ripple = ripple; } /// - /// TF generator + /// Generates transfer function. /// - /// - /// - /// - private static TransferFunction MakeTf(double freq, int order, double ripple = 0.1) + /// Normalized cutoff frequency in range [0..0.5] + /// Filter order + /// Ripple (in dB) + private static TransferFunction MakeTf(double frequency, int order, double ripple = 0.1) { - return DesignFilter.IirHpTf(freq, - PrototypeChebyshevII.Poles(order, ripple), - PrototypeChebyshevII.Zeros(order)); + return DesignFilter.IirHpTf(frequency, PrototypeChebyshevII.Poles(order, ripple)); } /// - /// Change filter coeffs online + /// Changes filter coefficients online (preserving the state of the filter). /// - /// - /// - public void Change(double freq, double ripple = 0.1) => Change(MakeTf(freq, _a.Length - 1, ripple)); + /// Normalized cutoff frequency in range [0..0.5] + /// Ripple (in dB) + public void Change(double frequency, double ripple = 0.1) + { + Frequency = frequency; + Ripple = ripple; + + Change(MakeTf(frequency, _a.Length - 1, ripple)); + } } } diff --git a/NWaves/Filters/ChebyshevII/LowPassFilter.cs b/NWaves/Filters/ChebyshevII/LowPassFilter.cs index 22846a1..8fb50df 100644 --- a/NWaves/Filters/ChebyshevII/LowPassFilter.cs +++ b/NWaves/Filters/ChebyshevII/LowPassFilter.cs @@ -4,38 +4,59 @@ namespace NWaves.Filters.ChebyshevII { /// - /// Represents low-pass Chebyshev-II filter. + /// Represents lowpass Chebyshev-II filter. /// public class LowPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets ripple (in dB). + /// + public double Ripple { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Ripple (in dB) - public LowPassFilter(double freq, int order, double ripple = 0.1) : base(MakeTf(freq, order, ripple)) + public LowPassFilter(double frequency, int order, double ripple = 0.1) : base(MakeTf(frequency, order, ripple)) { + Frequency = frequency; + Ripple = ripple; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Ripple (in dB) - private static TransferFunction MakeTf(double freq, int order, double ripple = 0.1) + private static TransferFunction MakeTf(double frequency, int order, double ripple = 0.1) { - return DesignFilter.IirLpTf(freq, - PrototypeChebyshevII.Poles(order, ripple), - PrototypeChebyshevII.Zeros(order)); + return DesignFilter.IirLpTf(frequency, PrototypeChebyshevII.Poles(order, ripple)); } /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Ripple (in dB) - public void Change(double freq, double ripple = 0.1) => Change(MakeTf(freq, _a.Length - 1, ripple)); + public void Change(double frequency, double ripple = 0.1) + { + Frequency = frequency; + Ripple = ripple; + + Change(MakeTf(frequency, _a.Length - 1, ripple)); + } } } diff --git a/NWaves/Filters/Elliptic/BandPassFilter.cs b/NWaves/Filters/Elliptic/BandPassFilter.cs index ea2c408..f3fa75e 100644 --- a/NWaves/Filters/Elliptic/BandPassFilter.cs +++ b/NWaves/Filters/Elliptic/BandPassFilter.cs @@ -4,35 +4,65 @@ namespace NWaves.Filters.Elliptic { /// - /// Represents band-pass elliptic filter. + /// Represents bandpass elliptic filter. /// public class BandPassFilter : ZiFilter { + /// + /// Gets low cutoff frequency. + /// + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets passband ripple (in dB). + /// + public double RipplePassband { get; private set; } + + /// + /// Gets stopband ripple (in dB). + /// + public double RippleStopband { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + /// /// Constructs of given - /// with given cutoff frequencies and . + /// with given cutoff frequencies and . /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - public BandPassFilter(double freq1, double freq2, int order, double ripplePass = 1, double rippleStop = 20) : - base(MakeTf(freq1, freq2, order, ripplePass, rippleStop)) + public BandPassFilter(double frequencyLow, double frequencyHigh, int order, double ripplePass = 1, double rippleStop = 20) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripplePass, rippleStop)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + RipplePassband = ripplePass; + RippleStopband = rippleStop; } /// /// Generates transfer function. /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - private static TransferFunction MakeTf(double freq1, double freq2, int order, double ripplePass = 1, double rippleStop = 20) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripplePass = 1, double rippleStop = 20) { - return DesignFilter.IirBpTf(freq1, freq2, + return DesignFilter.IirBpTf(frequencyLow, + frequencyHigh, PrototypeElliptic.Poles(order, ripplePass, rippleStop), PrototypeElliptic.Zeros(order, ripplePass, rippleStop)); } @@ -40,13 +70,18 @@ private static TransferFunction MakeTf(double freq1, double freq2, int order, do /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Passband ripple (in dB) /// Stopband ripple (in dB) - public void Change(double freq1, double freq2, double ripplePass = 1, double rippleStop = 20) + public void Change(double frequencyLow, double frequencyHigh, double ripplePass = 1, double rippleStop = 20) { - Change(MakeTf(freq1, freq2, (_a.Length - 1) / 2, ripplePass, rippleStop)); + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + RipplePassband = ripplePass; + RippleStopband = rippleStop; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripplePass, rippleStop)); } } } diff --git a/NWaves/Filters/Elliptic/BandStopFilter.cs b/NWaves/Filters/Elliptic/BandStopFilter.cs index ebdc552..4da7154 100644 --- a/NWaves/Filters/Elliptic/BandStopFilter.cs +++ b/NWaves/Filters/Elliptic/BandStopFilter.cs @@ -4,35 +4,65 @@ namespace NWaves.Filters.Elliptic { /// - /// Represents band-stop elliptic filter. + /// Represents bandstop elliptic filter. /// public class BandStopFilter : ZiFilter { + /// + /// Gets low cutoff frequency. + /// + public double FrequencyLow { get; private set; } + + /// + /// Gets high cutoff frequency. + /// + public double FrequencyHigh { get; private set; } + + /// + /// Gets passband ripple (in dB). + /// + public double RipplePassband { get; private set; } + + /// + /// Gets stopband ripple (in dB). + /// + public double RippleStopband { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => (_a.Length - 1) / 2; + /// /// Constructs of given - /// with given cutoff frequencies and . + /// with given cutoff frequencies and . /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - public BandStopFilter(double freq1, double freq2, int order, double ripplePass = 1, double rippleStop = 20) : - base(MakeTf(freq1, freq2, order, ripplePass, rippleStop)) + public BandStopFilter(double frequencyLow, double frequencyHigh, int order, double ripplePass = 1, double rippleStop = 20) + : base(MakeTf(frequencyLow, frequencyHigh, order, ripplePass, rippleStop)) { + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + RipplePassband = ripplePass; + RippleStopband = rippleStop; } /// /// Generates transfer function. /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - private static TransferFunction MakeTf(double freq1, double freq2, int order, double ripplePass = 1, double rippleStop = 20) + private static TransferFunction MakeTf(double frequencyLow, double frequencyHigh, int order, double ripplePass = 1, double rippleStop = 20) { - return DesignFilter.IirBsTf(freq1, freq2, + return DesignFilter.IirBsTf(frequencyLow, + frequencyHigh, PrototypeElliptic.Poles(order, ripplePass, rippleStop), PrototypeElliptic.Zeros(order, ripplePass, rippleStop)); } @@ -40,13 +70,18 @@ private static TransferFunction MakeTf(double freq1, double freq2, int order, do /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// First cutoff frequency - /// Second cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Passband ripple (in dB) /// Stopband ripple (in dB) - public void Change(double freq1, double freq2, double ripplePass = 1, double rippleStop = 20) + public void Change(double frequencyLow, double frequencyHigh, double ripplePass = 1, double rippleStop = 20) { - Change(MakeTf(freq1, freq2, (_a.Length - 1) / 2, ripplePass, rippleStop)); + FrequencyLow = frequencyLow; + FrequencyHigh = frequencyHigh; + RipplePassband = ripplePass; + RippleStopband = rippleStop; + + Change(MakeTf(frequencyLow, frequencyHigh, (_a.Length - 1) / 2, ripplePass, rippleStop)); } } } diff --git a/NWaves/Filters/Elliptic/HighPassFilter.cs b/NWaves/Filters/Elliptic/HighPassFilter.cs index 2b2d0d4..2855297 100644 --- a/NWaves/Filters/Elliptic/HighPassFilter.cs +++ b/NWaves/Filters/Elliptic/HighPassFilter.cs @@ -4,32 +4,55 @@ namespace NWaves.Filters.Elliptic { /// - /// Represents high-pass elliptic filter. + /// Represents highpass elliptic filter. /// public class HighPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets passband ripple (in dB). + /// + public double RipplePassband { get; private set; } + + /// + /// Gets stopband ripple (in dB). + /// + public double RippleStopband { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - public HighPassFilter(double freq, int order, double ripplePass = 1, double rippleStop = 20) : - base(MakeTf(freq, order, ripplePass, rippleStop)) + public HighPassFilter(double frequency, int order, double ripplePass = 1, double rippleStop = 20) : + base(MakeTf(frequency, order, ripplePass, rippleStop)) { + Frequency = frequency; + RipplePassband = ripplePass; + RippleStopband = rippleStop; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - private static TransferFunction MakeTf(double freq, int order, double ripplePass = 1, double rippleStop = 20) + private static TransferFunction MakeTf(double frequency, int order, double ripplePass = 1, double rippleStop = 20) { - return DesignFilter.IirHpTf(freq, + return DesignFilter.IirHpTf(frequency, PrototypeElliptic.Poles(order, ripplePass, rippleStop), PrototypeElliptic.Zeros(order, ripplePass, rippleStop)); } @@ -37,12 +60,16 @@ private static TransferFunction MakeTf(double freq, int order, double ripplePass /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Passband ripple (in dB) /// Stopband ripple (in dB) - public void Change(double freq, double ripplePass = 1, double rippleStop = 20) + public void Change(double frequency, double ripplePass = 1, double rippleStop = 20) { - Change(MakeTf(freq, _a.Length - 1, ripplePass, rippleStop)); + Frequency = frequency; + RipplePassband = ripplePass; + RippleStopband = rippleStop; + + Change(MakeTf(frequency, _a.Length - 1, ripplePass, rippleStop)); } } } diff --git a/NWaves/Filters/Elliptic/LowPassFilter.cs b/NWaves/Filters/Elliptic/LowPassFilter.cs index e4d2ce1..386f1fa 100644 --- a/NWaves/Filters/Elliptic/LowPassFilter.cs +++ b/NWaves/Filters/Elliptic/LowPassFilter.cs @@ -4,32 +4,55 @@ namespace NWaves.Filters.Elliptic { /// - /// Represents low-pass elliptic filter. + /// Represents lowpass elliptic filter. /// public class LowPassFilter : ZiFilter { /// - /// Constructs of given with given cutoff . + /// Gets cutoff frequency. /// - /// Cutoff frequency + public double Frequency { get; private set; } + + /// + /// Gets passband ripple (in dB). + /// + public double RipplePassband { get; private set; } + + /// + /// Gets stopband ripple (in dB). + /// + public double RippleStopband { get; private set; } + + /// + /// Gets filter order. + /// + public int Order => _a.Length - 1; + + /// + /// Constructs of given with given cutoff . + /// + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - public LowPassFilter(double freq, int order, double ripplePass = 1, double rippleStop = 20) : - base(MakeTf(freq, order, ripplePass, rippleStop)) + public LowPassFilter(double frequency, int order, double ripplePass = 1, double rippleStop = 20) : + base(MakeTf(frequency, order, ripplePass, rippleStop)) { + Frequency = frequency; + RipplePassband = ripplePass; + RippleStopband = rippleStop; } /// /// Generates transfer function. /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Filter order /// Passband ripple (in dB) /// Stopband ripple (in dB) - private static TransferFunction MakeTf(double freq, int order, double ripplePass = 1, double rippleStop = 20) + private static TransferFunction MakeTf(double frequency, int order, double ripplePass = 1, double rippleStop = 20) { - return DesignFilter.IirLpTf(freq, + return DesignFilter.IirLpTf(frequency, PrototypeElliptic.Poles(order, ripplePass, rippleStop), PrototypeElliptic.Zeros(order, ripplePass, rippleStop)); } @@ -37,12 +60,16 @@ private static TransferFunction MakeTf(double freq, int order, double ripplePass /// /// Changes filter coefficients online (preserving the state of the filter). /// - /// Cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Passband ripple (in dB) /// Stopband ripple (in dB) - public void Change(double freq, double ripplePass = 1, double rippleStop = 20) + public void Change(double frequency, double ripplePass = 1, double rippleStop = 20) { - Change(MakeTf(freq, _a.Length - 1, ripplePass, rippleStop)); + Frequency = frequency; + RipplePassband = ripplePass; + RippleStopband = rippleStop; + + Change(MakeTf(frequency, _a.Length - 1, ripplePass, rippleStop)); } } } diff --git a/NWaves/Filters/Fda/DesignFirFilter.cs b/NWaves/Filters/Fda/DesignFirFilter.cs index 4ec99ba..da9fcf6 100644 --- a/NWaves/Filters/Fda/DesignFirFilter.cs +++ b/NWaves/Filters/Fda/DesignFirFilter.cs @@ -18,23 +18,23 @@ public static partial class DesignFilter /// Designs ideal lowpass fractional-delay FIR filter using sinc-window method. /// /// Filter order - /// Normalized cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Fractional delay /// Window - public static double[] FirWinFdLp(int order, double freq, double delay, WindowType window = WindowType.Blackman) + public static double[] FirWinFdLp(int order, double frequency, double delay, WindowType window = WindowType.Blackman) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Cutoff frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Cutoff frequency"); var kernel = new double[order]; var middle = (order - 1) / 2; - var freq2Pi = 2 * Math.PI * freq; + var freq2Pi = 2 * Math.PI * frequency; for (var i = 0; i < order; i++) { var d = i - delay - middle; - kernel[i] = d == 0 ? 2 * freq : Math.Sin(freq2Pi * d) / (Math.PI * d); + kernel[i] = d == 0 ? 2 * frequency : Math.Sin(freq2Pi * d) / (Math.PI * d); } kernel.ApplyWindow(window); @@ -48,17 +48,17 @@ public static double[] FirWinFdLp(int order, double freq, double delay, WindowTy /// Designs ideal highpass fractional-delay FIR filter using sinc-window method. /// /// Filter order - /// Normalized cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Fractional delay /// Window - public static double[] FirWinFdHp(int order, double freq, double delay, WindowType window = WindowType.Blackman) + public static double[] FirWinFdHp(int order, double frequency, double delay, WindowType window = WindowType.Blackman) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Cutoff frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Cutoff frequency"); var kernel = new double[order]; var middle = (order - 1) / 2; - var freq2Pi = 2 * Math.PI * (0.5 - freq); + var freq2Pi = 2 * Math.PI * (0.5 - frequency); var sign = -1; @@ -66,7 +66,7 @@ public static double[] FirWinFdHp(int order, double freq, double delay, WindowTy { var d = i - delay - middle; - kernel[i] = d == 0 ? 2 * (0.5 - freq) : sign * Math.Sin(freq2Pi * d) / (Math.PI * d); + kernel[i] = d == 0 ? 2 * (0.5 - frequency) : sign * Math.Sin(freq2Pi * d) / (Math.PI * d); sign = -sign; } @@ -82,32 +82,32 @@ public static double[] FirWinFdHp(int order, double freq, double delay, WindowTy /// Designs ideal bandpass fractional-delay FIR filter using sinc-window method. /// /// Filter order - /// Left edge normalized cutoff frequency - /// Right edge normalized cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Fractional delay /// Window - public static double[] FirWinFdBp(int order, double freq1, double freq2, double delay, WindowType window = WindowType.Blackman) + public static double[] FirWinFdBp(int order, double frequencyLow, double frequencyHigh, double delay, WindowType window = WindowType.Blackman) { - Guard.AgainstInvalidRange(freq1, 0, 0.5, "lower frequency"); - Guard.AgainstInvalidRange(freq2, 0, 0.5, "upper frequency"); - Guard.AgainstInvalidRange(freq1, freq2, "lower frequency", "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, 0, 0.5, "low cutoff frequency"); + Guard.AgainstInvalidRange(frequencyHigh, 0, 0.5, "high cutoff frequency"); + Guard.AgainstInvalidRange(frequencyLow, frequencyHigh, "low cutoff frequency", "high cutoff frequency"); var kernel = new double[order]; var middle = (order - 1) / 2; - var freq12Pi = 2 * Math.PI * freq1; - var freq22Pi = 2 * Math.PI * freq2; + var freq12Pi = 2 * Math.PI * frequencyLow; + var freq22Pi = 2 * Math.PI * frequencyHigh; for (var i = 0; i < order; i++) { var d = i - delay - middle; - kernel[i] = d == 0 ? 2 * (freq2 - freq1) : (Math.Sin(freq22Pi * d) - Math.Sin(freq12Pi * d)) / (Math.PI * d); + kernel[i] = d == 0 ? 2 * (frequencyHigh - frequencyLow) : (Math.Sin(freq22Pi * d) - Math.Sin(freq12Pi * d)) / (Math.PI * d); } kernel.ApplyWindow(window); - NormalizeKernel(kernel, 2 * Math.PI * (freq1 + freq2) / 2); + NormalizeKernel(kernel, 2 * Math.PI * (frequencyLow + frequencyHigh) / 2); return kernel; } @@ -116,21 +116,21 @@ public static double[] FirWinFdBp(int order, double freq1, double freq2, double /// Designs ideal bandstop fractional-delay FIR filter using sinc-window method. /// /// Filter order - /// Left edge normalized cutoff frequency - /// Right edge Normalized cutoff frequency + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Fractional delay /// Window - public static double[] FirWinFdBs(int order, double freq1, double freq2, double delay, WindowType window = WindowType.Blackman) + public static double[] FirWinFdBs(int order, double frequencyLow, double frequencyHigh, double delay, WindowType window = WindowType.Blackman) { - Guard.AgainstInvalidRange(freq1, 0, 0.5, "lower frequency"); - Guard.AgainstInvalidRange(freq2, 0, 0.5, "upper frequency"); - Guard.AgainstInvalidRange(freq1, freq2, "lower frequency", "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, 0, 0.5, "low cutoff frequency"); + Guard.AgainstInvalidRange(frequencyHigh, 0, 0.5, "high cutoff frequency"); + Guard.AgainstInvalidRange(frequencyLow, frequencyHigh, "low cutoff frequency", "high cutoff frequency"); var kernel = new double[order]; var middle = (order - 1) / 2; - var freq12Pi = 2 * Math.PI * freq1; - var freq22Pi = 2 * Math.PI * (0.5 - freq2); + var freq12Pi = 2 * Math.PI * frequencyLow; + var freq22Pi = 2 * Math.PI * (0.5 - frequencyHigh); var sign = 1; @@ -138,7 +138,7 @@ public static double[] FirWinFdBs(int order, double freq1, double freq2, double { var d = i - delay - middle; - kernel[i] = d == 0 ? 2 * (0.5 - freq2 + freq1) : (Math.Sin(freq12Pi * d) + sign * Math.Sin(freq22Pi * d)) / (Math.PI * d); + kernel[i] = d == 0 ? 2 * (0.5 - frequencyHigh + frequencyLow) : (Math.Sin(freq12Pi * d) + sign * Math.Sin(freq22Pi * d)) / (Math.PI * d); sign = -sign; } @@ -151,7 +151,7 @@ public static double[] FirWinFdBs(int order, double freq1, double freq2, double } /// - /// Designs all-pass fractional-delay FIR filter using sinc-window method. + /// Designs ideal allpass fractional-delay FIR filter using sinc-window method. /// /// Filter order /// Fractional delay @@ -179,10 +179,10 @@ public static double[] FirWinFdAp(int order, double delay, WindowType window = W /// (normalizes kernel coefficients to map frequency response onto [0, 1]) /// /// Kernel - /// Frequency - public static void NormalizeKernel(double[] kernel, double freq = 0) + /// Frequency + public static void NormalizeKernel(double[] kernel, double frequency = 0) { - var w = Complex.FromPolarCoordinates(1, freq); + var w = Complex.FromPolarCoordinates(1, frequency); var gain = Complex.Abs(1 / MathUtils.EvaluatePolynomial(kernel, w)); @@ -197,80 +197,80 @@ public static void NormalizeKernel(double[] kernel, double freq = 0) #region FirWin functions - /// - /// FirWin(Lp|Hp|Bp|Bs) functions: - /// - /// as of ver.0.9.5, - /// they're coded as the special case of fractional-delay FIR filter design - /// with either delay=0 (odd order) or delay=0.5 (even order) - /// + // + // FirWin(Lp|Hp|Bp|Bs) functions: + // + // as of ver.0.9.5, + // they're coded as the special case of fractional-delay FIR filter design + // with either delay=0 (odd order) or delay=0.5 (even order) + // /// /// Designs ideal lowpass FIR filter using sinc-window method. /// /// Filter order - /// Normalized cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Window - public static double[] FirWinLp(int order, double freq, WindowType window = WindowType.Blackman) + public static double[] FirWinLp(int order, double frequency, WindowType window = WindowType.Blackman) { - return FirWinFdLp(order, freq, (order + 1) % 2 * 0.5, window); + return FirWinFdLp(order, frequency, (order + 1) % 2 * 0.5, window); } /// /// Designs ideal highpass FIR filter using sinc-window method. /// /// Filter order - /// Normalized cutoff frequency + /// Normalized cutoff frequency in range [0..0.5] /// Window - public static double[] FirWinHp(int order, double freq, WindowType window = WindowType.Blackman) + public static double[] FirWinHp(int order, double frequency, WindowType window = WindowType.Blackman) { - return FirWinFdHp(order, freq, (order + 1) % 2 * 0.5, window); + return FirWinFdHp(order, frequency, (order + 1) % 2 * 0.5, window); } /// /// Designs ideal bandpass FIR filter using sinc-window method. /// /// Filter order - /// Left edge cutoff frequency (normalized: fc1 = f1/fs) - /// Right edge cutoff frequency (normalized: fc2 = f2/fs) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Window - /// BP filter kernel - public static double[] FirWinBp(int order, double freq1, double freq2, WindowType window = WindowType.Blackman) + public static double[] FirWinBp(int order, double frequencyLow, double frequencyHigh, WindowType window = WindowType.Blackman) { - return FirWinFdBp(order, freq1, freq2, (order + 1) % 2 * 0.5, window); + return FirWinFdBp(order, frequencyLow, frequencyHigh, (order + 1) % 2 * 0.5, window); } /// /// Designs ideal bandstop FIR filter using sinc-window method. /// /// Filter order - /// Left edge cutoff frequency (normalized: fc1 = f1/fs) - /// Right edge cutoff frequency (normalized: fc2 = f2/fs) + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Window - /// BS filter kernel - public static double[] FirWinBs(int order, double freq1, double freq2, WindowType window = WindowType.Blackman) + public static double[] FirWinBs(int order, double frequencyLow, double frequencyHigh, WindowType window = WindowType.Blackman) { - return FirWinFdBs(order, freq1, freq2, (order + 1) % 2 * 0.5, window); + return FirWinFdBs(order, frequencyLow, frequencyHigh, (order + 1) % 2 * 0.5, window); } /// - /// FIR filter design using frequency sampling method + /// + /// Designs FIR filter using frequency sampling method /// (works identical to firwin2 in sciPy and fir2 in MATLAB). - /// - /// Note. By default, the FFT size is auto-computed. + /// + /// + /// Note. By default, the FFT size is auto-computed. /// If it is set explicitly, then (fftSize/2 + 1) must exceed the filter order. - /// + /// + /// /// Note. Array of frequencies can be null. - /// In this case the FFT size must be provided and size of gains array must be fftSize/2 + 1. - /// Frequencies will be uniformly sampled on range [0 .. 0.5]. - /// + /// In this case the must be provided and size of gains array must be fftSize/2 + 1. + /// Frequencies will be uniformly sampled on range [0..0.5]. + /// /// /// Filter order - /// Frequencies (frequency sampling points) in range [0, 0.5] + /// Frequencies (frequency sampling points), each in range [0..0.5] /// Filter gains at the frequency sampling points /// FFT size /// Window - /// Filter kernel public static double[] Fir(int order, double[] frequencies, double[] gain, @@ -355,7 +355,7 @@ public static double[] Fir(int order, #region equiripple FIR filter /// - /// Designs equiripple LP FIR filter using Remez (Parks-McClellan) algorithm. + /// Designs equiripple lowpass FIR filter using Remez (Parks-McClellan) algorithm. /// /// Filter order /// Passband edge frequency @@ -368,21 +368,20 @@ public static double[] FirEquirippleLp(int order, double fp, double fa, double w } /// - /// Designs equiripple HP FIR filter using Remez (Parks-McClellan) algorithm. + /// Designs equiripple highpass FIR filter using Remez (Parks-McClellan) algorithm. /// /// Filter order /// Stopband edge frequency /// Passband edge frequency /// Stopband weight /// Passband weight - /// Filter kernel public static double[] FirEquirippleHp(int order, double fa, double fp, double wa, double wp) { return new Remez(order, new[] { 0, fa, fp, 0.5 }, new[] { 0, 1.0 }, new[] { wa, wp }).Design(); } /// - /// Designs equiripple BP FIR filter using Remez (Parks-McClellan) algorithm. + /// Designs equiripple bandpass FIR filter using Remez (Parks-McClellan) algorithm. /// /// Filter order /// Left stopband edge frequency @@ -392,14 +391,13 @@ public static double[] FirEquirippleHp(int order, double fa, double fp, double w /// Left stopband weight /// Passband weight /// Right stopband weight - /// Filter kernel public static double[] FirEquirippleBp(int order, double fa1, double fp1, double fp2, double fa2, double wa1, double wp, double wa2) { return new Remez(order, new[] { 0, fa1, fp1, fp2, fa2, 0.5 }, new[] { 0, 1.0, 0 }, new[] { wa1, wp, wa2 }).Design(); } /// - /// Designs equiripple BS FIR filter using Remez (Parks-McClellan) algorithm. + /// Designs equiripple bandstop FIR filter using Remez (Parks-McClellan) algorithm. /// /// Filter order /// Left passband edge frequency @@ -409,7 +407,6 @@ public static double[] FirEquirippleBp(int order, double fa1, double fp1, double /// Left passband weight /// Stopband weight /// Right passband weight - /// Filter kernel public static double[] FirEquirippleBs(int order, double fp1, double fa1, double fa2, double fp2, double wp1, double wa, double wp2) { return new Remez(order, new[] { 0, fp1, fa1, fa2, fp2, 0.5 }, new[] { 1, 0.0, 1 }, new[] { wp1, wa, wp2 }).Design(); @@ -421,11 +418,10 @@ public static double[] FirEquirippleBs(int order, double fp1, double fa1, double #region convert LowPass FIR filter kernel between band forms /// - /// Method for making HP filter from the linear-phase LP filter. + /// Converts linear-phase lowpass filter to highpass filter with the same cutoff frequency. /// This method works only for odd-sized kernels. /// /// Lowpass filter kernel - /// Highpass filter kernel public static double[] FirLpToHp(double[] kernel) { Guard.AgainstEvenNumber(kernel.Length, "The order of the filter"); @@ -436,27 +432,24 @@ public static double[] FirLpToHp(double[] kernel) } /// - /// Method for making LP filter from the linear-phase HP filter - /// (not different from FirLpToHp method) + /// Converts linear-phase highpass filter to lowpass filter with the same cutoff frequency. + /// This method works only for odd-sized kernels. /// /// Highpass filter kernel - /// Lowpass filter kernel public static double[] FirHpToLp(double[] kernel) => FirLpToHp(kernel); /// - /// Method for making BS filter from the linear-phase BP filter - /// (not different from FirLpToHp method) + /// Converts linear-phase bandpass filter to bandstop filter with the same cutoff frequencies. + /// This method works only for odd-sized kernels. /// /// Bandpass filter kernel - /// Bandstop filter kernel public static double[] FirBpToBs(double[] kernel) => FirLpToHp(kernel); /// - /// Method for making BP filter from the linear-phase BS filter - /// (not different from FirLpToHp method) + /// Converts linear-phase bandstop filter to bandpass filter with the same cutoff frequencies. + /// This method works only for odd-sized kernels. /// /// Bandstop filter kernel - /// Bandpass filter kernel public static double[] FirBsToBp(double[] kernel) => FirLpToHp(kernel); #endregion diff --git a/NWaves/Filters/Fda/DesignIirFilter.cs b/NWaves/Filters/Fda/DesignIirFilter.cs index adf67ca..83e057e 100644 --- a/NWaves/Filters/Fda/DesignIirFilter.cs +++ b/NWaves/Filters/Fda/DesignIirFilter.cs @@ -18,13 +18,13 @@ public static partial class DesignFilter /// /// Designs IIR notch filter. /// - /// Normalized center frequency (must be in range [0, 0.5]) + /// Normalized center frequency in range [0..0.5] /// Q factor (characterizes notch filter -3dB bandwidth relative to its center frequency) - public static TransferFunction IirNotch(double freq, double q = 20.0) + public static TransferFunction IirNotch(double frequency, double q = 20.0) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Center frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Center frequency"); - var w0 = 2 * freq * Math.PI; + var w0 = 2 * frequency * Math.PI; var bw = w0 / q; var gb = 1 / Math.Sqrt(2); @@ -41,13 +41,13 @@ public static TransferFunction IirNotch(double freq, double q = 20.0) /// /// Designs IIR peak filter. /// - /// Normalized center frequency (must be in range [0, 0.5]) + /// Normalized center frequency in range [0..0.5] /// Q factor (characterizes peak filter -3dB bandwidth relative to its center frequency) - public static TransferFunction IirPeak(double freq, double q = 20.0) + public static TransferFunction IirPeak(double frequency, double q = 20.0) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Center frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Center frequency"); - var w0 = 2 * freq * Math.PI; + var w0 = 2 * frequency * Math.PI; var bw = w0 / q; var gb = 1 / Math.Sqrt(2); @@ -64,17 +64,17 @@ public static TransferFunction IirPeak(double freq, double q = 20.0) /// /// Designs IIR comb notch filter. /// - /// Normalized center frequency (must be in range [0, 0.5]) + /// Normalized center frequency in range [0..0.5] /// Q factor (characterizes notch filter -3dB bandwidth relative to its center frequency) - public static TransferFunction IirCombNotch(double freq, double q = 20.0) + public static TransferFunction IirCombNotch(double frequency, double q = 20.0) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Center frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Center frequency"); - var w0 = 2 * freq * Math.PI; + var w0 = 2 * frequency * Math.PI; var bw = w0 / q; var gb = 1 / Math.Sqrt(2); - var N = (int)(1 / freq); + var N = (int)(1 / frequency); var beta = Math.Sqrt((1 - gb * gb) / (gb * gb)) * Math.Tan(N * bw / 4); @@ -93,17 +93,17 @@ public static TransferFunction IirCombNotch(double freq, double q = 20.0) /// /// Designs IIR comb peak filter. /// - /// Normalized center frequency (must be in range [0, 0.5]) + /// Normalized center frequency in range [0..0.5] /// Q factor (characterizes peak filter -3dB bandwidth relative to its center frequency) - public static TransferFunction IirCombPeak(double freq, double q = 20.0) + public static TransferFunction IirCombPeak(double frequency, double q = 20.0) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Center frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Center frequency"); - var w0 = 2 * freq * Math.PI; + var w0 = 2 * frequency * Math.PI; var bw = w0 / q; var gb = 1 / Math.Sqrt(2); - var N = (int)(1 / freq); + var N = (int)(1 / frequency); var beta = Math.Sqrt(gb * gb / (1 - gb * gb)) * Math.Tan(N * bw / 4); @@ -127,17 +127,17 @@ public static TransferFunction IirCombPeak(double freq, double q = 20.0) /// /// Designs lowpass pole filter. /// - /// Normalized cutoff frequency in range [0, 0.5] + /// Normalized cutoff frequency in range [0..0.5] /// Analog prototype poles /// Analog prototype zeros - public static TransferFunction IirLpTf(double freq, Complex[] poles, Complex[] zeros = null) + public static TransferFunction IirLpTf(double frequency, Complex[] poles, Complex[] zeros = null) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Cutoff frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Cutoff frequency"); var pre = new double[poles.Length]; var pim = new double[poles.Length]; - var warpedFreq = Math.Tan(Math.PI * freq); + var warpedFreq = Math.Tan(Math.PI * frequency); // 1) poles of analog filter (scaled) @@ -193,17 +193,17 @@ public static TransferFunction IirLpTf(double freq, Complex[] poles, Complex[] z /// /// Designs highpass pole filter. /// - /// Normalized cutoff frequency in range [0, 0.5] + /// Normalized cutoff frequency in range [0..0.5] /// Analog prototype poles /// Analog prototype zeros - public static TransferFunction IirHpTf(double freq, Complex[] poles, Complex[] zeros = null) + public static TransferFunction IirHpTf(double frequency, Complex[] poles, Complex[] zeros = null) { - Guard.AgainstInvalidRange(freq, 0, 0.5, "Cutoff frequency"); + Guard.AgainstInvalidRange(frequency, 0, 0.5, "Cutoff frequency"); var pre = new double[poles.Length]; var pim = new double[poles.Length]; - var warpedFreq = Math.Tan(Math.PI * freq); + var warpedFreq = Math.Tan(Math.PI * frequency); // 1) poles of analog filter (scaled) @@ -259,23 +259,23 @@ public static TransferFunction IirHpTf(double freq, Complex[] poles, Complex[] z /// /// Designs bandpass pole filter. /// - /// Normalized left cutoff frequency in range [0, 0.5] - /// Normalized right cutoff frequency in range [0, 0.5] + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Analog prototype poles /// Analog prototype zeros - public static TransferFunction IirBpTf(double freq1, double freq2, Complex[] poles, Complex[] zeros = null) + public static TransferFunction IirBpTf(double frequencyLow, double frequencyHigh, Complex[] poles, Complex[] zeros = null) { - Guard.AgainstInvalidRange(freq1, 0, 0.5, "lower frequency"); - Guard.AgainstInvalidRange(freq2, 0, 0.5, "upper frequency"); - Guard.AgainstInvalidRange(freq1, freq2, "lower frequency", "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, 0, 0.5, "lower frequency"); + Guard.AgainstInvalidRange(frequencyHigh, 0, 0.5, "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, frequencyHigh, "lower frequency", "upper frequency"); var pre = new double[poles.Length * 2]; var pim = new double[poles.Length * 2]; - var centerFreq = 2 * Math.PI * (freq1 + freq2) / 2; + var centerFreq = 2 * Math.PI * (frequencyLow + frequencyHigh) / 2; - var warpedFreq1 = Math.Tan(Math.PI * freq1); - var warpedFreq2 = Math.Tan(Math.PI * freq2); + var warpedFreq1 = Math.Tan(Math.PI * frequencyLow); + var warpedFreq2 = Math.Tan(Math.PI * frequencyHigh); var f0 = Math.Sqrt(warpedFreq1 * warpedFreq2); var bw = warpedFreq2 - warpedFreq1; @@ -350,15 +350,15 @@ public static TransferFunction IirBpTf(double freq1, double freq2, Complex[] pol /// /// Designs bandstop pole filter. /// - /// Normalized left cutoff frequency in range [0, 0.5] - /// Normalized right cutoff frequency in range [0, 0.5] + /// Normalized low cutoff frequency in range [0..0.5] + /// Normalized high cutoff frequency in range [0..0.5] /// Analog prototype poles /// Analog prototype zeros - public static TransferFunction IirBsTf(double freq1, double freq2, Complex[] poles, Complex[] zeros = null) + public static TransferFunction IirBsTf(double frequencyLow, double frequencyHigh, Complex[] poles, Complex[] zeros = null) { - Guard.AgainstInvalidRange(freq1, 0, 0.5, "lower frequency"); - Guard.AgainstInvalidRange(freq2, 0, 0.5, "upper frequency"); - Guard.AgainstInvalidRange(freq1, freq2, "lower frequency", "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, 0, 0.5, "lower frequency"); + Guard.AgainstInvalidRange(frequencyHigh, 0, 0.5, "upper frequency"); + Guard.AgainstInvalidRange(frequencyLow, frequencyHigh, "lower frequency", "upper frequency"); // Calculation of filter coefficients is based on Neil Robertson's post: // https://www.dsprelated.com/showarticle/1131.php @@ -366,8 +366,8 @@ public static TransferFunction IirBsTf(double freq1, double freq2, Complex[] pol var pre = new double[poles.Length * 2]; var pim = new double[poles.Length * 2]; - var f1 = Math.Tan(Math.PI * freq1); - var f2 = Math.Tan(Math.PI * freq2); + var f1 = Math.Tan(Math.PI * frequencyLow); + var f2 = Math.Tan(Math.PI * frequencyHigh); var f0 = Math.Sqrt(f1 * f2); var bw = f2 - f1; diff --git a/NWaves/Filters/Fda/Remez.cs b/NWaves/Filters/Fda/Remez.cs index 3c8062b..4ab6499 100644 --- a/NWaves/Filters/Fda/Remez.cs +++ b/NWaves/Filters/Fda/Remez.cs @@ -17,7 +17,8 @@ namespace NWaves.Filters.Fda /// var remez = new Remez(order, freqs, response, weights);
///
/// var kernel = remez.Design();
- ///
+ ///
+ ///
/// // We can monitor the following properties:
///
/// remez.Iterations
@@ -107,20 +108,20 @@ public class Remez /// Constructs filter designer. ///
/// Order of filter - /// Array of normalized frequencies + /// Array of normalized frequencies /// Array of desired response values at given frequencies /// Array of weights at given frequencies /// Grid density - public Remez(int order, double[] freqs, double[] desired, double[] weights, int gridDensity = 16) + public Remez(int order, double[] frequencies, double[] desired, double[] weights, int gridDensity = 16) { Guard.AgainstEvenNumber(order, "The order of the filter"); - Guard.AgainstIncorrectFilterParams(freqs, desired, weights); + Guard.AgainstIncorrectFilterParams(frequencies, desired, weights); Order = order; K = Order / 2 + 2; - _freqs = freqs; + _freqs = frequencies; MakeGrid(desired, weights, gridDensity); @@ -418,10 +419,10 @@ private double Lagrange(double freq) } /// - /// Convert ripple (in dB) to passband weight. + /// Converts ripple (in dB) to passband weight. /// - /// Ripple (in dB) - public static double DbToPassbandWeight(double db) => (Math.Pow(10, db / 20) - 1) / (Math.Pow(10, db / 20) + 1); + /// Ripple (in dB) + public static double DbToPassbandWeight(double ripple) => (Math.Pow(10, ripple / 20) - 1) / (Math.Pow(10, ripple / 20) + 1); /// /// Converts ripple (in dB) to stopband weight. @@ -466,19 +467,20 @@ public static int EstimateOrder(double fp, double fa, double dp, double da) /// Parameters are given in conventional format. For example: /// /// - /// freqs: { 0, 0.2, 0.22, 0.32, 0.33, 0.5 } + /// frequencies: { 0, 0.2, 0.22, 0.32, 0.33, 0.5 } + ///
/// deltas: { 0.01, 0.1, 0.06 } ///
///
- /// Array of edge frequencies + /// Array of edge frequencies /// Array of weights - public static int EstimateOrder(double[] freqs, double[] deltas) + public static int EstimateOrder(double[] frequencies, double[] deltas) { var maxOrder = 0; for (int fi = 1, di = 0; di < deltas.Length - 1; fi += 2, di++) { - var order = EstimateOrder(freqs[fi], freqs[fi + 1], deltas[di], deltas[di + 1]); + var order = EstimateOrder(frequencies[fi], frequencies[fi + 1], deltas[di], deltas[di + 1]); if (order > maxOrder) { diff --git a/NWaves/Filters/Fda/VtlnWarper.cs b/NWaves/Filters/Fda/VtlnWarper.cs index a553dca..f9a2b25 100644 --- a/NWaves/Filters/Fda/VtlnWarper.cs +++ b/NWaves/Filters/Fda/VtlnWarper.cs @@ -38,42 +38,42 @@ public class VtlnWarper /// Constructs . ///
/// Warping factor - /// Lower frequency - /// Upper frequency + /// Lower frequency + /// Upper frequency /// Lower frequency for VTLN /// Upper frequency for VTLN public VtlnWarper(double alpha, - double lowFreq, - double highFreq, + double lowFrequency, + double highFrequency, double lowVtln, double highVtln) { - _lowFreq = lowFreq; - _highFreq = highFreq; + _lowFreq = lowFrequency; + _highFreq = highFrequency; _lowVtln = lowVtln * Math.Max(1, alpha); _highVtln = highVtln * Math.Min(1, alpha); _scale = 1 / alpha; - _scaleLeft = (_scale * _lowVtln - lowFreq) / (_lowVtln - lowFreq); - _scaleRight = (highFreq - _scale * _highVtln) / (highFreq - _highVtln); + _scaleLeft = (_scale * _lowVtln - lowFrequency) / (_lowVtln - lowFrequency); + _scaleRight = (highFrequency - _scale * _highVtln) / (highFrequency - _highVtln); } /// - /// Warps frequency . + /// Warps . /// - public double Warp(double freq) + public double Warp(double frequency) { - if (freq < _lowVtln) + if (frequency < _lowVtln) { - return _lowFreq + _scaleLeft * (freq - _lowFreq); + return _lowFreq + _scaleLeft * (frequency - _lowFreq); } - else if (freq < _highVtln) + else if (frequency < _highVtln) { - return _scale * freq; + return _scale * frequency; } - return _highFreq + _scaleRight * (freq - _highFreq); + return _highFreq + _scaleRight * (frequency - _highFreq); } } } diff --git a/NWaves/Filters/OnePole/HighPassFilter.cs b/NWaves/Filters/OnePole/HighPassFilter.cs index 2d6556b..4916b92 100644 --- a/NWaves/Filters/OnePole/HighPassFilter.cs +++ b/NWaves/Filters/OnePole/HighPassFilter.cs @@ -3,14 +3,14 @@ namespace NWaves.Filters.OnePole { /// - /// Represents one-pole high-pass filter. + /// Represents one-pole highpass filter. /// public class HighPassFilter : OnePoleFilter { /// /// Gets cutoff frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Constructs with given cutoff . @@ -27,6 +27,8 @@ public HighPassFilter(double frequency) /// Cutoff frequency private void SetCoefficients(double frequency) { + Frequency = frequency; + _a[0] = 1; _a[1] = (float)(Math.Exp(-2 * Math.PI * (0.5 - frequency))); diff --git a/NWaves/Filters/OnePole/LowPassFilter.cs b/NWaves/Filters/OnePole/LowPassFilter.cs index 4df68c3..737f3a9 100644 --- a/NWaves/Filters/OnePole/LowPassFilter.cs +++ b/NWaves/Filters/OnePole/LowPassFilter.cs @@ -3,14 +3,14 @@ namespace NWaves.Filters.OnePole { /// - /// Represents one-pole low-pass filter. + /// Represents one-pole lowpass filter. /// public class LowPassFilter : OnePoleFilter { /// /// Gets cutoff frequency. /// - public double Freq { get; protected set; } + public double Frequency { get; protected set; } /// /// Constructs with given cutoff . @@ -27,7 +27,7 @@ public LowPassFilter(double frequency) /// Cutoff frequency private void SetCoefficients(double frequency) { - Freq = frequency; + Frequency = frequency; _a[0] = 1; _a[1] = (float)(-Math.Exp(-2 * Math.PI * frequency)); diff --git a/NWaves/Windows/Window.cs b/NWaves/Windows/Window.cs index 741c322..8bf3d62 100644 --- a/NWaves/Windows/Window.cs +++ b/NWaves/Windows/Window.cs @@ -5,12 +5,12 @@ namespace NWaves.Windows { /// - /// Factory class for generating window coefficients of various types. + /// Generates window coefficients of various types. /// public static class Window { /// - /// Generate window coefficients of given and . + /// Generates window coefficients of given and . /// /// Window type /// Window length @@ -61,7 +61,7 @@ public static float[] OfType(WindowType type, int length, params object[] parame } /// - /// Generate rectangular window of given . + /// Generates rectangular window of given . /// public static float[] Rectangular(int length) { @@ -69,7 +69,7 @@ public static float[] Rectangular(int length) } /// - /// Generate triangular window of given . + /// Generates triangular window of given . /// public static float[] Triangular(int length) { @@ -80,7 +80,7 @@ public static float[] Triangular(int length) } /// - /// Generate Hamming window of given . + /// Generates Hamming window of given . /// public static float[] Hamming(int length) { @@ -91,7 +91,7 @@ public static float[] Hamming(int length) } /// - /// Generate Blackman window of given . + /// Generates Blackman window of given . /// public static float[] Blackman(int length) { @@ -102,7 +102,7 @@ public static float[] Blackman(int length) } /// - /// Generate Hann window of given . + /// Generates Hann window of given . /// public static float[] Hann(int length) { @@ -113,7 +113,7 @@ public static float[] Hann(int length) } /// - /// Generate Gaussian window of given . + /// Generates Gaussian window of given . /// public static float[] Gaussian(int length) { @@ -124,7 +124,7 @@ public static float[] Gaussian(int length) } /// - /// Generate Kaiser window of given . + /// Generates Kaiser window of given . /// public static float[] Kaiser(int length, double alpha = 12.0) { @@ -135,7 +135,7 @@ public static float[] Kaiser(int length, double alpha = 12.0) } /// - /// Generate Kaiser-Bessel Derived window of given . + /// Generates Kaiser-Bessel Derived window of given . /// public static float[] Kbd(int length, double alpha = 4.0) { @@ -160,7 +160,7 @@ public static float[] Kbd(int length, double alpha = 4.0) } /// - /// Generate Bartlett-Hann window of given . + /// Generates Bartlett-Hann window of given . /// public static float[] BartlettHann(int length) { @@ -171,7 +171,7 @@ public static float[] BartlettHann(int length) } /// - /// Generate Lanczos window of given . + /// Generates Lanczos window of given . /// public static float[] Lanczos(int length) { @@ -182,7 +182,7 @@ public static float[] Lanczos(int length) } /// - /// Generate Sin-beta window of given . + /// Generates Sin-beta window of given . /// public static float[] PowerOfSine(int length, double alpha = 1.5) { @@ -193,7 +193,7 @@ public static float[] PowerOfSine(int length, double alpha = 1.5) } /// - /// Generate Flat-top window of given . + /// Generates Flat-top window of given . /// public static float[] Flattop(int length) { @@ -204,7 +204,7 @@ public static float[] Flattop(int length) } /// - /// Generate coefficients for cepstrum liftering. + /// Generates coefficients for cepstrum liftering. /// /// Length of the window /// Denominator in liftering formula diff --git a/NWaves/Windows/WindowExtensions.cs b/NWaves/Windows/WindowExtensions.cs index ec07a42..d048371 100644 --- a/NWaves/Windows/WindowExtensions.cs +++ b/NWaves/Windows/WindowExtensions.cs @@ -4,14 +4,14 @@ namespace NWaves.Windows { /// - /// Class providing extension methods for applying windows to signals and arrays of samples. + /// Provides extension methods for applying windows to signals and arrays of samples. /// public static class WindowExtensions { /// - /// Apply window to array of . + /// Applies window to array of . /// - /// Signal samples + /// Samples /// Window coefficients public static void ApplyWindow(this float[] samples, float[] windowSamples) { @@ -22,9 +22,9 @@ public static void ApplyWindow(this float[] samples, float[] windowSamples) } /// - /// Apply window to array of . + /// Applies window to array of . /// - /// Signal samples + /// Samples /// Window coefficients public static void ApplyWindow(this double[] samples, double[] windowSamples) { @@ -35,7 +35,7 @@ public static void ApplyWindow(this double[] samples, double[] windowSamples) } /// - /// Apply window to . + /// Applies window to . /// /// Signal /// Window coefficients @@ -45,9 +45,9 @@ public static void ApplyWindow(this DiscreteSignal signal, float[] windowSamples } /// - /// Apply window with optional to array of . + /// Applies window with optional to array of . /// - /// Signal samples + /// Samples /// Window type /// Window parameters public static void ApplyWindow(this float[] samples, WindowType window, params object[] parameters) @@ -57,9 +57,9 @@ public static void ApplyWindow(this float[] samples, WindowType window, params o } /// - /// Apply window with optional to array of . + /// Applies window with optional to array of . /// - /// Signal samples + /// Samples /// Window type /// Window parameters public static void ApplyWindow(this double[] samples, WindowType window, params object[] parameters) @@ -69,7 +69,7 @@ public static void ApplyWindow(this double[] samples, WindowType window, params } /// - /// Apply window with optional to . + /// Applies window with optional to . /// /// Signal /// Window type