@remotion/media-utils 4.0.503 → 4.0.504

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.
@@ -994,65 +994,120 @@ var fftAccurate = function(vector) {
994
994
  };
995
995
 
996
996
  // src/fft/fft-fast.ts
997
- function reverseBits(num, numBits) {
998
- let result = 0;
999
- for (let i = 0;i < numBits; i++) {
1000
- result = result << 1 | num >> i & 1;
1001
- }
1002
- return result;
1003
- }
1004
- function hammingWindow(N) {
1005
- const win = new Array(N);
1006
- for (let i = 0;i < N; i++) {
1007
- win[i] = 0.8 - 0.46 * Math.cos(2 * Math.PI * i / (N - 1));
1008
- }
1009
- return win;
1010
- }
1011
- function bitReversePermutation(N) {
1012
- const bitReversed = new Array(N);
1013
- for (let i = 0;i < N; i++) {
1014
- bitReversed[i] = reverseBits(i, Math.log2(N));
1015
- }
1016
- return bitReversed;
1017
- }
1018
997
  var fftFast = function(vector) {
1019
998
  const N = vector.length;
1020
- const X = new Array(N);
1021
999
  if (N <= 1) {
1000
+ const base = new Array(N);
1022
1001
  for (let i = 0;i < vector.length; i++) {
1023
1002
  const value = vector[i];
1024
- X[i] = [value * 2, 0];
1003
+ base[i] = [value * 2, 0];
1025
1004
  }
1026
- return X;
1005
+ return base;
1027
1006
  }
1028
- const window2 = hammingWindow(N);
1029
- for (let i = 0;i < N; i++) {
1030
- X[i] = [vector[i] * window2[i], 0];
1031
- }
1032
- const bitReversed = bitReversePermutation(N);
1033
- for (let i = 0;i < N; i++) {
1034
- X[i] = [vector[bitReversed[i]], 0];
1007
+ const real = new Float64Array(N);
1008
+ const imag = new Float64Array(N);
1009
+ const halfN = N >> 1;
1010
+ let rev = 0;
1011
+ for (let i = 0;i < N; i += 2) {
1012
+ const v1 = vector[rev];
1013
+ const v2 = vector[rev + halfN];
1014
+ real[i] = v1 + v2;
1015
+ imag[i] = 0;
1016
+ real[i + 1] = v1 - v2;
1017
+ imag[i + 1] = 0;
1018
+ let bit = halfN >> 1;
1019
+ while (rev & bit) {
1020
+ rev ^= bit;
1021
+ bit >>= 1;
1022
+ }
1023
+ rev ^= bit;
1035
1024
  }
1036
- for (let s = 1;s <= Math.log2(N); s++) {
1025
+ const logN = Math.log2(N);
1026
+ for (let s = 2;s <= logN; s++) {
1037
1027
  const m = 1 << s;
1038
- const mHalf = m / 2;
1028
+ const mHalf = m >> 1;
1039
1029
  const angleIncrement = 2 * Math.PI / m;
1040
- for (let k = 0;k < N; k += m) {
1041
- let omegaReal = 1;
1042
- let omegaImag = 0;
1043
- for (let j = 0;j < mHalf; j++) {
1044
- const tReal = omegaReal * X[k + j + mHalf][0] - omegaImag * X[k + j + mHalf][1];
1045
- const tImag = omegaReal * X[k + j + mHalf][1] + omegaImag * X[k + j + mHalf][0];
1046
- const uReal = X[k + j][0];
1047
- const uImag = X[k + j][1];
1048
- X[k + j] = [uReal + tReal, uImag + tImag];
1049
- X[k + j + mHalf] = [uReal - tReal, uImag - tImag];
1050
- const tempReal = omegaReal * Math.cos(angleIncrement) - omegaImag * Math.sin(angleIncrement);
1051
- omegaImag = omegaReal * Math.sin(angleIncrement) + omegaImag * Math.cos(angleIncrement);
1052
- omegaReal = tempReal;
1030
+ const cosA = Math.cos(angleIncrement);
1031
+ const sinA = Math.sin(angleIncrement);
1032
+ const m2 = m << 1;
1033
+ if (s < logN) {
1034
+ for (let k = 0;k < N; k += m2) {
1035
+ const r10 = real[k];
1036
+ const r11 = imag[k];
1037
+ const r20 = real[k + mHalf];
1038
+ const r21 = imag[k + mHalf];
1039
+ real[k] = r10 + r20;
1040
+ imag[k] = r11 + r21;
1041
+ real[k + mHalf] = r10 - r20;
1042
+ imag[k + mHalf] = r11 - r21;
1043
+ const km = k + m;
1044
+ const r30 = real[km];
1045
+ const r31 = imag[km];
1046
+ const r40 = real[km + mHalf];
1047
+ const r41 = imag[km + mHalf];
1048
+ real[km] = r30 + r40;
1049
+ imag[km] = r31 + r41;
1050
+ real[km + mHalf] = r30 - r40;
1051
+ imag[km + mHalf] = r31 - r41;
1052
+ }
1053
+ } else {
1054
+ const r10 = real[0];
1055
+ const r11 = imag[0];
1056
+ const r20 = real[mHalf];
1057
+ const r21 = imag[mHalf];
1058
+ real[0] = r10 + r20;
1059
+ imag[0] = r11 + r21;
1060
+ real[mHalf] = r10 - r20;
1061
+ imag[mHalf] = r11 - r21;
1062
+ }
1063
+ let omegaReal = cosA;
1064
+ let omegaImag = sinA;
1065
+ for (let j = 1;j < mHalf; j++) {
1066
+ if (s < logN) {
1067
+ for (let k = j;k < N; k += m2) {
1068
+ const r10 = real[k];
1069
+ const r11 = imag[k];
1070
+ const r20 = real[k + mHalf];
1071
+ const r21 = imag[k + mHalf];
1072
+ const tR1 = omegaReal * r20 - omegaImag * r21;
1073
+ const tI1 = omegaReal * r21 + omegaImag * r20;
1074
+ real[k] = r10 + tR1;
1075
+ imag[k] = r11 + tI1;
1076
+ real[k + mHalf] = r10 - tR1;
1077
+ imag[k + mHalf] = r11 - tI1;
1078
+ const km = k + m;
1079
+ const r30 = real[km];
1080
+ const r31 = imag[km];
1081
+ const r40 = real[km + mHalf];
1082
+ const r41 = imag[km + mHalf];
1083
+ const tR2 = omegaReal * r40 - omegaImag * r41;
1084
+ const tI2 = omegaReal * r41 + omegaImag * r40;
1085
+ real[km] = r30 + tR2;
1086
+ imag[km] = r31 + tI2;
1087
+ real[km + mHalf] = r30 - tR2;
1088
+ imag[km + mHalf] = r31 - tI2;
1089
+ }
1090
+ } else {
1091
+ const r10 = real[j];
1092
+ const r11 = imag[j];
1093
+ const r20 = real[j + mHalf];
1094
+ const r21 = imag[j + mHalf];
1095
+ const tR = omegaReal * r20 - omegaImag * r21;
1096
+ const tI = omegaReal * r21 + omegaImag * r20;
1097
+ real[j] = r10 + tR;
1098
+ imag[j] = r11 + tI;
1099
+ real[j + mHalf] = r10 - tR;
1100
+ imag[j + mHalf] = r11 - tI;
1053
1101
  }
1102
+ const tempReal = omegaReal * cosA - omegaImag * sinA;
1103
+ omegaImag = omegaReal * sinA + omegaImag * cosA;
1104
+ omegaReal = tempReal;
1054
1105
  }
1055
1106
  }
1107
+ const X = new Array(N);
1108
+ for (let i = 0;i < N; i++) {
1109
+ X[i] = [real[i], imag[i]];
1110
+ }
1056
1111
  return X;
1057
1112
  };
1058
1113
 
@@ -1,76 +1,129 @@
1
1
  "use strict";
2
- // https://pastebin.com/raw/D42RbPe5
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.fftFast = void 0;
5
- // Function to reverse bits in an integer
6
- function reverseBits(num, numBits) {
7
- let result = 0;
8
- for (let i = 0; i < numBits; i++) {
9
- result = (result << 1) | ((num >> i) & 1);
10
- }
11
- return result;
12
- }
13
- // Hamming window function
14
- function hammingWindow(N) {
15
- const win = new Array(N);
16
- for (let i = 0; i < N; i++) {
17
- win[i] = 0.8 - 0.46 * Math.cos((2 * Math.PI * i) / (N - 1));
18
- }
19
- return win;
20
- }
21
- // Function to calculate the bit-reversed permutation indices
22
- function bitReversePermutation(N) {
23
- const bitReversed = new Array(N);
24
- for (let i = 0; i < N; i++) {
25
- bitReversed[i] = reverseBits(i, Math.log2(N));
26
- }
27
- return bitReversed;
28
- }
29
4
  const fftFast = function (vector) {
30
5
  const N = vector.length;
31
- const X = new Array(N);
32
6
  if (N <= 1) {
7
+ const base = new Array(N);
33
8
  for (let i = 0; i < vector.length; i++) {
34
9
  const value = vector[i];
35
- X[i] = [value * 2, 0];
10
+ base[i] = [value * 2, 0];
36
11
  }
37
- return X;
38
- }
39
- // Apply a windowing function to the input data
40
- const window = hammingWindow(N); // You can choose a different window function if needed
41
- for (let i = 0; i < N; i++) {
42
- X[i] = [vector[i] * window[i], 0];
12
+ return base;
43
13
  }
44
- // Bit-Reversal Permutation
45
- const bitReversed = bitReversePermutation(N);
46
- for (let i = 0; i < N; i++) {
47
- X[i] = [vector[bitReversed[i]], 0];
14
+ // Use typed arrays for calculation to avoid tuple property access overhead.
15
+ const real = new Float64Array(N);
16
+ const imag = new Float64Array(N);
17
+ const halfN = N >> 1;
18
+ let rev = 0;
19
+ // Combined bit-reversal and the first stage (s=1) to reduce passes and allocations.
20
+ for (let i = 0; i < N; i += 2) {
21
+ const v1 = vector[rev];
22
+ const v2 = vector[rev + halfN];
23
+ real[i] = v1 + v2;
24
+ imag[i] = 0;
25
+ real[i + 1] = v1 - v2;
26
+ imag[i + 1] = 0;
27
+ // Efficiently advance the bit-reversal index for the next even i (i+2).
28
+ let bit = halfN >> 1;
29
+ while (rev & bit) {
30
+ rev ^= bit;
31
+ bit >>= 1;
32
+ }
33
+ rev ^= bit;
48
34
  }
49
- // Cooley-Tukey FFT
50
- for (let s = 1; s <= Math.log2(N); s++) {
51
- const m = 1 << s; // Number of elements in each subarray
52
- const mHalf = m / 2; // Half the number of elements in each subarray
35
+ const logN = Math.log2(N);
36
+ for (let s = 2; s <= logN; s++) {
37
+ const m = 1 << s;
38
+ const mHalf = m >> 1;
53
39
  const angleIncrement = (2 * Math.PI) / m;
54
- for (let k = 0; k < N; k += m) {
55
- let omegaReal = 1.0;
56
- let omegaImag = 0.0;
57
- for (let j = 0; j < mHalf; j++) {
58
- const tReal = omegaReal * X[k + j + mHalf][0] - omegaImag * X[k + j + mHalf][1];
59
- const tImag = omegaReal * X[k + j + mHalf][1] + omegaImag * X[k + j + mHalf][0];
60
- const uReal = X[k + j][0];
61
- const uImag = X[k + j][1];
62
- X[k + j] = [uReal + tReal, uImag + tImag];
63
- X[k + j + mHalf] = [uReal - tReal, uImag - tImag];
64
- // Twiddle factor update
65
- const tempReal = omegaReal * Math.cos(angleIncrement) -
66
- omegaImag * Math.sin(angleIncrement);
67
- omegaImag =
68
- omegaReal * Math.sin(angleIncrement) +
69
- omegaImag * Math.cos(angleIncrement);
70
- omegaReal = tempReal;
40
+ const cosA = Math.cos(angleIncrement);
41
+ const sinA = Math.sin(angleIncrement);
42
+ const m2 = m << 1;
43
+ // Hoist j=0 butterfly to eliminate multiplications.
44
+ if (s < logN) {
45
+ for (let k = 0; k < N; k += m2) {
46
+ const r10 = real[k];
47
+ const r11 = imag[k];
48
+ const r20 = real[k + mHalf];
49
+ const r21 = imag[k + mHalf];
50
+ real[k] = r10 + r20;
51
+ imag[k] = r11 + r21;
52
+ real[k + mHalf] = r10 - r20;
53
+ imag[k + mHalf] = r11 - r21;
54
+ const km = k + m;
55
+ const r30 = real[km];
56
+ const r31 = imag[km];
57
+ const r40 = real[km + mHalf];
58
+ const r41 = imag[km + mHalf];
59
+ real[km] = r30 + r40;
60
+ imag[km] = r31 + r41;
61
+ real[km + mHalf] = r30 - r40;
62
+ imag[km + mHalf] = r31 - r41;
63
+ }
64
+ }
65
+ else {
66
+ const r10 = real[0];
67
+ const r11 = imag[0];
68
+ const r20 = real[mHalf];
69
+ const r21 = imag[mHalf];
70
+ real[0] = r10 + r20;
71
+ imag[0] = r11 + r21;
72
+ real[mHalf] = r10 - r20;
73
+ imag[mHalf] = r11 - r21;
74
+ }
75
+ // First twiddle factor update for j=0 -> j=1.
76
+ let omegaReal = cosA;
77
+ let omegaImag = sinA;
78
+ for (let j = 1; j < mHalf; j++) {
79
+ if (s < logN) {
80
+ for (let k = j; k < N; k += m2) {
81
+ const r10 = real[k];
82
+ const r11 = imag[k];
83
+ const r20 = real[k + mHalf];
84
+ const r21 = imag[k + mHalf];
85
+ const tR1 = omegaReal * r20 - omegaImag * r21;
86
+ const tI1 = omegaReal * r21 + omegaImag * r20;
87
+ real[k] = r10 + tR1;
88
+ imag[k] = r11 + tI1;
89
+ real[k + mHalf] = r10 - tR1;
90
+ imag[k + mHalf] = r11 - tI1;
91
+ const km = k + m;
92
+ const r30 = real[km];
93
+ const r31 = imag[km];
94
+ const r40 = real[km + mHalf];
95
+ const r41 = imag[km + mHalf];
96
+ const tR2 = omegaReal * r40 - omegaImag * r41;
97
+ const tI2 = omegaReal * r41 + omegaImag * r40;
98
+ real[km] = r30 + tR2;
99
+ imag[km] = r31 + tI2;
100
+ real[km + mHalf] = r30 - tR2;
101
+ imag[km + mHalf] = r31 - tI2;
102
+ }
71
103
  }
104
+ else {
105
+ const r10 = real[j];
106
+ const r11 = imag[j];
107
+ const r20 = real[j + mHalf];
108
+ const r21 = imag[j + mHalf];
109
+ const tR = omegaReal * r20 - omegaImag * r21;
110
+ const tI = omegaReal * r21 + omegaImag * r20;
111
+ real[j] = r10 + tR;
112
+ imag[j] = r11 + tI;
113
+ real[j + mHalf] = r10 - tR;
114
+ imag[j + mHalf] = r11 - tI;
115
+ }
116
+ // Bit-exact twiddle factor update.
117
+ const tempReal = omegaReal * cosA - omegaImag * sinA;
118
+ omegaImag = omegaReal * sinA + omegaImag * cosA;
119
+ omegaReal = tempReal;
72
120
  }
73
121
  }
122
+ // Final conversion to the required [number, number][] return type.
123
+ const X = new Array(N);
124
+ for (let i = 0; i < N; i++) {
125
+ X[i] = [real[i], imag[i]];
126
+ }
74
127
  return X;
75
128
  };
76
129
  exports.fftFast = fftFast;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-utils"
4
4
  },
5
5
  "name": "@remotion/media-utils",
6
- "version": "4.0.503",
6
+ "version": "4.0.504",
7
7
  "description": "Utilities for working with media files",
8
8
  "main": "dist/index.js",
9
9
  "scripts": {
@@ -20,7 +20,7 @@
20
20
  "url": "https://github.com/remotion-dev/remotion/issues"
21
21
  },
22
22
  "dependencies": {
23
- "remotion": "4.0.503",
23
+ "remotion": "4.0.504",
24
24
  "mediabunny": "1.50.8"
25
25
  },
26
26
  "peerDependencies": {
@@ -28,7 +28,7 @@
28
28
  "react-dom": ">=16.8.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@remotion/eslint-config-internal": "4.0.503",
31
+ "@remotion/eslint-config-internal": "4.0.504",
32
32
  "eslint": "9.19.0",
33
33
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
34
34
  },