speaker-calibration 2.2.248 → 2.2.249

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 (120) hide show
  1. package/.eslintignore +71 -71
  2. package/.eslintrc.json +40 -40
  3. package/.gitignore +81 -0
  4. package/.prettierignore +69 -69
  5. package/.prettierrc +14 -14
  6. package/LICENSE +20 -20
  7. package/README.md +133 -133
  8. package/__mocks__/fileMock.js +1 -1
  9. package/__mocks__/styleMock.js +1 -1
  10. package/babel.config.js +3 -3
  11. package/coverage/clover.xml +71 -71
  12. package/coverage/coverage-final.json +224 -224
  13. package/coverage/lcov-report/PythonServerInterface.js.html +265 -265
  14. package/coverage/lcov-report/base.css +354 -354
  15. package/coverage/lcov-report/block-navigation.js +82 -82
  16. package/coverage/lcov-report/index.html +123 -123
  17. package/coverage/lcov-report/prettify.css +101 -101
  18. package/coverage/lcov-report/prettify.js +937 -937
  19. package/coverage/lcov-report/sorter.js +189 -189
  20. package/coverage/lcov-report/src/index.html +121 -121
  21. package/coverage/lcov-report/src/server/PythonServerInterface.js.html +268 -268
  22. package/coverage/lcov-report/src/server/index.html +123 -123
  23. package/coverage/lcov-report/src/tasks/audioCalibrator.js.html +499 -499
  24. package/coverage/lcov-report/src/tasks/audioRecorder.js.html +412 -412
  25. package/coverage/lcov-report/src/tasks/index.html +143 -143
  26. package/coverage/lcov-report/src/tasks/volume/index.html +123 -123
  27. package/coverage/lcov-report/src/tasks/volume/volume.js.html +409 -409
  28. package/coverage/lcov-report/src/utils.js.html +172 -172
  29. package/coverage/lcov.info +91 -91
  30. package/dist/example/NoSleep.min.js +1 -1
  31. package/dist/example/fetch-languages-sheets.js +77 -77
  32. package/dist/example/i18n.js +29654 -30000
  33. package/dist/example/index.html +47 -47
  34. package/dist/example/listener.html +81 -81
  35. package/dist/example/server.js +51 -51
  36. package/dist/example/speaker.html +145 -145
  37. package/dist/example/speakerUI.js +273 -273
  38. package/dist/example/styles.css +152 -152
  39. package/dist/mlsGen.js +6814 -6814
  40. package/dist/mlsGen.wasm +0 -0
  41. package/dist/package-lock.json +1018 -1018
  42. package/dist/package.json +18 -18
  43. package/doc/AudioCalibrator.html +417 -417
  44. package/doc/AudioPeer.html +251 -251
  45. package/doc/AudioRecorder.html +195 -195
  46. package/doc/ImpulseResponse.html +215 -215
  47. package/doc/Listener.html +308 -308
  48. package/doc/MlsGenInterface.html +226 -226
  49. package/doc/MyEventEmitter.html +274 -274
  50. package/doc/PythonServerAPI.html +109 -109
  51. package/doc/Speaker.html +276 -276
  52. package/doc/Takes%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +128 -128
  53. package/doc/Takes%20the%20url%20of%20the%20current%20site%0Aand%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +138 -138
  54. package/doc/Takes%20the%20url%20of%20the%20current%20site%20and%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +137 -137
  55. package/doc/Volume.html +88 -88
  56. package/doc/audioCalibrator.js.html +179 -179
  57. package/doc/audioPeer.js.html +175 -175
  58. package/doc/audioRecorder.js.html +163 -163
  59. package/doc/creates%20a%20new%20AudioRecorder%20instance.%20%0ASets%20up%20the%20audio%20context%20and%20file%20reader..html +114 -114
  60. package/doc/fonts/OpenSans-Bold-webfont.svg +1829 -1829
  61. package/doc/fonts/OpenSans-BoldItalic-webfont.svg +1829 -1829
  62. package/doc/fonts/OpenSans-Italic-webfont.svg +1829 -1829
  63. package/doc/fonts/OpenSans-Light-webfont.svg +1830 -1830
  64. package/doc/fonts/OpenSans-LightItalic-webfont.svg +1834 -1834
  65. package/doc/fonts/OpenSans-Regular-webfont.svg +1830 -1830
  66. package/doc/global.html +308 -308
  67. package/doc/index.html +58 -58
  68. package/doc/listener.js.html +170 -170
  69. package/doc/mlsGen_mlsGenInterface.js.html +117 -117
  70. package/doc/myEventEmitter.js.html +124 -124
  71. package/doc/peer-connection_audioPeer.js.html +188 -188
  72. package/doc/peer-connection_listener.js.html +311 -311
  73. package/doc/peer-connection_speaker.js.html +381 -381
  74. package/doc/scripts/linenumber.js +25 -25
  75. package/doc/scripts/prettify/Apache-License-2.0.txt +202 -202
  76. package/doc/scripts/prettify/lang-css.js +24 -24
  77. package/doc/scripts/prettify/prettify.js +640 -640
  78. package/doc/server_PythonServerAPI.js.html +160 -160
  79. package/doc/speaker.js.html +248 -248
  80. package/doc/styles/jsdoc-default.css +371 -371
  81. package/doc/styles/prettify-jsdoc.css +111 -111
  82. package/doc/styles/prettify-tomorrow.css +163 -163
  83. package/doc/tasks_audioCalibrator.js.html +207 -207
  84. package/doc/tasks_audioRecorder.js.html +190 -190
  85. package/doc/tasks_impulse-response_impulseResponse.js.html +442 -442
  86. package/doc/tasks_impulse-response_mlsGen_mlsGenInterface.js.html +175 -175
  87. package/doc/tasks_volume_volume.js.html +185 -185
  88. package/doc/utils.js.html +105 -105
  89. package/jest.config.js +173 -173
  90. package/netlify.toml +26 -26
  91. package/package.json +78 -78
  92. package/src/config/firebase.js +26 -26
  93. package/src/index.html +21 -21
  94. package/src/listener-app/PhonePeer.js +474 -474
  95. package/src/listener-app/listener.js +377 -377
  96. package/src/main.js +22 -22
  97. package/src/myEventEmitter.js +83 -83
  98. package/src/peer-connection/audioPeer.js +100 -100
  99. package/src/peer-connection/listener.js +299 -299
  100. package/src/peer-connection/peerErrors.js +25 -25
  101. package/src/peer-connection/speaker.js +963 -963
  102. package/src/powerCheck.js +110 -110
  103. package/src/server/PythonServerAPI.js +959 -959
  104. package/src/tasks/combination/combination.js +29 -29
  105. package/src/tasks/combination/mlsGen/mlsGen.cpp +98 -98
  106. package/src/tasks/combination/mlsGen/mlsGen.hpp +303 -303
  107. package/src/tasks/combination/mlsGen/mlsGenInterface.js +131 -131
  108. package/src/tasks/combination/mlsGen/mlsGenTest.cpp +180 -180
  109. package/src/tasks/impulse-response/impulseResponse.js +610 -610
  110. package/src/tasks/impulse-response/mlsGen/mlsGen.cpp +98 -98
  111. package/src/tasks/impulse-response/mlsGen/mlsGen.hpp +303 -303
  112. package/src/tasks/impulse-response/mlsGen/mlsGenInterface.js +131 -131
  113. package/src/tasks/impulse-response/mlsGen/mlsGenTest.cpp +180 -180
  114. package/src/tasks/volume/volume.cpp +2 -2
  115. package/src/tasks/volume/volume.hpp +22 -22
  116. package/src/tasks/volume/volume.js +279 -279
  117. package/src/utils.js +205 -205
  118. package/webpack.config.js +65 -65
  119. package/.github/workflows/update-phrases.yml +0 -37
  120. package/makefile +0 -74
@@ -1,959 +1,959 @@
1
- import axios from 'axios';
2
- import {sleep} from '../utils';
3
- /**
4
- *
5
- */
6
- class PythonServerAPI {
7
- static PYTHON_SERVER_URL = 'https://easyeyes-python-flask-server.herokuapp.com';
8
-
9
- static TEST_SERVER_URL = 'http://127.0.0.1:5000';
10
- // static PYTHON_SERVER_URL = 'http://127.0.0.1:5000';
11
-
12
- /** @private */
13
- MAX_RETRY_COUNT = 3;
14
- /** @private */
15
- RETRY_DELAY_MS = 1000;
16
- /**
17
- * @param data- -
18
- * g = inverted impulse response, when convolved with the impulse
19
- * reponse, they cancel out.
20
- * @param data.payload
21
- * @param data.sampleRate
22
- * @param data.P
23
- * @param data-.payload
24
- * @param data-.sampleRate
25
- * @param data-.P
26
- * @returns
27
- * @example
28
- */
29
- getImpulseResponse = async ({mls, sampleRate, numPeriods, sig, fs2, L_new_n, dL_n}) => {
30
- const task = 'impulse-response';
31
- let res = null;
32
-
33
- const data = JSON.stringify({
34
- task,
35
- 'sample-rate': sampleRate,
36
- mls,
37
- numPeriods,
38
- sig,
39
- fs2,
40
- L_new_n,
41
- dL_n,
42
- });
43
-
44
- await axios({
45
- method: 'post',
46
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
47
- url: `/task/${task}`,
48
- headers: {
49
- 'Content-Type': 'application/json',
50
- },
51
- data,
52
- })
53
- .then(response => {
54
- res = response;
55
- })
56
- .catch(error => {
57
- throw error;
58
- });
59
- return res.data[task];
60
- };
61
-
62
- getAutocorrelation = async ({mls, payload, sampleRate, numPeriods}) => {
63
- const task = 'autocorrelation';
64
- let res = null;
65
-
66
- const data = JSON.stringify({
67
- task,
68
- payload: payload,
69
- 'sample-rate': sampleRate,
70
- mls,
71
- numPeriods,
72
- });
73
-
74
- await axios({
75
- method: 'post',
76
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
77
- url: `/task/${task}`,
78
- headers: {
79
- 'Content-Type': 'application/json',
80
- },
81
- data,
82
- })
83
- .then(response => {
84
- res = response;
85
- })
86
- .catch(error => {
87
- throw error;
88
- });
89
- return res.data[task];
90
- };
91
-
92
- getConvolution = async ({
93
- mls,
94
- inverse_response,
95
- inverse_response_no_bandpass,
96
- attenuatorGain_dB,
97
- mls_amplitude,
98
- }) => {
99
- const task = 'convolution';
100
- let res = null;
101
-
102
- const data = JSON.stringify({
103
- task,
104
- mls,
105
- inverse_response,
106
- inverse_response_no_bandpass,
107
- attenuatorGain_dB,
108
- mls_amplitude,
109
- });
110
-
111
- await axios({
112
- method: 'post',
113
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
114
- url: `/task/${task}`,
115
- headers: {
116
- 'Content-Type': 'application/json',
117
- },
118
- data,
119
- })
120
- .then(response => {
121
- res = response;
122
- })
123
- .catch(error => {
124
- throw error;
125
- });
126
- return res.data[task];
127
- };
128
-
129
- getFrequencyResponseFromImpulseResponse = async ({
130
- impulseResponseMicrophone,
131
- impulseResponseLoudspeaker,
132
- sampleRate,
133
- timeArray,
134
- totalDuration,
135
- totalDuration1000Hz,
136
- }) => {
137
- const task = 'frequency-response';
138
- let res = null;
139
-
140
- const data = JSON.stringify({
141
- task,
142
- impulse_response_microphone: impulseResponseMicrophone,
143
- impulse_response_loudspeaker: impulseResponseLoudspeaker,
144
- sample_rate: sampleRate,
145
- time_array: timeArray,
146
- total_duration: totalDuration,
147
- total_duration_1000hz: totalDuration1000Hz,
148
- });
149
-
150
- await axios({
151
- method: 'post',
152
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
153
- url: `/task/${task}`,
154
- headers: {
155
- 'Content-Type': 'application/json',
156
- },
157
- data,
158
- })
159
- .then(response => {
160
- res = response;
161
- })
162
- .catch(error => {
163
- throw error;
164
- });
165
- return res.data[task];
166
- };
167
-
168
- getMLS = async ({
169
- length,
170
- amplitude,
171
- calibrateSoundBurstMLSVersions,
172
- calibrateSoundBurstDownsample,
173
- }) => {
174
- const task = 'mls';
175
- let res = null;
176
-
177
- const data = JSON.stringify({
178
- task,
179
- length: length,
180
- amplitude: amplitude,
181
- calibrateSoundBurstMLSVersions: calibrateSoundBurstMLSVersions,
182
- calibrateSoundBurstDownsample: calibrateSoundBurstDownsample,
183
- });
184
-
185
- await axios({
186
- method: 'post',
187
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
188
- url: `/task/${task}`,
189
- headers: {
190
- 'Content-Type': 'application/json',
191
- },
192
- data,
193
- })
194
- .then(response => {
195
- res = response;
196
- })
197
- .catch(error => {
198
- throw error;
199
- });
200
-
201
- return res.data[task];
202
- };
203
-
204
- getShortURL = async originalURL => {
205
- const task = 'url';
206
- let res = null;
207
- console.log(originalURL);
208
- const data = JSON.stringify({
209
- URL: originalURL,
210
- });
211
-
212
- console.log(data);
213
-
214
- await axios({
215
- method: 'post',
216
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
217
- url: `/task/${task}`,
218
- headers: {
219
- 'Content-Type': 'application/json',
220
- },
221
- data,
222
- })
223
- .then(response => {
224
- res = response;
225
- console.log(res.data[task]);
226
- })
227
- .catch(error => {
228
- throw error;
229
- });
230
-
231
- return res.data[task];
232
- };
233
-
234
- getMemory = async () => {
235
- let res;
236
- await axios({
237
- method: 'post',
238
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
239
- url: `/memory`,
240
- headers: {
241
- 'Content-Type': 'application/json',
242
- },
243
- })
244
- .then(response => {
245
- console.log('memory used:', Math.round(response.data['memory']), 'mb');
246
- res = response.data['memory'];
247
- })
248
- .catch(error => {
249
- throw error;
250
- });
251
- return res;
252
- };
253
-
254
- checkMemory = async () => {
255
- console.log('wait for memory under 500 mb to continue calibration');
256
- await this.getMemory();
257
- // let memory = await this.getMemory();
258
- // while (memory >= 500) {
259
- // console.log("sleep 30s");
260
- // await sleep(30);
261
- // memory = await this.getMemory();
262
- // }
263
- };
264
-
265
- getMLSWithRetry = async ({
266
- length,
267
- amplitude,
268
- calibrateSoundBurstMLSVersions,
269
- calibrateSoundBurstDownsample,
270
- }) => {
271
- let retryCount = 0;
272
- let response = null;
273
-
274
- while (retryCount < this.MAX_RETRY_COUNT) {
275
- try {
276
- response = await this.getMLS({
277
- length,
278
- amplitude,
279
- calibrateSoundBurstMLSVersions,
280
- calibrateSoundBurstDownsample,
281
- });
282
- // If the request is successful, break out of the loop
283
- break;
284
- } catch (error) {
285
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
286
- retryCount++;
287
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
288
- }
289
- }
290
-
291
- if (response) {
292
- return response;
293
- } else {
294
- throw new Error(`Failed to get MLS after ${this.MAX_RETRY_COUNT} attempts.`);
295
- }
296
- };
297
-
298
- getPSD = async ({unconv_rec, conv_rec, sampleRate, downsample}) => {
299
- const task = 'psd';
300
- let res = null;
301
-
302
- const data = JSON.stringify({
303
- task,
304
- unconv_rec,
305
- conv_rec,
306
- sampleRate,
307
- downsample,
308
- });
309
-
310
- await axios({
311
- method: 'post',
312
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
313
- url: `/task/${task}`,
314
- headers: {
315
- 'Content-Type': 'application/json',
316
- },
317
- data,
318
- })
319
- .then(response => {
320
- res = response;
321
- })
322
- .catch(error => {
323
- throw error;
324
- });
325
- return res.data[task];
326
- };
327
-
328
- getBackgroundNoisePSD = async ({background_rec, sampleRate}) => {
329
- const task = 'background-psd';
330
- let res = null;
331
-
332
- const data = JSON.stringify({
333
- task,
334
- background_rec,
335
- sampleRate,
336
- });
337
-
338
- await axios({
339
- method: 'post',
340
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
341
- url: `/task/${task}`,
342
- headers: {
343
- 'Content-Type': 'application/json',
344
- },
345
- data,
346
- })
347
- .then(response => {
348
- res = response;
349
- })
350
- .catch(error => {
351
- throw error;
352
- });
353
- return res.data[task];
354
- };
355
-
356
- getBackgroundNoisePSDWithRetry = async ({background_rec, sampleRate}) => {
357
- let retryCount = 0;
358
- let response = null;
359
-
360
- while (retryCount < this.MAX_RETRY_COUNT) {
361
- try {
362
- response = await this.getBackgroundNoisePSD({background_rec, sampleRate});
363
- // If the request is successful, break out of the loop
364
- break;
365
- } catch (error) {
366
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
367
- retryCount++;
368
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
369
- }
370
- }
371
-
372
- if (response) {
373
- return response;
374
- } else {
375
- throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
376
- }
377
- };
378
-
379
- getSubtractedPSD = async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {
380
- const task = 'subtracted-psd';
381
- let res = null;
382
-
383
- const data = JSON.stringify({
384
- task,
385
- rec,
386
- knownGains,
387
- knownFrequencies,
388
- sampleRate,
389
- downsample,
390
- });
391
-
392
- await axios({
393
- method: 'post',
394
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
395
- url: `/task/${task}`,
396
- headers: {
397
- 'Content-Type': 'application/json',
398
- },
399
- data,
400
- })
401
- .then(response => {
402
- res = response;
403
- })
404
- .catch(error => {
405
- throw error;
406
- });
407
- return res.data[task];
408
- };
409
-
410
- getSubtractedPSDWithRetry = async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {
411
- let retryCount = 0;
412
- let response = null;
413
-
414
- while (retryCount < this.MAX_RETRY_COUNT) {
415
- try {
416
- response = await this.getSubtractedPSD(
417
- rec,
418
- knownGains,
419
- knownFrequencies,
420
- sampleRate,
421
- downsample
422
- );
423
- // If the request is successful, break out of the loop
424
- break;
425
- } catch (error) {
426
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
427
- retryCount++;
428
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
429
- }
430
- }
431
-
432
- if (response) {
433
- return response;
434
- } else {
435
- throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
436
- }
437
- };
438
-
439
- getPSDWithRetry = async ({unconv_rec, conv_rec, sampleRate, downsample}) => {
440
- let retryCount = 0;
441
- let response = null;
442
-
443
- while (retryCount < this.MAX_RETRY_COUNT) {
444
- try {
445
- response = await this.getPSD({unconv_rec, conv_rec, sampleRate, downsample});
446
- // If the request is successful, break out of the loop
447
- break;
448
- } catch (error) {
449
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
450
- retryCount++;
451
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
452
- }
453
- }
454
-
455
- if (response) {
456
- return response;
457
- } else {
458
- throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
459
- }
460
- };
461
-
462
- getComponentInverseImpulseResponse = async ({
463
- payload,
464
- mls,
465
- lowHz,
466
- highHz,
467
- componentIRGains,
468
- iirLength,
469
- componentIRFreqs,
470
- sampleRate,
471
- mlsAmplitude,
472
- irLength,
473
- calibrateSoundSmoothOctaves,
474
- calibrateSoundSmoothMinBandwidthHz,
475
- calibrateSoundBurstFilteredExtraDb,
476
- calibrateSoundIIRPhase,
477
- downsample,
478
- }) => {
479
- const task = 'component-inverse-impulse-response';
480
- let res = null;
481
-
482
- const data = JSON.stringify({
483
- task,
484
- payload,
485
- mls,
486
- lowHz,
487
- highHz,
488
- iirLength,
489
- componentIRGains,
490
- componentIRFreqs,
491
- sampleRate,
492
- mlsAmplitude,
493
- irLength,
494
- calibrateSoundSmoothOctaves,
495
- calibrateSoundSmoothMinBandwidthHz,
496
- calibrateSoundBurstFilteredExtraDb,
497
- calibrateSoundIIRPhase,
498
- downsample,
499
- });
500
-
501
- await axios({
502
- method: 'post',
503
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
504
- url: `/task/${task}`,
505
- headers: {
506
- 'Content-Type': 'application/json',
507
- },
508
- data,
509
- })
510
- .then(response => {
511
- res = response;
512
- })
513
- .catch(error => {
514
- throw error;
515
- });
516
-
517
- return res.data[task];
518
- };
519
- getSystemInverseImpulseResponse = async ({
520
- payload,
521
- mls,
522
- lowHz,
523
- highHz,
524
- iirLength,
525
- sampleRate,
526
- mlsAmplitude,
527
- calibrateSoundBurstFilteredExtraDb,
528
- calibrateSoundIIRPhase,
529
- downsample,
530
- }) => {
531
- const task = 'system-inverse-impulse-response';
532
- let res = null;
533
-
534
- const data = JSON.stringify({
535
- task,
536
- payload,
537
- mls,
538
- lowHz,
539
- iirLength,
540
- highHz,
541
- sampleRate,
542
- mlsAmplitude,
543
- calibrateSoundBurstFilteredExtraDb,
544
- calibrateSoundIIRPhase,
545
- downsample,
546
- });
547
-
548
- await axios({
549
- method: 'post',
550
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
551
- url: `/task/${task}`,
552
- headers: {
553
- 'Content-Type': 'application/json',
554
- },
555
- data,
556
- })
557
- .then(response => {
558
- res = response;
559
- })
560
- .catch(error => {
561
- throw error;
562
- });
563
-
564
- return res.data[task];
565
- };
566
-
567
- getMLSPSD = async ({mls, sampleRate, downsample}) => {
568
- const task = 'mls-psd';
569
- let res = null;
570
-
571
- const data = JSON.stringify({
572
- task,
573
- mls,
574
- sampleRate,
575
- downsample,
576
- });
577
-
578
- await axios({
579
- method: 'post',
580
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
581
- url: `/task/${task}`,
582
- headers: {
583
- 'Content-Type': 'application/json',
584
- },
585
- data,
586
- })
587
- .then(response => {
588
- res = response;
589
- })
590
- .catch(error => {
591
- throw error;
592
- });
593
-
594
- return res.data[task];
595
- };
596
-
597
- getMLSPSDWithRetry = async ({mls, sampleRate, downsample}) => {
598
- let retryCount = 0;
599
- let response = null;
600
-
601
- while (retryCount < this.MAX_RETRY_COUNT) {
602
- try {
603
- response = await this.getMLSPSD({mls, sampleRate, downsample});
604
- // If the request is successful, break out of the loop
605
- break;
606
- } catch (error) {
607
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
608
- retryCount++;
609
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
610
- }
611
- }
612
-
613
- if (response) {
614
- return response;
615
- } else {
616
- throw new Error(
617
- `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
618
- );
619
- }
620
- };
621
-
622
- getComponentInverseImpulseResponseWithRetry = async ({
623
- payload,
624
- mls,
625
- lowHz,
626
- highHz,
627
- componentIRGains,
628
- iirLength,
629
- componentIRFreqs,
630
- sampleRate,
631
- mlsAmplitude,
632
- irLength,
633
- calibrateSoundSmoothOctaves,
634
- calibrateSoundSmoothMinBandwidthHz,
635
- calibrateSoundBurstFilteredExtraDb,
636
- calibrateSoundIIRPhase,
637
- downsample,
638
- }) => {
639
- let retryCount = 0;
640
- let response = null;
641
-
642
- while (retryCount < this.MAX_RETRY_COUNT) {
643
- try {
644
- response = await this.getComponentInverseImpulseResponse({
645
- payload,
646
- mls,
647
- lowHz,
648
- highHz,
649
- componentIRGains,
650
- iirLength,
651
- componentIRFreqs,
652
- sampleRate,
653
- mlsAmplitude,
654
- irLength,
655
- calibrateSoundSmoothOctaves,
656
- calibrateSoundSmoothMinBandwidthHz,
657
- calibrateSoundBurstFilteredExtraDb,
658
- calibrateSoundIIRPhase,
659
- downsample,
660
- });
661
- // If the request is successful, break out of the loop
662
- break;
663
- } catch (error) {
664
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
665
- retryCount++;
666
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
667
- }
668
- }
669
-
670
- if (response) {
671
- return response;
672
- } else {
673
- throw new Error(
674
- `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
675
- );
676
- }
677
- };
678
-
679
- getSystemInverseImpulseResponseWithRetry = async ({
680
- payload,
681
- mls,
682
- lowHz,
683
- highHz,
684
- iirLength,
685
- sampleRate,
686
- mlsAmplitude,
687
- calibrateSoundBurstFilteredExtraDb,
688
- calibrateSoundIIRPhase,
689
- downsample,
690
- }) => {
691
- let retryCount = 0;
692
- let response = null;
693
-
694
- while (retryCount < this.MAX_RETRY_COUNT) {
695
- try {
696
- response = await this.getSystemInverseImpulseResponse({
697
- payload,
698
- mls,
699
- lowHz,
700
- highHz,
701
- iirLength,
702
- sampleRate,
703
- mlsAmplitude,
704
- calibrateSoundBurstFilteredExtraDb,
705
- calibrateSoundIIRPhase,
706
- downsample,
707
- });
708
- // If the request is successful, break out of the loop
709
- break;
710
- } catch (error) {
711
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
712
- retryCount++;
713
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
714
- }
715
- }
716
-
717
- if (response) {
718
- return response;
719
- } else {
720
- throw new Error(
721
- `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
722
- );
723
- }
724
- };
725
-
726
- getVolumeCalibration = async ({payload, sampleRate, lCalib}) => {
727
- const task = 'volume';
728
- let res = null;
729
-
730
- console.log({payload});
731
-
732
- const data = JSON.stringify({
733
- task,
734
- payload,
735
- 'sample-rate': sampleRate,
736
- lCalib,
737
- });
738
-
739
- const response = await axios({
740
- method: 'post',
741
- baseURL: PythonServerAPI.PYTHON_SERVER_URL,
742
- url: `/task/${task}`,
743
- headers: {
744
- 'Content-Type': 'application/json',
745
- },
746
- data,
747
- })
748
- .then(response => {
749
- // if response.data is a string, parse it
750
- if (typeof response.data === 'string') {
751
- // response.data = response.data.replaceAll('Infinity', 99999999);
752
- // response.data = JSON.parse(response.data);
753
- //if there is Infinity in the string, throw an error
754
- if (response.data.includes('Infinity')) {
755
- throw new Error(
756
- 'Server returned Infinity. Please make sure the microphone is recording correctly'
757
- );
758
- }
759
- response.data = JSON.parse(response.data);
760
- }
761
- return response.data[task];
762
- })
763
- .catch(error => {
764
- alert(
765
- 'Invalid data. Please make sure the microphone is recording correctly and press on "Re-Record"'
766
- );
767
- throw error;
768
- });
769
-
770
- console.log(response);
771
- return response;
772
- };
773
-
774
- getVolumeCalibrationParameters = async ({
775
- inDBValues,
776
- outDBSPLValues,
777
- lCalib,
778
- componentGainDBSPL,
779
- }) => {
780
- const task = 'volume-parameters';
781
- let res = null;
782
-
783
- const data = JSON.stringify({
784
- task,
785
- inDBValues,
786
- outDBSPLValues,
787
- lCalib,
788
- componentGainDBSPL,
789
- });
790
-
791
- await axios({
792
- method: 'post',
793
- baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
794
- url: `/task/${task}`,
795
- headers: {
796
- 'Content-Type': 'application/json',
797
- },
798
- data,
799
- })
800
- .then(response => {
801
- res = response;
802
- console.log('data', data, 'res', res.data[task]);
803
- })
804
- .catch(error => {
805
- throw error;
806
- });
807
-
808
- // console.log(res.data[task]);
809
- //below is an example of res.data[task]
810
- //{
811
- // R: 16.56981076554259,
812
- // RMSError: 1.9289162528535229
813
- // T: -47.79799120884434,
814
- // W: 61.0485247483732,
815
- // backgroundDBSPL: 43.88233142069752,
816
- // gainDBSPL: -128.24742161208985
817
- //}
818
- return res.data[task];
819
- };
820
-
821
- irConvolution = async ({input_signal, microphone_ir, loudspeaker_ir}) => {
822
- const task = 'ir-convolution';
823
- let res = null;
824
-
825
- const data = JSON.stringify({
826
- input_signal,
827
- microphone_ir,
828
- loudspeaker_ir,
829
- });
830
-
831
- await axios({
832
- method: 'post',
833
- baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
834
- url: `/task/${task}`,
835
- headers: {
836
- 'Content-Type': 'application/json',
837
- },
838
- data,
839
- })
840
- .then(response => {
841
- res = response;
842
- })
843
- .catch(error => {
844
- throw error;
845
- });
846
- console.log('res in irConvolution: ', res);
847
- return res.data[task];
848
- };
849
-
850
- allHzPowerCheck = async ({
851
- payload,
852
- sampleRate,
853
- binDesiredSec,
854
- burstSec,
855
- repeats,
856
- warmUp,
857
- downsample,
858
- }) => {
859
- const task = 'all-hz-check';
860
- let res = null;
861
-
862
- console.log({payload, sampleRate, binDesiredSec, burstSec, repeats, warmUp});
863
-
864
- const data = JSON.stringify({
865
- payload,
866
- sampleRate,
867
- binDesiredSec,
868
- burstSec,
869
- repeats,
870
- warmUp,
871
- downsample,
872
- });
873
-
874
- await axios({
875
- method: 'post',
876
- baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
877
- url: `/task/${task}`,
878
- headers: {
879
- 'Content-Type': 'application/json',
880
- },
881
- data,
882
- })
883
- .then(response => {
884
- res = response;
885
- if (typeof res.data === 'string') {
886
- //if there is NaN in the string, replace it with 0
887
- res.data = res.data.replace('NaN', '0');
888
- res.data = JSON.parse(res.data);
889
- }
890
- console.log('res', res);
891
- })
892
- .catch(error => {
893
- throw error;
894
- });
895
- return res.data[task];
896
- };
897
-
898
- volumePowerCheck = async ({payload, sampleRate, preSec, Sec, binDesiredSec}) => {
899
- const task = 'volume-check';
900
- let res = null;
901
-
902
- const data = JSON.stringify({
903
- payload,
904
- sampleRate,
905
- preSec,
906
- Sec,
907
- binDesiredSec,
908
- });
909
-
910
- await axios({
911
- method: 'post',
912
- baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
913
- url: `/task/${task}`,
914
- headers: {
915
- 'Content-Type': 'application/json',
916
- },
917
- data,
918
- })
919
- .then(response => {
920
- res = response;
921
- console.log(res.data[task]);
922
- })
923
- .catch(error => {
924
- throw error;
925
- });
926
- return res.data[task];
927
- };
928
-
929
- volumePowerCheckWithRetry = async ({payload, sampleRate, preSec, Sec, binDesiredSec}) => {
930
- let retryCount = 0;
931
- let response = null;
932
-
933
- while (retryCount < this.MAX_RETRY_COUNT) {
934
- try {
935
- response = await this.volumePowerCheck({
936
- payload,
937
- sampleRate,
938
- preSec,
939
- Sec,
940
- binDesiredSec,
941
- });
942
- // If the request is successful, break out of the loop
943
- break;
944
- } catch (error) {
945
- console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
946
- retryCount++;
947
- await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
948
- }
949
- }
950
-
951
- if (response) {
952
- return response;
953
- } else {
954
- throw new Error(`Failed to get volume power check after ${this.MAX_RETRY_COUNT} attempts.`);
955
- }
956
- };
957
- }
958
-
959
- export default PythonServerAPI;
1
+ import axios from 'axios';
2
+ import {sleep} from '../utils';
3
+ /**
4
+ *
5
+ */
6
+ class PythonServerAPI {
7
+ static PYTHON_SERVER_URL = 'https://easyeyes-python-flask-server.herokuapp.com';
8
+
9
+ static TEST_SERVER_URL = 'http://127.0.0.1:5000';
10
+ // static PYTHON_SERVER_URL = 'http://127.0.0.1:5000';
11
+
12
+ /** @private */
13
+ MAX_RETRY_COUNT = 3;
14
+ /** @private */
15
+ RETRY_DELAY_MS = 1000;
16
+ /**
17
+ * @param data- -
18
+ * g = inverted impulse response, when convolved with the impulse
19
+ * reponse, they cancel out.
20
+ * @param data.payload
21
+ * @param data.sampleRate
22
+ * @param data.P
23
+ * @param data-.payload
24
+ * @param data-.sampleRate
25
+ * @param data-.P
26
+ * @returns
27
+ * @example
28
+ */
29
+ getImpulseResponse = async ({mls, sampleRate, numPeriods, sig, fs2, L_new_n, dL_n}) => {
30
+ const task = 'impulse-response';
31
+ let res = null;
32
+
33
+ const data = JSON.stringify({
34
+ task,
35
+ 'sample-rate': sampleRate,
36
+ mls,
37
+ numPeriods,
38
+ sig,
39
+ fs2,
40
+ L_new_n,
41
+ dL_n,
42
+ });
43
+
44
+ await axios({
45
+ method: 'post',
46
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
47
+ url: `/task/${task}`,
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ },
51
+ data,
52
+ })
53
+ .then(response => {
54
+ res = response;
55
+ })
56
+ .catch(error => {
57
+ throw error;
58
+ });
59
+ return res.data[task];
60
+ };
61
+
62
+ getAutocorrelation = async ({mls, payload, sampleRate, numPeriods}) => {
63
+ const task = 'autocorrelation';
64
+ let res = null;
65
+
66
+ const data = JSON.stringify({
67
+ task,
68
+ payload: payload,
69
+ 'sample-rate': sampleRate,
70
+ mls,
71
+ numPeriods,
72
+ });
73
+
74
+ await axios({
75
+ method: 'post',
76
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
77
+ url: `/task/${task}`,
78
+ headers: {
79
+ 'Content-Type': 'application/json',
80
+ },
81
+ data,
82
+ })
83
+ .then(response => {
84
+ res = response;
85
+ })
86
+ .catch(error => {
87
+ throw error;
88
+ });
89
+ return res.data[task];
90
+ };
91
+
92
+ getConvolution = async ({
93
+ mls,
94
+ inverse_response,
95
+ inverse_response_no_bandpass,
96
+ attenuatorGain_dB,
97
+ mls_amplitude,
98
+ }) => {
99
+ const task = 'convolution';
100
+ let res = null;
101
+
102
+ const data = JSON.stringify({
103
+ task,
104
+ mls,
105
+ inverse_response,
106
+ inverse_response_no_bandpass,
107
+ attenuatorGain_dB,
108
+ mls_amplitude,
109
+ });
110
+
111
+ await axios({
112
+ method: 'post',
113
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
114
+ url: `/task/${task}`,
115
+ headers: {
116
+ 'Content-Type': 'application/json',
117
+ },
118
+ data,
119
+ })
120
+ .then(response => {
121
+ res = response;
122
+ })
123
+ .catch(error => {
124
+ throw error;
125
+ });
126
+ return res.data[task];
127
+ };
128
+
129
+ getFrequencyResponseFromImpulseResponse = async ({
130
+ impulseResponseMicrophone,
131
+ impulseResponseLoudspeaker,
132
+ sampleRate,
133
+ timeArray,
134
+ totalDuration,
135
+ totalDuration1000Hz,
136
+ }) => {
137
+ const task = 'frequency-response';
138
+ let res = null;
139
+
140
+ const data = JSON.stringify({
141
+ task,
142
+ impulse_response_microphone: impulseResponseMicrophone,
143
+ impulse_response_loudspeaker: impulseResponseLoudspeaker,
144
+ sample_rate: sampleRate,
145
+ time_array: timeArray,
146
+ total_duration: totalDuration,
147
+ total_duration_1000hz: totalDuration1000Hz,
148
+ });
149
+
150
+ await axios({
151
+ method: 'post',
152
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
153
+ url: `/task/${task}`,
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ },
157
+ data,
158
+ })
159
+ .then(response => {
160
+ res = response;
161
+ })
162
+ .catch(error => {
163
+ throw error;
164
+ });
165
+ return res.data[task];
166
+ };
167
+
168
+ getMLS = async ({
169
+ length,
170
+ amplitude,
171
+ calibrateSoundBurstMLSVersions,
172
+ calibrateSoundBurstDownsample,
173
+ }) => {
174
+ const task = 'mls';
175
+ let res = null;
176
+
177
+ const data = JSON.stringify({
178
+ task,
179
+ length: length,
180
+ amplitude: amplitude,
181
+ calibrateSoundBurstMLSVersions: calibrateSoundBurstMLSVersions,
182
+ calibrateSoundBurstDownsample: calibrateSoundBurstDownsample,
183
+ });
184
+
185
+ await axios({
186
+ method: 'post',
187
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
188
+ url: `/task/${task}`,
189
+ headers: {
190
+ 'Content-Type': 'application/json',
191
+ },
192
+ data,
193
+ })
194
+ .then(response => {
195
+ res = response;
196
+ })
197
+ .catch(error => {
198
+ throw error;
199
+ });
200
+
201
+ return res.data[task];
202
+ };
203
+
204
+ getShortURL = async originalURL => {
205
+ const task = 'url';
206
+ let res = null;
207
+ console.log(originalURL);
208
+ const data = JSON.stringify({
209
+ URL: originalURL,
210
+ });
211
+
212
+ console.log(data);
213
+
214
+ await axios({
215
+ method: 'post',
216
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
217
+ url: `/task/${task}`,
218
+ headers: {
219
+ 'Content-Type': 'application/json',
220
+ },
221
+ data,
222
+ })
223
+ .then(response => {
224
+ res = response;
225
+ console.log(res.data[task]);
226
+ })
227
+ .catch(error => {
228
+ throw error;
229
+ });
230
+
231
+ return res.data[task];
232
+ };
233
+
234
+ getMemory = async () => {
235
+ let res;
236
+ await axios({
237
+ method: 'post',
238
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
239
+ url: `/memory`,
240
+ headers: {
241
+ 'Content-Type': 'application/json',
242
+ },
243
+ })
244
+ .then(response => {
245
+ console.log('memory used:', Math.round(response.data['memory']), 'mb');
246
+ res = response.data['memory'];
247
+ })
248
+ .catch(error => {
249
+ throw error;
250
+ });
251
+ return res;
252
+ };
253
+
254
+ checkMemory = async () => {
255
+ console.log('wait for memory under 500 mb to continue calibration');
256
+ await this.getMemory();
257
+ // let memory = await this.getMemory();
258
+ // while (memory >= 500) {
259
+ // console.log("sleep 30s");
260
+ // await sleep(30);
261
+ // memory = await this.getMemory();
262
+ // }
263
+ };
264
+
265
+ getMLSWithRetry = async ({
266
+ length,
267
+ amplitude,
268
+ calibrateSoundBurstMLSVersions,
269
+ calibrateSoundBurstDownsample,
270
+ }) => {
271
+ let retryCount = 0;
272
+ let response = null;
273
+
274
+ while (retryCount < this.MAX_RETRY_COUNT) {
275
+ try {
276
+ response = await this.getMLS({
277
+ length,
278
+ amplitude,
279
+ calibrateSoundBurstMLSVersions,
280
+ calibrateSoundBurstDownsample,
281
+ });
282
+ // If the request is successful, break out of the loop
283
+ break;
284
+ } catch (error) {
285
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
286
+ retryCount++;
287
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
288
+ }
289
+ }
290
+
291
+ if (response) {
292
+ return response;
293
+ } else {
294
+ throw new Error(`Failed to get MLS after ${this.MAX_RETRY_COUNT} attempts.`);
295
+ }
296
+ };
297
+
298
+ getPSD = async ({unconv_rec, conv_rec, sampleRate, downsample}) => {
299
+ const task = 'psd';
300
+ let res = null;
301
+
302
+ const data = JSON.stringify({
303
+ task,
304
+ unconv_rec,
305
+ conv_rec,
306
+ sampleRate,
307
+ downsample,
308
+ });
309
+
310
+ await axios({
311
+ method: 'post',
312
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
313
+ url: `/task/${task}`,
314
+ headers: {
315
+ 'Content-Type': 'application/json',
316
+ },
317
+ data,
318
+ })
319
+ .then(response => {
320
+ res = response;
321
+ })
322
+ .catch(error => {
323
+ throw error;
324
+ });
325
+ return res.data[task];
326
+ };
327
+
328
+ getBackgroundNoisePSD = async ({background_rec, sampleRate}) => {
329
+ const task = 'background-psd';
330
+ let res = null;
331
+
332
+ const data = JSON.stringify({
333
+ task,
334
+ background_rec,
335
+ sampleRate,
336
+ });
337
+
338
+ await axios({
339
+ method: 'post',
340
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
341
+ url: `/task/${task}`,
342
+ headers: {
343
+ 'Content-Type': 'application/json',
344
+ },
345
+ data,
346
+ })
347
+ .then(response => {
348
+ res = response;
349
+ })
350
+ .catch(error => {
351
+ throw error;
352
+ });
353
+ return res.data[task];
354
+ };
355
+
356
+ getBackgroundNoisePSDWithRetry = async ({background_rec, sampleRate}) => {
357
+ let retryCount = 0;
358
+ let response = null;
359
+
360
+ while (retryCount < this.MAX_RETRY_COUNT) {
361
+ try {
362
+ response = await this.getBackgroundNoisePSD({background_rec, sampleRate});
363
+ // If the request is successful, break out of the loop
364
+ break;
365
+ } catch (error) {
366
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
367
+ retryCount++;
368
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
369
+ }
370
+ }
371
+
372
+ if (response) {
373
+ return response;
374
+ } else {
375
+ throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
376
+ }
377
+ };
378
+
379
+ getSubtractedPSD = async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {
380
+ const task = 'subtracted-psd';
381
+ let res = null;
382
+
383
+ const data = JSON.stringify({
384
+ task,
385
+ rec,
386
+ knownGains,
387
+ knownFrequencies,
388
+ sampleRate,
389
+ downsample,
390
+ });
391
+
392
+ await axios({
393
+ method: 'post',
394
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
395
+ url: `/task/${task}`,
396
+ headers: {
397
+ 'Content-Type': 'application/json',
398
+ },
399
+ data,
400
+ })
401
+ .then(response => {
402
+ res = response;
403
+ })
404
+ .catch(error => {
405
+ throw error;
406
+ });
407
+ return res.data[task];
408
+ };
409
+
410
+ getSubtractedPSDWithRetry = async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {
411
+ let retryCount = 0;
412
+ let response = null;
413
+
414
+ while (retryCount < this.MAX_RETRY_COUNT) {
415
+ try {
416
+ response = await this.getSubtractedPSD(
417
+ rec,
418
+ knownGains,
419
+ knownFrequencies,
420
+ sampleRate,
421
+ downsample
422
+ );
423
+ // If the request is successful, break out of the loop
424
+ break;
425
+ } catch (error) {
426
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
427
+ retryCount++;
428
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
429
+ }
430
+ }
431
+
432
+ if (response) {
433
+ return response;
434
+ } else {
435
+ throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
436
+ }
437
+ };
438
+
439
+ getPSDWithRetry = async ({unconv_rec, conv_rec, sampleRate, downsample}) => {
440
+ let retryCount = 0;
441
+ let response = null;
442
+
443
+ while (retryCount < this.MAX_RETRY_COUNT) {
444
+ try {
445
+ response = await this.getPSD({unconv_rec, conv_rec, sampleRate, downsample});
446
+ // If the request is successful, break out of the loop
447
+ break;
448
+ } catch (error) {
449
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
450
+ retryCount++;
451
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
452
+ }
453
+ }
454
+
455
+ if (response) {
456
+ return response;
457
+ } else {
458
+ throw new Error(`Failed to get PSD after ${this.MAX_RETRY_COUNT} attempts.`);
459
+ }
460
+ };
461
+
462
+ getComponentInverseImpulseResponse = async ({
463
+ payload,
464
+ mls,
465
+ lowHz,
466
+ highHz,
467
+ componentIRGains,
468
+ iirLength,
469
+ componentIRFreqs,
470
+ sampleRate,
471
+ mlsAmplitude,
472
+ irLength,
473
+ calibrateSoundSmoothOctaves,
474
+ calibrateSoundSmoothMinBandwidthHz,
475
+ calibrateSoundBurstFilteredExtraDb,
476
+ calibrateSoundIIRPhase,
477
+ downsample,
478
+ }) => {
479
+ const task = 'component-inverse-impulse-response';
480
+ let res = null;
481
+
482
+ const data = JSON.stringify({
483
+ task,
484
+ payload,
485
+ mls,
486
+ lowHz,
487
+ highHz,
488
+ iirLength,
489
+ componentIRGains,
490
+ componentIRFreqs,
491
+ sampleRate,
492
+ mlsAmplitude,
493
+ irLength,
494
+ calibrateSoundSmoothOctaves,
495
+ calibrateSoundSmoothMinBandwidthHz,
496
+ calibrateSoundBurstFilteredExtraDb,
497
+ calibrateSoundIIRPhase,
498
+ downsample,
499
+ });
500
+
501
+ await axios({
502
+ method: 'post',
503
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
504
+ url: `/task/${task}`,
505
+ headers: {
506
+ 'Content-Type': 'application/json',
507
+ },
508
+ data,
509
+ })
510
+ .then(response => {
511
+ res = response;
512
+ })
513
+ .catch(error => {
514
+ throw error;
515
+ });
516
+
517
+ return res.data[task];
518
+ };
519
+ getSystemInverseImpulseResponse = async ({
520
+ payload,
521
+ mls,
522
+ lowHz,
523
+ highHz,
524
+ iirLength,
525
+ sampleRate,
526
+ mlsAmplitude,
527
+ calibrateSoundBurstFilteredExtraDb,
528
+ calibrateSoundIIRPhase,
529
+ downsample,
530
+ }) => {
531
+ const task = 'system-inverse-impulse-response';
532
+ let res = null;
533
+
534
+ const data = JSON.stringify({
535
+ task,
536
+ payload,
537
+ mls,
538
+ lowHz,
539
+ iirLength,
540
+ highHz,
541
+ sampleRate,
542
+ mlsAmplitude,
543
+ calibrateSoundBurstFilteredExtraDb,
544
+ calibrateSoundIIRPhase,
545
+ downsample,
546
+ });
547
+
548
+ await axios({
549
+ method: 'post',
550
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
551
+ url: `/task/${task}`,
552
+ headers: {
553
+ 'Content-Type': 'application/json',
554
+ },
555
+ data,
556
+ })
557
+ .then(response => {
558
+ res = response;
559
+ })
560
+ .catch(error => {
561
+ throw error;
562
+ });
563
+
564
+ return res.data[task];
565
+ };
566
+
567
+ getMLSPSD = async ({mls, sampleRate, downsample}) => {
568
+ const task = 'mls-psd';
569
+ let res = null;
570
+
571
+ const data = JSON.stringify({
572
+ task,
573
+ mls,
574
+ sampleRate,
575
+ downsample,
576
+ });
577
+
578
+ await axios({
579
+ method: 'post',
580
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
581
+ url: `/task/${task}`,
582
+ headers: {
583
+ 'Content-Type': 'application/json',
584
+ },
585
+ data,
586
+ })
587
+ .then(response => {
588
+ res = response;
589
+ })
590
+ .catch(error => {
591
+ throw error;
592
+ });
593
+
594
+ return res.data[task];
595
+ };
596
+
597
+ getMLSPSDWithRetry = async ({mls, sampleRate, downsample}) => {
598
+ let retryCount = 0;
599
+ let response = null;
600
+
601
+ while (retryCount < this.MAX_RETRY_COUNT) {
602
+ try {
603
+ response = await this.getMLSPSD({mls, sampleRate, downsample});
604
+ // If the request is successful, break out of the loop
605
+ break;
606
+ } catch (error) {
607
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
608
+ retryCount++;
609
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
610
+ }
611
+ }
612
+
613
+ if (response) {
614
+ return response;
615
+ } else {
616
+ throw new Error(
617
+ `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
618
+ );
619
+ }
620
+ };
621
+
622
+ getComponentInverseImpulseResponseWithRetry = async ({
623
+ payload,
624
+ mls,
625
+ lowHz,
626
+ highHz,
627
+ componentIRGains,
628
+ iirLength,
629
+ componentIRFreqs,
630
+ sampleRate,
631
+ mlsAmplitude,
632
+ irLength,
633
+ calibrateSoundSmoothOctaves,
634
+ calibrateSoundSmoothMinBandwidthHz,
635
+ calibrateSoundBurstFilteredExtraDb,
636
+ calibrateSoundIIRPhase,
637
+ downsample,
638
+ }) => {
639
+ let retryCount = 0;
640
+ let response = null;
641
+
642
+ while (retryCount < this.MAX_RETRY_COUNT) {
643
+ try {
644
+ response = await this.getComponentInverseImpulseResponse({
645
+ payload,
646
+ mls,
647
+ lowHz,
648
+ highHz,
649
+ componentIRGains,
650
+ iirLength,
651
+ componentIRFreqs,
652
+ sampleRate,
653
+ mlsAmplitude,
654
+ irLength,
655
+ calibrateSoundSmoothOctaves,
656
+ calibrateSoundSmoothMinBandwidthHz,
657
+ calibrateSoundBurstFilteredExtraDb,
658
+ calibrateSoundIIRPhase,
659
+ downsample,
660
+ });
661
+ // If the request is successful, break out of the loop
662
+ break;
663
+ } catch (error) {
664
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
665
+ retryCount++;
666
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
667
+ }
668
+ }
669
+
670
+ if (response) {
671
+ return response;
672
+ } else {
673
+ throw new Error(
674
+ `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
675
+ );
676
+ }
677
+ };
678
+
679
+ getSystemInverseImpulseResponseWithRetry = async ({
680
+ payload,
681
+ mls,
682
+ lowHz,
683
+ highHz,
684
+ iirLength,
685
+ sampleRate,
686
+ mlsAmplitude,
687
+ calibrateSoundBurstFilteredExtraDb,
688
+ calibrateSoundIIRPhase,
689
+ downsample,
690
+ }) => {
691
+ let retryCount = 0;
692
+ let response = null;
693
+
694
+ while (retryCount < this.MAX_RETRY_COUNT) {
695
+ try {
696
+ response = await this.getSystemInverseImpulseResponse({
697
+ payload,
698
+ mls,
699
+ lowHz,
700
+ highHz,
701
+ iirLength,
702
+ sampleRate,
703
+ mlsAmplitude,
704
+ calibrateSoundBurstFilteredExtraDb,
705
+ calibrateSoundIIRPhase,
706
+ downsample,
707
+ });
708
+ // If the request is successful, break out of the loop
709
+ break;
710
+ } catch (error) {
711
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
712
+ retryCount++;
713
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
714
+ }
715
+ }
716
+
717
+ if (response) {
718
+ return response;
719
+ } else {
720
+ throw new Error(
721
+ `Failed to get inverse impulse response after ${this.MAX_RETRY_COUNT} attempts.`
722
+ );
723
+ }
724
+ };
725
+
726
+ getVolumeCalibration = async ({payload, sampleRate, lCalib}) => {
727
+ const task = 'volume';
728
+ let res = null;
729
+
730
+ console.log({payload});
731
+
732
+ const data = JSON.stringify({
733
+ task,
734
+ payload,
735
+ 'sample-rate': sampleRate,
736
+ lCalib,
737
+ });
738
+
739
+ const response = await axios({
740
+ method: 'post',
741
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL,
742
+ url: `/task/${task}`,
743
+ headers: {
744
+ 'Content-Type': 'application/json',
745
+ },
746
+ data,
747
+ })
748
+ .then(response => {
749
+ // if response.data is a string, parse it
750
+ if (typeof response.data === 'string') {
751
+ // response.data = response.data.replaceAll('Infinity', 99999999);
752
+ // response.data = JSON.parse(response.data);
753
+ //if there is Infinity in the string, throw an error
754
+ if (response.data.includes('Infinity')) {
755
+ throw new Error(
756
+ 'Server returned Infinity. Please make sure the microphone is recording correctly'
757
+ );
758
+ }
759
+ response.data = JSON.parse(response.data);
760
+ }
761
+ return response.data[task];
762
+ })
763
+ .catch(error => {
764
+ alert(
765
+ 'Invalid data. Please make sure the microphone is recording correctly and press on "Re-Record"'
766
+ );
767
+ throw error;
768
+ });
769
+
770
+ console.log(response);
771
+ return response;
772
+ };
773
+
774
+ getVolumeCalibrationParameters = async ({
775
+ inDBValues,
776
+ outDBSPLValues,
777
+ lCalib,
778
+ componentGainDBSPL,
779
+ }) => {
780
+ const task = 'volume-parameters';
781
+ let res = null;
782
+
783
+ const data = JSON.stringify({
784
+ task,
785
+ inDBValues,
786
+ outDBSPLValues,
787
+ lCalib,
788
+ componentGainDBSPL,
789
+ });
790
+
791
+ await axios({
792
+ method: 'post',
793
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
794
+ url: `/task/${task}`,
795
+ headers: {
796
+ 'Content-Type': 'application/json',
797
+ },
798
+ data,
799
+ })
800
+ .then(response => {
801
+ res = response;
802
+ console.log('data', data, 'res', res.data[task]);
803
+ })
804
+ .catch(error => {
805
+ throw error;
806
+ });
807
+
808
+ // console.log(res.data[task]);
809
+ //below is an example of res.data[task]
810
+ //{
811
+ // R: 16.56981076554259,
812
+ // RMSError: 1.9289162528535229
813
+ // T: -47.79799120884434,
814
+ // W: 61.0485247483732,
815
+ // backgroundDBSPL: 43.88233142069752,
816
+ // gainDBSPL: -128.24742161208985
817
+ //}
818
+ return res.data[task];
819
+ };
820
+
821
+ irConvolution = async ({input_signal, microphone_ir, loudspeaker_ir}) => {
822
+ const task = 'ir-convolution';
823
+ let res = null;
824
+
825
+ const data = JSON.stringify({
826
+ input_signal,
827
+ microphone_ir,
828
+ loudspeaker_ir,
829
+ });
830
+
831
+ await axios({
832
+ method: 'post',
833
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
834
+ url: `/task/${task}`,
835
+ headers: {
836
+ 'Content-Type': 'application/json',
837
+ },
838
+ data,
839
+ })
840
+ .then(response => {
841
+ res = response;
842
+ })
843
+ .catch(error => {
844
+ throw error;
845
+ });
846
+ console.log('res in irConvolution: ', res);
847
+ return res.data[task];
848
+ };
849
+
850
+ allHzPowerCheck = async ({
851
+ payload,
852
+ sampleRate,
853
+ binDesiredSec,
854
+ burstSec,
855
+ repeats,
856
+ warmUp,
857
+ downsample,
858
+ }) => {
859
+ const task = 'all-hz-check';
860
+ let res = null;
861
+
862
+ console.log({payload, sampleRate, binDesiredSec, burstSec, repeats, warmUp});
863
+
864
+ const data = JSON.stringify({
865
+ payload,
866
+ sampleRate,
867
+ binDesiredSec,
868
+ burstSec,
869
+ repeats,
870
+ warmUp,
871
+ downsample,
872
+ });
873
+
874
+ await axios({
875
+ method: 'post',
876
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
877
+ url: `/task/${task}`,
878
+ headers: {
879
+ 'Content-Type': 'application/json',
880
+ },
881
+ data,
882
+ })
883
+ .then(response => {
884
+ res = response;
885
+ if (typeof res.data === 'string') {
886
+ //if there is NaN in the string, replace it with 0
887
+ res.data = res.data.replace('NaN', '0');
888
+ res.data = JSON.parse(res.data);
889
+ }
890
+ console.log('res', res);
891
+ })
892
+ .catch(error => {
893
+ throw error;
894
+ });
895
+ return res.data[task];
896
+ };
897
+
898
+ volumePowerCheck = async ({payload, sampleRate, preSec, Sec, binDesiredSec}) => {
899
+ const task = 'volume-check';
900
+ let res = null;
901
+
902
+ const data = JSON.stringify({
903
+ payload,
904
+ sampleRate,
905
+ preSec,
906
+ Sec,
907
+ binDesiredSec,
908
+ });
909
+
910
+ await axios({
911
+ method: 'post',
912
+ baseURL: PythonServerAPI.PYTHON_SERVER_URL, //server
913
+ url: `/task/${task}`,
914
+ headers: {
915
+ 'Content-Type': 'application/json',
916
+ },
917
+ data,
918
+ })
919
+ .then(response => {
920
+ res = response;
921
+ console.log(res.data[task]);
922
+ })
923
+ .catch(error => {
924
+ throw error;
925
+ });
926
+ return res.data[task];
927
+ };
928
+
929
+ volumePowerCheckWithRetry = async ({payload, sampleRate, preSec, Sec, binDesiredSec}) => {
930
+ let retryCount = 0;
931
+ let response = null;
932
+
933
+ while (retryCount < this.MAX_RETRY_COUNT) {
934
+ try {
935
+ response = await this.volumePowerCheck({
936
+ payload,
937
+ sampleRate,
938
+ preSec,
939
+ Sec,
940
+ binDesiredSec,
941
+ });
942
+ // If the request is successful, break out of the loop
943
+ break;
944
+ } catch (error) {
945
+ console.error(`Error occurred. Retrying... (${retryCount + 1}/${this.MAX_RETRY_COUNT})`);
946
+ retryCount++;
947
+ await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));
948
+ }
949
+ }
950
+
951
+ if (response) {
952
+ return response;
953
+ } else {
954
+ throw new Error(`Failed to get volume power check after ${this.MAX_RETRY_COUNT} attempts.`);
955
+ }
956
+ };
957
+ }
958
+
959
+ export default PythonServerAPI;