dsp-collection 0.2.5 → 0.2.6

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 (62) hide show
  1. package/README.md +5 -2
  2. package/filter/SpecFilt.d.ts +10 -10
  3. package/filter/SpecFilt.js +98 -99
  4. package/math/Complex.d.ts +42 -42
  5. package/math/Complex.js +130 -130
  6. package/math/ComplexArray.d.ts +36 -36
  7. package/math/ComplexArray.js +170 -171
  8. package/math/MathUtils.d.ts +9 -7
  9. package/math/MathUtils.js +116 -82
  10. package/math/MutableComplex.d.ts +22 -22
  11. package/math/MutableComplex.js +64 -65
  12. package/math/NumApprox.d.ts +3 -3
  13. package/math/NumApprox.js +67 -68
  14. package/math/PolyReal.d.ts +13 -13
  15. package/math/PolyReal.js +226 -227
  16. package/package.json +11 -3
  17. package/signal/AdaptiveStft.d.ts +12 -12
  18. package/signal/AdaptiveStft.js +57 -58
  19. package/signal/Autocorrelation.d.ts +5 -5
  20. package/signal/Autocorrelation.js +53 -54
  21. package/signal/Dft.d.ts +9 -9
  22. package/signal/Dft.js +87 -88
  23. package/signal/EnvelopeDetection.d.ts +1 -1
  24. package/signal/EnvelopeDetection.js +9 -10
  25. package/signal/Fft.d.ts +9 -9
  26. package/signal/Fft.js +275 -276
  27. package/signal/Goertzel.d.ts +5 -5
  28. package/signal/Goertzel.js +48 -49
  29. package/signal/InstFreq.d.ts +8 -8
  30. package/signal/InstFreq.js +26 -27
  31. package/signal/PitchDetectionHarm.d.ts +26 -26
  32. package/signal/PitchDetectionHarm.js +68 -69
  33. package/signal/Resampling.d.ts +7 -7
  34. package/signal/Resampling.js +218 -219
  35. package/signal/WindowFunctions.d.ts +40 -40
  36. package/signal/WindowFunctions.js +194 -195
  37. package/utils/ArrayUtils.d.ts +9 -9
  38. package/utils/ArrayUtils.js +68 -69
  39. package/utils/DspUtils.d.ts +4 -2
  40. package/utils/DspUtils.js +12 -7
  41. package/utils/MiscUtils.d.ts +6 -6
  42. package/utils/MiscUtils.js +20 -21
  43. package/filter/SpecFilt.js.map +0 -1
  44. package/math/Complex.js.map +0 -1
  45. package/math/ComplexArray.js.map +0 -1
  46. package/math/MathUtils.js.map +0 -1
  47. package/math/MutableComplex.js.map +0 -1
  48. package/math/NumApprox.js.map +0 -1
  49. package/math/PolyReal.js.map +0 -1
  50. package/signal/AdaptiveStft.js.map +0 -1
  51. package/signal/Autocorrelation.js.map +0 -1
  52. package/signal/Dft.js.map +0 -1
  53. package/signal/EnvelopeDetection.js.map +0 -1
  54. package/signal/Fft.js.map +0 -1
  55. package/signal/Goertzel.js.map +0 -1
  56. package/signal/InstFreq.js.map +0 -1
  57. package/signal/PitchDetectionHarm.js.map +0 -1
  58. package/signal/Resampling.js.map +0 -1
  59. package/signal/WindowFunctions.js.map +0 -1
  60. package/utils/ArrayUtils.js.map +0 -1
  61. package/utils/DspUtils.js.map +0 -1
  62. package/utils/MiscUtils.js.map +0 -1
package/signal/Fft.js CHANGED
@@ -1,276 +1,275 @@
1
- import ComplexArray from "../math/ComplexArray.js";
2
- import MutableComplex from "../math/MutableComplex.js";
3
- import * as MathUtils from "../math/MathUtils.js";
4
- var cooleyTukeySineTableCache;
5
- export function fft(x, direction = true) {
6
- const n = x.length;
7
- if (n <= 1) {
8
- return x.slice();
9
- }
10
- const x2 = direction ? x : swapReIm(x);
11
- const x3 = MathUtils.isPowerOf2(n) ? fftCooleyTukey(x2) : fftBluestein(x2);
12
- const x4 = direction ? x3 : swapReIm(x3);
13
- return x4;
14
- }
15
- function fftCooleyTukey(x) {
16
- const n = x.length;
17
- const sineTable = getCachedCooleyTukeySineTable(n);
18
- const a = copyBitReversed(x);
19
- applyButterflies(a, sineTable);
20
- return a;
21
- }
22
- function applyButterflies(a, sineTable) {
23
- const temp = new MutableComplex();
24
- const n = a.length;
25
- const re = a.re;
26
- const im = a.im;
27
- for (let mMax = 1; mMax < n; mMax *= 2) {
28
- const step = mMax * 2;
29
- const sinStep = n / step;
30
- for (let m = 0; m < mMax; m++) {
31
- const wIndex = m * sinStep;
32
- const wRe = sineTable.re[wIndex];
33
- const wIm = sineTable.im[wIndex];
34
- for (let i = m; i < n; i += step) {
35
- const j = i + mMax;
36
- temp.setMul(re[j], im[j], wRe, wIm);
37
- re[j] = re[i] - temp.re;
38
- im[j] = im[i] - temp.im;
39
- re[i] += temp.re;
40
- im[i] += temp.im;
41
- }
42
- }
43
- }
44
- }
45
- function copyBitReversed(a1) {
46
- const n = a1.length;
47
- const a2 = new ComplexArray(n);
48
- let i1 = 0;
49
- for (let i2 = 0; i2 < n; i2++) {
50
- a2.re[i2] = a1.re[i1];
51
- a2.im[i2] = a1.im[i1];
52
- i1 = incrementBitReversed(i1, n);
53
- }
54
- return a2;
55
- }
56
- function incrementBitReversed(i, n) {
57
- let m = n >> 1;
58
- let a = i;
59
- while (a & m) {
60
- a -= m;
61
- m >>= 1;
62
- }
63
- return a | m;
64
- }
65
- function fftBluestein(x) {
66
- const n = x.length;
67
- const m = MathUtils.getNextPowerOf2(2 * n - 3);
68
- const sineTable = createSineOfSquareTable(n, 2 * n);
69
- const a1 = new ComplexArray(m);
70
- for (let i = 0; i < n; i++) {
71
- a1.setMul(i, x.re[i], x.im[i], sineTable.re[i], -sineTable.im[i]);
72
- }
73
- const a2 = new ComplexArray(m);
74
- for (let i = 0; i < n; i++) {
75
- ComplexArray.copy1(sineTable, i, a2, i);
76
- }
77
- for (let i = 1; i < n; i++) {
78
- ComplexArray.copy1(sineTable, i, a2, m - i);
79
- }
80
- const a3 = convolve(a1, a2);
81
- const a4 = new ComplexArray(n);
82
- for (let i = 0; i < n; i++) {
83
- a4.setMul(i, a3.re[i], a3.im[i], sineTable.re[i], -sineTable.im[i]);
84
- }
85
- return a4;
86
- }
87
- function convolve(a1, a2) {
88
- const n = a1.length;
89
- if (a2.length != n) {
90
- throw new Error("Array lengths are not equal.");
91
- }
92
- const a3 = fft(a1);
93
- const a4 = fft(a2);
94
- a3.mulByArray(a4);
95
- const a5 = fft(a3, false);
96
- a5.mulAllByReal(1 / n);
97
- return a5;
98
- }
99
- function getCachedCooleyTukeySineTable(n) {
100
- if (!cooleyTukeySineTableCache) {
101
- cooleyTukeySineTableCache = new Array(16);
102
- }
103
- const log2N = MathUtils.floorLog2(n);
104
- if (!cooleyTukeySineTableCache[log2N]) {
105
- cooleyTukeySineTableCache[log2N] = createCooleyTukeySineTable(n);
106
- }
107
- return cooleyTukeySineTableCache[log2N];
108
- }
109
- function createCooleyTukeySineTable(n) {
110
- return createSineTable(n / 2, n, false);
111
- }
112
- function createSineTable(tableLength, waveLength, rotationalDirection = true) {
113
- const w = 2 * Math.PI / waveLength;
114
- const a = new ComplexArray(tableLength);
115
- for (let i = 0; i < tableLength; i++) {
116
- const t = i * w;
117
- a.re[i] = Math.cos(t);
118
- a.im[i] = rotationalDirection ? Math.sin(t) : -Math.sin(t);
119
- }
120
- return a;
121
- }
122
- function createSineOfSquareTable(tableLength, waveLength) {
123
- const w = 2 * Math.PI / waveLength;
124
- const a = new ComplexArray(tableLength);
125
- for (let i = 0; i < tableLength; i++) {
126
- const t = (i * i) % waveLength * w;
127
- a.re[i] = Math.cos(t);
128
- a.im[i] = Math.sin(t);
129
- }
130
- return a;
131
- }
132
- function swapReIm(a) {
133
- const a2 = new ComplexArray();
134
- a2.length = a.length;
135
- a2.re = a.im;
136
- a2.im = a.re;
137
- return a2;
138
- }
139
- export function fftReal(x) {
140
- return fft(new ComplexArray(x));
141
- }
142
- export function fftRealHalf(x, inclNyquist = false) {
143
- if (x.length <= 1) {
144
- return new ComplexArray(x);
145
- }
146
- const m = x.length;
147
- if (m % 2 != 0) {
148
- throw new Error("Input array size is not even.");
149
- }
150
- const n = m / 2;
151
- const a1 = new ComplexArray(n);
152
- for (let i = 0; i < n; i++) {
153
- a1.re[i] = x[2 * i];
154
- a1.im[i] = x[2 * i + 1];
155
- }
156
- const a2 = fft(a1);
157
- const a3 = new ComplexArray(n + (inclNyquist ? 1 : 0));
158
- a3.re[0] = a2.re[0] + a2.im[0];
159
- a3.im[0] = 0;
160
- if (inclNyquist) {
161
- a3.re[n] = a2.re[0] - a2.im[0];
162
- a3.im[n] = 0;
163
- }
164
- const temp1 = new MutableComplex();
165
- const temp2 = new MutableComplex();
166
- const w = Math.PI / n;
167
- for (let i = 1; i < n; i++) {
168
- const sRe = Math.sin(i * w);
169
- const sIm = Math.cos(i * w);
170
- temp1.setMul(a2.re[i], a2.im[i], (1 - sRe) / 2, -sIm / 2);
171
- temp2.setMul(a2.re[n - i], a2.im[n - i], (1 + sRe) / 2, -sIm / 2);
172
- a3.re[i] = temp1.re + temp2.re;
173
- a3.im[i] = temp1.im - temp2.im;
174
- }
175
- return a3;
176
- }
177
- export function fftRealSpectrum(x, inclNyquist = false) {
178
- const n = x.length;
179
- if (n == 0) {
180
- throw new Error("Input array must not be empty.");
181
- }
182
- let a;
183
- if (n % 2 == 0) {
184
- a = fftRealHalf(x, inclNyquist);
185
- }
186
- else {
187
- const a0 = fftReal(x);
188
- a = a0.subarray(0, Math.floor(n / 2) + 1);
189
- }
190
- for (let i = 0; i < a.length; i++) {
191
- const r = (i == 0 || i == n / 2) ? 1 / n : 2 / n;
192
- a.mulByReal(i, r);
193
- }
194
- return a;
195
- }
196
- export function fftShift(x) {
197
- const n = x.length;
198
- const d = Math.floor(n / 2);
199
- const a = new ComplexArray(n);
200
- for (let p = 0; p < n; p++) {
201
- ComplexArray.copy1(x, p, a, (p + d) % n);
202
- }
203
- return a;
204
- }
205
- export function iFftRealHalfSimple(x, len, inclNyquist = false) {
206
- if (x.length == 0 || len <= 0) {
207
- return new Float64Array(0);
208
- }
209
- const x2 = createFullSpectrumFromHalfSpectrum(x, len, inclNyquist);
210
- const a = fft(x2, false);
211
- return a.re;
212
- }
213
- function createFullSpectrumFromHalfSpectrum(x, len, inclNyquist) {
214
- const x2 = new ComplexArray(len);
215
- ComplexArray.copy1(x, 0, x2, 0);
216
- if (inclNyquist && len % 2 == 0 && x.length > len / 2) {
217
- ComplexArray.copy1(x, len / 2, x2, len / 2);
218
- }
219
- const n2 = Math.min(x.length - 1, Math.floor((len - 1) / 2));
220
- for (let i = 0; i < n2; i++) {
221
- const p1 = 1 + i;
222
- const p2 = len - 1 - i;
223
- x2.re[p2] = x.re[p1];
224
- x2.im[p2] = -x.im[p1];
225
- }
226
- return x2;
227
- }
228
- export function iFftRealHalfOpt(x, len, inclNyquist = false) {
229
- if (len <= 0) {
230
- return new Float64Array(0);
231
- }
232
- if (len % 2 != 0) {
233
- throw new Error("output length is not even.");
234
- }
235
- const n = len / 2;
236
- const a1 = new ComplexArray(n);
237
- a1.re[0] = xRe(0);
238
- a1.im[0] = xRe(0);
239
- if (inclNyquist) {
240
- a1.re[0] += xRe(n);
241
- a1.im[0] -= xRe(n);
242
- }
243
- const temp1 = new MutableComplex();
244
- const temp2 = new MutableComplex();
245
- const w = Math.PI / n;
246
- for (let i = 1; i < n; i++) {
247
- const sRe = Math.sin(i * w);
248
- const sIm = Math.cos(i * w);
249
- temp1.setMul(xRe(i), xIm(i), (1 - sRe) / 2, sIm / 2);
250
- temp2.setMul(xRe(n - i), xIm(n - i), (1 + sRe) / 2, sIm / 2);
251
- a1.re[i] = temp1.re + temp2.re;
252
- a1.im[i] = temp1.im - temp2.im;
253
- }
254
- const a2 = fft(a1, false);
255
- const a3 = new Float64Array(2 * n);
256
- for (let i = 0; i < n; i++) {
257
- a3[2 * i] = a2.re[i];
258
- a3[2 * i + 1] = a2.im[i];
259
- }
260
- return a3;
261
- function xRe(i) {
262
- return (i < x.length) ? x.re[i] : 0;
263
- }
264
- function xIm(i) {
265
- return (i < x.length) ? x.im[i] : 0;
266
- }
267
- }
268
- export function iFftRealHalf(x, len, inclNyquist = false) {
269
- if (len % 2 == 0) {
270
- return iFftRealHalfOpt(x, len, inclNyquist);
271
- }
272
- else {
273
- return iFftRealHalfSimple(x, len, inclNyquist);
274
- }
275
- }
276
- //# sourceMappingURL=Fft.js.map
1
+ import ComplexArray from "../math/ComplexArray.js";
2
+ import MutableComplex from "../math/MutableComplex.js";
3
+ import * as MathUtils from "../math/MathUtils.js";
4
+ var cooleyTukeySineTableCache;
5
+ export function fft(x, direction = true) {
6
+ const n = x.length;
7
+ if (n <= 1) {
8
+ return x.slice();
9
+ }
10
+ const x2 = direction ? x : swapReIm(x);
11
+ const x3 = MathUtils.isPowerOf2(n) ? fftCooleyTukey(x2) : fftBluestein(x2);
12
+ const x4 = direction ? x3 : swapReIm(x3);
13
+ return x4;
14
+ }
15
+ function fftCooleyTukey(x) {
16
+ const n = x.length;
17
+ const sineTable = getCachedCooleyTukeySineTable(n);
18
+ const a = copyBitReversed(x);
19
+ applyButterflies(a, sineTable);
20
+ return a;
21
+ }
22
+ function applyButterflies(a, sineTable) {
23
+ const temp = new MutableComplex();
24
+ const n = a.length;
25
+ const re = a.re;
26
+ const im = a.im;
27
+ for (let mMax = 1; mMax < n; mMax *= 2) {
28
+ const step = mMax * 2;
29
+ const sinStep = n / step;
30
+ for (let m = 0; m < mMax; m++) {
31
+ const wIndex = m * sinStep;
32
+ const wRe = sineTable.re[wIndex];
33
+ const wIm = sineTable.im[wIndex];
34
+ for (let i = m; i < n; i += step) {
35
+ const j = i + mMax;
36
+ temp.setMul(re[j], im[j], wRe, wIm);
37
+ re[j] = re[i] - temp.re;
38
+ im[j] = im[i] - temp.im;
39
+ re[i] += temp.re;
40
+ im[i] += temp.im;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ function copyBitReversed(a1) {
46
+ const n = a1.length;
47
+ const a2 = new ComplexArray(n);
48
+ let i1 = 0;
49
+ for (let i2 = 0; i2 < n; i2++) {
50
+ a2.re[i2] = a1.re[i1];
51
+ a2.im[i2] = a1.im[i1];
52
+ i1 = incrementBitReversed(i1, n);
53
+ }
54
+ return a2;
55
+ }
56
+ function incrementBitReversed(i, n) {
57
+ let m = n >> 1;
58
+ let a = i;
59
+ while (a & m) {
60
+ a -= m;
61
+ m >>= 1;
62
+ }
63
+ return a | m;
64
+ }
65
+ function fftBluestein(x) {
66
+ const n = x.length;
67
+ const m = MathUtils.getNextPowerOf2(2 * n - 3);
68
+ const sineTable = createSineOfSquareTable(n, 2 * n);
69
+ const a1 = new ComplexArray(m);
70
+ for (let i = 0; i < n; i++) {
71
+ a1.setMul(i, x.re[i], x.im[i], sineTable.re[i], -sineTable.im[i]);
72
+ }
73
+ const a2 = new ComplexArray(m);
74
+ for (let i = 0; i < n; i++) {
75
+ ComplexArray.copy1(sineTable, i, a2, i);
76
+ }
77
+ for (let i = 1; i < n; i++) {
78
+ ComplexArray.copy1(sineTable, i, a2, m - i);
79
+ }
80
+ const a3 = convolve(a1, a2);
81
+ const a4 = new ComplexArray(n);
82
+ for (let i = 0; i < n; i++) {
83
+ a4.setMul(i, a3.re[i], a3.im[i], sineTable.re[i], -sineTable.im[i]);
84
+ }
85
+ return a4;
86
+ }
87
+ function convolve(a1, a2) {
88
+ const n = a1.length;
89
+ if (a2.length != n) {
90
+ throw new Error("Array lengths are not equal.");
91
+ }
92
+ const a3 = fft(a1);
93
+ const a4 = fft(a2);
94
+ a3.mulByArray(a4);
95
+ const a5 = fft(a3, false);
96
+ a5.mulAllByReal(1 / n);
97
+ return a5;
98
+ }
99
+ function getCachedCooleyTukeySineTable(n) {
100
+ if (!cooleyTukeySineTableCache) {
101
+ cooleyTukeySineTableCache = new Array(16);
102
+ }
103
+ const log2N = MathUtils.floorLog2(n);
104
+ if (!cooleyTukeySineTableCache[log2N]) {
105
+ cooleyTukeySineTableCache[log2N] = createCooleyTukeySineTable(n);
106
+ }
107
+ return cooleyTukeySineTableCache[log2N];
108
+ }
109
+ function createCooleyTukeySineTable(n) {
110
+ return createSineTable(n / 2, n, false);
111
+ }
112
+ function createSineTable(tableLength, waveLength, rotationalDirection = true) {
113
+ const w = 2 * Math.PI / waveLength;
114
+ const a = new ComplexArray(tableLength);
115
+ for (let i = 0; i < tableLength; i++) {
116
+ const t = i * w;
117
+ a.re[i] = Math.cos(t);
118
+ a.im[i] = rotationalDirection ? Math.sin(t) : -Math.sin(t);
119
+ }
120
+ return a;
121
+ }
122
+ function createSineOfSquareTable(tableLength, waveLength) {
123
+ const w = 2 * Math.PI / waveLength;
124
+ const a = new ComplexArray(tableLength);
125
+ for (let i = 0; i < tableLength; i++) {
126
+ const t = (i * i) % waveLength * w;
127
+ a.re[i] = Math.cos(t);
128
+ a.im[i] = Math.sin(t);
129
+ }
130
+ return a;
131
+ }
132
+ function swapReIm(a) {
133
+ const a2 = new ComplexArray();
134
+ a2.length = a.length;
135
+ a2.re = a.im;
136
+ a2.im = a.re;
137
+ return a2;
138
+ }
139
+ export function fftReal(x) {
140
+ return fft(new ComplexArray(x));
141
+ }
142
+ export function fftRealHalf(x, inclNyquist = false) {
143
+ if (x.length <= 1) {
144
+ return new ComplexArray(x);
145
+ }
146
+ const m = x.length;
147
+ if (m % 2 != 0) {
148
+ throw new Error("Input array size is not even.");
149
+ }
150
+ const n = m / 2;
151
+ const a1 = new ComplexArray(n);
152
+ for (let i = 0; i < n; i++) {
153
+ a1.re[i] = x[2 * i];
154
+ a1.im[i] = x[2 * i + 1];
155
+ }
156
+ const a2 = fft(a1);
157
+ const a3 = new ComplexArray(n + (inclNyquist ? 1 : 0));
158
+ a3.re[0] = a2.re[0] + a2.im[0];
159
+ a3.im[0] = 0;
160
+ if (inclNyquist) {
161
+ a3.re[n] = a2.re[0] - a2.im[0];
162
+ a3.im[n] = 0;
163
+ }
164
+ const temp1 = new MutableComplex();
165
+ const temp2 = new MutableComplex();
166
+ const w = Math.PI / n;
167
+ for (let i = 1; i < n; i++) {
168
+ const sRe = Math.sin(i * w);
169
+ const sIm = Math.cos(i * w);
170
+ temp1.setMul(a2.re[i], a2.im[i], (1 - sRe) / 2, -sIm / 2);
171
+ temp2.setMul(a2.re[n - i], a2.im[n - i], (1 + sRe) / 2, -sIm / 2);
172
+ a3.re[i] = temp1.re + temp2.re;
173
+ a3.im[i] = temp1.im - temp2.im;
174
+ }
175
+ return a3;
176
+ }
177
+ export function fftRealSpectrum(x, inclNyquist = false) {
178
+ const n = x.length;
179
+ if (n == 0) {
180
+ throw new Error("Input array must not be empty.");
181
+ }
182
+ let a;
183
+ if (n % 2 == 0) {
184
+ a = fftRealHalf(x, inclNyquist);
185
+ }
186
+ else {
187
+ const a0 = fftReal(x);
188
+ a = a0.subarray(0, Math.floor(n / 2) + 1);
189
+ }
190
+ for (let i = 0; i < a.length; i++) {
191
+ const r = (i == 0 || i == n / 2) ? 1 / n : 2 / n;
192
+ a.mulByReal(i, r);
193
+ }
194
+ return a;
195
+ }
196
+ export function fftShift(x) {
197
+ const n = x.length;
198
+ const d = Math.floor(n / 2);
199
+ const a = new ComplexArray(n);
200
+ for (let p = 0; p < n; p++) {
201
+ ComplexArray.copy1(x, p, a, (p + d) % n);
202
+ }
203
+ return a;
204
+ }
205
+ export function iFftRealHalfSimple(x, len, inclNyquist = false) {
206
+ if (x.length == 0 || len <= 0) {
207
+ return new Float64Array(0);
208
+ }
209
+ const x2 = createFullSpectrumFromHalfSpectrum(x, len, inclNyquist);
210
+ const a = fft(x2, false);
211
+ return a.re;
212
+ }
213
+ function createFullSpectrumFromHalfSpectrum(x, len, inclNyquist) {
214
+ const x2 = new ComplexArray(len);
215
+ ComplexArray.copy1(x, 0, x2, 0);
216
+ if (inclNyquist && len % 2 == 0 && x.length > len / 2) {
217
+ ComplexArray.copy1(x, len / 2, x2, len / 2);
218
+ }
219
+ const n2 = Math.min(x.length - 1, Math.floor((len - 1) / 2));
220
+ for (let i = 0; i < n2; i++) {
221
+ const p1 = 1 + i;
222
+ const p2 = len - 1 - i;
223
+ x2.re[p2] = x.re[p1];
224
+ x2.im[p2] = -x.im[p1];
225
+ }
226
+ return x2;
227
+ }
228
+ export function iFftRealHalfOpt(x, len, inclNyquist = false) {
229
+ if (len <= 0) {
230
+ return new Float64Array(0);
231
+ }
232
+ if (len % 2 != 0) {
233
+ throw new Error("output length is not even.");
234
+ }
235
+ const n = len / 2;
236
+ const a1 = new ComplexArray(n);
237
+ a1.re[0] = xRe(0);
238
+ a1.im[0] = xRe(0);
239
+ if (inclNyquist) {
240
+ a1.re[0] += xRe(n);
241
+ a1.im[0] -= xRe(n);
242
+ }
243
+ const temp1 = new MutableComplex();
244
+ const temp2 = new MutableComplex();
245
+ const w = Math.PI / n;
246
+ for (let i = 1; i < n; i++) {
247
+ const sRe = Math.sin(i * w);
248
+ const sIm = Math.cos(i * w);
249
+ temp1.setMul(xRe(i), xIm(i), (1 - sRe) / 2, sIm / 2);
250
+ temp2.setMul(xRe(n - i), xIm(n - i), (1 + sRe) / 2, sIm / 2);
251
+ a1.re[i] = temp1.re + temp2.re;
252
+ a1.im[i] = temp1.im - temp2.im;
253
+ }
254
+ const a2 = fft(a1, false);
255
+ const a3 = new Float64Array(2 * n);
256
+ for (let i = 0; i < n; i++) {
257
+ a3[2 * i] = a2.re[i];
258
+ a3[2 * i + 1] = a2.im[i];
259
+ }
260
+ return a3;
261
+ function xRe(i) {
262
+ return (i < x.length) ? x.re[i] : 0;
263
+ }
264
+ function xIm(i) {
265
+ return (i < x.length) ? x.im[i] : 0;
266
+ }
267
+ }
268
+ export function iFftRealHalf(x, len, inclNyquist = false) {
269
+ if (len % 2 == 0) {
270
+ return iFftRealHalfOpt(x, len, inclNyquist);
271
+ }
272
+ else {
273
+ return iFftRealHalfSimple(x, len, inclNyquist);
274
+ }
275
+ }
@@ -1,5 +1,5 @@
1
- import MutableComplex from "../math/MutableComplex.js";
2
- import ComplexArray from "../math/ComplexArray.js";
3
- export declare function goertzelSingle(x: ArrayLike<number>, relativeFrequency: number): MutableComplex;
4
- export declare function goertzel(x: ArrayLike<number>): ComplexArray;
5
- export declare function goertzelSpectrum(x: ArrayLike<number>, inclNyquist?: boolean): ComplexArray;
1
+ import MutableComplex from "../math/MutableComplex.ts";
2
+ import ComplexArray from "../math/ComplexArray.ts";
3
+ export declare function goertzelSingle(x: ArrayLike<number>, relativeFrequency: number): MutableComplex;
4
+ export declare function goertzel(x: ArrayLike<number>): ComplexArray;
5
+ export declare function goertzelSpectrum(x: ArrayLike<number>, inclNyquist?: boolean): ComplexArray;
@@ -1,49 +1,48 @@
1
- import Complex from "../math/Complex.js";
2
- import MutableComplex from "../math/MutableComplex.js";
3
- import ComplexArray from "../math/ComplexArray.js";
4
- export function goertzelSingle(x, relativeFrequency) {
5
- const n = x.length;
6
- if (n == 0) {
7
- throw new Error("Input array must not be empty.");
8
- }
9
- const w = 2 * Math.PI / n * relativeFrequency;
10
- const c = Complex.expj(w);
11
- const cr2 = c.re * 2;
12
- let s1 = 0;
13
- let s2 = 0;
14
- for (let p = 0; p < n; p++) {
15
- const s0 = x[p] + cr2 * s1 - s2;
16
- s2 = s1;
17
- s1 = s0;
18
- }
19
- return new MutableComplex(c.re * s1 - s2, c.im * s1);
20
- }
21
- export function goertzel(x) {
22
- const n = x.length;
23
- const a = new ComplexArray(n);
24
- for (let frequency = 0; frequency < n; frequency++) {
25
- const c = goertzelSingle(x, frequency);
26
- a.set(frequency, c);
27
- }
28
- return a;
29
- }
30
- export function goertzelSpectrum(x, inclNyquist = false) {
31
- const n = x.length;
32
- if (n == 0) {
33
- throw new Error("Input array must not be empty.");
34
- }
35
- const m = (n % 2 == 0 && inclNyquist) ? n / 2 + 1 : Math.ceil(n / 2);
36
- const a = new ComplexArray(m);
37
- for (let frequency = 0; frequency < m; frequency++) {
38
- const c = goertzelSingle(x, frequency);
39
- if (frequency == 0 || frequency == n / 2) {
40
- c.divByReal(n);
41
- }
42
- else {
43
- c.mulByReal(2 / n);
44
- }
45
- a.set(frequency, c);
46
- }
47
- return a;
48
- }
49
- //# sourceMappingURL=Goertzel.js.map
1
+ import Complex from "../math/Complex.js";
2
+ import MutableComplex from "../math/MutableComplex.js";
3
+ import ComplexArray from "../math/ComplexArray.js";
4
+ export function goertzelSingle(x, relativeFrequency) {
5
+ const n = x.length;
6
+ if (n == 0) {
7
+ throw new Error("Input array must not be empty.");
8
+ }
9
+ const w = 2 * Math.PI / n * relativeFrequency;
10
+ const c = Complex.expj(w);
11
+ const cr2 = c.re * 2;
12
+ let s1 = 0;
13
+ let s2 = 0;
14
+ for (let p = 0; p < n; p++) {
15
+ const s0 = x[p] + cr2 * s1 - s2;
16
+ s2 = s1;
17
+ s1 = s0;
18
+ }
19
+ return new MutableComplex(c.re * s1 - s2, c.im * s1);
20
+ }
21
+ export function goertzel(x) {
22
+ const n = x.length;
23
+ const a = new ComplexArray(n);
24
+ for (let frequency = 0; frequency < n; frequency++) {
25
+ const c = goertzelSingle(x, frequency);
26
+ a.set(frequency, c);
27
+ }
28
+ return a;
29
+ }
30
+ export function goertzelSpectrum(x, inclNyquist = false) {
31
+ const n = x.length;
32
+ if (n == 0) {
33
+ throw new Error("Input array must not be empty.");
34
+ }
35
+ const m = (n % 2 == 0 && inclNyquist) ? n / 2 + 1 : Math.ceil(n / 2);
36
+ const a = new ComplexArray(m);
37
+ for (let frequency = 0; frequency < m; frequency++) {
38
+ const c = goertzelSingle(x, frequency);
39
+ if (frequency == 0 || frequency == n / 2) {
40
+ c.divByReal(n);
41
+ }
42
+ else {
43
+ c.mulByReal(2 / n);
44
+ }
45
+ a.set(frequency, c);
46
+ }
47
+ return a;
48
+ }
@@ -1,8 +1,8 @@
1
- import * as WindowFunctions from "./WindowFunctions.js";
2
- export interface InstFreqSingleResult {
3
- instFrequency: number;
4
- measuringFrequency: number;
5
- amplitude: number;
6
- }
7
- export declare function instFreqSingle_relWindow(samples: Float64Array | Float32Array, position: number, roughtMeasuringFrequency: number, shiftFactor: number, relWindowWidth: number, windowFunction: WindowFunctions.WindowFunction | undefined): InstFreqSingleResult | undefined;
8
- export declare function instFreqSingle_maxWindow(samples: Float64Array | Float32Array, position: number, roughtMeasuringFrequency: number, shiftFactor: number, maxWindowWidth: number, windowFunction: WindowFunctions.WindowFunction | undefined): InstFreqSingleResult | undefined;
1
+ import * as WindowFunctions from "./WindowFunctions.ts";
2
+ export interface InstFreqSingleResult {
3
+ instFrequency: number;
4
+ measuringFrequency: number;
5
+ amplitude: number;
6
+ }
7
+ export declare function instFreqSingle_relWindow(samples: Float64Array | Float32Array, position: number, roughtMeasuringFrequency: number, shiftFactor: number, relWindowWidth: number, windowFunction: WindowFunctions.WindowFunction | undefined): InstFreqSingleResult | undefined;
8
+ export declare function instFreqSingle_maxWindow(samples: Float64Array | Float32Array, position: number, roughtMeasuringFrequency: number, shiftFactor: number, maxWindowWidth: number, windowFunction: WindowFunctions.WindowFunction | undefined): InstFreqSingleResult | undefined;