speaker-calibration 2.2.245 → 2.2.247
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/example/i18n.js +2294 -2168
- package/dist/listener.js +1 -1
- package/dist/main.js +4 -4
- package/dist/phonePeer.js +1 -1
- package/package.json +1 -1
- package/src/peer-connection/speaker.js +82 -2
- package/src/powerCheck.js +103 -92
- package/src/server/PythonServerAPI.js +45 -1
- package/src/tasks/combination/combination.js +96 -46
package/package.json
CHANGED
|
@@ -141,6 +141,80 @@ class Speaker extends AudioPeer {
|
|
|
141
141
|
return params;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
//no need to connect to the listener, just simulate the calibration
|
|
145
|
+
static simulateCalibration = async (
|
|
146
|
+
params,
|
|
147
|
+
CalibratorInstance,
|
|
148
|
+
connectionManager,
|
|
149
|
+
timeOut = 180000
|
|
150
|
+
) => {
|
|
151
|
+
window.speaker = new Speaker(params, CalibratorInstance, connectionManager);
|
|
152
|
+
const {speaker} = window;
|
|
153
|
+
speaker.ac = CalibratorInstance;
|
|
154
|
+
//set sampling rates
|
|
155
|
+
speaker.ac.setSamplingRates(speaker.calibrateSoundHz);
|
|
156
|
+
speaker.ac.setSampleSize(speaker.calibrateSoundSamplingDesiredBits);
|
|
157
|
+
speaker.result = await speaker.ac.startCalibration(
|
|
158
|
+
null,
|
|
159
|
+
params.gainValues,
|
|
160
|
+
params.ICalib,
|
|
161
|
+
params.knownIR,
|
|
162
|
+
params.microphoneName,
|
|
163
|
+
params.calibrateSoundCheck,
|
|
164
|
+
params.isSmartPhone,
|
|
165
|
+
params.calibrateSoundBurstDb,
|
|
166
|
+
params.calibrateSoundBurstFilteredExtraDb,
|
|
167
|
+
params.calibrateSoundBurstLevelReTBool,
|
|
168
|
+
params.calibrateSoundBurstUses1000HzGainBool,
|
|
169
|
+
params.calibrateSoundBurstRepeats,
|
|
170
|
+
params.calibrateSoundBurstSec,
|
|
171
|
+
params._calibrateSoundBurstPreSec,
|
|
172
|
+
params._calibrateSoundBurstPostSec,
|
|
173
|
+
params.calibrateSoundHz,
|
|
174
|
+
params.calibrateSoundIRSec,
|
|
175
|
+
params.calibrateSoundIIRSec,
|
|
176
|
+
params.calibrateSoundIIRPhase,
|
|
177
|
+
params.calibrateSound1000HzPreSec,
|
|
178
|
+
params.calibrateSound1000HzSec,
|
|
179
|
+
params.calibrateSound1000HzPostSec,
|
|
180
|
+
params.calibrateSoundBackgroundSecs,
|
|
181
|
+
params.calibrateSoundSmoothOctaves,
|
|
182
|
+
params.calibrateSoundSmoothMinBandwidthHz,
|
|
183
|
+
params.calibrateSoundPowerBinDesiredSec,
|
|
184
|
+
params.calibrateSoundPowerDbSDToleratedDb,
|
|
185
|
+
params.calibrateSoundTaperSec,
|
|
186
|
+
params.micManufacturer,
|
|
187
|
+
params.micSerialNumber,
|
|
188
|
+
params.micModelNumber,
|
|
189
|
+
params.micModelName,
|
|
190
|
+
params.calibrateMicrophonesBool,
|
|
191
|
+
params.authorEmails,
|
|
192
|
+
params.webAudioDeviceNames,
|
|
193
|
+
params.IDsToSaveInSoundProfileLibrary,
|
|
194
|
+
params.restartButton,
|
|
195
|
+
params.reminder,
|
|
196
|
+
params.calibrateSoundLimit,
|
|
197
|
+
params.calibrateSoundBurstNormalizeBy1000HzGainBool,
|
|
198
|
+
params.calibrateSoundBurstScalarDB,
|
|
199
|
+
params.calibrateSound1000HzMaxSD_dB,
|
|
200
|
+
params.calibrateSound1000HzMaxTries,
|
|
201
|
+
params._calibrateSoundBurstMaxSD_dB,
|
|
202
|
+
params.calibrateSoundSamplingDesiredBits,
|
|
203
|
+
params.language,
|
|
204
|
+
params.loudspeakerModelName,
|
|
205
|
+
params.phrases,
|
|
206
|
+
params.soundSubtitleId,
|
|
207
|
+
params.calibrateSoundBurstDownsample,
|
|
208
|
+
params.calibrateSoundSimulateMicrophone,
|
|
209
|
+
params.calibrateSoundSimulateMicrophoneTime,
|
|
210
|
+
params.calibrateSoundSimulateLoudspeaker,
|
|
211
|
+
params.calibrateSoundSimulateLoudspeakerTime,
|
|
212
|
+
params.isLoudspeakerCalibration
|
|
213
|
+
);
|
|
214
|
+
speaker.#removeUIElems();
|
|
215
|
+
return speaker.result;
|
|
216
|
+
};
|
|
217
|
+
|
|
144
218
|
/**
|
|
145
219
|
* Async factory method that creates the Speaker object, and returns a promise that resolves to the result of the calibration.
|
|
146
220
|
*
|
|
@@ -270,7 +344,10 @@ class Speaker extends AudioPeer {
|
|
|
270
344
|
params.soundSubtitleId,
|
|
271
345
|
params.calibrateSoundBurstDownsample,
|
|
272
346
|
params.calibrateSoundSimulateMicrophone,
|
|
273
|
-
params.
|
|
347
|
+
params.calibrateSoundSimulateMicrophoneTime,
|
|
348
|
+
params.calibrateSoundSimulateLoudspeaker,
|
|
349
|
+
params.calibrateSoundSimulateLoudspeakerTime,
|
|
350
|
+
params.isLoudspeakerCalibration
|
|
274
351
|
);
|
|
275
352
|
speaker.#removeUIElems();
|
|
276
353
|
//remove the call
|
|
@@ -859,7 +936,10 @@ class Speaker extends AudioPeer {
|
|
|
859
936
|
params.soundSubtitleId,
|
|
860
937
|
params.calibrateSoundBurstDownsample,
|
|
861
938
|
params.calibrateSoundSimulateMicrophone,
|
|
862
|
-
params.
|
|
939
|
+
params.calibrateSoundSimulateMicrophoneTime,
|
|
940
|
+
params.calibrateSoundSimulateLoudspeaker,
|
|
941
|
+
params.calibrateSoundSimulateLoudspeakerTime,
|
|
942
|
+
params.isLoudspeakerCalibration
|
|
863
943
|
);
|
|
864
944
|
clearInterval(permissionCheckInterval);
|
|
865
945
|
window.speaker.#removeUIElems();
|
package/src/powerCheck.js
CHANGED
|
@@ -1,99 +1,110 @@
|
|
|
1
|
-
export const volumePowerCheck = (
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
1
|
+
export const volumePowerCheck = (
|
|
2
|
+
rec,
|
|
3
|
+
fs,
|
|
4
|
+
preSec,
|
|
5
|
+
Sec,
|
|
6
|
+
_calibrateSoundPowerBinDesiredSec,
|
|
7
|
+
postSec
|
|
8
|
+
) => {
|
|
9
|
+
const coarseHz = 1 / _calibrateSoundPowerBinDesiredSec;
|
|
10
|
+
const power = rec.map(x => Math.pow(x, 2)); // Squared values of the signal
|
|
11
|
+
|
|
12
|
+
// Adjust coarseHz so that fs is an integer multiple of coarseHz.
|
|
13
|
+
let n = Math.round(fs / coarseHz);
|
|
14
|
+
|
|
15
|
+
// Sampling times for plotting
|
|
16
|
+
const t = Array.from({length: power.length}, (_, i) => i / fs);
|
|
17
|
+
|
|
18
|
+
const coarseSamples = Math.ceil(power.length / n);
|
|
19
|
+
const coarsePowerDb = new Array(coarseSamples).fill(0);
|
|
20
|
+
const coarseT = new Array(coarseSamples).fill(0);
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < coarseSamples; i++) {
|
|
23
|
+
const indices = Array.from(
|
|
24
|
+
{length: Math.min(n, power.length - i * n)},
|
|
25
|
+
(_, idx) => i * n + idx
|
|
26
|
+
);
|
|
27
|
+
const extremeIndices = [indices[0], indices[indices.length - 1]];
|
|
28
|
+
|
|
29
|
+
const avgPower = indices.reduce((sum, idx) => sum + power[idx], 0) / indices.length;
|
|
30
|
+
coarsePowerDb[i] = 10 * Math.log10(avgPower);
|
|
31
|
+
|
|
32
|
+
const avgTime = (t[extremeIndices[0]] + t[extremeIndices[1]]) / 2;
|
|
33
|
+
coarseT[i] = avgTime;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const prepSamples = Math.round(coarseHz * preSec);
|
|
37
|
+
const postSamples = Math.round(coarseHz * (preSec + Sec));
|
|
38
|
+
const postSamplesEnd = Math.round(coarseHz * (preSec + Sec + postSec));
|
|
39
|
+
const sd = Math.round(standardDeviation(coarsePowerDb.slice(prepSamples)) * 10) / 10;
|
|
40
|
+
|
|
41
|
+
const coarseTRounded = coarseT.map(t => Math.round(t * 1000) / 1000); // Round to 3 decimal places
|
|
42
|
+
const coarsePowerDbRounded = coarsePowerDb.map(db => Math.round(db * 1000) / 1000); // Round to 3 decimal places
|
|
43
|
+
|
|
44
|
+
const start = interpolate(coarseT, coarsePowerDb, preSec);
|
|
45
|
+
const end = interpolate(coarseT, coarsePowerDb, preSec + Sec);
|
|
46
|
+
|
|
47
|
+
let preT = coarseTRounded.slice(0, prepSamples);
|
|
48
|
+
let preDb = coarsePowerDbRounded.slice(0, prepSamples);
|
|
49
|
+
|
|
50
|
+
// Adjust starting point of preT and preDb
|
|
51
|
+
if (preT[preT.length - 1] < preSec) {
|
|
52
|
+
preT.push(preSec);
|
|
53
|
+
preDb.push(start);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let recT = coarseTRounded.slice(prepSamples, postSamples);
|
|
57
|
+
let recDb = coarsePowerDbRounded.slice(prepSamples, postSamples);
|
|
58
|
+
|
|
59
|
+
if (recT[0] > preSec) {
|
|
60
|
+
recT.unshift(preSec);
|
|
61
|
+
recDb.unshift(start);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (recT[recT.length - 1] < preSec + Sec) {
|
|
65
|
+
recT.push(preSec + Sec);
|
|
66
|
+
recDb.push(end);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let postT = coarseTRounded.slice(postSamples, postSamplesEnd);
|
|
70
|
+
let postDb = coarsePowerDbRounded.slice(postSamples, postSamplesEnd);
|
|
71
|
+
|
|
72
|
+
if (postT[0] > preSec + Sec) {
|
|
73
|
+
postT.unshift(preSec + Sec);
|
|
74
|
+
postDb.unshift(end);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {preT, preDb, recT, recDb, postT, postDb, sd};
|
|
78
|
+
};
|
|
68
79
|
|
|
69
80
|
// Helper function for interpolation
|
|
70
81
|
export const interpolate = (x, y, target) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
let lowIdx = 0;
|
|
83
|
+
while (lowIdx < x.length - 1 && x[lowIdx] < target) {
|
|
84
|
+
lowIdx++;
|
|
85
|
+
}
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
const x0 = x[lowIdx - 1];
|
|
88
|
+
const y0 = y[lowIdx - 1];
|
|
89
|
+
const x1 = x[lowIdx];
|
|
90
|
+
const y1 = y[lowIdx];
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
92
|
+
// Linear interpolation
|
|
93
|
+
return y0 + ((target - x0) * (y1 - y0)) / (x1 - x0);
|
|
94
|
+
};
|
|
84
95
|
|
|
85
96
|
// Helper function to calculate standard deviation
|
|
86
|
-
export const standardDeviation =
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export const getPower =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
97
|
+
export const standardDeviation = arr => {
|
|
98
|
+
const mean = arr.reduce((sum, val) => sum + val, 0) / arr.length;
|
|
99
|
+
const variance = arr.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / arr.length;
|
|
100
|
+
return Math.sqrt(variance);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const getPower = dataArray => {
|
|
104
|
+
const squaredValues = dataArray.map(value => value * value);
|
|
105
|
+
const sum_of_squares = squaredValues.reduce((total, value) => total + value, 0);
|
|
106
|
+
const squared_mean = sum_of_squares / dataArray.length;
|
|
107
|
+
const dbLevel = 20 * Math.log10(Math.sqrt(squared_mean));
|
|
108
|
+
const roundedDbLevel = Math.round(dbLevel * 10) / 10;
|
|
109
|
+
return roundedDbLevel;
|
|
110
|
+
};
|
|
@@ -126,6 +126,45 @@ class PythonServerAPI {
|
|
|
126
126
|
return res.data[task];
|
|
127
127
|
};
|
|
128
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
|
+
|
|
129
168
|
getMLS = async ({
|
|
130
169
|
length,
|
|
131
170
|
amplitude,
|
|
@@ -843,7 +882,12 @@ class PythonServerAPI {
|
|
|
843
882
|
})
|
|
844
883
|
.then(response => {
|
|
845
884
|
res = response;
|
|
846
|
-
|
|
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);
|
|
847
891
|
})
|
|
848
892
|
.catch(error => {
|
|
849
893
|
throw error;
|
|
@@ -834,14 +834,18 @@ class Combination extends AudioCalibrator {
|
|
|
834
834
|
payload_skipped_warmUp,
|
|
835
835
|
this._calibrateSoundBurstDownsample
|
|
836
836
|
);
|
|
837
|
+
// console.log('usedPeriodStart', usedPeriodStart);
|
|
838
|
+
// console.log('payload', payload);
|
|
839
|
+
// console.log('payload_skipped_warmUp', payload_skipped_warmUp);
|
|
840
|
+
// console.log('payload_skipped_warmUp_downsampled', payload_skipped_warmUp_downsampled);
|
|
841
|
+
const factor = 1;
|
|
842
|
+
//simulationEnabled ? this._calibrateSoundBurstDownsample : 1;
|
|
837
843
|
await this.pyServerAPI
|
|
838
844
|
.getAutocorrelation({
|
|
839
845
|
mls: mls,
|
|
840
846
|
payload: payload_skipped_warmUp_downsampled,
|
|
841
847
|
sampleRate: fMLS,
|
|
842
|
-
numPeriods:
|
|
843
|
-
(this.numMLSPerCapture - this.num_mls_to_skip) /
|
|
844
|
-
(2 * this._calibrateSoundBurstDownsample),
|
|
848
|
+
numPeriods: (this.numMLSPerCapture - this.num_mls_to_skip) / factor,
|
|
845
849
|
downsample: this._calibrateSoundBurstDownsample,
|
|
846
850
|
})
|
|
847
851
|
.then(async res => {
|
|
@@ -854,9 +858,7 @@ class Combination extends AudioCalibrator {
|
|
|
854
858
|
.getImpulseResponse({
|
|
855
859
|
mls,
|
|
856
860
|
sampleRate: fMLS,
|
|
857
|
-
numPeriods:
|
|
858
|
-
(this.numMLSPerCapture - this.num_mls_to_skip) /
|
|
859
|
-
(2 * this._calibrateSoundBurstDownsample),
|
|
861
|
+
numPeriods: (this.numMLSPerCapture - this.num_mls_to_skip) / factor,
|
|
860
862
|
sig: payload_skipped_warmUp_downsampled,
|
|
861
863
|
fs2: this.fs2,
|
|
862
864
|
L_new_n: this.L_new_n,
|
|
@@ -2759,7 +2761,8 @@ class Combination extends AudioCalibrator {
|
|
|
2759
2761
|
this.sourceSamplingRate || 96000,
|
|
2760
2762
|
this.calibrateSound1000HzPreSec,
|
|
2761
2763
|
this.calibrateSound1000HzSec,
|
|
2762
|
-
this._calibrateSoundPowerBinDesiredSec
|
|
2764
|
+
this._calibrateSoundPowerBinDesiredSec,
|
|
2765
|
+
this.calibrateSound1000HzPostSec
|
|
2763
2766
|
);
|
|
2764
2767
|
console.log(res);
|
|
2765
2768
|
this.recordingChecks['volume'][this.inDB] = res;
|
|
@@ -2821,8 +2824,8 @@ class Combination extends AudioCalibrator {
|
|
|
2821
2824
|
// Run the simulation for initial calibration
|
|
2822
2825
|
await this.simulatedVolumeCalibrationSteps(
|
|
2823
2826
|
calibrationToneSignal,
|
|
2824
|
-
this.
|
|
2825
|
-
this.
|
|
2827
|
+
this.calibrateSoundSimulateLoudspeaker1000Hz,
|
|
2828
|
+
this.calibrateSoundSimulateMicrophone1000Hz,
|
|
2826
2829
|
this.#sendToServerForProcessing,
|
|
2827
2830
|
lCalib,
|
|
2828
2831
|
checkRec
|
|
@@ -2883,8 +2886,8 @@ class Combination extends AudioCalibrator {
|
|
|
2883
2886
|
// Run the simulation for this gain value
|
|
2884
2887
|
await this.simulatedVolumeCalibrationSteps(
|
|
2885
2888
|
calibrationToneSignal,
|
|
2886
|
-
this.
|
|
2887
|
-
this.
|
|
2889
|
+
this.calibrateSoundSimulateLoudspeaker1000Hz,
|
|
2890
|
+
this.calibrateSoundSimulateMicrophone1000Hz,
|
|
2888
2891
|
this.#sendToServerForProcessing,
|
|
2889
2892
|
lCalib,
|
|
2890
2893
|
checkRec
|
|
@@ -3315,7 +3318,10 @@ class Combination extends AudioCalibrator {
|
|
|
3315
3318
|
soundSubtitleId,
|
|
3316
3319
|
calibrateSoundBurstDownsample = 1,
|
|
3317
3320
|
calibrateSoundSimulateMicrophone = null,
|
|
3318
|
-
|
|
3321
|
+
calibrateSoundSimulateMicrophoneTime = null,
|
|
3322
|
+
calibrateSoundSimulateLoudspeaker = null,
|
|
3323
|
+
calibrateSoundSimulateLoudspeakerTime = null,
|
|
3324
|
+
isLoudspeakerCalibration = true
|
|
3319
3325
|
) => {
|
|
3320
3326
|
this._calibrateSoundBurstDownsample = calibrateSoundBurstDownsample;
|
|
3321
3327
|
this._calibrateSoundBurstPreSec = _calibrateSoundBurstPreSec;
|
|
@@ -3361,7 +3367,15 @@ class Combination extends AudioCalibrator {
|
|
|
3361
3367
|
this.calibrateSoundSamplingDesiredBits = calibrateSoundSamplingDesiredBits;
|
|
3362
3368
|
this.phrases = phrases;
|
|
3363
3369
|
this.soundSubtitleId = soundSubtitleId;
|
|
3364
|
-
|
|
3370
|
+
const simulationEnabled =
|
|
3371
|
+
this.calibrateSoundSimulateMicrophone !== null &&
|
|
3372
|
+
this.calibrateSoundSimulateLoudspeaker !== null;
|
|
3373
|
+
//pre + repeats * sec + post
|
|
3374
|
+
const allHzDuation =
|
|
3375
|
+
this._calibrateSoundBurstPreSec +
|
|
3376
|
+
this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec +
|
|
3377
|
+
this._calibrateSoundBurstPostSec;
|
|
3378
|
+
if (isSmartPhone && !simulationEnabled) {
|
|
3365
3379
|
const leftQuote = '\u201C'; // "
|
|
3366
3380
|
const rightQuote = '\u201D'; // "
|
|
3367
3381
|
this.webAudioDeviceNames.microphone = this.deviceInfo.microphoneFromAPI;
|
|
@@ -3412,8 +3426,8 @@ class Combination extends AudioCalibrator {
|
|
|
3412
3426
|
DeviceType: isSmartPhone ? this.deviceInfo.devicetype : 'N/A',
|
|
3413
3427
|
ID_from_51Degrees: isSmartPhone ? this.deviceInfo.DeviceId : 'N/A',
|
|
3414
3428
|
calibrateMicrophonesBool: calibrateMicrophonesBool,
|
|
3415
|
-
screenHeight: this.deviceInfo
|
|
3416
|
-
screenWidth: this.deviceInfo
|
|
3429
|
+
screenHeight: this.deviceInfo?.screenHeight,
|
|
3430
|
+
screenWidth: this.deviceInfo?.screenWidth,
|
|
3417
3431
|
webAudioDeviceNames: {
|
|
3418
3432
|
loudspeaker: this.webAudioDeviceNames.loudspeaker,
|
|
3419
3433
|
microphone: this.webAudioDeviceNames.microphone,
|
|
@@ -3433,40 +3447,76 @@ class Combination extends AudioCalibrator {
|
|
|
3433
3447
|
|
|
3434
3448
|
// this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, 'default');
|
|
3435
3449
|
// this.addMicrophoneInfo(ID, OEM, micInfo);
|
|
3436
|
-
if (
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3450
|
+
if (!simulationEnabled) {
|
|
3451
|
+
if (componentIR == null) {
|
|
3452
|
+
//mode 'ir'
|
|
3453
|
+
//global variable this.componentIR must be set
|
|
3454
|
+
await this.readFrqGainFromFirestore(ID, OEM, true).then(data => {
|
|
3455
|
+
if (data !== null) {
|
|
3456
|
+
this.componentIR = data.ir;
|
|
3457
|
+
micInfo['parentTimestamp'] = data.createDate ? data.createDate : new Date();
|
|
3458
|
+
micInfo['parentFilenameJSON'] = data.jsonFileName ? data.jsonFileName : '';
|
|
3459
|
+
}
|
|
3460
|
+
});
|
|
3446
3461
|
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
+
// await this.readFrqGain(ID, OEM).then(data => {
|
|
3463
|
+
// return data;
|
|
3464
|
+
// });
|
|
3465
|
+
|
|
3466
|
+
// lCalib = await this.readGainat1000Hz(ID, OEM);
|
|
3467
|
+
lCalib = await this.readGainat1000HzFromFirestore(ID, OEM, true);
|
|
3468
|
+
micInfo['gainDBSPL'] = lCalib;
|
|
3469
|
+
// this.componentGainDBSPL = this.convertToDB(lCalib);
|
|
3470
|
+
this.componentGainDBSPL = lCalib;
|
|
3471
|
+
//TODO: if this call to database is unknown, cannot perform experiment => return false
|
|
3472
|
+
if (this.componentIR == null) {
|
|
3473
|
+
this.status =
|
|
3474
|
+
`Microphone (${OEM},${ID}) is not found in the database. Please add it to the database.`.toString();
|
|
3475
|
+
this.emit('update', {message: this.status});
|
|
3476
|
+
return false;
|
|
3477
|
+
}
|
|
3478
|
+
} else {
|
|
3479
|
+
this.transducerType = 'Microphone';
|
|
3480
|
+
this.componentIR = componentIR;
|
|
3481
|
+
lCalib = this.findGainatFrequency(this.componentIR.Freq, this.componentIR.Gain, 1000);
|
|
3482
|
+
// this.componentGainDBSPL = this.convertToDB(lCalib);
|
|
3483
|
+
this.componentGainDBSPL = lCalib;
|
|
3484
|
+
// await this.writeIsSmartPhone(ID, isSmartPhone, OEM);
|
|
3462
3485
|
}
|
|
3463
3486
|
} else {
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3487
|
+
//simulation.
|
|
3488
|
+
const frequencyResponse = await this.pyServerAPI.getFrequencyResponseFromImpulseResponse({
|
|
3489
|
+
impulseResponseMicrophone: this.calibrateSoundSimulateMicrophone,
|
|
3490
|
+
impulseResponseLoudspeaker: this.calibrateSoundSimulateLoudspeaker,
|
|
3491
|
+
sampleRate: this.sourceSamplingRate,
|
|
3492
|
+
timeArray: calibrateSoundSimulateMicrophoneTime,
|
|
3493
|
+
totalDuration: allHzDuation,
|
|
3494
|
+
totalDuration1000Hz: this.CALIBRATION_TONE_DURATION,
|
|
3495
|
+
});
|
|
3496
|
+
this.calibrateSoundSimulateMicrophone = frequencyResponse.impulse_response_microphone;
|
|
3497
|
+
this.calibrateSoundSimulateLoudspeaker = frequencyResponse.impulse_response_loudspeaker;
|
|
3498
|
+
this.calibrateSoundSimulateMicrophone1000Hz =
|
|
3499
|
+
frequencyResponse.impulse_response_1000hz_microphone;
|
|
3500
|
+
this.calibrateSoundSimulateLoudspeaker1000Hz =
|
|
3501
|
+
frequencyResponse.impulse_response_1000hz_loudspeaker;
|
|
3502
|
+
|
|
3503
|
+
if (isLoudspeakerCalibration) {
|
|
3504
|
+
//define this.componentIR, this.componentGainDBSPL
|
|
3505
|
+
this.componentIR = {
|
|
3506
|
+
Freq: frequencyResponse.frequencies_microphone,
|
|
3507
|
+
Gain: frequencyResponse.gains_microphone,
|
|
3508
|
+
};
|
|
3509
|
+
this.componentGainDBSPL = frequencyResponse.gain_at_1000hz_microphone;
|
|
3510
|
+
lCalib = this.componentGainDBSPL;
|
|
3511
|
+
} else {
|
|
3512
|
+
//define this.componentIR, this.componentGainDBSPL
|
|
3513
|
+
this.componentIR = {
|
|
3514
|
+
Freq: frequencyResponse.frequencies_loudspeaker,
|
|
3515
|
+
Gain: frequencyResponse.gains_loudspeaker,
|
|
3516
|
+
};
|
|
3517
|
+
this.componentGainDBSPL = frequencyResponse.gain_at_1000hz_loudspeaker;
|
|
3518
|
+
lCalib = this.componentGainDBSPL;
|
|
3519
|
+
}
|
|
3470
3520
|
}
|
|
3471
3521
|
|
|
3472
3522
|
this.oldComponentIR = JSON.parse(JSON.stringify(this.componentIR));
|