--- source_files: - DataPRO/FftSharp/Windows/Bartlett.cs - DataPRO/FftSharp/Windows/Cosine.cs - DataPRO/FftSharp/Windows/Welch.cs - DataPRO/FftSharp/Windows/Rectangular.cs - DataPRO/FftSharp/Windows/Hanning.cs - DataPRO/FftSharp/Windows/Hamming.cs - DataPRO/FftSharp/Windows/FlatTop.cs - DataPRO/FftSharp/Windows/Blackman.cs - DataPRO/FftSharp/Windows/BlackmanHarris.cs - DataPRO/FftSharp/Windows/Tukey.cs - DataPRO/FftSharp/Windows/Kaiser.cs generated_at: "2026-04-16T04:24:07.110679+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "330f92c33efc913c" --- # Windows ## Documentation: FftSharp.Windows Module ### 1. Purpose This module provides a suite of window functions used in spectral analysis (e.g., before applying the FFT) to mitigate spectral leakage. Each window class implements a specific mathematical formulation to taper the signal at its edges, reducing discontinuities introduced by the finite-length FFT. The classes inherit from an abstract `Window` base class and implement the `IWindow` interface, offering a consistent API for generating window coefficients of a given size. These windows are intended for use in signal processing pipelines where accurate frequency-domain representation is required. ### 2. Public Interface All window classes are concrete, non-abstract subclasses of `Window` and implement `IWindow`. Each defines a public constructor (with optional parameters for tunable windows) and overrides `Name`, `Description`, and the protected `windowValue(int index, int size)` method. The base `Window` class (not shown in source) is assumed to expose a public method (e.g., `Generate(int size)`) that populates an array by calling `windowValue` for each index. - **`Bartlett`** - `Name`: `"Bartlett–Hann"` - `Description`: Triangular (2nd-order B-spline), convolution of two half-sized rectangular windows. - `windowValue(index, size)`: `1 - |(index - size/2) / (size/2)|` - **`Cosine`** - `Name`: `"Cosine"` - `Description`: Simple sine-shaped window (`sin(π·i/(N−1))`), reaches zero at edges; discouraged for practical use. - `windowValue(index, size)`: `Math.Sin(index * Math.PI / (size - 1))` - **`Welch`** - `Name`: `"Welch"` - `Description`: Parabolic window, better frequency response than Bartlett below π, but with a distinct bump above π; used for antialiasing/resampling. - `windowValue(index, size)`: `1 - ((index - (size-1)/2) / ((size-1)/2))²` - **`Rectangular`** - `Name`: `"Rectangular"` - `Description`: Boxcar/Dirichlet window (all ones); preserves transients but causes high spectral leakage. - `windowValue(index, size)`: `1` - **`Hanning`** - `Name`: `"Hanning"` - `Description`: Sinusoidal window touching zero at edges; low leakage, good for general use. - `windowValue(index, size)`: `0.5 - 0.5 * cos(2π·i / size)` - **`Hamming`** - `Name`: `"Hamming"` - `Description`: Sinusoidal window *not* zero at edges; designed to cancel the largest sidelobe. - `windowValue(index, size)`: `0.54 - 0.46 * cos(2π·i / size)` - **`FlatTop`** - `Name`: `"FlatTop"` - `Description`: Partially negative-valued window; minimal scalloping loss, ideal for amplitude measurement. Inherits from `Blackman` with fixed coefficients. - Constructor: `FlatTop()` calls `base(0.2810639, 0.5208972, 0.1980399)` - Uses `Blackman.windowValue` with those coefficients: `A - B·cos(2π·i/size) + C·cos(4π·i/size)` - **`Blackman`** - `Name`: `"Blackman"` - `Description`: Three-term cosine window; exact coefficients null 3rd/4th sidelobes. - Constructors: - `Blackman()` — uses default coefficients (`A=0.42659071`, `B=0.49656062`, `C=0.07684867`) - `Blackman(double a, double b, double c)` — custom coefficients - `windowValue(index, size)`: `A - B·cos(2π·i/size) + C·cos(4π·i/size)` - **`BlackmanHarris`** - `Name`: `"Blackman-Harris"` - `Description`: Four-term cosine window; wide main lobe but strong sidelobe suppression. - Constructors: - `BlackmanHarris()` — uses default coefficients (`A=0.35875`, `B=0.48829`, `C=0.14128`, `D=0.01168`) - `BlackmanHarris(double a, double b, double c, double d)` — custom coefficients - `windowValue(index, size)`: `A - B·cos(2π·i/size) + C·cos(4π·i/size) - D·cos(6π·i/size)` - **`Tukey`** - `Name`: `"Tukey"` - `Description`: Flat center with cosine taper at edges; controlled by `Alpha` (0–1). Ideal for transient analysis. - Constructors: - `Tukey()` — `Alpha = 0.5` - `Tukey(double alpha = 0.5)` - `windowValue(index, size)`: - If `index < edgeSizePoints` or `index > size - edgeSizePoints`: `(1 - cos(index * 2π / (Alpha * size))) / 2` - Else: `1` - Where `edgeSizePoints = (int)(size * Alpha / 2)` - **`Kaiser`** - `Name`: `"Kaiser-Bessel"` - `Description`: Tunable via `Beta`; balances main lobe width, sidelobe height, and distance. - Constructors: - `Kaiser()` — `Beta = 15` - `Kaiser(double beta)` - `windowValue(index, size)`: `I0(Beta * sqrt(1 - ((index - (size-1)/2) / ((size-1)/2))²)) / I0(Beta)` - `I0(double x)`: Modified Bessel function of the first kind (order 0), implemented via piecewise series. ### 3. Invariants - All windows are **symmetric** about `index = (size - 1) / 2`. This is evident from the use of `(index - center)` in all formulas. - Window values are computed for indices `0 ≤ index < size`. - For all windows except `Rectangular`, `windowValue(0, size) == windowValue(size - 1, size)`. - For `Hanning`, `Hamming`, `Blackman`, `BlackmanHarris`, and `FlatTop`, the window is periodic with period `size` in the cosine argument (i.e., `cos(2π·i/size)`). - `Tukey` uses integer truncation for `edgeSizePoints`, which may cause asymmetry for odd `size` and non-integer `size * Alpha / 2`. - `Kaiser` window is defined only for `size > 1`; division by zero occurs if `size == 1` (since `alpha = (size-1)/2 = 0`). ### 4. Dependencies - **Internal**: All classes depend on the abstract base class `Window` and interface `IWindow` (not shown), which define the contract for window generation (e.g., a public method like `double[] Generate(int size)`). - **External**: - `System` namespace (for `Math`, `Abs`, `Cos`, `Sin`, `Exp`, `Sqrt`, `Pow`). - `FlatTop` inherits from `Blackman`, reusing its `windowValue` implementation with fixed coefficients. - **Inferred usage**: These classes are likely consumed by an FFT processing pipeline (e.g., `FftSharp.Fft` or similar) that applies windowing before forward FFT and/or after inverse FFT. ### 5. Gotchas - **`Cosine` window naming**: Despite the class name, `windowValue` computes `sin(π·i/(N−1))`, not a cosine. This is likely intentional (sine is a shifted cosine), but the name may mislead. - **`Bartlett` vs. standard Bartlett**: The description says "Bartlett–Hann", but the formula matches the *standard* Bartlett (triangular) window, not the Bartlett–Hann (which combines triangular and cosine terms). This may be a documentation or naming error. - **`Tukey` edge handling**: For non-integer `size * Alpha / 2`, `edgeSizePoints` truncates, causing asymmetric tapering when `size` is odd and `Alpha` is not tuned to avoid this. - **`Kaiser` division by zero**: If `size == 1`, `alpha = 0`, leading to division by zero in `((index - alpha) / alpha)²`. This case is not guarded. - **`FlatTop` inheritance**: `FlatTop` inherits from `Blackman` and hardcodes coefficients, but `Blackman`’s constructor is not `protected`, so `FlatTop` must call `base(...)` explicitly. This tight coupling makes `FlatTop` inflexible (e.g., no custom coefficients). - **Missing `IWindow` implementation**: The source does not show the `IWindow` interface or `Window` base class, so the exact public API (e.g., method names, return types) is inferred. - **No validation of `size`**: All `windowValue` methods assume `size > 1`. For `size == 1`, `Welch` and `Kaiser` involve division by zero; `Tukey`’s `edgeSizePoints` becomes 0, but the logic may still hold. None identified beyond the above.