This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
using System;
namespace FftSharp.Windows
{
public class Bartlett : Window, IWindow
{
public override string Name => "BartlettHann";
public override string Description =>
"The BartlettHann window is triangular in shape (a 2nd order B-spline) which is effectively the " +
"convolution of two half-sized rectangular windows.";
protected override double windowValue(int index, int size)
{
return 1 - Math.Abs((double)(index - (size / 2)) / (size / 2));
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace FftSharp.Windows
{
public class Blackman : Window, IWindow
{
private readonly double A = 0.42659071;
private readonly double B = 0.49656062;
private readonly double C = 0.07684867;
public override string Name => "Blackman";
public override string Description =>
"These exact values place zeros at the third and fourth sidelobes, " +
"but result in a discontinuity at the edges and a 6 dB/oct fall-off. " +
"The truncated coefficients do not null the sidelobes as well, but have an improved 18 dB/oct fall-off.";
public Blackman() { }
public Blackman(double a, double b, double c) : this()
{
(A, B, C) = (a, b, c);
}
protected override double windowValue(int index, int size)
{
return A - B * Math.Cos(2 * Math.PI * index / size) + C * Math.Cos(4 * Math.PI * index / size);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace FftSharp.Windows
{
public class BlackmanHarris : Window, IWindow
{
private readonly double A = 0.35875;
private readonly double B = 0.48829;
private readonly double C = 0.14128;
private readonly double D = 0.01168;
public override string Name => "Blackman-Harris";
public override string Description =>
"The Blackman-Harris window is similar to Hamming and Hanning windows. " +
"The resulting spectrum has a wide peak, but good side lobe compression.";
public BlackmanHarris() { }
public BlackmanHarris(double a, double b, double c, double d) : this()
{
(A, B, C, D) = (a, b, c, d);
}
protected override double windowValue(int index, int size)
{
return A - B * Math.Cos(2 * Math.PI * index / size) + C * Math.Cos(4 * Math.PI * index / size) - D * Math.Cos(6 * Math.PI * index / size);
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
namespace FftSharp.Windows
{
public class Cosine : Window, IWindow
{
public override string Name => "Cosine";
public override string Description =>
"This window is simply a cosine function. It reaches zero on both sides and is similar to " +
"Blackman, Hamming, Hanning, and flat top windows, but probably should not be used in practice.";
protected override double windowValue(int index, int size)
{
return Math.Sin(index * Math.PI / (size - 1));
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FftSharp.Windows
{
public class FlatTop : Blackman
{
public override string Name => "FlatTop";
public override string Description =>
"A flat top window is a partially negative-valued window that has minimal scalloping loss in the frequency domain. " +
"These properties are desirable for the measurement of amplitudes of sinusoidal frequency components. " +
"Drawbacks of the broad bandwidth are poor frequency resolution and high noise bandwidth. " +
"The flat top window crosses the zero line causing a broader peak in the frequency domain, " +
"which is closer to the true amplitude of the signal than with other windows";
public FlatTop() : base(0.2810639, 0.5208972, 0.1980399)
{
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
namespace FftSharp.Windows
{
public class Hamming : Window, IWindow
{
public override string Name => "Hamming";
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.";
protected override double windowValue(int index, int size)
{
return 0.54 - 0.46 * Math.Cos(2 * Math.PI * index / size);
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
namespace FftSharp.Windows
{
public class Hanning : Window, IWindow
{
public override string Name => "Hanning";
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.";
protected override double windowValue(int index, int size)
{
return 0.5 - 0.5 * Math.Cos(2 * Math.PI * index / size);
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
namespace FftSharp.Windows
{
public class Kaiser : Window, IWindow
{
public readonly double Beta;
public override string Name => $"Kaiser-Bessel";
public override string Description =>
"A Kaiser-Bessel window strikes a balance among the various conflicting goals of amplitude " +
"accuracy, side lobe distance, and side lobe height. It compares roughly to the BlackmanHarris window functions, " +
"but for the same main lobe width, the near side lobes tend to be higher, but the further out side lobes are lower. " +
"Choosing this window often reveals signals close to the noise floor";
public Kaiser()
{
Beta = 15;
}
public Kaiser(double beta)
{
Beta = beta;
}
public static double I0(double x)
{
// Derived from code workby oygx210/navguide:
// https://github.com/oygx210/navguide/blob/master/src/common/bessel.c
double ax = Math.Abs(x);
if (ax < 3.75)
{
double y = Math.Pow(x / 3.75, 2);
double[] m = { 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2 };
return 1.0 + y * (m[0] + y * (m[1] + y * (m[2] + y * (m[3] + y * (m[4] + y * m[5])))));
}
else
{
double y = 3.75 / ax;
double[] m = { 0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2 };
return (Math.Exp(ax) / Math.Sqrt(ax)) * (m[0] + y * (m[1] + y * (m[2] + y * (m[3] + y * (m[4] + y * (m[5] + y * (m[6] + y * (m[7] + y * m[8]))))))));
}
}
protected override double windowValue(int index, int size)
{
int M = size;
double alpha = (M - 1) / 2.0;
return I0(Beta * Math.Sqrt(1 - Math.Pow((index - alpha) / alpha, 2))) / I0(Beta);
}
}
}

View File

@@ -0,0 +1,16 @@
namespace FftSharp.Windows
{
public class Rectangular : Window, IWindow
{
public override string Name => "Rectangular";
public override string Description =>
"The rectangular window (sometimes known as the boxcar or Dirichlet window) is the simplest window, " +
"equivalent to replacing all but N values of a data sequence by zeros, making it appear as though " +
"the waveform suddenly turns on and off. This window preserves transients at the start and end of the signal.";
protected override double windowValue(int index, int size)
{
return 1;
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
namespace FftSharp.Windows
{
public class Tukey : Window, IWindow
{
private readonly double Alpha;
public override string Name => "Tukey";
public override string Description =>
"A Tukey window has a flat center and tapers at the edges according to a cosine function. " +
"The amount of taper is defined by alpha (with low values being less taper). " +
"Tukey windows are ideal for analyzing transient data since the amplitude of transient signal " +
"in the time domain is less likely to be altered compared to using Hanning or flat top.";
public Tukey()
{
Alpha = .5;
}
public Tukey(double alpha = .5)
{
Alpha = alpha;
}
protected override double windowValue(int index, int size)
{
double m = 2 * Math.PI / (Alpha * size);
int edgeSizePoints = (int)(size * Alpha / 2);
bool isEdge = (index < edgeSizePoints) || (index > size - edgeSizePoints);
return isEdge ? (1 - Math.Cos(index * m)) / 2 : 1;
}
}
}

View File

@@ -0,0 +1,18 @@
namespace FftSharp.Windows
{
public class Welch : Window, IWindow
{
public override string Name => "Welch";
public override string Description =>
"The Welch window is typically used for antialiasing and resampling. " +
"Its frequency response is better than that of the Bartlett windowed cosc function below pi, " +
"but it shows again a rather distinctive bump above.";
protected override double windowValue(int index, int size)
{
double halfN = (size - 1) / 2.0;
double b = (index - halfN) / halfN;
return 1 - b * b;
}
}
}