127 lines
8.1 KiB
Markdown
127 lines
8.1 KiB
Markdown
---
|
||
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. |