-
-
Notifications
You must be signed in to change notification settings - Fork 144
/
window.ts
95 lines (78 loc) · 2.14 KB
/
window.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { FloatArray } from "@thi.ng/api";
import { isNumber } from "@thi.ng/checks";
import { PI, TAU } from "@thi.ng/math";
import { WindowFn } from "../api";
// https://en.wikipedia.org/wiki/Window_function
const PI4 = 4 * PI;
const PI6 = 6 * PI;
const sin = Math.sin;
const cos = Math.cos;
/**
* Creates or fills a given buffer with results of window function `fn`.
* The buffer size MUST be the same as the signal length given to
* {@link fft}.
*
* @param fn
* @param lenOfBuf
*/
export const window = (fn: WindowFn, lenOfBuf: number | FloatArray) => {
const buf = isNumber(lenOfBuf) ? new Float64Array(lenOfBuf) : lenOfBuf;
const n = buf.length - 1;
for (let i = 0; i <= n; i++) {
buf[i] = fn(i, n);
}
return buf;
};
export const windowRect: WindowFn = () => 1;
export const windowSin: WindowFn = (i, n) => sin((PI * i) / n);
export const windowSinPow = (k: number): WindowFn => (i, n) =>
sin((PI * i) / n) ** k;
export const windowLanczos: WindowFn = (i, n) => {
i = PI * ((2 * i) / n - 1);
return sin(i) / i;
};
const windowCosSum = (k: number): WindowFn => {
let ik = 1 - k;
return (i, n) => k - ik * cos((TAU * i) / n);
};
const windowCosSum3 = (k1: number, k2: number, k3: number): WindowFn => (
i,
n
) => {
i /= n;
return k1 + k2 * cos(TAU * i) + k3 * cos(PI4 * i);
};
const windowCosSum4 = (
k1: number,
k2: number,
k3: number,
k4: number
): WindowFn => (i, n) => {
i /= n;
return k1 + k2 * cos(TAU * i) + k3 * cos(PI4 * i) + k4 * cos(PI6 * i);
};
export const windowHann = windowCosSum(0.5);
export const windowHamming = windowCosSum(0.53836);
export const windowBlackman = windowCosSum3(0.42, -0.5, 0.08);
export const windowBlackmanHarris = windowCosSum4(
0.35875,
-0.48829,
0.14128,
0.01168
);
export const windowNuttall = windowCosSum4(
0.355768,
-0.487396,
0.144232,
-0.012604
);
export const windowBlackmanNuttall = windowCosSum4(
0.3635819,
-0.4891775,
0.1365995,
-0.0106411
);
export const windowGauss = (a = 0.4): WindowFn => (i, n) => {
n /= 2;
return Math.exp(-0.5 * ((i - n) / (a * n)) ** 2);
};