carta1 1.0.19 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/codec/transforms/fft.js
CHANGED
|
@@ -12,12 +12,8 @@ export class FFT {
|
|
|
12
12
|
*/
|
|
13
13
|
static fft(real, imag) {
|
|
14
14
|
const n = real.length
|
|
15
|
-
if (n !== imag.length)
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if ((n & (n - 1)) !== 0) {
|
|
19
|
-
throw new Error('Input size must be a power of 2.')
|
|
20
|
-
}
|
|
15
|
+
if (n !== imag.length) throw new Error('Mismatched array lengths.')
|
|
16
|
+
if ((n & (n - 1)) !== 0) throw new Error('Length must be power of 2.')
|
|
21
17
|
if (n <= 1) return
|
|
22
18
|
|
|
23
19
|
let cache = FFT._cache.get(n)
|
|
@@ -26,168 +22,91 @@ export class FFT {
|
|
|
26
22
|
FFT._cache.set(n, cache)
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
const
|
|
25
|
+
const bitRev = cache.bitRev
|
|
26
|
+
const cosTbl = cache.cos
|
|
27
|
+
const sinTbl = cache.sin
|
|
30
28
|
|
|
31
|
-
// Bit
|
|
29
|
+
// Bit reversal
|
|
32
30
|
for (let i = 0; i < n; i++) {
|
|
33
31
|
const j = bitRev[i]
|
|
34
32
|
if (j > i) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const tempI = imag[i]
|
|
33
|
+
let tr = real[i]
|
|
34
|
+
let ti = imag[i]
|
|
38
35
|
real[i] = real[j]
|
|
39
36
|
imag[i] = imag[j]
|
|
40
|
-
real[j] =
|
|
41
|
-
imag[j] =
|
|
37
|
+
real[j] = tr
|
|
38
|
+
imag[j] = ti
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
//
|
|
46
|
-
// Stride 2 - no twiddle factors needed
|
|
42
|
+
// First stage: stride=2
|
|
47
43
|
for (let i = 0; i < n; i += 2) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
imag[i + 1] = evenI - oddI
|
|
44
|
+
let r0 = real[i],
|
|
45
|
+
i0 = imag[i]
|
|
46
|
+
let r1 = real[i + 1],
|
|
47
|
+
i1 = imag[i + 1]
|
|
48
|
+
real[i] = r0 + r1
|
|
49
|
+
imag[i] = i0 + i1
|
|
50
|
+
real[i + 1] = r0 - r1
|
|
51
|
+
imag[i + 1] = i0 - i1
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
//
|
|
54
|
+
// Second stage: stride=4
|
|
60
55
|
if (n >= 4) {
|
|
61
56
|
for (let i = 0; i < n; i += 4) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
real[i] =
|
|
69
|
-
imag[i] =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
real[i + 1] = evenR + tR
|
|
83
|
-
imag[i + 1] = evenI + tI
|
|
84
|
-
real[i + 3] = evenR - tR
|
|
85
|
-
imag[i + 3] = evenI - tI
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Stride 8 - unrolled for better performance
|
|
90
|
-
if (n >= 8) {
|
|
91
|
-
for (let i = 0; i < n; i += 8) {
|
|
92
|
-
// W^0 = 1
|
|
93
|
-
let idx0 = i
|
|
94
|
-
let idx4 = i + 4
|
|
95
|
-
let r0 = real[idx0],
|
|
96
|
-
i0 = imag[idx0]
|
|
97
|
-
let r4 = real[idx4],
|
|
98
|
-
i4 = imag[idx4]
|
|
99
|
-
real[idx0] = r0 + r4
|
|
100
|
-
imag[idx0] = i0 + i4
|
|
101
|
-
real[idx4] = r0 - r4
|
|
102
|
-
imag[idx4] = i0 - i4
|
|
103
|
-
|
|
104
|
-
// W^1 = cos(-π/4) - i*sin(-π/4)
|
|
105
|
-
let idx1 = i + 1
|
|
106
|
-
let idx5 = i + 5
|
|
107
|
-
r0 = real[idx1]
|
|
108
|
-
i0 = imag[idx1]
|
|
109
|
-
r4 = real[idx5]
|
|
110
|
-
i4 = imag[idx5]
|
|
111
|
-
const sqrt2_2 = 0.7071067811865476
|
|
112
|
-
let tR = sqrt2_2 * (r4 + i4)
|
|
113
|
-
let tI = sqrt2_2 * (i4 - r4)
|
|
114
|
-
real[idx1] = r0 + tR
|
|
115
|
-
imag[idx1] = i0 + tI
|
|
116
|
-
real[idx5] = r0 - tR
|
|
117
|
-
imag[idx5] = i0 - tI
|
|
118
|
-
|
|
119
|
-
// W^2 = -i
|
|
120
|
-
let idx2 = i + 2
|
|
121
|
-
let idx6 = i + 6
|
|
122
|
-
r0 = real[idx2]
|
|
123
|
-
i0 = imag[idx2]
|
|
124
|
-
r4 = real[idx6]
|
|
125
|
-
i4 = imag[idx6]
|
|
126
|
-
tR = i4
|
|
127
|
-
tI = -r4
|
|
128
|
-
real[idx2] = r0 + tR
|
|
129
|
-
imag[idx2] = i0 + tI
|
|
130
|
-
real[idx6] = r0 - tR
|
|
131
|
-
imag[idx6] = i0 - tI
|
|
132
|
-
|
|
133
|
-
// W^3 = cos(-3π/4) - i*sin(-3π/4)
|
|
134
|
-
let idx3 = i + 3
|
|
135
|
-
let idx7 = i + 7
|
|
136
|
-
r0 = real[idx3]
|
|
137
|
-
i0 = imag[idx3]
|
|
138
|
-
r4 = real[idx7]
|
|
139
|
-
i4 = imag[idx7]
|
|
140
|
-
tR = sqrt2_2 * (-r4 + i4)
|
|
141
|
-
tI = sqrt2_2 * (-r4 - i4)
|
|
142
|
-
real[idx3] = r0 + tR
|
|
143
|
-
imag[idx3] = i0 + tI
|
|
144
|
-
real[idx7] = r0 - tR
|
|
145
|
-
imag[idx7] = i0 - tI
|
|
57
|
+
let r0 = real[i],
|
|
58
|
+
i0 = imag[i]
|
|
59
|
+
let r2 = real[i + 2],
|
|
60
|
+
i2 = imag[i + 2]
|
|
61
|
+
real[i] = r0 + r2
|
|
62
|
+
imag[i] = i0 + i2
|
|
63
|
+
real[i + 2] = r0 - r2
|
|
64
|
+
imag[i + 2] = i0 - i2
|
|
65
|
+
|
|
66
|
+
r0 = real[i + 1]
|
|
67
|
+
i0 = imag[i + 1]
|
|
68
|
+
r2 = real[i + 3]
|
|
69
|
+
i2 = imag[i + 3]
|
|
70
|
+
// W^1 = -i
|
|
71
|
+
let tR = i2
|
|
72
|
+
let tI = -r2
|
|
73
|
+
real[i + 1] = r0 + tR
|
|
74
|
+
imag[i + 1] = i0 + tI
|
|
75
|
+
real[i + 3] = r0 - tR
|
|
76
|
+
imag[i + 3] = i0 - tI
|
|
146
77
|
}
|
|
147
78
|
}
|
|
148
79
|
|
|
149
|
-
//
|
|
150
|
-
for (let stride =
|
|
80
|
+
// Higher stages
|
|
81
|
+
for (let stride = 8; stride <= n; stride <<= 1) {
|
|
151
82
|
const halfStride = stride >>> 1
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
real[oddIdx] = r0 - r1
|
|
166
|
-
imag[oddIdx] = i0 - i1
|
|
167
|
-
|
|
168
|
-
// Remaining butterflies with twiddle factors
|
|
169
|
-
let twiddleIdx = step
|
|
83
|
+
const tblStep = n / stride
|
|
84
|
+
for (let base = 0; base < n; base += stride) {
|
|
85
|
+
// k = 0
|
|
86
|
+
let r0 = real[base],
|
|
87
|
+
i0 = imag[base]
|
|
88
|
+
let r1 = real[base + halfStride],
|
|
89
|
+
i1 = imag[base + halfStride]
|
|
90
|
+
real[base] = r0 + r1
|
|
91
|
+
imag[base] = i0 + i1
|
|
92
|
+
real[base + halfStride] = r0 - r1
|
|
93
|
+
imag[base + halfStride] = i0 - i1
|
|
94
|
+
|
|
95
|
+
let tw = tblStep
|
|
170
96
|
for (let k = 1; k < halfStride; k++) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
real[evenIdx] = evenR + tR
|
|
186
|
-
imag[evenIdx] = evenI + tI
|
|
187
|
-
real[oddIdx] = evenR - tR
|
|
188
|
-
imag[oddIdx] = evenI - tI
|
|
189
|
-
|
|
190
|
-
twiddleIdx += step
|
|
97
|
+
const c = cosTbl[tw]
|
|
98
|
+
const s = sinTbl[tw]
|
|
99
|
+
r1 = real[base + k]
|
|
100
|
+
i1 = imag[base + k]
|
|
101
|
+
let r2 = real[base + k + halfStride]
|
|
102
|
+
let i2 = imag[base + k + halfStride]
|
|
103
|
+
let tr = r2 * c - i2 * s
|
|
104
|
+
let ti = r2 * s + i2 * c
|
|
105
|
+
real[base + k] = r1 + tr
|
|
106
|
+
imag[base + k] = i1 + ti
|
|
107
|
+
real[base + k + halfStride] = r1 - tr
|
|
108
|
+
imag[base + k + halfStride] = i1 - ti
|
|
109
|
+
tw += tblStep
|
|
191
110
|
}
|
|
192
111
|
}
|
|
193
112
|
}
|
|
@@ -198,27 +117,20 @@ export class FFT {
|
|
|
198
117
|
* @private
|
|
199
118
|
*/
|
|
200
119
|
static _buildCache(n) {
|
|
201
|
-
const log2n = Math.log2(n) | 0
|
|
202
|
-
|
|
203
|
-
// Optimized bit-reversal using iterative approach
|
|
204
120
|
const bitRev = new Uint32Array(n)
|
|
121
|
+
const log2n = Math.log2(n) | 0
|
|
205
122
|
for (let i = 1; i < n; i++) {
|
|
206
123
|
bitRev[i] = (bitRev[i >>> 1] >>> 1) | ((i & 1) << (log2n - 1))
|
|
207
124
|
}
|
|
208
|
-
|
|
209
|
-
// Pre-compute twiddle factors with better precision
|
|
210
125
|
const halfN = n >>> 1
|
|
211
126
|
const cosTbl = new Float32Array(halfN)
|
|
212
127
|
const sinTbl = new Float32Array(halfN)
|
|
213
|
-
|
|
214
|
-
// Use higher precision calculation then cast to Float32
|
|
215
|
-
const angleStep = (-2 * Math.PI) / n
|
|
128
|
+
const ang = (-2 * Math.PI) / n
|
|
216
129
|
for (let i = 0; i < halfN; i++) {
|
|
217
|
-
const
|
|
218
|
-
cosTbl[i] = Math.
|
|
219
|
-
sinTbl[i] = Math.
|
|
130
|
+
const a = ang * i
|
|
131
|
+
cosTbl[i] = Math.cos(a)
|
|
132
|
+
sinTbl[i] = Math.sin(a)
|
|
220
133
|
}
|
|
221
|
-
|
|
222
134
|
return { bitRev, cos: cosTbl, sin: sinTbl }
|
|
223
135
|
}
|
|
224
136
|
}
|