From a1f45fe1351f691469289d61a606391e1b6326bc Mon Sep 17 00:00:00 2001 From: Giorgos Sgouridis Date: Fri, 18 Aug 2023 17:35:19 +0200 Subject: [PATCH] implements HammingPeriodic and HanningPeriodic --- src/FftSharp.Tests/WindowValueTests.cs | 20 ++++++++++++++++- src/FftSharp/Windows/Hamming.cs | 9 +++++--- src/FftSharp/Windows/HammingPeriodic.cs | 29 +++++++++++++++++++++++++ src/FftSharp/Windows/Hanning.cs | 7 ++++-- src/FftSharp/Windows/HanningPeriodic.cs | 29 +++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/FftSharp/Windows/HammingPeriodic.cs create mode 100644 src/FftSharp/Windows/HanningPeriodic.cs diff --git a/src/FftSharp.Tests/WindowValueTests.cs b/src/FftSharp.Tests/WindowValueTests.cs index e186023..678a423 100644 --- a/src/FftSharp.Tests/WindowValueTests.cs +++ b/src/FftSharp.Tests/WindowValueTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using System; using System.Collections.Generic; using System.Linq; @@ -70,6 +70,15 @@ public void Test_Hamming() AssertEqual(Known_hamming_14, new Windows.Hamming().Create(14)); } + [Test] + public void Test_HammingPeriodic() + { + double[] Known_hamming_periodic_13 = { 0.08, 0.13269023, 0.27869022, 0.48455313, 0.70311825, 0.88431494,0.98663324, 0.98663324, 0.88431494, 0.70311825, 0.48455313, 0.27869022, 0.13269023 }; + double[] Known_hamming_periodic_14 = { 0.08, 0.12555432, 0.25319469, 0.43764037, 0.64235963, 0.82680531, 0.95444568, 1.0, 0.95444568, 0.82680531, 0.64235963, 0.43764037, 0.25319469, 0.12555432 }; + AssertEqual(Known_hamming_periodic_13, new Windows.HammingPeriodic().Create(13)); + AssertEqual(Known_hamming_periodic_14, new Windows.HammingPeriodic().Create(14)); + } + [Test] public void Test_Hanning() { @@ -79,6 +88,15 @@ public void Test_Hanning() AssertEqual(Known_hanning_14, new Windows.Hanning().Create(14)); } + [Test] + public void Test_HanningPeriodic() + { + double[] Known_hanning_periodic_13 = { 0.0, 0.05727199, 0.21596763, 0.43973166, 0.67730244, 0.87425537, 0.98547091, 0.98547091, 0.87425537, 0.67730244, 0.43973166, 0.21596763, 0.05727199 }; + double[] Known_hanning_periodic_14 = { 0.0, 0.04951557, 0.1882551, 0.38873953, 0.61126047, 0.8117449, 0.95048443, 1.0, 0.95048443, 0.8117449, 0.61126047, 0.38873953, 0.1882551, 0.04951557 }; + AssertEqual(Known_hanning_periodic_13, new Windows.HanningPeriodic().Create(13)); + AssertEqual(Known_hanning_periodic_14, new Windows.HanningPeriodic().Create(14)); + } + [Test] public void Test_Rectangular() { diff --git a/src/FftSharp/Windows/Hamming.cs b/src/FftSharp/Windows/Hamming.cs index 34d54ee..f0d743b 100644 --- a/src/FftSharp/Windows/Hamming.cs +++ b/src/FftSharp/Windows/Hamming.cs @@ -8,14 +8,17 @@ public class Hamming : Window, IWindow public override string Description => "The Hamming window has a sinusoidal shape does NOT touch zero at the edges (unlike the similar Hanning window). " + "It is similar to the Hanning window but its abrupt edges are designed to cancel the largest side lobe. " + - "It may be a good choice for low-quality (8-bit) auto where side lobes lie beyond the quantization noise floor."; + "It may be a good choice for low-quality (8-bit) auto where side lobes lie beyond the quantization noise floor." + + "A symmetric window, for use in filter design."; public override double[] Create(int size, bool normalize = false) { double[] window = new double[size]; + double phaseStep = (2.0 * Math.PI) / (size - 1.0); + for (int i = 0; i < size; i++) - window[i] = 0.54 - 0.46 * Math.Cos(2 * Math.PI * i / (size - 1)); + window[i] = 0.54 - 0.46 * Math.Cos(i * phaseStep); if (normalize) NormalizeInPlace(window); @@ -23,4 +26,4 @@ public override double[] Create(int size, bool normalize = false) return window; } } -} +} \ No newline at end of file diff --git a/src/FftSharp/Windows/HammingPeriodic.cs b/src/FftSharp/Windows/HammingPeriodic.cs new file mode 100644 index 0000000..de48c97 --- /dev/null +++ b/src/FftSharp/Windows/HammingPeriodic.cs @@ -0,0 +1,29 @@ +using System; + +namespace FftSharp.Windows +{ + public class HammingPeriodic : Window, IWindow + { + public override string Name => "HammingPeriodic"; + public override string Description => + "The Hamming window has a sinusoidal shape does NOT touch zero at the edges (unlike the similar Hanning window). " + + "It is similar to the Hanning window but its abrupt edges are designed to cancel the largest side lobe. " + + "It may be a good choice for low-quality (8-bit) auto where side lobes lie beyond the quantization noise floor." + + "A periodic window, for use in spectral analysis."; + + public override double[] Create(int size, bool normalize = false) + { + double[] window = new double[size]; + + double phaseStep = (2.0 * Math.PI) / size; + + for (int i = 0; i < size; i++) + window[i] = 0.54 - 0.46 * Math.Cos(i * phaseStep); + + if (normalize) + NormalizeInPlace(window); + + return window; + } + } +} diff --git a/src/FftSharp/Windows/Hanning.cs b/src/FftSharp/Windows/Hanning.cs index 85c7cd1..4f0176a 100644 --- a/src/FftSharp/Windows/Hanning.cs +++ b/src/FftSharp/Windows/Hanning.cs @@ -8,14 +8,17 @@ public class Hanning : Window, IWindow public override string Description => "The Hanning window has a sinusoidal shape which touches zero at the edges (unlike the similar Hamming window). " + "It has good frequency resolution, low spectral leakage, and is satisfactory for 95 percent of use cases. " + - "If you do not know the nature of the signal but you want to apply a smoothing window, start with the Hann window."; + "If you do not know the nature of the signal but you want to apply a smoothing window, start with the Hann window." + + "A symmetric window, for use in filter design."; public override double[] Create(int size, bool normalize = false) { double[] window = new double[size]; + double phaseStep = (2.0 * Math.PI) / (size - 1.0); + for (int i = 0; i < size; i++) - window[i] = 0.5 - 0.5 * Math.Cos(2 * Math.PI * i / (size - 1)); + window[i] = 0.5 - 0.5 * Math.Cos(i * phaseStep); if (normalize) NormalizeInPlace(window); diff --git a/src/FftSharp/Windows/HanningPeriodic.cs b/src/FftSharp/Windows/HanningPeriodic.cs new file mode 100644 index 0000000..362760a --- /dev/null +++ b/src/FftSharp/Windows/HanningPeriodic.cs @@ -0,0 +1,29 @@ +using System; + +namespace FftSharp.Windows +{ + public class HanningPeriodic : Window, IWindow + { + public override string Name => "HanningPeriodic"; + public override string Description => + "The Hanning window has a sinusoidal shape which touches zero at the edges (unlike the similar Hamming window). " + + "It has good frequency resolution, low spectral leakage, and is satisfactory for 95 percent of use cases. " + + "If you do not know the nature of the signal but you want to apply a smoothing window, start with the Hann window." + + "A periodic window, for use in spectral analysis."; + + public override double[] Create(int size, bool normalize = false) + { + double[] window = new double[size]; + + double phaseStep = (2.0 * Math.PI) / size; + + for (int i = 0; i < size; i++) + window[i] = 0.5 - 0.5 * Math.Cos(i * phaseStep); + + if (normalize) + NormalizeInPlace(window); + + return window; + } + } +} \ No newline at end of file