55 lines
2.0 KiB
C#
55 lines
2.0 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|