///|
/// The type of a window function used to taper a finite signal before
/// spectral analysis or FIR filter design.
pub(all) enum WindowType {
///
/// Rectangular window (no tapering; every sample weighted by 1).
Rectangular
///
/// Hann window: `0.5 - 0.5*cos(2*pi*i/(n-1))`.
Hann
///
/// Hamming window: `0.54 - 0.46*cos(2*pi*i/(n-1))`.
Hamming
///
/// Blackman window: `0.42 - 0.5*cos(2*pi*i/(n-1)) + 0.08*cos(4*pi*i/(n-1))`.
Blackman
}
///|
/// Generates a symmetric window of length `n` for the given `window_type`.
///
/// Parameters:
///
/// * `window_type` : the kind of window to generate.
/// * `n` : the window length in samples. A length of `1` yields `[1.0]`.
///
/// Returns an array of `n` weights in `[0, 1]`.
pub fn window(window_type : WindowType, n : Int32) -> Array[Double] {
if n <= 1 {
return [1.0]
}
let nf = (n - 1).to_double()
match window_type {
Rectangular => Array::make(n, 1.0)
Hann =>
Array::makei(n, fn(i) {
0.5 - 0.5 * @math.cos(2.0 * @math.PI * i.to_double() / nf)
})
Hamming =>
Array::makei(n, fn(i) {
0.54 - 0.46 * @math.cos(2.0 * @math.PI * i.to_double() / nf)
})
Blackman =>
Array::makei(n, fn(i) {
let t = 2.0 * @math.PI * i.to_double() / nf
0.42 - 0.5 * @math.cos(t) + 0.08 * @math.cos(2.0 * t)
})
}
}
///|
/// Applies `window_type` to `x` sample by sample and returns the result.
///
/// The input array is not modified.
pub fn apply_window(
x : Array[Double],
window_type : WindowType,
) -> Array[Double] {
let w = window(window_type, x.length())
Array::makei(x.length(), fn(i) { x[i] * w[i] })
}
///|
/// Shortcut for [`window`](https://mooncakes.io/docs/2227057182/moonbit-dsp/latest/#~2227057182%2Fmoonbit-dsp.window)`(Rectangular, n)`.
pub fn rectangular_window(n : Int32) -> Array[Double] {
window(Rectangular, n)
}
///|
/// Shortcut for [`window`](https://mooncakes.io/docs/2227057182/moonbit-dsp/latest/#~2227057182%2Fmoonbit-dsp.window)`(Hann, n)`.
pub fn hann_window(n : Int32) -> Array[Double] {
window(Hann, n)
}
///|
/// Shortcut for [`window`](https://mooncakes.io/docs/2227057182/moonbit-dsp/latest/#~2227057182%2Fmoonbit-dsp.window)`(Hamming, n)`.
pub fn hamming_window(n : Int32) -> Array[Double] {
window(Hamming, n)
}
///|
/// Shortcut for [`window`](https://mooncakes.io/docs/2227057182/moonbit-dsp/latest/#~2227057182%2Fmoonbit-dsp.window)`(Blackman, n)`.
pub fn blackman_window(n : Int32) -> Array[Double] {
window(Blackman, n)
}