speaker-calibration 2.2.152 → 2.2.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +623 -499
- package/package.json +4 -4
- package/src/server/PythonServerAPI.js +7 -6
- package/src/tasks/combination/combination.js +67 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "speaker-calibration",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.154",
|
|
4
4
|
"description": "Speaker calibration library for auditory testing",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"directories": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": "git://github.com/EasyEyes/speaker-calibration.git",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"axios": "^
|
|
34
|
+
"axios": "^1.6.7",
|
|
35
35
|
"fftw-js": "^0.1.4",
|
|
36
36
|
"firebase": "^9.23.0",
|
|
37
37
|
"np": "^7.7.0",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
"eslint-plugin-no-floating-promise": "^1.0.2",
|
|
56
56
|
"express": "^4.17.1",
|
|
57
57
|
"jest": "^27.5.1",
|
|
58
|
-
"jsdoc": "^
|
|
58
|
+
"jsdoc": "^4.0.2",
|
|
59
59
|
"nodemon": "^2.0.15",
|
|
60
60
|
"prettier": "^2.5.1",
|
|
61
61
|
"style-loader": "^2.0.0",
|
|
62
|
-
"webpack": "
|
|
62
|
+
"webpack": "^5.90.3",
|
|
63
63
|
"webpack-bundle-analyzer": "^4.5.0",
|
|
64
64
|
"webpack-cli": "^4.9.2"
|
|
65
65
|
},
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
class PythonServerAPI {
|
|
9
|
-
static PYTHON_SERVER_URL = 'https://easyeyes-python-flask-server.herokuapp.com';
|
|
9
|
+
// static PYTHON_SERVER_URL = 'https://easyeyes-python-flask-server.herokuapp.com';
|
|
10
10
|
|
|
11
11
|
static TEST_SERVER_URL = 'http://127.0.0.1:5000';
|
|
12
|
-
|
|
12
|
+
static PYTHON_SERVER_URL ='http://127.0.0.1:5000';
|
|
13
13
|
|
|
14
14
|
/** @private */
|
|
15
15
|
MAX_RETRY_COUNT = 3;
|
|
@@ -141,14 +141,15 @@ class PythonServerAPI {
|
|
|
141
141
|
return res.data[task];
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
-
getMLS = async ({length,amplitude}) => {
|
|
144
|
+
getMLS = async ({length,amplitude,calibrateSoundBurstMLSVersions}) => {
|
|
145
145
|
const task = 'mls';
|
|
146
146
|
let res = null;
|
|
147
147
|
|
|
148
148
|
const data = JSON.stringify({
|
|
149
149
|
task,
|
|
150
150
|
length: length,
|
|
151
|
-
amplitude: amplitude
|
|
151
|
+
amplitude: amplitude,
|
|
152
|
+
calibrateSoundBurstMLSVersions: calibrateSoundBurstMLSVersions,
|
|
152
153
|
});
|
|
153
154
|
|
|
154
155
|
await axios({
|
|
@@ -204,13 +205,13 @@ class PythonServerAPI {
|
|
|
204
205
|
};
|
|
205
206
|
|
|
206
207
|
|
|
207
|
-
getMLSWithRetry = async ({length,amplitude}) => {
|
|
208
|
+
getMLSWithRetry = async ({length,amplitude,calibrateSoundBurstMLSVersions}) => {
|
|
208
209
|
let retryCount = 0;
|
|
209
210
|
let response = null;
|
|
210
211
|
|
|
211
212
|
while (retryCount < this.MAX_RETRY_COUNT) {
|
|
212
213
|
try {
|
|
213
|
-
response = await this.getMLS({length,amplitude});
|
|
214
|
+
response = await this.getMLS({length,amplitude, calibrateSoundBurstMLSVersions});
|
|
214
215
|
// If the request is successful, break out of the loop
|
|
215
216
|
break;
|
|
216
217
|
} catch (error) {
|
|
@@ -287,6 +287,7 @@ class Combination extends AudioCalibrator {
|
|
|
287
287
|
dL_n;
|
|
288
288
|
L_new_n;
|
|
289
289
|
fs2;
|
|
290
|
+
icapture = 0;
|
|
290
291
|
|
|
291
292
|
/**generate string template that gets reevaluated as variable increases */
|
|
292
293
|
generateTemplate = () => {
|
|
@@ -352,7 +353,8 @@ class Combination extends AudioCalibrator {
|
|
|
352
353
|
const filteredComputedIRs = computedIRs.filter(element => {
|
|
353
354
|
return element != undefined;
|
|
354
355
|
}); //log any errors that are found in this step
|
|
355
|
-
|
|
356
|
+
console.log("filteredComputedIRs", filteredComputedIRs);
|
|
357
|
+
const mls = this.#mls[this.icapture];
|
|
356
358
|
const lowHz = this.#lowHz; //gain of 1 below cutoff, need gain of 0
|
|
357
359
|
const highHz = this.#highHz; //check error for anything other than 10 kHz
|
|
358
360
|
const iirLength = this.iirLength;
|
|
@@ -430,7 +432,7 @@ class Combination extends AudioCalibrator {
|
|
|
430
432
|
});
|
|
431
433
|
const componentIRGains = this.componentIR['Gain'];
|
|
432
434
|
const componentIRFreqs = this.componentIR['Freq'];
|
|
433
|
-
const mls = this.#mls;
|
|
435
|
+
const mls = this.#mls[this.icapture];
|
|
434
436
|
const lowHz = this.#lowHz;
|
|
435
437
|
const iirLength = this.iirLength;
|
|
436
438
|
const irLength = this.irLength;
|
|
@@ -550,7 +552,7 @@ class Combination extends AudioCalibrator {
|
|
|
550
552
|
'Obtaining last all hz unfiltered recording from #allHzUnfilteredRecordings to send to server for processing'
|
|
551
553
|
);
|
|
552
554
|
const numSignals = allSignals.length;
|
|
553
|
-
const mls = this.#mlsBufferView;
|
|
555
|
+
const mls = this.#mlsBufferView[this.icapture];
|
|
554
556
|
const payload =
|
|
555
557
|
signalCsv && signalCsv.length > 0 ? csvToArray(signalCsv) : allSignals[numSignals - 1];
|
|
556
558
|
console.log('sending rec');
|
|
@@ -571,9 +573,22 @@ class Combination extends AudioCalibrator {
|
|
|
571
573
|
})
|
|
572
574
|
.then(async result => {
|
|
573
575
|
if (result) {
|
|
576
|
+
console.log("JS used memory:", performance.memory.usedJSHeapSize/1024/1024, "mb");
|
|
574
577
|
if (result['sd'] < this._calibrateSoundPowerDbSDToleratedDb) {
|
|
575
578
|
this.recordingChecks['unfiltered'].push(result);
|
|
576
579
|
await this.pyServerAPI.checkMemory();
|
|
580
|
+
// let start = new Date().getTime() / 1000;
|
|
581
|
+
// const payloadT = tf.tensor1d(payload);
|
|
582
|
+
// payloadT.print();
|
|
583
|
+
// const xfft = payloadT.rfft(); // tf.spe
|
|
584
|
+
// xfft.array().then(array => {
|
|
585
|
+
// console.log("fft:", array);
|
|
586
|
+
// let setItem = new Set(array);
|
|
587
|
+
// console.log("all zero", setItem.size === 1 && setItem.has(0));
|
|
588
|
+
// });
|
|
589
|
+
// console.log("dimention:", xfft.shape);
|
|
590
|
+
// let end = new Date().getTime() / 1000;
|
|
591
|
+
// console.log("Time taken:", end - start, "seconds");
|
|
577
592
|
await this.pyServerAPI.getAutocorrelation({
|
|
578
593
|
sampleRate: this.sourceSamplingRate || 96000,
|
|
579
594
|
payload,
|
|
@@ -588,12 +603,8 @@ class Combination extends AudioCalibrator {
|
|
|
588
603
|
this.impulseResponses.push(
|
|
589
604
|
await this.pyServerAPI
|
|
590
605
|
.getImpulseResponse({
|
|
591
|
-
sampleRate: this.sourceSamplingRate || 96000,
|
|
592
|
-
mls,
|
|
593
|
-
mls,
|
|
594
|
-
P: this.#P, //get rid of this
|
|
595
606
|
mls,
|
|
596
|
-
|
|
607
|
+
sampleRate: this.sourceSamplingRate || 96000,
|
|
597
608
|
numPeriods: this.numMLSPerCapture,
|
|
598
609
|
sig: payload,
|
|
599
610
|
fs2: this.fs2,
|
|
@@ -654,7 +665,7 @@ class Combination extends AudioCalibrator {
|
|
|
654
665
|
let time_to_wait = 0;
|
|
655
666
|
if (this.mode === 'unfiltered') {
|
|
656
667
|
//unfiltered
|
|
657
|
-
time_to_wait = (this.#mls.length / this.sourceSamplingRate) * this.numMLSPerCapture;
|
|
668
|
+
time_to_wait = (this.#mls[0].length / this.sourceSamplingRate) * this.numMLSPerCapture;
|
|
658
669
|
time_to_wait = time_to_wait * 1.1;
|
|
659
670
|
} else if (this.mode === 'filtered') {
|
|
660
671
|
//filtered
|
|
@@ -704,7 +715,7 @@ class Combination extends AudioCalibrator {
|
|
|
704
715
|
let number_of_bursts_to_skip = this.num_mls_to_skip;
|
|
705
716
|
let time_to_sleep = 0;
|
|
706
717
|
if (this.mode === 'unfiltered') {
|
|
707
|
-
time_to_sleep = (this.#mls.length / this.sourceSamplingRate) * number_of_bursts_to_skip;
|
|
718
|
+
time_to_sleep = (this.#mls[0].length / this.sourceSamplingRate) * number_of_bursts_to_skip;
|
|
708
719
|
} else if (this.mode === 'filtered') {
|
|
709
720
|
console.log(this.#currentConvolution.length);
|
|
710
721
|
// time_to_sleep =
|
|
@@ -818,7 +829,7 @@ class Combination extends AudioCalibrator {
|
|
|
818
829
|
* @param {*} dataBufferArray
|
|
819
830
|
* @example
|
|
820
831
|
*/
|
|
821
|
-
#setCalibrationNodesFromBuffer = (dataBufferArray = [this.#mlsBufferView]) => {
|
|
832
|
+
#setCalibrationNodesFromBuffer = (dataBufferArray = [this.#mlsBufferView[this.icapture]]) => {
|
|
822
833
|
if (dataBufferArray.length === 1) {
|
|
823
834
|
this.#createCalibrationNodeFromBuffer(dataBufferArray[0]);
|
|
824
835
|
} else {
|
|
@@ -1041,6 +1052,7 @@ class Combination extends AudioCalibrator {
|
|
|
1041
1052
|
.map(value => 10 * Math.log10(value));
|
|
1042
1053
|
|
|
1043
1054
|
this.SDofFilteredRange['mls'] = standardDeviation(mls_psd);
|
|
1055
|
+
console.log('mls_psd', this.SDofFilteredRange['mls']);
|
|
1044
1056
|
this.SDofFilteredRange['system'] = standardDeviation(filtered_psd);
|
|
1045
1057
|
this.incrementStatusBar();
|
|
1046
1058
|
this.status =
|
|
@@ -1100,7 +1112,7 @@ class Combination extends AudioCalibrator {
|
|
|
1100
1112
|
this.addTimeStamp('Get PSD of mls sequence');
|
|
1101
1113
|
if (this.isCalibrating) return null;
|
|
1102
1114
|
let mls_psd = await this.pyServerAPI
|
|
1103
|
-
.getMLSPSDWithRetry({mls: this.#mlsBufferView, sampleRate: this.sourceSamplingRate || 96000})
|
|
1115
|
+
.getMLSPSDWithRetry({mls: this.#mlsBufferView[0], sampleRate: this.sourceSamplingRate || 96000})
|
|
1104
1116
|
.then(res => {
|
|
1105
1117
|
this.incrementStatusBar();
|
|
1106
1118
|
this.status =
|
|
@@ -1350,6 +1362,15 @@ class Combination extends AudioCalibrator {
|
|
|
1350
1362
|
let unconv_results = await this.pyServerAPI
|
|
1351
1363
|
.getSubtractedPSDWithRetry(unconv_rec, knownGain, knownFreq, sampleRate)
|
|
1352
1364
|
.then(res => {
|
|
1365
|
+
console.log(res);
|
|
1366
|
+
let mls_psd = res.y
|
|
1367
|
+
.filter(
|
|
1368
|
+
(value, index) =>
|
|
1369
|
+
res.x[index] >= this.#lowHz && res.x[index] <= this.systemFMaxHz
|
|
1370
|
+
)
|
|
1371
|
+
.map(value => 10 * Math.log10(value));
|
|
1372
|
+
this.SDofFilteredRange['mls'] = standardDeviation(mls_psd);
|
|
1373
|
+
console.log('mls sd', this.SDofFilteredRange['mls']);
|
|
1353
1374
|
this.incrementStatusBar();
|
|
1354
1375
|
this.status =
|
|
1355
1376
|
`All Hz Calibration: done computing the PSD graphs...`.toString() +
|
|
@@ -1449,7 +1470,7 @@ class Combination extends AudioCalibrator {
|
|
|
1449
1470
|
if (this.isCalibrating) return null;
|
|
1450
1471
|
let mls_psd = await this.pyServerAPI
|
|
1451
1472
|
.getMLSPSDWithRetry({
|
|
1452
|
-
mls: this.#mlsBufferView,
|
|
1473
|
+
mls: this.#mlsBufferView[this.icapture],
|
|
1453
1474
|
sampleRate: this.sourceSamplingRate || 96000,
|
|
1454
1475
|
})
|
|
1455
1476
|
.then(res => {
|
|
@@ -1595,9 +1616,8 @@ class Combination extends AudioCalibrator {
|
|
|
1595
1616
|
res.x_unconv[index] >= this.#lowHz && res.x_conv[index] <= this.systemFMaxHz
|
|
1596
1617
|
)
|
|
1597
1618
|
.map(value => 10 * Math.log10(value));
|
|
1598
|
-
|
|
1619
|
+
this.SDofFilteredRange['mls'] = standardDeviation(mls_psd);
|
|
1599
1620
|
this.SDofFilteredRange['system'] = standardDeviation(filtered_psd);
|
|
1600
|
-
this.SDofFilteredRange['unfiltered'] = standardDeviation(mls_psd);
|
|
1601
1621
|
this.incrementStatusBar();
|
|
1602
1622
|
this.status =
|
|
1603
1623
|
`All Hz Calibration: done computing the PSD graphs...`.toString() +
|
|
@@ -1657,7 +1677,7 @@ class Combination extends AudioCalibrator {
|
|
|
1657
1677
|
if (this.isCalibrating) return null;
|
|
1658
1678
|
let mls_psd = await this.pyServerAPI
|
|
1659
1679
|
.getMLSPSDWithRetry({
|
|
1660
|
-
mls: this.#mlsBufferView,
|
|
1680
|
+
mls: this.#mlsBufferView[this.icapture],
|
|
1661
1681
|
sampleRate: this.sourceSamplingRate || 96000,
|
|
1662
1682
|
})
|
|
1663
1683
|
.then(res => {
|
|
@@ -1823,6 +1843,7 @@ class Combination extends AudioCalibrator {
|
|
|
1823
1843
|
* @example
|
|
1824
1844
|
*/
|
|
1825
1845
|
startCalibrationImpulseResponse = async stream => {
|
|
1846
|
+
console.log("JS used memory:", performance.memory.usedJSHeapSize/1024/1024, "mb");
|
|
1826
1847
|
let desired_time = this.desired_time_per_mls;
|
|
1827
1848
|
let checkRec = 'allhz';
|
|
1828
1849
|
|
|
@@ -1845,7 +1866,11 @@ class Combination extends AudioCalibrator {
|
|
|
1845
1866
|
this.addTimeStamp('Get MLS sequence');
|
|
1846
1867
|
if (this.isCalibrating) return null;
|
|
1847
1868
|
await this.pyServerAPI
|
|
1848
|
-
.getMLSWithRetry({
|
|
1869
|
+
.getMLSWithRetry({
|
|
1870
|
+
length,
|
|
1871
|
+
amplitude,
|
|
1872
|
+
calibrateSoundBurstMLSVersions: this.numCaptures
|
|
1873
|
+
})
|
|
1849
1874
|
.then(res => {
|
|
1850
1875
|
console.log(res);
|
|
1851
1876
|
this.#mlsBufferView = res['mls'];
|
|
@@ -1877,18 +1902,21 @@ class Combination extends AudioCalibrator {
|
|
|
1877
1902
|
this.numSuccessfulCaptured = 0;
|
|
1878
1903
|
|
|
1879
1904
|
if (this.isCalibrating) return null;
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
this
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1905
|
+
for (var i = 0; i < this.numCaptures; i++) {
|
|
1906
|
+
this.icapture = i;
|
|
1907
|
+
await this.calibrationSteps(
|
|
1908
|
+
stream,
|
|
1909
|
+
this.#playCalibrationAudio, // play audio func (required)
|
|
1910
|
+
this.#createCalibrationNodeFromBuffer(this.#mlsBufferView[this.icapture]), // before play func
|
|
1911
|
+
this.#awaitSignalOnset, // before record
|
|
1912
|
+
() => this.numSuccessfulCaptured < 1, // loop while true
|
|
1913
|
+
this.#awaitDesiredMLSLength, // during record
|
|
1914
|
+
this.#afterMLSRecord, // after record
|
|
1915
|
+
this.mode,
|
|
1916
|
+
checkRec
|
|
1917
|
+
);
|
|
1918
|
+
this.stopCalibrationAudio();
|
|
1919
|
+
}
|
|
1892
1920
|
checkRec = false;
|
|
1893
1921
|
|
|
1894
1922
|
// at this stage we've captured all the required signals,
|
|
@@ -2222,6 +2250,7 @@ class Combination extends AudioCalibrator {
|
|
|
2222
2250
|
};
|
|
2223
2251
|
|
|
2224
2252
|
startCalibrationVolume = async (stream, gainValues, lCalib, componentGainDBSPL) => {
|
|
2253
|
+
console.log("JS used memory:", performance.memory.usedJSHeapSize/1024/1024, "mb");
|
|
2225
2254
|
if (this.isCalibrating) return null;
|
|
2226
2255
|
const trialIterations = gainValues.length;
|
|
2227
2256
|
this.status_denominator += trialIterations;
|
|
@@ -2231,7 +2260,6 @@ class Combination extends AudioCalibrator {
|
|
|
2231
2260
|
const outDBSPLValues = [];
|
|
2232
2261
|
const outDBSPL1000Values = [];
|
|
2233
2262
|
let checkRec = "loudest";
|
|
2234
|
-
|
|
2235
2263
|
// do one calibration that will be discarded
|
|
2236
2264
|
const soundLevelToDiscard = -60;
|
|
2237
2265
|
const gainToDiscard = Math.pow(10, soundLevelToDiscard / 20);
|
|
@@ -2772,19 +2800,17 @@ class Combination extends AudioCalibrator {
|
|
|
2772
2800
|
});
|
|
2773
2801
|
}
|
|
2774
2802
|
await this.pyServerAPI.checkMemory();
|
|
2775
|
-
let volumeResults = await this.startCalibrationVolume(
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
);
|
|
2781
|
-
if (!volumeResults) return;
|
|
2803
|
+
// let volumeResults = await this.startCalibrationVolume(
|
|
2804
|
+
// stream,
|
|
2805
|
+
// gainValues,
|
|
2806
|
+
// lCalib,
|
|
2807
|
+
// this.componentGainDBSPL
|
|
2808
|
+
// );
|
|
2809
|
+
// if (!volumeResults) return;
|
|
2782
2810
|
|
|
2783
|
-
this.T = volumeResults["parameters"]["T"];
|
|
2784
|
-
this.gainDBSPL = volumeResults["parameters"]["gainDBSPL"];
|
|
2811
|
+
// this.T = volumeResults["parameters"]["T"];
|
|
2812
|
+
// this.gainDBSPL = volumeResults["parameters"]["gainDBSPL"];
|
|
2785
2813
|
|
|
2786
|
-
// console.log("VOLUME RESULTS");
|
|
2787
|
-
// console.log(volumeResults);
|
|
2788
2814
|
let impulseResponseResults = await this.startCalibrationImpulseResponse(stream);
|
|
2789
2815
|
if (!impulseResponseResults) return;
|
|
2790
2816
|
impulseResponseResults['background_noise'] = this.background_noise;
|