spec-cat 0.1.0 → 0.1.2

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.
Files changed (110) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Bqlz6CoK.js → BE_75kPa.js} +1 -1
  3. package/.output/public/_nuxt/{B2wdmh_w.js → BJ7m4fRW.js} +53 -53
  4. package/.output/public/_nuxt/{KNuzSjk0.js → CCNYUZ9m.js} +1 -1
  5. package/.output/public/_nuxt/{BvosqTnx.js → DGtcdWVl.js} +1 -1
  6. package/.output/public/_nuxt/DxEx-kFx.js +1 -0
  7. package/.output/public/_nuxt/{BwcbSlWF.js → DyMq_cQC.js} +2 -2
  8. package/.output/public/_nuxt/{COTT6rNZ.js → _cj5lOdZ.js} +1 -1
  9. package/.output/public/_nuxt/builds/latest.json +1 -1
  10. package/.output/public/_nuxt/builds/meta/3a0aacc1-0bd1-4d15-8b8a-3cee48cbfc69.json +1 -0
  11. package/.output/public/_nuxt/{BUOk7wkI.js → gDut6QrP.js} +1 -1
  12. package/.output/public/_nuxt/{C5wk2twv.js → nJpWpjzg.js} +1 -1
  13. package/.output/public/_nuxt/{DBab5Zcv.js → waQ9fPC1.js} +1 -1
  14. package/.output/server/chunks/_/codexProvider.mjs +64 -18
  15. package/.output/server/chunks/_/codexProvider.mjs.map +1 -1
  16. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  17. package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  18. package/.output/server/chunks/nitro/nitro.mjs +702 -703
  19. package/.output/server/chunks/routes/_ws.mjs +37 -7
  20. package/.output/server/chunks/routes/_ws.mjs.map +1 -1
  21. package/.output/server/node_modules/@huggingface/jinja/dist/index.js +1572 -0
  22. package/.output/server/node_modules/@huggingface/jinja/package.json +55 -0
  23. package/.output/server/node_modules/@xenova/transformers/package.json +84 -0
  24. package/.output/server/node_modules/@xenova/transformers/src/backends/onnx.js +50 -0
  25. package/.output/server/node_modules/@xenova/transformers/src/configs.js +107 -0
  26. package/.output/server/node_modules/@xenova/transformers/src/env.js +128 -0
  27. package/.output/server/node_modules/@xenova/transformers/src/models.js +6267 -0
  28. package/.output/server/node_modules/@xenova/transformers/src/pipelines.js +3287 -0
  29. package/.output/server/node_modules/@xenova/transformers/src/processors.js +2248 -0
  30. package/.output/server/node_modules/@xenova/transformers/src/tokenizers.js +4479 -0
  31. package/.output/server/node_modules/@xenova/transformers/src/transformers.js +24 -0
  32. package/.output/server/node_modules/@xenova/transformers/src/utils/audio.js +672 -0
  33. package/.output/server/node_modules/@xenova/transformers/src/utils/core.js +175 -0
  34. package/.output/server/node_modules/@xenova/transformers/src/utils/data-structures.js +415 -0
  35. package/.output/server/node_modules/@xenova/transformers/src/utils/generation.js +873 -0
  36. package/.output/server/node_modules/@xenova/transformers/src/utils/hub.js +658 -0
  37. package/.output/server/node_modules/@xenova/transformers/src/utils/image.js +731 -0
  38. package/.output/server/node_modules/@xenova/transformers/src/utils/maths.js +985 -0
  39. package/.output/server/node_modules/@xenova/transformers/src/utils/tensor.js +1239 -0
  40. package/.output/server/node_modules/color/index.js +496 -0
  41. package/.output/server/node_modules/color/package.json +47 -0
  42. package/.output/server/node_modules/color-convert/conversions.js +839 -0
  43. package/.output/server/node_modules/color-convert/index.js +81 -0
  44. package/.output/server/node_modules/color-convert/package.json +48 -0
  45. package/.output/server/node_modules/color-convert/route.js +97 -0
  46. package/.output/server/node_modules/color-name/index.js +152 -0
  47. package/.output/server/node_modules/color-name/package.json +28 -0
  48. package/.output/server/node_modules/color-string/index.js +242 -0
  49. package/.output/server/node_modules/color-string/package.json +39 -0
  50. package/.output/server/node_modules/detect-libc/lib/detect-libc.js +313 -0
  51. package/.output/server/node_modules/detect-libc/lib/elf.js +39 -0
  52. package/.output/server/node_modules/detect-libc/lib/filesystem.js +51 -0
  53. package/.output/server/node_modules/detect-libc/lib/process.js +24 -0
  54. package/.output/server/node_modules/detect-libc/package.json +44 -0
  55. package/.output/server/node_modules/is-arrayish/index.js +9 -0
  56. package/.output/server/node_modules/is-arrayish/package.json +45 -0
  57. package/.output/server/node_modules/onnxruntime-common/dist/ort-common.node.js +7 -0
  58. package/.output/server/node_modules/onnxruntime-common/package.json +31 -0
  59. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/darwin/arm64/onnxruntime_binding.node +0 -0
  60. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/darwin/x64/onnxruntime_binding.node +0 -0
  61. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/linux/arm64/libonnxruntime.so.1.14.0 +0 -0
  62. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/linux/arm64/onnxruntime_binding.node +0 -0
  63. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/linux/x64/libonnxruntime.so.1.14.0 +0 -0
  64. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/linux/x64/onnxruntime_binding.node +0 -0
  65. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/win32/arm64/onnxruntime_binding.node +0 -0
  66. package/.output/server/node_modules/onnxruntime-node/bin/napi-v3/win32/x64/onnxruntime_binding.node +0 -0
  67. package/.output/server/node_modules/onnxruntime-node/dist/backend.js +75 -0
  68. package/.output/server/node_modules/onnxruntime-node/dist/binding.js +10 -0
  69. package/.output/server/node_modules/onnxruntime-node/dist/index.js +23 -0
  70. package/.output/server/node_modules/onnxruntime-node/package.json +58 -0
  71. package/.output/server/node_modules/onnxruntime-web/dist/ort-web.node.js +7 -0
  72. package/.output/server/node_modules/onnxruntime-web/package.json +84 -0
  73. package/.output/server/node_modules/semver/classes/semver.js +333 -0
  74. package/.output/server/node_modules/semver/functions/coerce.js +62 -0
  75. package/.output/server/node_modules/semver/functions/compare.js +7 -0
  76. package/.output/server/node_modules/semver/functions/gte.js +5 -0
  77. package/.output/server/node_modules/semver/functions/parse.js +18 -0
  78. package/.output/server/node_modules/semver/internal/constants.js +37 -0
  79. package/.output/server/node_modules/semver/internal/debug.js +11 -0
  80. package/.output/server/node_modules/semver/internal/identifiers.js +29 -0
  81. package/.output/server/node_modules/semver/internal/parse-options.js +17 -0
  82. package/.output/server/node_modules/semver/internal/re.js +223 -0
  83. package/.output/server/node_modules/semver/package.json +78 -0
  84. package/.output/server/node_modules/sharp/build/Release/sharp-linux-x64.node +0 -0
  85. package/.output/server/node_modules/sharp/lib/channel.js +174 -0
  86. package/.output/server/node_modules/sharp/lib/colour.js +184 -0
  87. package/.output/server/node_modules/sharp/lib/composite.js +210 -0
  88. package/.output/server/node_modules/sharp/lib/constructor.js +439 -0
  89. package/.output/server/node_modules/sharp/lib/index.js +16 -0
  90. package/.output/server/node_modules/sharp/lib/input.js +631 -0
  91. package/.output/server/node_modules/sharp/lib/is.js +155 -0
  92. package/.output/server/node_modules/sharp/lib/libvips.js +140 -0
  93. package/.output/server/node_modules/sharp/lib/operation.js +919 -0
  94. package/.output/server/node_modules/sharp/lib/output.js +1413 -0
  95. package/.output/server/node_modules/sharp/lib/platform.js +30 -0
  96. package/.output/server/node_modules/sharp/lib/resize.js +582 -0
  97. package/.output/server/node_modules/sharp/lib/sharp.js +38 -0
  98. package/.output/server/node_modules/sharp/lib/utility.js +287 -0
  99. package/.output/server/node_modules/sharp/package.json +204 -0
  100. package/.output/server/node_modules/sharp/vendor/8.14.5/linux-x64/THIRD-PARTY-NOTICES.md +43 -0
  101. package/.output/server/node_modules/sharp/vendor/8.14.5/linux-x64/lib/libvips-cpp.so.42 +0 -0
  102. package/.output/server/node_modules/sharp/vendor/8.14.5/linux-x64/platform.json +1 -0
  103. package/.output/server/node_modules/sharp/vendor/8.14.5/linux-x64/versions.json +31 -0
  104. package/.output/server/node_modules/simple-swizzle/index.js +29 -0
  105. package/.output/server/node_modules/simple-swizzle/package.json +36 -0
  106. package/.output/server/package.json +15 -1
  107. package/README.md +2 -0
  108. package/package.json +12 -19
  109. package/.output/public/_nuxt/5FxpIoe_.js +0 -1
  110. package/.output/public/_nuxt/builds/meta/21578a05-1b7e-4847-a8ff-7480800ea4a6.json +0 -1
@@ -0,0 +1,985 @@
1
+
2
+ /**
3
+ * @file Helper module for mathematical processing.
4
+ *
5
+ * These functions and classes are only used internally,
6
+ * meaning an end-user shouldn't need to access anything here.
7
+ *
8
+ * @module utils/maths
9
+ */
10
+
11
+ /**
12
+ * @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray
13
+ * @typedef {BigInt64Array | BigUint64Array} BigTypedArray
14
+ * @typedef {TypedArray | BigTypedArray} AnyTypedArray
15
+ */
16
+
17
+ /**
18
+ * @param {TypedArray} input
19
+ */
20
+ export function interpolate_data(input, [in_channels, in_height, in_width], [out_height, out_width], mode = 'bilinear', align_corners = false) {
21
+ // TODO use mode and align_corners
22
+
23
+ // Output image dimensions
24
+ const x_scale = out_width / in_width;
25
+ const y_scale = out_height / in_height;
26
+
27
+ // Output image
28
+ // @ts-ignore
29
+ const out_img = new input.constructor(out_height * out_width * in_channels);
30
+
31
+ // Pre-calculate strides
32
+ const inStride = in_height * in_width;
33
+ const outStride = out_height * out_width;
34
+
35
+ for (let i = 0; i < out_height; ++i) {
36
+ for (let j = 0; j < out_width; ++j) {
37
+ // Calculate output offset
38
+ const outOffset = i * out_width + j;
39
+
40
+ // Calculate input pixel coordinates
41
+ const x = (j + 0.5) / x_scale - 0.5;
42
+ const y = (i + 0.5) / y_scale - 0.5;
43
+
44
+ // Calculate the four nearest input pixels
45
+ // We also check if the input pixel coordinates are within the image bounds
46
+ let x1 = Math.floor(x);
47
+ let y1 = Math.floor(y);
48
+ const x2 = Math.min(x1 + 1, in_width - 1);
49
+ const y2 = Math.min(y1 + 1, in_height - 1);
50
+
51
+ x1 = Math.max(x1, 0);
52
+ y1 = Math.max(y1, 0);
53
+
54
+
55
+ // Calculate the fractional distances between the input pixel and the four nearest pixels
56
+ const s = x - x1;
57
+ const t = y - y1;
58
+
59
+ // Perform bilinear interpolation
60
+ const w1 = (1 - s) * (1 - t);
61
+ const w2 = s * (1 - t);
62
+ const w3 = (1 - s) * t;
63
+ const w4 = s * t;
64
+
65
+ // Calculate the four nearest input pixel indices
66
+ const yStride = y1 * in_width;
67
+ const xStride = y2 * in_width;
68
+ const idx1 = yStride + x1;
69
+ const idx2 = yStride + x2;
70
+ const idx3 = xStride + x1;
71
+ const idx4 = xStride + x2;
72
+
73
+ for (let k = 0; k < in_channels; ++k) {
74
+ // Calculate channel offset
75
+ const cOffset = k * inStride;
76
+
77
+ out_img[k * outStride + outOffset] =
78
+ w1 * input[cOffset + idx1] +
79
+ w2 * input[cOffset + idx2] +
80
+ w3 * input[cOffset + idx3] +
81
+ w4 * input[cOffset + idx4];
82
+ }
83
+ }
84
+ }
85
+
86
+ return out_img;
87
+ }
88
+
89
+
90
+ /**
91
+ * Helper method to permute a `AnyTypedArray` directly
92
+ * @template {AnyTypedArray} T
93
+ * @param {T} array
94
+ * @param {number[]} dims
95
+ * @param {number[]} axes
96
+ * @returns {[T, number[]]} The permuted array and the new shape.
97
+ */
98
+ export function permute_data(array, dims, axes) {
99
+ // Calculate the new shape of the permuted array
100
+ // and the stride of the original array
101
+ const shape = new Array(axes.length);
102
+ const stride = new Array(axes.length);
103
+
104
+ for (let i = axes.length - 1, s = 1; i >= 0; --i) {
105
+ stride[i] = s;
106
+ shape[i] = dims[axes[i]];
107
+ s *= shape[i];
108
+ }
109
+
110
+ // Precompute inverse mapping of stride
111
+ const invStride = axes.map((_, i) => stride[axes.indexOf(i)]);
112
+
113
+ // Create the permuted array with the new shape
114
+ // @ts-ignore
115
+ const permutedData = new array.constructor(array.length);
116
+
117
+ // Permute the original array to the new array
118
+ for (let i = 0; i < array.length; ++i) {
119
+ let newIndex = 0;
120
+ for (let j = dims.length - 1, k = i; j >= 0; --j) {
121
+ newIndex += (k % dims[j]) * invStride[j];
122
+ k = Math.floor(k / dims[j]);
123
+ }
124
+ permutedData[newIndex] = array[i];
125
+ }
126
+
127
+ return [permutedData, shape];
128
+ }
129
+
130
+
131
+ /**
132
+ * Compute the softmax of an array of numbers.
133
+ * @template {TypedArray|number[]} T
134
+ * @param {T} arr The array of numbers to compute the softmax of.
135
+ * @returns {T} The softmax array.
136
+ */
137
+ export function softmax(arr) {
138
+ // Compute the maximum value in the array
139
+ const maxVal = max(arr)[0];
140
+
141
+ // Compute the exponentials of the array values
142
+ const exps = arr.map(x => Math.exp(x - maxVal));
143
+
144
+ // Compute the sum of the exponentials
145
+ // @ts-ignore
146
+ const sumExps = exps.reduce((acc, val) => acc + val, 0);
147
+
148
+ // Compute the softmax values
149
+ const softmaxArr = exps.map(x => x / sumExps);
150
+
151
+ return /** @type {T} */(softmaxArr);
152
+ }
153
+
154
+ /**
155
+ * Calculates the logarithm of the softmax function for the input array.
156
+ * @template {TypedArray|number[]} T
157
+ * @param {T} arr The input array to calculate the log_softmax function for.
158
+ * @returns {T} The resulting log_softmax array.
159
+ */
160
+ export function log_softmax(arr) {
161
+ // Compute the softmax values
162
+ const softmaxArr = softmax(arr);
163
+
164
+ // Apply log formula to each element
165
+ const logSoftmaxArr = softmaxArr.map(x => Math.log(x));
166
+
167
+ return /** @type {T} */(logSoftmaxArr);
168
+ }
169
+
170
+ /**
171
+ * Calculates the dot product of two arrays.
172
+ * @param {number[]} arr1 The first array.
173
+ * @param {number[]} arr2 The second array.
174
+ * @returns {number} The dot product of arr1 and arr2.
175
+ */
176
+ export function dot(arr1, arr2) {
177
+ let result = 0;
178
+ for (let i = 0; i < arr1.length; ++i) {
179
+ result += arr1[i] * arr2[i];
180
+ }
181
+ return result;
182
+ }
183
+
184
+
185
+ /**
186
+ * Get the top k items from an iterable, sorted by descending order
187
+ * @param {any[]|TypedArray} items The items to be sorted
188
+ * @param {number|null} [top_k=0] The number of top items to return (default: 0 = return all)
189
+ * @returns {[number, any][]} The top k items, sorted by descending order
190
+ */
191
+ export function getTopItems(items, top_k = 0) {
192
+ // if top == 0, return all
193
+
194
+ items = Array.from(items)
195
+ .map((x, i) => [i, x]) // Get indices ([index, score])
196
+ .sort((a, b) => b[1] - a[1]) // Sort by log probabilities
197
+
198
+ if (top_k !== null && top_k > 0) {
199
+ items = items.slice(0, top_k); // Get top k items
200
+ }
201
+
202
+ return items
203
+ }
204
+
205
+ /**
206
+ * Computes the cosine similarity between two arrays.
207
+ *
208
+ * @param {number[]} arr1 The first array.
209
+ * @param {number[]} arr2 The second array.
210
+ * @returns {number} The cosine similarity between the two arrays.
211
+ */
212
+ export function cos_sim(arr1, arr2) {
213
+ // Calculate dot product of the two arrays
214
+ const dotProduct = dot(arr1, arr2);
215
+
216
+ // Calculate the magnitude of the first array
217
+ const magnitudeA = magnitude(arr1);
218
+
219
+ // Calculate the magnitude of the second array
220
+ const magnitudeB = magnitude(arr2);
221
+
222
+ // Calculate the cosine similarity
223
+ const cosineSimilarity = dotProduct / (magnitudeA * magnitudeB);
224
+
225
+ return cosineSimilarity;
226
+ }
227
+
228
+ /**
229
+ * Calculates the magnitude of a given array.
230
+ * @param {number[]} arr The array to calculate the magnitude of.
231
+ * @returns {number} The magnitude of the array.
232
+ */
233
+ export function magnitude(arr) {
234
+ return Math.sqrt(arr.reduce((acc, val) => acc + val * val, 0));
235
+ }
236
+
237
+
238
+ /**
239
+ * Returns the value and index of the minimum element in an array.
240
+ * @param {number[]|TypedArray} arr array of numbers.
241
+ * @returns {number[]} the value and index of the minimum element, of the form: [valueOfMin, indexOfMin]
242
+ * @throws {Error} If array is empty.
243
+ */
244
+ export function min(arr) {
245
+ if (arr.length === 0) throw Error('Array must not be empty');
246
+ let min = arr[0];
247
+ let indexOfMin = 0;
248
+ for (let i = 1; i < arr.length; ++i) {
249
+ if (arr[i] < min) {
250
+ min = arr[i];
251
+ indexOfMin = i;
252
+ }
253
+ }
254
+ return [min, indexOfMin];
255
+ }
256
+
257
+
258
+ /**
259
+ * Returns the value and index of the maximum element in an array.
260
+ * @param {number[]|AnyTypedArray} arr array of numbers.
261
+ * @returns {[number, number]} the value and index of the maximum element, of the form: [valueOfMax, indexOfMax]
262
+ * @throws {Error} If array is empty.
263
+ */
264
+ export function max(arr) {
265
+ if (arr.length === 0) throw Error('Array must not be empty');
266
+ let max = arr[0];
267
+ let indexOfMax = 0;
268
+ for (let i = 1; i < arr.length; ++i) {
269
+ if (arr[i] > max) {
270
+ max = arr[i];
271
+ indexOfMax = i;
272
+ }
273
+ }
274
+ return [Number(max), indexOfMax];
275
+ }
276
+
277
+ function isPowerOfTwo(number) {
278
+ // Check if the number is greater than 0 and has only one bit set to 1
279
+ return (number > 0) && ((number & (number - 1)) === 0);
280
+ }
281
+
282
+ /**
283
+ * Implementation of Radix-4 FFT.
284
+ *
285
+ * P2FFT class provides functionality for performing Fast Fourier Transform on arrays
286
+ * which are a power of two in length.
287
+ * Code adapted from https://www.npmjs.com/package/fft.js
288
+ */
289
+ class P2FFT {
290
+ /**
291
+ * @param {number} size The size of the input array. Must be a power of two larger than 1.
292
+ * @throws {Error} FFT size must be a power of two larger than 1.
293
+ */
294
+ constructor(size) {
295
+ this.size = size | 0; // convert to a 32-bit signed integer
296
+ if (this.size <= 1 || !isPowerOfTwo(this.size))
297
+ throw new Error('FFT size must be a power of two larger than 1');
298
+
299
+ this._csize = size << 1;
300
+
301
+ this.table = new Float64Array(this.size * 2);
302
+ for (let i = 0; i < this.table.length; i += 2) {
303
+ const angle = Math.PI * i / this.size;
304
+ this.table[i] = Math.cos(angle);
305
+ this.table[i + 1] = -Math.sin(angle);
306
+ }
307
+
308
+ // Find size's power of two
309
+ let power = 0;
310
+ for (let t = 1; this.size > t; t <<= 1)
311
+ ++power;
312
+
313
+ // Calculate initial step's width:
314
+ // * If we are full radix-4, it is 2x smaller to give inital len=8
315
+ // * Otherwise it is the same as `power` to give len=4
316
+ this._width = power % 2 === 0 ? power - 1 : power;
317
+
318
+ // Pre-compute bit-reversal patterns
319
+ this._bitrev = new Int32Array(1 << this._width);
320
+ for (let j = 0; j < this._bitrev.length; ++j) {
321
+ this._bitrev[j] = 0;
322
+ for (let shift = 0; shift < this._width; shift += 2) {
323
+ const revShift = this._width - shift - 2;
324
+ this._bitrev[j] |= ((j >>> shift) & 3) << revShift;
325
+ }
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Create a complex number array with size `2 * size`
331
+ *
332
+ * @returns {Float64Array} A complex number array with size `2 * size`
333
+ */
334
+ createComplexArray() {
335
+ return new Float64Array(this._csize);
336
+ }
337
+
338
+ /**
339
+ * Converts a complex number representation stored in a Float64Array to an array of real numbers.
340
+ *
341
+ * @param {Float64Array} complex The complex number representation to be converted.
342
+ * @param {number[]} [storage] An optional array to store the result in.
343
+ * @returns {number[]} An array of real numbers representing the input complex number representation.
344
+ */
345
+ fromComplexArray(complex, storage) {
346
+ const res = storage || new Array(complex.length >>> 1);
347
+ for (let i = 0; i < complex.length; i += 2)
348
+ res[i >>> 1] = complex[i];
349
+ return res;
350
+ }
351
+
352
+ /**
353
+ * Convert a real-valued input array to a complex-valued output array.
354
+ * @param {Float64Array} input The real-valued input array.
355
+ * @param {Float64Array} [storage] Optional buffer to store the output array.
356
+ * @returns {Float64Array} The complex-valued output array.
357
+ */
358
+ toComplexArray(input, storage) {
359
+ const res = storage || this.createComplexArray();
360
+ for (let i = 0; i < res.length; i += 2) {
361
+ res[i] = input[i >>> 1];
362
+ res[i + 1] = 0;
363
+ }
364
+ return res;
365
+ }
366
+
367
+ /**
368
+ * Performs a Fast Fourier Transform (FFT) on the given input data and stores the result in the output buffer.
369
+ *
370
+ * @param {Float64Array} out The output buffer to store the result.
371
+ * @param {Float64Array} data The input data to transform.
372
+ *
373
+ * @throws {Error} Input and output buffers must be different.
374
+ *
375
+ * @returns {void}
376
+ */
377
+ transform(out, data) {
378
+ if (out === data)
379
+ throw new Error('Input and output buffers must be different');
380
+
381
+ this._transform4(out, data, 1 /* DONE */);
382
+ }
383
+
384
+ /**
385
+ * Performs a real-valued forward FFT on the given input buffer and stores the result in the given output buffer.
386
+ * The input buffer must contain real values only, while the output buffer will contain complex values. The input and
387
+ * output buffers must be different.
388
+ *
389
+ * @param {Float64Array} out The output buffer.
390
+ * @param {Float64Array} data The input buffer containing real values.
391
+ *
392
+ * @throws {Error} If the input and output buffers are the same.
393
+ */
394
+ realTransform(out, data) {
395
+ if (out === data)
396
+ throw new Error('Input and output buffers must be different');
397
+
398
+ this._realTransform4(out, data, 1 /* DONE */);
399
+ }
400
+
401
+ /**
402
+ * Performs an inverse FFT transformation on the given `data` array, and stores the result in `out`.
403
+ * The `out` array must be a different buffer than the `data` array. The `out` array will contain the
404
+ * result of the transformation. The `data` array will not be modified.
405
+ *
406
+ * @param {Float64Array} out The output buffer for the transformed data.
407
+ * @param {Float64Array} data The input data to transform.
408
+ * @throws {Error} If `out` and `data` refer to the same buffer.
409
+ * @returns {void}
410
+ */
411
+ inverseTransform(out, data) {
412
+ if (out === data)
413
+ throw new Error('Input and output buffers must be different');
414
+
415
+ this._transform4(out, data, -1 /* DONE */);
416
+ for (let i = 0; i < out.length; ++i)
417
+ out[i] /= this.size;
418
+ }
419
+
420
+ /**
421
+ * Performs a radix-4 implementation of a discrete Fourier transform on a given set of data.
422
+ *
423
+ * @param {Float64Array} out The output buffer for the transformed data.
424
+ * @param {Float64Array} data The input buffer of data to be transformed.
425
+ * @param {number} inv A scaling factor to apply to the transform.
426
+ * @returns {void}
427
+ */
428
+ _transform4(out, data, inv) {
429
+ // radix-4 implementation
430
+
431
+ const size = this._csize;
432
+
433
+ // Initial step (permute and transform)
434
+ const width = this._width;
435
+ let step = 1 << width;
436
+ let len = (size / step) << 1;
437
+
438
+ let outOff;
439
+ let t;
440
+ const bitrev = this._bitrev;
441
+ if (len === 4) {
442
+ for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {
443
+ const off = bitrev[t];
444
+ this._singleTransform2(data, out, outOff, off, step);
445
+ }
446
+ } else {
447
+ // len === 8
448
+ for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {
449
+ const off = bitrev[t];
450
+ this._singleTransform4(data, out, outOff, off, step, inv);
451
+ }
452
+ }
453
+
454
+ // Loop through steps in decreasing order
455
+ const table = this.table;
456
+ for (step >>= 2; step >= 2; step >>= 2) {
457
+ len = (size / step) << 1;
458
+ const quarterLen = len >>> 2;
459
+
460
+ // Loop through offsets in the data
461
+ for (outOff = 0; outOff < size; outOff += len) {
462
+ // Full case
463
+ const limit = outOff + quarterLen - 1;
464
+ for (let i = outOff, k = 0; i < limit; i += 2, k += step) {
465
+ const A = i;
466
+ const B = A + quarterLen;
467
+ const C = B + quarterLen;
468
+ const D = C + quarterLen;
469
+
470
+ // Original values
471
+ const Ar = out[A];
472
+ const Ai = out[A + 1];
473
+ const Br = out[B];
474
+ const Bi = out[B + 1];
475
+ const Cr = out[C];
476
+ const Ci = out[C + 1];
477
+ const Dr = out[D];
478
+ const Di = out[D + 1];
479
+
480
+ const tableBr = table[k];
481
+ const tableBi = inv * table[k + 1];
482
+ const MBr = Br * tableBr - Bi * tableBi;
483
+ const MBi = Br * tableBi + Bi * tableBr;
484
+
485
+ const tableCr = table[2 * k];
486
+ const tableCi = inv * table[2 * k + 1];
487
+ const MCr = Cr * tableCr - Ci * tableCi;
488
+ const MCi = Cr * tableCi + Ci * tableCr;
489
+
490
+ const tableDr = table[3 * k];
491
+ const tableDi = inv * table[3 * k + 1];
492
+ const MDr = Dr * tableDr - Di * tableDi;
493
+ const MDi = Dr * tableDi + Di * tableDr;
494
+
495
+ // Pre-Final values
496
+ const T0r = Ar + MCr;
497
+ const T0i = Ai + MCi;
498
+ const T1r = Ar - MCr;
499
+ const T1i = Ai - MCi;
500
+ const T2r = MBr + MDr;
501
+ const T2i = MBi + MDi;
502
+ const T3r = inv * (MBr - MDr);
503
+ const T3i = inv * (MBi - MDi);
504
+
505
+ // Final values
506
+ out[A] = T0r + T2r;
507
+ out[A + 1] = T0i + T2i;
508
+ out[B] = T1r + T3i;
509
+ out[B + 1] = T1i - T3r;
510
+ out[C] = T0r - T2r;
511
+ out[C + 1] = T0i - T2i;
512
+ out[D] = T1r - T3i;
513
+ out[D + 1] = T1i + T3r;
514
+ }
515
+ }
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Performs a radix-2 implementation of a discrete Fourier transform on a given set of data.
521
+ *
522
+ * @param {Float64Array} data The input buffer of data to be transformed.
523
+ * @param {Float64Array} out The output buffer for the transformed data.
524
+ * @param {number} outOff The offset at which to write the output data.
525
+ * @param {number} off The offset at which to begin reading the input data.
526
+ * @param {number} step The step size for indexing the input data.
527
+ * @returns {void}
528
+ */
529
+ _singleTransform2(data, out, outOff, off, step) {
530
+ // radix-2 implementation
531
+ // NOTE: Only called for len=4
532
+
533
+ const evenR = data[off];
534
+ const evenI = data[off + 1];
535
+ const oddR = data[off + step];
536
+ const oddI = data[off + step + 1];
537
+
538
+ out[outOff] = evenR + oddR;
539
+ out[outOff + 1] = evenI + oddI;
540
+ out[outOff + 2] = evenR - oddR;
541
+ out[outOff + 3] = evenI - oddI;
542
+ }
543
+
544
+ /**
545
+ * Performs radix-4 transformation on input data of length 8
546
+ *
547
+ * @param {Float64Array} data Input data array of length 8
548
+ * @param {Float64Array} out Output data array of length 8
549
+ * @param {number} outOff Index of output array to start writing from
550
+ * @param {number} off Index of input array to start reading from
551
+ * @param {number} step Step size between elements in input array
552
+ * @param {number} inv Scaling factor for inverse transform
553
+ *
554
+ * @returns {void}
555
+ */
556
+ _singleTransform4(data, out, outOff, off, step, inv) {
557
+ // radix-4
558
+ // NOTE: Only called for len=8
559
+ const step2 = step * 2;
560
+ const step3 = step * 3;
561
+
562
+ // Original values
563
+ const Ar = data[off];
564
+ const Ai = data[off + 1];
565
+ const Br = data[off + step];
566
+ const Bi = data[off + step + 1];
567
+ const Cr = data[off + step2];
568
+ const Ci = data[off + step2 + 1];
569
+ const Dr = data[off + step3];
570
+ const Di = data[off + step3 + 1];
571
+
572
+ // Pre-Final values
573
+ const T0r = Ar + Cr;
574
+ const T0i = Ai + Ci;
575
+ const T1r = Ar - Cr;
576
+ const T1i = Ai - Ci;
577
+ const T2r = Br + Dr;
578
+ const T2i = Bi + Di;
579
+ const T3r = inv * (Br - Dr);
580
+ const T3i = inv * (Bi - Di);
581
+
582
+ // Final values
583
+ out[outOff] = T0r + T2r;
584
+ out[outOff + 1] = T0i + T2i;
585
+ out[outOff + 2] = T1r + T3i;
586
+ out[outOff + 3] = T1i - T3r;
587
+ out[outOff + 4] = T0r - T2r;
588
+ out[outOff + 5] = T0i - T2i;
589
+ out[outOff + 6] = T1r - T3i;
590
+ out[outOff + 7] = T1i + T3r;
591
+ }
592
+
593
+ /**
594
+ * Real input radix-4 implementation
595
+ * @param {Float64Array} out Output array for the transformed data
596
+ * @param {Float64Array} data Input array of real data to be transformed
597
+ * @param {number} inv The scale factor used to normalize the inverse transform
598
+ */
599
+ _realTransform4(out, data, inv) {
600
+ // Real input radix-4 implementation
601
+ const size = this._csize;
602
+
603
+ // Initial step (permute and transform)
604
+ const width = this._width;
605
+ let step = 1 << width;
606
+ let len = (size / step) << 1;
607
+
608
+ let outOff;
609
+ let t;
610
+ const bitrev = this._bitrev;
611
+ if (len === 4) {
612
+ for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {
613
+ const off = bitrev[t];
614
+ this._singleRealTransform2(data, out, outOff, off >>> 1, step >>> 1);
615
+ }
616
+ } else {
617
+ // len === 8
618
+ for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {
619
+ const off = bitrev[t];
620
+ this._singleRealTransform4(data, out, outOff, off >>> 1, step >>> 1, inv);
621
+ }
622
+ }
623
+
624
+ // Loop through steps in decreasing order
625
+ const table = this.table;
626
+ for (step >>= 2; step >= 2; step >>= 2) {
627
+ len = (size / step) << 1;
628
+ const halfLen = len >>> 1;
629
+ const quarterLen = halfLen >>> 1;
630
+ const hquarterLen = quarterLen >>> 1;
631
+
632
+ // Loop through offsets in the data
633
+ for (outOff = 0; outOff < size; outOff += len) {
634
+ for (let i = 0, k = 0; i <= hquarterLen; i += 2, k += step) {
635
+ const A = outOff + i;
636
+ const B = A + quarterLen;
637
+ const C = B + quarterLen;
638
+ const D = C + quarterLen;
639
+
640
+ // Original values
641
+ const Ar = out[A];
642
+ const Ai = out[A + 1];
643
+ const Br = out[B];
644
+ const Bi = out[B + 1];
645
+ const Cr = out[C];
646
+ const Ci = out[C + 1];
647
+ const Dr = out[D];
648
+ const Di = out[D + 1];
649
+
650
+ // Middle values
651
+ const MAr = Ar;
652
+ const MAi = Ai;
653
+
654
+ const tableBr = table[k];
655
+ const tableBi = inv * table[k + 1];
656
+ const MBr = Br * tableBr - Bi * tableBi;
657
+ const MBi = Br * tableBi + Bi * tableBr;
658
+
659
+ const tableCr = table[2 * k];
660
+ const tableCi = inv * table[2 * k + 1];
661
+ const MCr = Cr * tableCr - Ci * tableCi;
662
+ const MCi = Cr * tableCi + Ci * tableCr;
663
+
664
+ const tableDr = table[3 * k];
665
+ const tableDi = inv * table[3 * k + 1];
666
+ const MDr = Dr * tableDr - Di * tableDi;
667
+ const MDi = Dr * tableDi + Di * tableDr;
668
+
669
+ // Pre-Final values
670
+ const T0r = MAr + MCr;
671
+ const T0i = MAi + MCi;
672
+ const T1r = MAr - MCr;
673
+ const T1i = MAi - MCi;
674
+ const T2r = MBr + MDr;
675
+ const T2i = MBi + MDi;
676
+ const T3r = inv * (MBr - MDr);
677
+ const T3i = inv * (MBi - MDi);
678
+
679
+ // Final values
680
+ out[A] = T0r + T2r;
681
+ out[A + 1] = T0i + T2i;
682
+ out[B] = T1r + T3i;
683
+ out[B + 1] = T1i - T3r;
684
+
685
+ // Output final middle point
686
+ if (i === 0) {
687
+ out[C] = T0r - T2r;
688
+ out[C + 1] = T0i - T2i;
689
+ continue;
690
+ }
691
+
692
+ // Do not overwrite ourselves
693
+ if (i === hquarterLen)
694
+ continue;
695
+
696
+ const SA = outOff + quarterLen - i;
697
+ const SB = outOff + halfLen - i;
698
+
699
+ out[SA] = T1r - inv * T3i;
700
+ out[SA + 1] = -T1i - inv * T3r;
701
+ out[SB] = T0r - inv * T2r;
702
+ out[SB + 1] = -T0i + inv * T2i;
703
+ }
704
+ }
705
+ }
706
+
707
+ // Complete the spectrum by adding its mirrored negative frequency components.
708
+ const half = size >>> 1;
709
+ for (let i = 2; i < half; i += 2) {
710
+ out[size - i] = out[i];
711
+ out[size - i + 1] = -out[i + 1];
712
+ }
713
+ }
714
+
715
+ /**
716
+ * Performs a single real input radix-2 transformation on the provided data
717
+ *
718
+ * @param {Float64Array} data The input data array
719
+ * @param {Float64Array} out The output data array
720
+ * @param {number} outOff The output offset
721
+ * @param {number} off The input offset
722
+ * @param {number} step The step
723
+ *
724
+ * @returns {void}
725
+ */
726
+ _singleRealTransform2(data, out, outOff, off, step) {
727
+ // radix-2 implementation
728
+ // NOTE: Only called for len=4
729
+
730
+ const evenR = data[off];
731
+ const oddR = data[off + step];
732
+
733
+ out[outOff] = evenR + oddR;
734
+ out[outOff + 1] = 0;
735
+ out[outOff + 2] = evenR - oddR;
736
+ out[outOff + 3] = 0;
737
+ }
738
+
739
+ /**
740
+ * Computes a single real-valued transform using radix-4 algorithm.
741
+ * This method is only called for len=8.
742
+ *
743
+ * @param {Float64Array} data The input data array.
744
+ * @param {Float64Array} out The output data array.
745
+ * @param {number} outOff The offset into the output array.
746
+ * @param {number} off The offset into the input array.
747
+ * @param {number} step The step size for the input array.
748
+ * @param {number} inv The value of inverse.
749
+ */
750
+ _singleRealTransform4(data, out, outOff, off, step, inv) {
751
+ // radix-4
752
+ // NOTE: Only called for len=8
753
+ const step2 = step * 2;
754
+ const step3 = step * 3;
755
+
756
+ // Original values
757
+ const Ar = data[off];
758
+ const Br = data[off + step];
759
+ const Cr = data[off + step2];
760
+ const Dr = data[off + step3];
761
+
762
+ // Pre-Final values
763
+ const T0r = Ar + Cr;
764
+ const T1r = Ar - Cr;
765
+ const T2r = Br + Dr;
766
+ const T3r = inv * (Br - Dr);
767
+
768
+ // Final values
769
+ out[outOff] = T0r + T2r;
770
+ out[outOff + 1] = 0;
771
+ out[outOff + 2] = T1r;
772
+ out[outOff + 3] = -T3r;
773
+ out[outOff + 4] = T0r - T2r;
774
+ out[outOff + 5] = 0;
775
+ out[outOff + 6] = T1r;
776
+ out[outOff + 7] = T3r;
777
+ }
778
+ }
779
+
780
+ /**
781
+ * NP2FFT class provides functionality for performing Fast Fourier Transform on arrays
782
+ * which are not a power of two in length. In such cases, the chirp-z transform is used.
783
+ *
784
+ * For more information, see: https://math.stackexchange.com/questions/77118/non-power-of-2-ffts/77156#77156
785
+ */
786
+ class NP2FFT {
787
+
788
+ /**
789
+ * Constructs a new NP2FFT object.
790
+ * @param {number} fft_length The length of the FFT
791
+ */
792
+ constructor(fft_length) {
793
+ // Helper variables
794
+ const a = 2 * (fft_length - 1);
795
+ const b = 2 * (2 * fft_length - 1);
796
+ const nextP2 = 2 ** (Math.ceil(Math.log2(b)))
797
+ this.bufferSize = nextP2;
798
+ this._a = a;
799
+
800
+ // Define buffers
801
+ // Compute chirp for transform
802
+ const chirp = new Float64Array(b);
803
+ const ichirp = new Float64Array(nextP2);
804
+ this._chirpBuffer = new Float64Array(nextP2);
805
+ this._buffer1 = new Float64Array(nextP2);
806
+ this._buffer2 = new Float64Array(nextP2);
807
+ this._outBuffer1 = new Float64Array(nextP2);
808
+ this._outBuffer2 = new Float64Array(nextP2);
809
+
810
+ // Compute complex exponentiation
811
+ const theta = -2 * Math.PI / fft_length;
812
+ const baseR = Math.cos(theta);
813
+ const baseI = Math.sin(theta);
814
+
815
+ // Precompute helper for chirp-z transform
816
+ for (let i = 0; i < b >> 1; ++i) {
817
+ // Compute complex power:
818
+ const e = (i + 1 - fft_length) ** 2 / 2.0;
819
+
820
+ // Compute the modulus and argument of the result
821
+ const result_mod = Math.sqrt(baseR ** 2 + baseI ** 2) ** e;
822
+ const result_arg = e * Math.atan2(baseI, baseR);
823
+
824
+ // Convert the result back to rectangular form
825
+ // and assign to chirp and ichirp
826
+ const i2 = 2 * i;
827
+ chirp[i2] = result_mod * Math.cos(result_arg);
828
+ chirp[i2 + 1] = result_mod * Math.sin(result_arg);
829
+
830
+ // conjugate
831
+ ichirp[i2] = chirp[i2];
832
+ ichirp[i2 + 1] = - chirp[i2 + 1];
833
+ }
834
+ this._slicedChirpBuffer = chirp.subarray(a, b);
835
+
836
+ // create object to perform Fast Fourier Transforms
837
+ // with `nextP2` complex numbers
838
+ this._f = new P2FFT(nextP2 >> 1);
839
+ this._f.transform(this._chirpBuffer, ichirp);
840
+ }
841
+
842
+ _transform(output, input, real) {
843
+ const ib1 = this._buffer1;
844
+ const ib2 = this._buffer2;
845
+ const ob2 = this._outBuffer1;
846
+ const ob3 = this._outBuffer2;
847
+ const cb = this._chirpBuffer;
848
+ const sb = this._slicedChirpBuffer;
849
+ const a = this._a;
850
+
851
+ if (real) {
852
+ // Real multiplication
853
+ for (let j = 0; j < sb.length; j += 2) {
854
+ const j2 = j + 1
855
+ const j3 = j >> 1;
856
+
857
+ const a_real = input[j3];
858
+ ib1[j] = a_real * sb[j];
859
+ ib1[j2] = a_real * sb[j2];
860
+ }
861
+ } else {
862
+ // Complex multiplication
863
+ for (let j = 0; j < sb.length; j += 2) {
864
+ const j2 = j + 1
865
+ ib1[j] = input[j] * sb[j] - input[j2] * sb[j2];
866
+ ib1[j2] = input[j] * sb[j2] + input[j2] * sb[j];
867
+ }
868
+ }
869
+ this._f.transform(ob2, ib1);
870
+
871
+ for (let j = 0; j < cb.length; j += 2) {
872
+ const j2 = j + 1;
873
+
874
+ ib2[j] = ob2[j] * cb[j] - ob2[j2] * cb[j2];
875
+ ib2[j2] = ob2[j] * cb[j2] + ob2[j2] * cb[j];
876
+ }
877
+ this._f.inverseTransform(ob3, ib2);
878
+
879
+ for (let j = 0; j < ob3.length; j += 2) {
880
+ const a_real = ob3[j + a];
881
+ const a_imag = ob3[j + a + 1];
882
+ const b_real = sb[j];
883
+ const b_imag = sb[j + 1];
884
+
885
+ output[j] = a_real * b_real - a_imag * b_imag;
886
+ output[j + 1] = a_real * b_imag + a_imag * b_real;
887
+ }
888
+ }
889
+
890
+ transform(output, input) {
891
+ this._transform(output, input, false);
892
+ }
893
+
894
+ realTransform(output, input) {
895
+ this._transform(output, input, true);
896
+ }
897
+ }
898
+
899
+ export class FFT {
900
+ constructor(fft_length) {
901
+ this.fft_length = fft_length;
902
+ this.isPowerOfTwo = isPowerOfTwo(fft_length);
903
+ if (this.isPowerOfTwo) {
904
+ this.fft = new P2FFT(fft_length);
905
+ this.outputBufferSize = 2 * fft_length;
906
+ } else {
907
+ this.fft = new NP2FFT(fft_length);
908
+ this.outputBufferSize = this.fft.bufferSize;
909
+ }
910
+ }
911
+
912
+ realTransform(out, input) {
913
+ this.fft.realTransform(out, input);
914
+ }
915
+
916
+ transform(out, input) {
917
+ this.fft.transform(out, input);
918
+ }
919
+ }
920
+
921
+
922
+ /**
923
+ * Performs median filter on the provided data. Padding is done by mirroring the data.
924
+ * @param {AnyTypedArray} data The input array
925
+ * @param {number} windowSize The window size
926
+ */
927
+ export function medianFilter(data, windowSize) {
928
+
929
+ if (windowSize % 2 === 0 || windowSize <= 0) {
930
+ throw new Error('Window size must be a positive odd number');
931
+ }
932
+
933
+ // @ts-ignore
934
+ const outputArray = new data.constructor(data.length);
935
+
936
+ // @ts-ignore
937
+ const buffer = new data.constructor(windowSize); // Reusable array for storing values
938
+
939
+ const halfWindowSize = Math.floor(windowSize / 2);
940
+
941
+ for (let i = 0; i < data.length; ++i) {
942
+ let valuesIndex = 0;
943
+
944
+ for (let j = -halfWindowSize; j <= halfWindowSize; ++j) {
945
+ let index = i + j;
946
+ if (index < 0) {
947
+ index = Math.abs(index);
948
+ } else if (index >= data.length) {
949
+ index = 2 * (data.length - 1) - index;
950
+ }
951
+
952
+ buffer[valuesIndex++] = data[index];
953
+ }
954
+
955
+ buffer.sort();
956
+ outputArray[i] = buffer[halfWindowSize];
957
+ }
958
+
959
+ return outputArray;
960
+ }
961
+
962
+ /**
963
+ * Helper function to round a number to a given number of decimals
964
+ * @param {number} num The number to round
965
+ * @param {number} decimals The number of decimals
966
+ * @returns {number} The rounded number
967
+ */
968
+ export function round(num, decimals) {
969
+ const pow = Math.pow(10, decimals);
970
+ return Math.round(num * pow) / pow;
971
+ }
972
+
973
+ /**
974
+ * Helper function to round a number to the nearest integer, with ties rounded to the nearest even number.
975
+ * Also known as "bankers' rounding". This is the default rounding mode in python. For example:
976
+ * 1.5 rounds to 2 and 2.5 rounds to 2.
977
+ *
978
+ * @param {number} x The number to round
979
+ * @returns {number} The rounded number
980
+ */
981
+ export function bankers_round(x) {
982
+ const r = Math.round(x);
983
+ const br = Math.abs(x) % 1 === 0.5 ? (r % 2 === 0 ? r : r - 1) : r;
984
+ return br;
985
+ }