speaker-calibration 2.2.267 → 2.2.268

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 CHANGED
@@ -180,7 +180,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core
180
180
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
181
181
 
182
182
  "use strict";
183
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array-buffer.slice.js */ \"./node_modules/core-js/modules/es.array-buffer.slice.js\");\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.float32-array.js */ \"./node_modules/core-js/modules/es.typed-array.float32-array.js\");\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.typed-array.fill.js */ \"./node_modules/core-js/modules/es.typed-array.fill.js\");\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.typed-array.set.js */ \"./node_modules/core-js/modules/es.typed-array.set.js\");\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.typed-array.sort.js */ \"./node_modules/core-js/modules/es.typed-array.sort.js\");\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../audioCalibrator */ \"./src/tasks/audioCalibrator.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils */ \"./src/utils.js\");\n/* harmony import */ var _powerCheck__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../powerCheck */ \"./src/powerCheck.js\");\n/* harmony import */ var _config_firebase__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../config/firebase */ \"./src/config/firebase.js\");\n/* harmony import */ var firebase_database__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! firebase/database */ \"./node_modules/firebase/database/dist/esm/index.esm.js\");\n/* harmony import */ var firebase_firestore__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! firebase/firestore */ \"./node_modules/firebase/firestore/dist/esm/index.esm.js\");\n\n\n\n\n\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import { phrases } from '../../../dist/example/i18n';\n\n/**\r\n *\r\n */\nvar _download = /*#__PURE__*/new WeakMap();\nvar _mlsGenInterface = /*#__PURE__*/new WeakMap();\nvar _mlsBufferView = /*#__PURE__*/new WeakMap();\nvar _mlsOrder = /*#__PURE__*/new WeakMap();\nvar _lowHz = /*#__PURE__*/new WeakMap();\nvar _highHz = /*#__PURE__*/new WeakMap();\nvar _mls = /*#__PURE__*/new WeakMap();\nvar _P = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_FREQUENCY = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_TYPE = /*#__PURE__*/new WeakMap();\nvar _currentConvolution = /*#__PURE__*/new WeakMap();\nvar _awaitDesiredMLSLength = /*#__PURE__*/new WeakMap();\nvar _awaitBackgroundNoiseRecording = /*#__PURE__*/new WeakMap();\nvar _awaitSignalOnset = /*#__PURE__*/new WeakMap();\nvar _afterMLSRecord = /*#__PURE__*/new WeakMap();\nvar _afterMLSwIIRRecord = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNodeFromBuffer = /*#__PURE__*/new WeakMap();\nvar _setCalibrationNodesFromBuffer = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudio = /*#__PURE__*/new WeakMap();\nvar _getTruncatedSignal = /*#__PURE__*/new WeakMap();\nvar _createCalibrationToneWithGainValue = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNode = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudioVolume = /*#__PURE__*/new WeakMap();\nvar _sendToServerForProcessing = /*#__PURE__*/new WeakMap();\nclass Combination extends _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__[\"default\"] {\n /**\r\n * Default constructor. Creates an instance with any number of paramters passed or the default parameters defined here.\r\n *\r\n * @param {Object<boolean, number, number, number>} calibratorParams - paramter object\r\n * @param {boolean} [calibratorParams.download = false] - boolean flag to download captures\r\n * @param {number} [calibratorParams.mlsOrder = 18] - order of the MLS to be generated\r\n * @param {number} [calibratorParams.numCaptures = 5] - number of captures to perform\r\n * @param {number} [calibratorParams.numMLSPerCapture = 2] - number of bursts of MLS per capture\r\n */\n constructor(_ref) {\n var _this;\n let {\n download = false,\n mlsOrder = 18,\n numCaptures = 3,\n numMLSPerCapture = 2,\n lowHz: _lowHz2 = 20,\n highHz: _highHz2 = 10000\n } = _ref;\n super(numCaptures, numMLSPerCapture);\n _this = this;\n /** @private */\n _defineProperty(this, \"stepNum\", 0);\n /** @private */\n _defineProperty(this, \"totalSteps\", 25);\n /** @private */\n _classPrivateFieldInitSpec(this, _download, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsGenInterface, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsBufferView, void 0);\n /** @private */\n _defineProperty(this, \"componentInvertedImpulseResponse\", null);\n /** @private */\n _defineProperty(this, \"systemInvertedImpulseResponse\", null);\n //averaged and subtracted ir returned from calibration used to calculated iir\n /** @private */\n _defineProperty(this, \"ir\", null);\n /** @private */\n _defineProperty(this, \"impulseResponses\", []);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsOrder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _lowHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _highHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mls, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _P, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _defineProperty(this, \"offsetGainNode\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolutionNoBandpass\", void 0);\n /** @private */\n _defineProperty(this, \"componentIROrigin\", {\n Freq: [],\n Gain: []\n });\n /** @private */\n _defineProperty(this, \"systemConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"systemConvolutionNoBandpass\", void 0);\n ////////////////////////volume\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_FREQUENCY, 1000);\n // Hz\n\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_TYPE, 'sine');\n _defineProperty(this, \"CALIBRATION_TONE_DURATION\", 5);\n // seconds\n _defineProperty(this, \"calibrateSound1000HzPreSec\", 3.5);\n _defineProperty(this, \"calibrateSound1000HzSec\", 1.0);\n _defineProperty(this, \"calibrateSound1000HzPostSec\", 0.5);\n /** @private */\n _defineProperty(this, \"outDBSPL\", null);\n _defineProperty(this, \"THD\", null);\n _defineProperty(this, \"outDBSPL1000\", null);\n /** @private */\n _defineProperty(this, \"TAPER_SECS\", 0.01);\n // seconds\n /** @private */\n _defineProperty(this, \"status_denominator\", 8);\n /** @private */\n _defineProperty(this, \"status_numerator\", 0);\n /** @private */\n _defineProperty(this, \"percent_complete\", 0);\n /** @private */\n _defineProperty(this, \"status\", \"\");\n /**@private */\n _defineProperty(this, \"status_literal\", \"<div style=\\\"display: flex; justify-content: center;\\\"><div style=\\\"width: 200px; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\"));\n /**@private */\n _defineProperty(this, \"componentIR\", null);\n /**@private */\n _defineProperty(this, \"oldComponentIR\", null);\n /**@private */\n _defineProperty(this, \"systemIR\", null);\n /**@private */\n _defineProperty(this, \"_calibrateSoundCheck\", '');\n _defineProperty(this, \"deviceType\", null);\n _defineProperty(this, \"deviceName\", null);\n _defineProperty(this, \"deviceInfo\", null);\n _defineProperty(this, \"desired_time_per_mls\", 0);\n _defineProperty(this, \"num_mls_to_skip\", 0);\n _defineProperty(this, \"desired_sampling_rate\", 0);\n _classPrivateFieldInitSpec(this, _currentConvolution, []);\n _defineProperty(this, \"mode\", 'unfiltered');\n _defineProperty(this, \"sourceNode\", void 0);\n _defineProperty(this, \"autocorrelations\", []);\n _defineProperty(this, \"iirLength\", 0);\n _defineProperty(this, \"irLength\", 0);\n _defineProperty(this, \"calibrateSoundIIRPhase\", 'linear');\n _defineProperty(this, \"componentInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"componentIRInTimeDomain\", []);\n _defineProperty(this, \"systemInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"_calibrateSoundBackgroundSecs\", void 0);\n _defineProperty(this, \"_calibrateSoundSmoothOctaves\", void 0);\n _defineProperty(this, \"background_noise\", {});\n _defineProperty(this, \"numSuccessfulBackgroundCaptured\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstFilteredExtraDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstLevelReTBool\", void 0);\n _defineProperty(this, \"SDofFilteredRange\", {\n mls: undefined,\n component: undefined,\n system: undefined\n });\n _defineProperty(this, \"transducerType\", 'Loudspeaker');\n _defineProperty(this, \"componentIRPhase\", []);\n _defineProperty(this, \"systemIRPhase\", []);\n _defineProperty(this, \"webAudioDeviceNames\", {\n loudspeaker: '',\n microphone: '',\n loudspeakerText: '',\n microphoneText: ''\n });\n _defineProperty(this, \"waveforms\", {\n volume: {}\n });\n _defineProperty(this, \"recordingChecks\", {\n volume: {},\n unfiltered: [],\n system: [],\n component: [],\n warnings: []\n });\n _defineProperty(this, \"inDB\", void 0);\n _defineProperty(this, \"soundCheck\", '');\n _defineProperty(this, \"filteredMLSRange\", {\n component: {\n Min: null,\n Max: null\n },\n system: {\n Min: null,\n Max: null\n }\n });\n /** @private */\n _defineProperty(this, \"timeStamp\", []);\n _defineProperty(this, \"restartCalibration\", false);\n _defineProperty(this, \"calibrateSoundLimit\", 1);\n _defineProperty(this, \"filteredMLSAttenuation\", {\n component: 1,\n system: 1,\n maxAbsSystem: 1,\n maxAbsComponent: 1\n });\n // Generate a signal for the MLS sequence\n _defineProperty(this, \"generateMLSSignal\", (mls, burstDownsample) => {\n // Generate a signal using the MLS sequence, upsampling if needed\n if (burstDownsample > 1) {\n return this.upsampleSignal(mls, burstDownsample);\n }\n return mls;\n });\n // Simulate MLS calibration by convolving with impulse responses\n _defineProperty(this, \"simulatedMLSCalibration\", async (mlsSignal, loudspeakerIR, microphoneIR) => {\n console.log('[SIMULATION] Running MLS impulse response calibration simulation');\n const duration = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n // Convolve MLS with loudspeaker IR and microphone IR\n const simulatedRecording = await this.pyServerAPI.irConvolution({\n input_signal: mlsSignal,\n microphone_ir: microphoneIR,\n loudspeaker_ir: loudspeakerIR,\n duration: duration,\n sample_rate: this.sourceSamplingRate / this._calibrateSoundBurstDownsample\n }).then(res => {\n return res['output_signal'];\n });\n // Save the simulated recording using proper method\n await this.saveUnfilteredRecording(simulatedRecording);\n console.log('simulatedRecording', simulatedRecording.length, this.getAllUnfilteredRecordedSignals().length, microphoneIR.length, loudspeakerIR.length, mlsSignal.length);\n // Process the recording\n await this.sendRecordingToServerForProcessing();\n return simulatedRecording;\n });\n //parameter result from volume calibration\n _defineProperty(this, \"T\", 0);\n //gainDBSPL result from volume calibration\n _defineProperty(this, \"gainDBSPL\", 0);\n //not always just using _calibrateSoundBurstDb for MLS so created a new parameter\n _defineProperty(this, \"power_dB\", 0);\n //system\n _defineProperty(this, \"systemAttenuatorGainDB\", 0);\n _defineProperty(this, \"systemFMaxHz\", 0);\n //component\n _defineProperty(this, \"componentAttentuatorGainDB\", 0);\n _defineProperty(this, \"componentFMaxHz\", 0);\n _defineProperty(this, \"dL_n\", void 0);\n _defineProperty(this, \"L_new_n\", void 0);\n _defineProperty(this, \"fs2\", void 0);\n _defineProperty(this, \"icapture\", 0);\n _defineProperty(this, \"permissionStatus\", null);\n //impulse responses for simulated loudspeaker and microphone\n _defineProperty(this, \"calibrateSoundSimulateMicrophone\", null);\n _defineProperty(this, \"calibrateSoundSimulateLoudspeaker\", null);\n /**generate string template that gets reevaluated as variable increases */\n _defineProperty(this, \"generateTemplate\", status => {\n if (this.isCalibrating) {\n return '';\n }\n if (this.percent_complete > 100) {\n this.percent_complete = 100;\n }\n let MLSsd = '';\n let componentSD = '';\n let systemSD = '';\n let flags = '';\n const soundSubtitle = document.getElementById(this.soundSubtitleId);\n if (soundSubtitle) {\n const reportWebAudioNames = \"\".concat(this.webAudioDeviceNames.loudspeakerText, \"<br/> \").concat(this.webAudioDeviceNames.microphoneText);\n soundSubtitle.innerHTML = reportWebAudioNames;\n }\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n const simulateText = simulationEnabled ? \"\\n Simulating Loudspeaker: \".concat(this.calibrateSoundSimulateLoudspeakerFileName, \", Microphone: \").concat(this.calibrateSoundSimulateMicrophoneFileName, \"\\n <br>\") : '';\n const samplingParamText = this.phrases.RC_SamplingHzBits[this.language].replace('[[N11]]', this.sourceSamplingRate).replace('[[N22]]', this.sinkSamplingRate).replace('[[N33]]', this.calibrateSoundSamplingDesiredBits);\n const reportParameters = \"\".concat(simulateText).concat(samplingParamText, \" \\u2193\").concat(this._calibrateSoundBurstDownsample, \":1\");\n if (this.flags) {\n flags = \"<br> autoGainControl: \".concat(this.flags.autoGainControl, \", echoCancellation: \").concat(this.flags.echoCancellation, \", noiseSuppression: \").concat(this.flags.noiseSuppression);\n }\n if (this.SDofFilteredRange['mls']) {\n MLSsd = \"<br> Record MLS power SD: \".concat(this.SDofFilteredRange['mls'], \" dB\");\n }\n if (this.SDofFilteredRange['system']) {\n systemSD = \"<br> Loudspeaker+Microphone correction SD: \".concat(this.SDofFilteredRange['system'], \" dB\");\n }\n if (this.SDofFilteredRange['component']) {\n componentSD = \"<br> \".concat(this.transducerType, \" correction SD: \").concat(this.SDofFilteredRange['component'], \" dB\");\n }\n const template = \"<div style=\\\"display: flex; justify-content: flex-start; margin-top: 0.4rem;\\\"><div style=\\\"width: 100%; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\");\n return \"\\n \".concat(reportParameters, \" \\n \").concat(MLSsd, \"\\n \").concat(systemSD, \"\\n \").concat(componentSD, \"\\n \").concat(flags, \"\\n <br>\").concat(status, \"\\n \").concat(template);\n });\n /** increment numerator and percent for status bar */\n _defineProperty(this, \"incrementStatusBar\", () => {\n this.status_numerator += 1;\n this.percent_complete = this.status_numerator / this.status_denominator * 100;\n });\n _defineProperty(this, \"setDeviceType\", deviceType => {\n this.deviceType = deviceType;\n });\n _defineProperty(this, \"setDeviceName\", deviceName => {\n this.deviceName = deviceName;\n });\n _defineProperty(this, \"setDeviceInfo\", deviceInfo => {\n this.deviceInfo = deviceInfo;\n });\n _defineProperty(this, \"setPermissionStatus\", permissionStatus => {\n this.permissionStatus = permissionStatus;\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendSystemImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute speaker+mic IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n }); //log any errors that are found in this step\n console.log('filteredComputedIRs', filteredComputedIRs);\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this); //gain of 1 below cutoff, need gain of 0\n const highHz = _classPrivateFieldGet(_highHz, this); //check error for anything other than 10 kHz\n const iirLength = this.iirLength;\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n // const payload_downsampled = filteredComputedIRs_slice.map(ir =>\n // this.downsampleSignal(ir, this._calibrateSoundBurstDownsample)\n // );\n return await this.pyServerAPI.getSystemInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs_slice,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.systemInvertedImpulseResponse = res['iir'];\n this.systemIR = res['ir'];\n this.systemInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.systemAttenuatorGainDB = res['attenuatorGain_dB'];\n this.systemFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.systemInvertedImpulseResponse,\n inverse_response_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.systemAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log(result);\n this.systemConvolution = result['convolution'];\n this.systemConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n\n // attenuate the system convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of system convolution\n\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.systemConvolution);\n this.filteredMLSAttenuation.system = this.systemConvolution.reduce((a, b) => a + b ** 2, 0) / this.systemConvolution.length;\n this.filteredMLSAttenuation.maxAbsSystem = max;\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendComponentImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute speaker or mic IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n });\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n // const payload_downsampled = filteredComputedIRs_slice.map(ir =>\n // this.downsampleSignal(ir, this._calibrateSoundBurstDownsample)\n // );\n let componentIRGains = this.componentIR['Gain'];\n const componentIRFreqs = this.componentIR['Freq'];\n //normalize the component IR gains\n componentIRGains = componentIRGains.map(value => {\n return value - this._calibrateSoundBurstScalarDB - this._calibrateSoundBurstDb;\n });\n if (this._calibrateSoundBurstNormalizeBy1000HzGainBool) {\n const sineGainAt1000Hz_dB = this.gainDBSPL;\n componentIRGains = componentIRGains.map(value => {\n return value - sineGainAt1000Hz_dB;\n });\n }\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this);\n const iirLength = this.iirLength;\n const irLength = this.irLength;\n const highHz = _classPrivateFieldGet(_highHz, this);\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return this.pyServerAPI.getComponentInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs_slice,\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n irLength,\n calibrateSoundSmoothOctaves: this._calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz: this._calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.componentInvertedImpulseResponse = res['iir'];\n this.componentInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.componentIR['Gain'] = res['ir'];\n this.componentIR['Freq'] = res['frequencies'];\n this.componentIRPhase = res['component_angle'];\n this.systemIRPhase = res['system_angle'];\n this.componentIROrigin['Freq'] = res['frequencies'];\n this.componentIROrigin['Gain'] = res['irOrigin'];\n this.componentIRInTimeDomain = res['irTime'];\n this.componentAttenuatorGainDB = res['attenuatorGain_dB'];\n this.componentFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.componentInvertedImpulseResponse,\n inverse_response_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.componentAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log('result', result);\n this.componentConvolution = result['convolution'];\n this.componentConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n // attenuate the component convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of component convolution\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.componentConvolution);\n // if (max > this.calibrateSoundLimit) {\n // const gain = this.calibrateSoundLimit / max;\n // // apply gain to component convolution\n // this.componentConvolution = this.componentConvolution.map(value => value * gain);\n // this.filteredMLSAttenuation.component = gain;\n // }\n this.filteredMLSAttenuation.component = this.componentConvolution.reduce((a, b) => a + b ** 2, 0) / this.componentConvolution.length;\n this.filteredMLSAttenuation.maxAbsComponent = max;\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n });\n /**\r\n * Upsamples a signal by repeating each sample N times\r\n * @param {Array<number>} signal - The input signal to upsample\r\n * @param {number} N - The upsampling factor\r\n * @returns {Array<number>} - The upsampled signal\r\n */\n _defineProperty(this, \"upsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n\n //if signal is an array of arrays, upsample each array individually\n try {\n if (Array.isArray(signal[0])) {\n return signal.map(arr => this.upsampleSignal(arr, N));\n }\n } catch (err) {\n console.error(err);\n return signal;\n }\n const result = [];\n for (let sample of signal) {\n // Repeat each sample N times\n for (let i = 0; i < N; i++) {\n result.push(sample);\n }\n }\n return result;\n });\n /**\r\n * Downsamples a signal by averaging groups of N samples\r\n * @param {Array<number>} signal - The input signal to downsample\r\n * @param {number} N - The downsampling factor\r\n * @returns {Array<number>} - The downsampled signal\r\n */\n _defineProperty(this, \"downsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n\n //if signal is an array of arrays, downsample each array individually\n try {\n if (Array.isArray(signal[0])) {\n return signal.map(arr => this.downsampleSignal(arr, N));\n }\n } catch (err) {\n console.error(err);\n return signal;\n }\n const result = [];\n for (let i = 0; i < signal.length; i += N) {\n const chunk = signal.slice(i, Math.min(i + N, signal.length));\n // Calculate average of the chunk\n const avg = chunk.reduce((sum, val) => sum + val, 0) / chunk.length;\n result.push(avg);\n }\n return result;\n });\n _defineProperty(this, \"sendBackgroundRecording\", () => {\n const allSignals = this.getAllBackgroundRecordings();\n const numSignals = allSignals.length;\n const background_rec_whole = allSignals[numSignals - 1];\n const fraction = 0.5 / (this._calibrateSoundBackgroundSecs + 0.5);\n // Calculate the starting index for slicing the array\n const startIndex = Math.round(fraction * background_rec_whole.length);\n // Slice the array from the calculated start index to the end of the array\n const background_rec = background_rec_whole.slice(startIndex);\n console.log('Sending background recording to server for processing');\n let backgroundSec = this._calibrateSoundBackgroundSecs + 0.5;\n this.addTimeStamp(\"Record \".concat(backgroundSec.toFixed(1), \" s of background.\"));\n const fBackground = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const background_rec_downsampled = this.downsampleSignal(background_rec, this._calibrateSoundBurstDownsample);\n this.pyServerAPI.getBackgroundNoisePSDWithRetry({\n background_rec: background_rec_downsampled,\n sampleRate: fBackground\n }).then(res => {\n if (this.numSuccessfulBackgroundCaptured < 1) {\n this.numSuccessfulBackgroundCaptured += 1;\n //storing all background data in background_psd object\n this.background_noise['x_background'] = res['x_background'];\n this.background_noise['y_background'] = res['y_background'];\n this.background_noise['recording'] = background_rec;\n }\n this.addTimeStamp('Compute spectrum of background');\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends the recorded signal, or a given csv string of a signal, to the back end server for processing\r\n *\r\n * @param {<array>String} signalCsv - Optional csv string of a previously recorded signal, if given, this signal will be processed\r\n * @example\r\n */\n _defineProperty(this, \"sendRecordingToServerForProcessing\", async signalCsv => {\n const allSignals = this.getAllUnfilteredRecordedSignals();\n console.log('Obtaining last all hz unfiltered recording from #allHzUnfilteredRecordings to send to server for processing');\n const numSignals = allSignals.length;\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const payload = signalCsv && signalCsv.length > 0 ? (0,_utils__WEBPACK_IMPORTED_MODULE_8__.csvToArray)(signalCsv) : allSignals[numSignals - 1];\n console.log('sending rec');\n this.stepNum += 1;\n console.log('send rec ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration Step: computing the IR of the last recording...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const payload_downsampled = this.downsampleSignal(payload, this._calibrateSoundBurstDownsample);\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n await this.pyServerAPI.allHzPowerCheck({\n payload: payload_downsampled,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this._calibrateSoundBurstRepeats,\n warmUp: this._calibrateSoundBurstPreSec,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0 && !simulationEnabled) {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"(\".concat(pre.toFixed(1), \" + \").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \" + \").concat(post.toFixed(1), \" s) of MLS ver.\") + \" \".concat(this.icapture, \". SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB));\n this.recordingChecks['unfiltered'].push(result);\n this.recordingChecks['warnings'].push(\"All Hz. Re-record because SD \".concat(result['sd'], \" >\\n \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording because SD \".concat(result['sd'], \" >\\n \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.clearLastUnfilteredRecordedSignals();\n this.numSuccessfulCaptured += 1;\n } else {\n if (result['sd'] <= this._calibrateSoundBurstMaxSD_dB) {\n console.log('SD: ' + result['sd'] + ', less than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"=\".concat(pre.toFixed(1), \"+\").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \"+\").concat(post.toFixed(1), \" s of MLS ver.\") + \" \".concat(this.icapture, \". SD = \").concat(result['sd'], \" <= \").concat(this._calibrateSoundBurstMaxSD_dB));\n } else {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"=\".concat(pre.toFixed(1), \"+\").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \"+\").concat(post.toFixed(1), \" s\") + \"of MLS ver. \".concat(this.icapture, \". SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB));\n }\n if (this.numSuccessfulCaptured == 1) {\n console.log('pop last unfiltered mls volume check');\n this.recordingChecks['unfiltered'].pop();\n }\n this.recordingChecks['unfiltered'].push(result);\n console.log('start calculate impulse response');\n // const usedPeriodStart = this._calibrateSoundBurstPreSec * this.sourceSamplingRate;\n const usedPeriodStart = this.num_mls_to_skip * this.sourceSamplingRate;\n const usedPeriodEnd = (this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec) * this.sourceSamplingRate;\n // const payload_skipped_warmUp = payload.slice(usedPeriodStart, usedPeriodEnd);\n const payload_skipped_warmUp = payload.slice(usedPeriodStart);\n console.log('payload.length', payload.length);\n console.log('usedPeriodStart', usedPeriodStart);\n console.log('usedPeriodEnd', usedPeriodEnd);\n console.log('payload_skipped_warmUp.length', payload_skipped_warmUp.length);\n const payload_skipped_warmUp_downsampled = this.downsampleSignal(payload_skipped_warmUp, this._calibrateSoundBurstDownsample);\n console.log('payload_skipped_warmUp_downsampled', payload_skipped_warmUp_downsampled.length);\n // console.log('usedPeriodStart', usedPeriodStart);\n // console.log('payload', payload);\n // console.log('payload_skipped_warmUp', payload_skipped_warmUp);\n // console.log('payload_skipped_warmUp_downsampled', payload_skipped_warmUp_downsampled);\n const factor = 1;\n //simulationEnabled ? this._calibrateSoundBurstDownsample : 1;\n await this.pyServerAPI.getAutocorrelation({\n mls: mls,\n payload: payload_skipped_warmUp_downsampled,\n sampleRate: fMLS,\n numPeriods: this._calibrateSoundBurstRepeats / factor,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.autocorrelations.push(res['autocorrelation']);\n this.fs2 = res['fs2'];\n this.L_new_n = res['L_new_n'];\n this.dL_n = res['dL_n'];\n this.impulseResponses.push(await this.pyServerAPI.getImpulseResponse({\n mls,\n sampleRate: fMLS,\n numPeriods: this._calibrateSoundBurstRepeats / factor,\n sig: payload_skipped_warmUp_downsampled,\n fs2: this.fs2,\n L_new_n: this.L_new_n,\n dL_n: this.dL_n,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \"/\").concat(this.numCaptures, \" IRs computed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res['ir'];\n }).catch(err => {\n console.error(err);\n }));\n });\n }\n console.log('number of unfiltered recording checks:' + this.recordingChecks['unfiltered'].length);\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /**\r\n * Passed to the calibration steps function, awaits the desired amount of seconds to capture the desired number\r\n * of MLS periods defined in the constructor.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitDesiredMLSLength, async () => {\n // seconds per MLS = P / SR\n // await N * P / SR\n this.stepNum += 1;\n console.log('await desired length ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the calibration signal...\".toString() + \"\\niteration \".concat(this.stepNum));\n this.emit('update', {\n message: this.status\n });\n let time_to_wait = 0;\n if (this.mode === 'unfiltered') {\n //unfiltered\n //should be: pre + (burst * repeats) + post\n // time_to_wait = (this.#mls[0].length / this.sourceSamplingRate) * this.numMLSPerCapture;\n // time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n time_to_wait = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstSec * this._calibrateSoundBurstRepeats + this._calibrateSoundBurstPostSec;\n } else if (this.mode === 'filtered') {\n //filtered\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (this.numMLSPerCapture / (this.num_mls_to_skip + this.numMLSPerCapture));\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) * this.numMLSPerCapture;\n // time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n time_to_wait = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstSec * this._calibrateSoundBurstRepeats + this._calibrateSoundBurstPostSec;\n } else {\n throw new Error('Mode broke in awaitDesiredMLSLength');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /**\r\n * Passed to the background noise recording function, awaits the desired amount of seconds to capture the desired number\r\n * of seconds of background noise\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitBackgroundNoiseRecording, async () => {\n console.log('Waiting ' + this._calibrateSoundBackgroundSecs + ' second(s) to record background noise');\n let time_to_wait = this._calibrateSoundBackgroundSecs + 0.5;\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /** .\r\n * .\r\n * .\r\n * Passed to the calibration steps function, awaits the onset of the signal to ensure a steady state\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitSignalOnset, async () => {\n this.stepNum += 1;\n console.log('await signal onset ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: waiting for the signal to stabilize...\".toString());\n this.emit('update', {\n message: this.status\n });\n let number_of_bursts_to_skip = 0;\n let time_to_sleep = 0;\n if (this.mode === 'unfiltered') {\n time_to_sleep = this._calibrateSoundBurstPreSec;\n } else if (this.mode === 'filtered') {\n console.log(_classPrivateFieldGet(_currentConvolution, this).length);\n // time_to_sleep =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (number_of_bursts_to_skip / (number_of_bursts_to_skip + this.numMLSPerCapture));\n time_to_sleep = _classPrivateFieldGet(_currentConvolution, this).length / this.sourceSamplingRate * number_of_bursts_to_skip;\n } else {\n throw new Error('Mode broke in awaitSignalOnset');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_sleep);\n });\n /**\r\n * Called immediately after a recording is captured. Used to process the resulting signal\r\n * whether by sending the result to a server or by computing a result locally.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _afterMLSRecord, async () => {\n console.log('after record');\n await this.sendRecordingToServerForProcessing();\n });\n _classPrivateFieldInitSpec(this, _afterMLSwIIRRecord, async () => {\n await this.checkPowerVariation();\n });\n /** .\r\n * .\r\n * .\r\n * Created an S Curver Buffer to taper the signal onset\r\n *\r\n * @param {*} onSetBool\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"createSCurveBuffer\", function () {\n let onSetBool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n const curve = new Float32Array(_this.TAPER_SECS * _this.sourceSamplingRate + 1);\n const frequency = 1 / (4 * _this.TAPER_SECS);\n let j = 0;\n for (let i = 0; i < _this.TAPER_SECS * _this.sourceSamplingRate + 1; i += 1) {\n const phase = 2 * Math.PI * frequency * j;\n const onsetTaper = Math.pow(Math.sin(phase), 2);\n const offsetTaper = Math.pow(Math.cos(phase), 2);\n curve[i] = onSetBool ? onsetTaper : offsetTaper;\n j += 1 / _this.sourceSamplingRate;\n }\n return curve;\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @param dataBuffer\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNodeFromBuffer, dataBuffer => {\n const mlsSignal = dataBuffer;\n // reorderMLS(\n // dataBuffer,\n // this.calibrateSound1000HzPreSec,\n // this.sourceSamplingRate\n // );\n console.log('length databuffer');\n console.log(mlsSignal.length);\n if (!this.sourceAudioContext) {\n this.makeNewSourceAudioContext();\n }\n const buffer = this.sourceAudioContext.createBuffer(1,\n // number of channels\n mlsSignal.length, this.sourceAudioContext.sampleRate // sample rate\n );\n const data = buffer.getChannelData(0); // get data\n\n // fill the buffer with our data\n try {\n for (let i = 0; i < mlsSignal.length; i += 1) {\n data[i] = mlsSignal[i];\n }\n } catch (error) {\n console.error(error);\n }\n this.sourceNode = this.sourceAudioContext.createBufferSource();\n this.sourceNode.buffer = buffer;\n if (this.mode === 'filtered') {\n //used to not loop filtered\n this.sourceNode.loop = true;\n } else {\n this.sourceNode.loop = true;\n }\n this.sourceNode.connect(this.sourceAudioContext.destination);\n this.addCalibrationNode(this.sourceNode);\n });\n /**\r\n * Given a data buffer, creates the required calibration node\r\n *\r\n * @param {*} dataBufferArray\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setCalibrationNodesFromBuffer, function () {\n let dataBufferArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [_classPrivateFieldGet(_mlsBufferView, _this)[_this.icapture]];\n if (dataBufferArray.length === 1) {\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, _this).call(_this, dataBufferArray[0]);\n } else {\n throw new Error('The length of the data buffer array must be 1');\n }\n });\n /**\r\n * Creates an audio context and plays it for a few seconds.\r\n *\r\n * @private\r\n * @returns - Resolves when the audio is done playing.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _playCalibrationAudio, () => {\n this.calibrationNodes[0].start(0);\n this.status = \"\";\n if (this.mode === 'unfiltered') {\n console.log('play calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: playing the calibration tone...\".toString()).toString();\n } else if (this.mode === 'filtered') {\n console.log('play convolved audio ' + this.stepNum);\n this.status = this.generateTemplate().toString(\"All Hz Calibration: playing the convolved calibration tone...\".toString());\n } else {\n throw new Error('Mode is incorrect');\n }\n this.emit('update', {\n message: this.status\n });\n this.stepNum += 1;\n console.log('sink sampling rate');\n console.log(this.sinkSamplingRate);\n console.log('source sampling rate');\n console.log(this.sourceSamplingRate);\n console.log('sample size');\n console.log(this.sampleSize);\n });\n /** .\r\n * .\r\n * .\r\n * Stops the audio with tapered offset\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"stopCalibrationAudio\", () => {\n if (this.calibrationNodes.length === 0) {\n return;\n }\n this.calibrationNodes[0].stop(0);\n this.calibrationNodes = [];\n if (this.sourceNode) this.sourceNode.disconnect();\n this.stepNum += 1;\n console.log('stop calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: stopping the calibration tone...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"playMLSwithIIR\", async (stream, convolution) => {\n let checkRec = false;\n this.mode = 'filtered';\n console.log('play mls with iir');\n //this.invertedImpulseResponse = iir\n\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, convolution),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2, _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSwIIRRecord, this),\n // after record\n this.mode, checkRec);\n });\n /**\r\n * Simulates playing convolved MLS with IIR and recording the result\r\n * @param {Array<number>} convolution - The convolved MLS signal\r\n * @param {Array<number>} loudspeakerIR - The loudspeaker impulse response\r\n * @param {Array<number>} microphoneIR - The microphone impulse response\r\n * @returns {Promise<void>}\r\n */\n _defineProperty(this, \"simulatePlayMLSwithIIR\", async (convolution, loudspeakerIR, microphoneIR) => {\n console.log('[SIMULATION] Simulate playing MLS with IIR');\n this.mode = 'filtered';\n const duration = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n // Further convolve with loudspeaker and microphone IRs to simulate recording\n const simulatedRecording = await this.pyServerAPI.irConvolution({\n input_signal: convolution,\n loudspeaker_ir: loudspeakerIR,\n microphone_ir: microphoneIR,\n duration: duration,\n sample_rate: this.sourceSamplingRate / this._calibrateSoundBurstDownsample\n }).then(res => {\n return res['output_signal'];\n });\n\n // Save the simulated recording\n await this.saveFilteredRecording(simulatedRecording);\n this.numSuccessfulCaptured = 2; // Mark as successfully captured to avoid retries\n\n // Process the recording\n await this.checkPowerVariation();\n this.stepNum += 1;\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration [SIMULATION]: Filtered recording processed...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"bothSoundCheck\", async stream => {\n let iir_ir_and_plots;\n\n // Check if simulation is enabled\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode for component check\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let component_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n component_conv_recs = component_conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let return_component_conv_rec = component_conv_recs[component_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n this.numSuccessfulCaptured = 0;\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'speakerAndMic';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode for system check\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let system_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n system_conv_recs = system_conv_recs.map(rec => {\n return rec.map(value => value / linearScaleAttenuation);\n });\n }\n let return_system_conv_rec = system_conv_recs[system_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n if (simulationEnabled) {\n console.log('[SIMULATION] Processing simulated recordings');\n } else {\n this.sourceAudioContext.close();\n }\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = component_conv_recs[component_conv_recs.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n //psd of component\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute spectrum of MLS recording');\n if (this.isCalibrating) return null;\n let component_unconv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered recording (speaker or mic)');\n if (this.isCalibrating) return null;\n let component_conv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.componentFMaxHz);\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n conv_rec = system_conv_recs[system_conv_recs.length - 1];\n //psd of system\n this.addTimeStamp('Compute spectrum of filtered recording (speaker+mic) and unfiltered recording');\n if (this.isCalibrating) return null;\n let system_recs_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls_psd', this.SDofFilteredRange['mls']);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd. done\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[0], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker+mic)');\n if (this.isCalibrating) return null;\n let system_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let system_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker or mic)');\n if (this.isCalibrating) return null;\n let component_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let component_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n filtered_recording: {\n component: return_component_conv_rec,\n system: return_system_conv_rec\n },\n unfiltered_recording: this.getAllUnfilteredRecordedSignals()[0],\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: system_filtered_mls_psd['x_mls'],\n y: system_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: system_no_bandpass_filtered_mls_psd['x_mls'],\n y: system_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: system_recs_psd['x_unconv'],\n y: system_recs_psd['y_unconv']\n },\n conv: {\n x: system_recs_psd['x_conv'],\n y: system_recs_psd['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: component_filtered_mls_psd['x_mls'],\n y: component_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: component_no_bandpass_filtered_mls_psd['x_mls'],\n y: component_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: component_unconv_rec_psd['x'],\n y: component_unconv_rec_psd['y']\n },\n conv: {\n x: component_conv_rec_psd['x'],\n y: component_conv_rec_psd['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n return iir_ir_and_plots;\n });\n _defineProperty(this, \"singleSoundCheck\", async stream => {\n let iir_ir_and_plots;\n\n // Check if simulation is enabled\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (this._calibrateSoundCheck != 'speakerAndMic') {\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n } else {\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'speakerAndMic';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n }\n let conv_recs = this.getAllFilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'speakerOrMic') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'speakerOrMic') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n this.clearAllFilteredRecordedSignals();\n console.log('Obtaining unfiltered recording from #allHzUnfilteredRecordings to calculate spectrum');\n console.log('Obtaining filtered recording from #allHzFilteredRecordings to calculate spectrum');\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = conv_recs[conv_recs.length - 1];\n let return_conv_rec = conv_rec;\n if (simulationEnabled) {\n console.log('[SIMULATION] Processing simulated recordings');\n } else {\n this.sourceAudioContext.close();\n }\n if (this._calibrateSoundCheck != 'speakerAndMic') {\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute spectrum of MLS recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let unconv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n console.log(res);\n let mls_psd = res.y.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls sd', this.SDofFilteredRange['mls']);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker+mic IIR-filtered MLS recording');\n if (this.isCalibrating) return null;\n let conv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= _classPrivateFieldGet(_highHz, this));\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker or mic');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: unconv_results['x'],\n y: unconv_results['y']\n },\n conv: {\n x: conv_results['x'],\n y: conv_results['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n } else {\n this.addTimeStamp('Compute spectrum of filtered recording (speaker+mic) and unfiltered recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let results = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker+mic)');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: results['x_unconv'],\n y: results['y_unconv']\n },\n conv: {\n x: results['x_conv'],\n y: results['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n }\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n this.downloadSingleUnfilteredRecording();\n this.downloadSingleFilteredRecording();\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n return iir_ir_and_plots;\n });\n /**\r\n * Public method to start the calibration process. Objects intialized from webassembly allocate new memory\r\n * and must be manually freed. This function is responsible for intializing the MlsGenInterface,\r\n * and wrapping the calibration steps with a garbage collection safe gaurd.\r\n *\r\n * @public\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startCalibrationImpulseResponse\", async stream => {\n let desired_time = this.desired_time_per_mls;\n let checkRec = 'allhz';\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n console.log('MLS sequence should be of length: ' + fMLS * desired_time);\n length = fMLS * desired_time;\n this.power_dB = 0;\n if (!this._calibrateSoundBurstLevelReTBool) {\n this.power_dB = this._calibrateSoundBurstDb;\n } else {\n this.power_dB = this._calibrateSoundBurstDb + (this.T - this.gainDBSPL);\n }\n const amplitude = Math.pow(10, this.power_dB / 20) / Math.SQRT2;\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getMLSWithRetry({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions: this.numCaptures,\n calibrateSoundBurstDownsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n console.log(res);\n _classPrivateFieldSet(_mlsBufferView, this, this.upsampleSignal(res['mls'], this._calibrateSoundBurstDownsample));\n _classPrivateFieldSet(_mls, this, this.upsampleSignal(res['unscaledMLS'], this._calibrateSoundBurstDownsample));\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute MLS sequence');\n this.numSuccessfulBackgroundCaptured = 0;\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (this._calibrateSoundBackgroundSecs > 0 && !simulationEnabled) {\n this.mode = 'background';\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the background noise...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n await this.recordBackground(stream,\n //stream\n () => this.numSuccessfulBackgroundCaptured < 1,\n //loop condition\n _classPrivateFieldGet(_awaitBackgroundNoiseRecording, this),\n //sleep to record\n this.sendBackgroundRecording,\n //send to get PSD\n this.mode, checkRec);\n this.incrementStatusBar();\n }\n this.mode = 'unfiltered';\n this.numSuccessfulCaptured = 0;\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n console.log('[SIMULATION] Using simulation mode for MLS calibration');\n\n // Run simulation for each capture\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n if (this.isCalibrating) return null;\n // From Denis July 20th, 2025:\n // Imagine playing the 10 s MLS, repeatedly, forever, and we record part of it. That piece should be\n // 2.5+10+10+1 second long. To synthesize this, the pre-interval should be the final 2.5 sec of MLS.\n // Followed by two whole MLS. Followed by the initial 1 sec of MLS. Again, all the pieces together\n // should be one contiguous piece cut out from an infinitely repeating MLS.\n // Get the MLS signal for this capture\n const mlsSignal = _classPrivateFieldGet(_mlsBufferView, this)[this.icapture];\n // reorderMLS(\n // this.#mlsBufferView[this.icapture],\n // this.calibrateSound1000HzPreSec,\n // this.sourceSamplingRate\n // );\n\n // Run the simulation\n await this.simulatedMLSCalibration(mlsSignal, this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n this.stepNum += 1;\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration [SIMULATION]: \".concat(i + 1, \"/\").concat(this.numCaptures, \" simulated captures processed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n } else {\n // Use actual recording mode\n\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, _classPrivateFieldGet(_mlsBufferView, this)[this.icapture]),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2,\n // loop while true\n _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSRecord, this),\n // after record\n this.mode, checkRec);\n this.stopCalibrationAudio();\n }\n }\n checkRec = false;\n\n // at this stage we've captured all the required signals,\n // and have received IRs for each one\n // so let's send all the IRs to the server to be converted to a single IIR\n if (this.isCalibrating) return null;\n await this.sendSystemImpulseResponsesToServerForProcessing();\n await this.pyServerAPI.checkMemory();\n if (this.isCalibrating) return null;\n await this.sendComponentImpulseResponsesToServerForProcessing();\n this.numSuccessfulCaptured = 0;\n let iir_ir_and_plots;\n if (this._calibrateSoundCheck != 'none') {\n //do single check\n if (this._calibrateSoundCheck == 'speakerOrMic' || this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.singleSoundCheck(stream);\n if (this.isCalibrating) return null;\n } else {\n //both\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.bothSoundCheck(stream);\n if (this.isCalibrating) return null;\n }\n\n // } else {\n // let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n // let conv_rec = this.componentInvertedImpulseResponse;\n // if (this.isCalibrating) return null;\n // let component_iir_psd = await this.pyServerAPI\n // .getPSDWithRetry({\n // unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n // conv_rec: this.componentInvertedImpulseResponse,\n // sampleRate: fMLS,\n // downsample: this._calibrateSoundBurstDownsample,\n // })\n // .then(res => {\n // this.incrementStatusBar();\n // this.status = this.generateTemplate(\n // `All Hz Calibration: done computing the PSD graphs...`.toString()\n // ).toString();\n // this.emit('update', {message: this.status});\n // return res;\n // })\n // .catch(err => {\n // console.error(err);\n // });\n // unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n // conv_rec = this.systemInvertedImpulseResponse;\n // if (this.isCalibrating) return null;\n // let system_iir_psd = await this.pyServerAPI\n // .getPSDWithRetry({\n // unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n // conv_rec: this.systemInvertedImpulseResponse,\n // sampleRate: fMLS,\n // downsample: this._calibrateSoundBurstDownsample,\n // })\n // .then(res => {\n // this.incrementStatusBar();\n // this.status = this.generateTemplate(\n // `All Hz Calibration: done computing the PSD graphs...`.toString()\n // ).toString();\n // this.emit('update', {message: this.status});\n // return res;\n // })\n // .catch(err => {\n // console.error(err);\n // });\n\n // let gainValue = this.getGainDBSPL();\n // let return_unconv_rec = unconv_rec;\n // let return_conv_rec = conv_rec;\n // iir_ir_and_plots = {\n // unfiltered_recording: return_unconv_rec,\n // filtered_recording: return_conv_rec,\n // system: {\n // iir: this.systemInvertedImpulseResponse,\n // iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n // ir: this.systemIR,\n // iir_psd: {\n // y: system_iir_psd['y_conv'],\n // x: system_iir_psd['y_conv'],\n // y_no_bandpass: system_iir_psd['y_unconv'],\n // x_no_bandpass: system_iir_psd['x_unconv'],\n // },\n // filtered_recording: [],\n // convolution: this.systemConvolution,\n // convolutionNoBandpass: this.systemConvolutionNoBandpass,\n // psd: {\n // unconv: {\n // x: [],\n // y: [],\n // },\n // conv: {\n // x: [],\n // y: [],\n // },\n // },\n // },\n // component: {\n // iir: this.componentInvertedImpulseResponse,\n // iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n // ir: this.componentIR,\n // ir_in_time_domain: this.componentIRInTimeDomain,\n // iir_psd: {\n // y: component_iir_psd['y_conv'],\n // x: component_iir_psd['x_conv'],\n // y_no_bandpass: component_iir_psd['y_unconv'],\n // x_no_bandpass: component_iir_psd['x_unconv'],\n // },\n // convolution: this.componentConvolution,\n // convolutionNoBandpass: this.componentConvolutionNoBandpass,\n // psd: {\n // unconv: {\n // x: [],\n // y: [],\n // },\n // conv: {\n // x: [],\n // y: [],\n // },\n // },\n // gainDBSPL: gainValue,\n // },\n // mls: this.#mlsBufferView,\n // autocorrelations: this.autocorrelations,\n // impulseResponses: [],\n // };\n // if (this.isCalibrating) return null;\n // await Promise.all(this.impulseResponses).then(res => {\n // for (let i = 0; i < res.length; i++) {\n // if (res[i] != undefined) {\n // iir_ir_and_plots['impulseResponses'].push(res[i]);\n // }\n // }\n // });\n\n // if (this.#download) {\n // saveToCSV(this.#mls, 'MLS.csv');\n // saveToCSV(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n // saveToCSV(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n // saveToCSV(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n // saveToCSV(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n // for (let i = 0; i < this.autocorrelations.length; i++) {\n // saveToCSV(this.autocorrelations[i], `autocorrelation_${i}`);\n // }\n // const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n // for (let i = 0; i < res.length; i++) {\n // if (res[i] != undefined) {\n // saveToCSV(res[i], `IR_${i}`);\n // }\n // }\n // });\n // }\n // }\n } else {\n let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n let conv_rec = this.componentInvertedImpulseResponse;\n let return_unconv_rec = unconv_rec;\n let return_conv_rec = conv_rec;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\").toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\").toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n autocorrelations: this.autocorrelations,\n impulseResponses: [] // filled below\n };\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(resArray => {\n for (let i = 0; i < resArray.length; i++) {\n if (resArray[i] != undefined) {\n iir_ir_and_plots.impulseResponses.push(resArray[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n await Promise.all(this.impulseResponses).then(resArray => {\n for (let i = 0; i < resArray.length; i++) {\n if (resArray[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(resArray[i], \"IR_\".concat(i));\n }\n }\n });\n }\n }\n if (this.isCalibrating) return null;\n this.percent_complete = 100;\n this.status = this.generateTemplate(\"All Hz Calibration: Finished\".toString()).toString();\n this.addTimeStamp('Plot results');\n this.emit('update', {\n message: this.status\n });\n console.log('irr_ir_and_plots for none: ', iir_ir_and_plots);\n return iir_ir_and_plots;\n });\n //////////////////////volume\n _defineProperty(this, \"handleIncomingData\", data => {\n console.log('Received data: ', data);\n if (data.type === 'soundGainDBSPL') {\n this.soundGainDBSPL = data.value;\n } else {\n throw new Error(\"Unknown data type: \".concat(data.type));\n }\n });\n _classPrivateFieldInitSpec(this, _getTruncatedSignal, function () {\n let left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3.5;\n let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4.5;\n const start = Math.floor(left * _this.sourceSamplingRate);\n const end = Math.floor(right * _this.sourceSamplingRate);\n const result = Array.from(_this.getLastVolumeRecordedSignal().slice(start, end));\n console.log('Obtaining last 1000 hz recording from #allVolumeRecordings to send for processing');\n /**\r\n * function to check that capture was properly made\r\n * @param {*} list\r\n */\n const checkResult = list => {\n const setItem = new Set(list);\n if (setItem.size === 1 && setItem.has(0)) {\n console.warn('The last capture failed, all recorded signal is zero', _this.getAllVolumeRecordedSignals());\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n if (setItem.size === 0) {\n console.warn('The last capture failed, no recorded signal');\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n };\n checkResult(result);\n return result;\n });\n /** \r\n * \r\n * \r\n Construct a calibration Node with the calibration parameters and given gain value\r\n * @param {*} gainValue\r\n * */\n _classPrivateFieldInitSpec(this, _createCalibrationToneWithGainValue, gainValue => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n const taperGainNode = audioContext.createGain();\n const offsetGainNode = audioContext.createGain();\n const totalDuration = this.CALIBRATION_TONE_DURATION;\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n // Multiply by sqrt(2) so that requested dB (based on RMS) maps to oscillator peak\n gainNode.gain.value = gainValue * Math.SQRT2;\n oscilator.connect(gainNode);\n gainNode.connect(taperGainNode);\n const onsetCurve = this.createSCurveBuffer();\n taperGainNode.gain.setValueCurveAtTime(onsetCurve, 0, this.TAPER_SECS);\n taperGainNode.connect(offsetGainNode);\n const offsetCurve = this.createSCurveBuffer(false);\n offsetGainNode.gain.setValueCurveAtTime(offsetCurve, totalDuration - this.TAPER_SECS, this.TAPER_SECS);\n offsetGainNode.connect(audioContext.destination);\n const gainValuesOverTime = [];\n const sampleRate = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // Number of samples per second\n const interval = 1 / sampleRate; // Time between samples\n\n for (let t = 0; t <= totalDuration; t += interval) {\n let gainValueAtTime = gainValue;\n\n // Apply the onset curve\n if (t < this.TAPER_SECS) {\n const onsetIndex = Math.floor(t / this.TAPER_SECS * onsetCurve.length);\n gainValueAtTime *= onsetCurve[onsetIndex];\n }\n\n // Apply the offset curve\n if (t > totalDuration - this.TAPER_SECS) {\n const offsetTime = t - (totalDuration - this.TAPER_SECS);\n const offsetIndex = Math.floor(offsetTime / this.TAPER_SECS * offsetCurve.length);\n gainValueAtTime *= offsetCurve[offsetIndex];\n }\n gainValuesOverTime.push(gainValueAtTime);\n }\n this.waveforms['volume'][this.inDB] = gainValuesOverTime;\n this.addCalibrationNode(oscilator);\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNode, () => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = 0.04;\n oscilator.connect(gainNode);\n gainNode.connect(audioContext.destination);\n this.addCalibrationNode(oscilator);\n });\n _classPrivateFieldInitSpec(this, _playCalibrationAudioVolume, async () => {\n if (this.numCalibratingRoundsCompleted == 1) {\n this.recordingChecks['warnings'].push(\"1000Hz. Re-record \".concat(this.inDB, \" dB because SD \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\"));\n const currentStatus = \"1000 Hz: Re-recording at \".concat(this.inDB, \" dB because SD \\n \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \\n \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\").toString();\n this.status = this.generateTemplate(currentStatus).toString();\n this.emit('update', {\n message: this.status\n });\n }\n const totalDuration = this.CALIBRATION_TONE_DURATION;\n console.log('this.calibrationNodes', this.calibrationNodes);\n this.calibrationNodes[0].start(0);\n this.calibrationNodes[0].stop(totalDuration);\n console.log(\"Playing a buffer of \".concat(this.CALIBRATION_TONE_DURATION, \" seconds of audio\"));\n console.log(\"Waiting a total of \".concat(totalDuration, \" seconds\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(totalDuration);\n });\n _defineProperty(this, \"stopCalibrationAudioVolume\", () => {\n if (this.calibrationNodes.length > 0) {\n this.calibrationNodes[0].stop();\n }\n this.calibrationNodes = [];\n });\n _classPrivateFieldInitSpec(this, _sendToServerForProcessing, async lCalib => {\n console.log('Sending data to server');\n let left = this.calibrateSound1000HzPreSec;\n let right = this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec;\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getVolumeCalibration({\n sampleRate: this.sourceSamplingRate,\n payload: _classPrivateFieldGet(_getTruncatedSignal, this).call(this, left, right),\n lCalib: lCalib\n }).then(res => {\n //if res is undefined, throw an error\n if (res === undefined) {\n throw new Error('No response from server in getVolumeCalibration function. Please try again.');\n }\n console.log('res', res);\n if (this.outDBSPL === null) {\n this.incrementStatusBar();\n this.outDBSPL = res['outDbSPL'];\n this.outDBSPL1000 = res['outDbSPL1000'];\n this.THD = res['thd'];\n }\n }).catch(err => {\n console.warn(err);\n });\n const rec = this.getLastVolumeRecordedSignal();\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(0, this.calibrateSound1000HzPreSec * this.sourceSamplingRate)).toFixed(1));\n console.log('used period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(this.calibrateSound1000HzPreSec * this.sourceSamplingRate, (this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n console.log('post period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice((this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n const res = (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.volumePowerCheck)(rec, this.sourceSamplingRate || 96000, this.calibrateSound1000HzPreSec, this.calibrateSound1000HzSec, this._calibrateSoundPowerBinDesiredSec, this.calibrateSound1000HzPostSec);\n console.log(res);\n this.recordingChecks['volume'][this.inDB] = res;\n console.log('Recording checks in sendToServer', this.recordingChecks['volume']);\n const getSD = () => this.recordingChecks['volume'][this.inDB]['sd'];\n // const getSDMessage = () => {\n // //SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB. SD = 1.3 dB\n // // And reporting each rejected recording as\n // // SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB, SD = 19.7 > 4 dB.\n\n // if (this.numCalibratingRoundsCompleted == 1)\n // return `. SD = ${getSD()} > ${this.calibrateSound1000HzMaxSD_dB} dB.`;\n // return `. SD = ${getSD()} dB`;\n // };\n // const total_dur =\n // this.calibrateSound1000HzPreSec +\n // this.calibrateSound1000HzSec +\n // this.calibrateSound1000HzPostSec;\n\n // this.addTimeStamp(\n // `${this.calibrateSound1000HzPreSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzPostSec.toFixed(1)} s.` +\n // `1000 Hz at ${this.inDB} dB${getSDMessage()}`\n // );\n });\n _defineProperty(this, \"startCalibrationVolume\", async (stream, gainValues, lCalib, componentGainDBSPL) => {\n if (this.isCalibrating) return null;\n const trialIterations = gainValues.length;\n this.status_denominator += trialIterations;\n const thdValues = [];\n const inDBValues = [];\n let inDB = 0;\n const outDBSPLValues = [];\n const outDBSPL1000Values = [];\n let checkRec = 'loudest';\n // do one calibration that will be discarded\n const soundLevelToDiscard = -60;\n const gainToDiscard = Math.pow(10, soundLevelToDiscard / 20);\n this.inDB = soundLevelToDiscard;\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(soundLevelToDiscard, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.startTime = new Date().getTime();\n this.calibrationNodes = [];\n\n // Check if simulation is enabled (both impulse responses are available)\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (simulationEnabled) {\n console.log('Using simulation mode with provided impulse responses');\n // Generate the calibration tone signal for simulation\n const calibrationToneSignal = this.generateCalibrationToneSignal(gainToDiscard);\n\n // Run the simulation for initial calibration\n await this.simulatedVolumeCalibrationSteps(calibrationToneSignal, this.calibrateSoundSimulateLoudspeaker1000Hz, this.calibrateSoundSimulateMicrophone1000Hz, _classPrivateFieldGet(_sendToServerForProcessing, this), lCalib, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } else {\n // Use actual recording mode\n do {\n console.log('while loop');\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainToDiscard, lCalib,\n //todo make this a class parameter\n checkRec, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n }\n\n //reset the values\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n\n // run the calibration at different gain values provided by the user\n for (let i = 0; i < trialIterations; i++) {\n //convert gain to DB and add to inDB\n if (i == trialIterations - 1) {\n checkRec = 'loudest';\n }\n inDB = Math.log10(gainValues[i]) * 20;\n // precision to 1 decimal place\n inDB = Math.round(inDB * 10) / 10;\n this.inDB = inDB;\n inDBValues.push(inDB);\n console.log('next update');\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(inDB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (simulationEnabled) {\n console.log('simulationEnabled', gainValues[i]);\n // Generate the calibration tone signal for current gain value\n const calibrationToneSignal = this.generateCalibrationToneSignal(gainValues[i]);\n\n // Run the simulation for this gain value\n await this.simulatedVolumeCalibrationSteps(calibrationToneSignal, this.calibrateSoundSimulateLoudspeaker1000Hz, this.calibrateSoundSimulateMicrophone1000Hz, _classPrivateFieldGet(_sendToServerForProcessing, this), lCalib, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } else {\n // Use actual recording mode\n do {\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainValues[i], lCalib,\n //todo make this a class parameter\n checkRec, () => {\n var _this$recordingChecks;\n return ((_this$recordingChecks = this.recordingChecks) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks['volume']) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks[this.inDB]) === null || _this$recordingChecks === void 0 ? void 0 : _this$recordingChecks['sd']) || 0;\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n }\n outDBSPL1000Values.push(this.outDBSPL1000);\n thdValues.push(this.THD);\n outDBSPLValues.push(this.outDBSPL);\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n }\n if (this.isCalibrating) return null;\n // get the volume calibration parameters from the server\n this.addTimeStamp('Compute 1000 Hz calibration parameters');\n console.log('inDBValues', inDBValues);\n console.log('outDBSPL1000Values', outDBSPL1000Values);\n console.log('lCalib', lCalib);\n console.log('componentGainDBSPL', componentGainDBSPL);\n const parameters = await this.pyServerAPI.getVolumeCalibrationParameters({\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPL1000Values,\n lCalib: lCalib,\n componentGainDBSPL\n }).then(res => {\n this.incrementStatusBar();\n return res;\n }).catch(err => {\n throw err;\n });\n if (this.isCalibrating) return null;\n const result = {\n parameters: parameters,\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPLValues,\n outDBSPL1000Values: outDBSPL1000Values,\n thdValues: thdValues\n };\n return result;\n });\n _defineProperty(this, \"writeFrqGainToFirestore\", async (speakerID, frq, gain, OEM, documentID) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n // const sampledFrq = [];\n // const sampledGain = [];\n // for (let i = 0; i < frq.length; i += 100) {\n // sampledFrq.push(frq[i]);\n // sampledGain.push(gain[i]);\n // }\n\n const data = {\n Freq: frq,\n Gain: gain\n };\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n linear: data\n });\n\n // divide frq and gain into smaller chunks and write to firestore one chunk at a time\n // use arrayUnion to append to the array\n // const chunkSize = 600;\n // const chunkedFrq = [];\n // const chunkedGain = [];\n // for (let i = 0; i < frq.length; i += chunkSize) {\n // chunkedFrq.push(frq.slice(i, i + chunkSize));\n // chunkedGain.push(gain.slice(i, i + chunkSize));\n // }\n // const docRef = doc(database, 'Microphones', documentID);\n // for (let i = 0; i < chunkedFrq.length; i++) {\n // await updateDoc(docRef, {\n // linear: {\n // Freq: arrayUnion(...chunkedFrq[i]),\n // Gain: arrayUnion(...chunkedGain[i]),\n // },\n // });\n // }\n });\n // function to write frq and gain to firebase database given speakerID\n _defineProperty(this, \"writeFrqGain\", async (speakerID, frq, gain, OEM) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n\n const sampledFrq = [];\n const sampledGain = [];\n for (let i = 0; i < frq.length; i += 100) {\n sampledFrq.push(frq[i]);\n sampledGain.push(gain[i]);\n }\n const data = {\n Freq: sampledFrq,\n Gain: sampledGain\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")), data);\n });\n // Function to Read frq and gain from firebase database given speakerID\n // returns an array of frq and gain if speakerID exists, returns null otherwise\n _defineProperty(this, \"readFrqGainFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the linear field of the first document\n if (querySnapshot.size > 0) {\n const timestamp = new firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.Timestamp(querySnapshot.docs[0].data().createDate.seconds, querySnapshot.docs[0].data().createDate.nanoseconds);\n return {\n ir: querySnapshot.docs[0].data().linear,\n createDate: timestamp.toDate(),\n jsonFileName: querySnapshot.docs[0].data().jsonFileName\n };\n }\n return null;\n });\n _defineProperty(this, \"readFrqGain\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000HzFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the Gain1000 field of the first document\n if (querySnapshot.size > 0) {\n return querySnapshot.docs[0].data().Gain1000;\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000Hz\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"writeGainat1000HzToFirestore\", async (speakerID, gain, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n Gain1000: gain\n });\n });\n _defineProperty(this, \"writeGainat1000Hz\", async (speakerID, gain, OEM) => {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")), gain);\n });\n _defineProperty(this, \"writeIsSmartPhoneToFirestore\", async (speakerID, isSmartPhone, OEM) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', true));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n if (querySnapshot.size > 0) {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: false\n });\n return docRef.id;\n } else {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: true\n });\n return docRef.id;\n }\n });\n _defineProperty(this, \"writeIsSmartPhone\", async (speakerID, isSmartPhone, OEM) => {\n const data = {\n isSmartPhone: isSmartPhone\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/isSmartPhone\")), isSmartPhone);\n });\n _defineProperty(this, \"writeMicrophoneInfoToFirestore\", async (speakerID, micInfo, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.setDoc)(docRef, micInfo, {\n merge: true\n });\n });\n _defineProperty(this, \"doesMicrophoneExistInFirestore\", async (speakerID, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphone', OEM, speakerID, documentID);\n const docSnap = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDoc)(docRef);\n if (docSnap.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"doesMicrophoneExist\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID)));\n if (snapshot.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"addMicrophoneInfo\", async (speakerID, OEM, micInfo) => {\n // add to database if /info does not exist\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")));\n if (!snapshot.exists()) {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")), micInfo);\n }\n });\n _defineProperty(this, \"convertToDB\", gain => {\n return Math.log10(gain) * 20;\n });\n _defineProperty(this, \"findGainatFrequency\", (frequencies, gains, targetFrequency) => {\n // Find the index of the first frequency in the array greater than the target frequency\n let index = 0;\n while (index < frequencies.length && frequencies[index] < targetFrequency) {\n index++;\n }\n\n // Handle cases when the target frequency is outside the range of the given data\n if (index === 0) {\n return gains[0];\n } else if (index === frequencies.length) {\n return gains[gains.length - 1];\n } else {\n // Interpolate the gain based on the surrounding frequencies\n const x0 = frequencies[index - 1];\n const y0 = gains[index - 1];\n const x1 = frequencies[index];\n const y1 = gains[index];\n return this.interpolate(targetFrequency, x0, y0, x1, y1);\n }\n });\n _defineProperty(this, \"checkPowerVariation\", async () => {\n let recordings = this.getAllFilteredRecordedSignals();\n // remove filteredMLSAttenuation from the recordings\n\n // recordings = recordings.map(recording => {\n // if (this.soundCheck == 'component') {\n // return recording.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return recording.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n const rec = recordings[recordings.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const payload_downsampled = this.downsampleSignal(rec, this._calibrateSoundBurstDownsample);\n await this.pyServerAPI.allHzPowerCheck({\n payload: payload_downsampled,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this._calibrateSoundBurstRepeats,\n warmUp: this._calibrateSoundBurstPreSec,\n downsample: this._calibrateSoundBurstDownsample\n }).then(result => {\n if (result) {\n const total_dur = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n let soundCheckLabel;\n if (this.soundCheck === 'component') {\n soundCheckLabel = 'speaker or mic';\n } else if (this.soundCheck === 'speakerAndMic') {\n soundCheckLabel = 'speaker+mic';\n } else {\n soundCheckLabel = this.soundCheck;\n }\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(soundCheckLabel, \" IIR. SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.recordingChecks['warnings'].push(\"All Hz. Re-record \".concat(this.inDB, \" because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n // numSuccessfulCaptured no longer to count number of successful capture but count attemps\n // is sd below _calibrateSoundBurstMaxSD_dB then count two attemps\n // else count one attemp\n this.numSuccessfulCaptured += 1;\n } else {\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(soundCheckLabel, \" IIR. SD = \").concat(result['sd'], \" \").concat(result['sd'] > this._calibrateSoundBurstMaxSD_dB ? '>' : '<=', \" \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n console.log('this.recordingChecks: ', this.recordingChecks);\n console.log('this.soundCheck: ', this.soundCheck);\n if (this.recordingChecks[this.soundCheck]) {\n this.recordingChecks[this.soundCheck].push(result);\n } else {\n this.recordingChecks[this.soundCheck] = [result];\n }\n // Now we do at most 2 attempts if sd > _calibrateSoundBurstMaxSD_dB\n // Second attempt is the final\n if (this.numSuccessfulCaptured < 2) {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n this.incrementStatusBar();\n console.log('after mls w iir record for some reason add numSucc capt ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \" recording of convolved MLS captured\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n }\n }\n });\n });\n _defineProperty(this, \"getGainDBSPL\", () => {\n var freqIndex = this.componentIR.Freq.indexOf(1000);\n\n // If freqIndex is not -1 (meaning 1000 is found in the freq array)\n if (freqIndex !== -1) {\n // Get the corresponding gain value using the index\n var gainValue = this.componentIR.Gain[freqIndex];\n return gainValue;\n } else {\n console.log('Freq 1000 not found in the array.');\n return null;\n }\n });\n // Example of how to use the writeFrqGain and readFrqGain functions\n // writeFrqGain('speaker1', [1, 2, 3], [4, 5, 6]);\n // Speaker1 is the speakerID you want to write to in the database\n // readFrqGain('MiniDSPUMIK_1').then(data => console.log(data));\n // MiniDSPUMIK_1 is the speakerID with some Data in the database\n //adding gainDBSPL\n _defineProperty(this, \"startCalibration\", async function (stream, gainValues) {\n var _this$deviceInfo, _this$deviceInfo2;\n let lCalib = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 104.92978421490648;\n let componentIR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n let microphoneName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'MiniDSP-UMIK1-711-4754-vertical';\n let _calibrateSoundCheck = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'speakerOrMic';\n let isSmartPhone = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;\n let _calibrateSoundBurstDb = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : -18;\n let _calibrateSoundBurstFilteredExtraDb = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 6;\n let _calibrateSoundBurstLevelReTBool = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;\n let _calibrateSoundBurstUses1000HzGainBool = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let _calibrateSoundBurstRepeats = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : 3;\n let _calibrateSoundBurstSec = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : 1;\n let _calibrateSoundBurstPreSec = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : 1;\n let _calibrateSoundBurstPostSec = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : 1;\n let _calibrateSoundHz = arguments.length > 15 && arguments[15] !== undefined ? arguments[15] : 48000;\n let _calibrateSoundIRSec = arguments.length > 16 && arguments[16] !== undefined ? arguments[16] : 0.2;\n let _calibrateSoundIIRSec = arguments.length > 17 && arguments[17] !== undefined ? arguments[17] : 0.2;\n let _calibrateSoundIIRPhase = arguments.length > 18 && arguments[18] !== undefined ? arguments[18] : 'linear';\n let calibrateSound1000HzPreSec = arguments.length > 19 && arguments[19] !== undefined ? arguments[19] : 0.5;\n let calibrateSound1000HzSec = arguments.length > 20 && arguments[20] !== undefined ? arguments[20] : 0.5;\n let calibrateSound1000HzPostSec = arguments.length > 21 && arguments[21] !== undefined ? arguments[21] : 0.5;\n let _calibrateSoundBackgroundSecs = arguments.length > 22 && arguments[22] !== undefined ? arguments[22] : 0;\n let _calibrateSoundSmoothOctaves = arguments.length > 23 && arguments[23] !== undefined ? arguments[23] : 0.33;\n let _calibrateSoundSmoothMinBandwidthHz = arguments.length > 24 && arguments[24] !== undefined ? arguments[24] : 200;\n let _calibrateSoundPowerBinDesiredSec = arguments.length > 25 && arguments[25] !== undefined ? arguments[25] : 0.2;\n let _calibrateSoundPowerDbSDToleratedDb = arguments.length > 26 && arguments[26] !== undefined ? arguments[26] : 1;\n let _calibrateSoundTaperSec = arguments.length > 27 && arguments[27] !== undefined ? arguments[27] : 0.01;\n let micManufacturer = arguments.length > 28 && arguments[28] !== undefined ? arguments[28] : '';\n let micSerialNumber = arguments.length > 29 && arguments[29] !== undefined ? arguments[29] : '';\n let micModelNumber = arguments.length > 30 && arguments[30] !== undefined ? arguments[30] : '';\n let micModelName = arguments.length > 31 && arguments[31] !== undefined ? arguments[31] : '';\n let calibrateMicrophonesBool = arguments.length > 32 ? arguments[32] : undefined;\n let authorEmails = arguments.length > 33 ? arguments[33] : undefined;\n let webAudioDeviceNames = arguments.length > 34 && arguments[34] !== undefined ? arguments[34] : {\n loudspeaker: 'loudspeaker',\n microphone: 'microphone',\n microphoneText: 'xxx XXX'\n };\n let userIDs = arguments.length > 35 ? arguments[35] : undefined;\n let restartButton = arguments.length > 36 ? arguments[36] : undefined;\n let reminder = arguments.length > 37 ? arguments[37] : undefined;\n let calibrateSoundLimit = arguments.length > 38 ? arguments[38] : undefined;\n let _calibrateSoundBurstNormalizeBy1000HzGainBool = arguments.length > 39 && arguments[39] !== undefined ? arguments[39] : false;\n let _calibrateSoundBurstScalarDB = arguments.length > 40 && arguments[40] !== undefined ? arguments[40] : 71;\n let calibrateSound1000HzMaxSD_dB = arguments.length > 41 && arguments[41] !== undefined ? arguments[41] : 4;\n let calibrateSound1000HzMaxTries = arguments.length > 42 && arguments[42] !== undefined ? arguments[42] : 4;\n let _calibrateSoundBurstMaxSD_dB = arguments.length > 43 && arguments[43] !== undefined ? arguments[43] : 4;\n let calibrateSoundSamplingDesiredBits = arguments.length > 44 && arguments[44] !== undefined ? arguments[44] : 24;\n let language = arguments.length > 45 ? arguments[45] : undefined;\n let loudspeakerModelName = arguments.length > 46 && arguments[46] !== undefined ? arguments[46] : '';\n let phrases = arguments.length > 47 ? arguments[47] : undefined;\n let soundSubtitleId = arguments.length > 48 ? arguments[48] : undefined;\n let calibrateSoundBurstDownsample = arguments.length > 49 && arguments[49] !== undefined ? arguments[49] : 1;\n let calibrateSoundSimulateMicrophone = arguments.length > 50 && arguments[50] !== undefined ? arguments[50] : null;\n let calibrateSoundSimulateMicrophoneTime = arguments.length > 51 && arguments[51] !== undefined ? arguments[51] : null;\n let calibrateSoundSimulateLoudspeaker = arguments.length > 52 && arguments[52] !== undefined ? arguments[52] : null;\n let calibrateSoundSimulateLoudspeakerTime = arguments.length > 53 && arguments[53] !== undefined ? arguments[53] : null;\n let calibrateSoundSimulateMicrophoneFrequencies = arguments.length > 54 && arguments[54] !== undefined ? arguments[54] : null;\n let calibrateSoundSimulateLoudspeakerFrequencies = arguments.length > 55 && arguments[55] !== undefined ? arguments[55] : null;\n let calibrateSoundSimulateMicrophoneType = arguments.length > 56 && arguments[56] !== undefined ? arguments[56] : 'impulseResponse';\n let calibrateSoundSimulateLoudspeakerType = arguments.length > 57 && arguments[57] !== undefined ? arguments[57] : 'impulseResponse';\n let calibrateSoundSimulateMicrophoneFileName = arguments.length > 58 && arguments[58] !== undefined ? arguments[58] : null;\n let calibrateSoundSimulateLoudspeakerFileName = arguments.length > 59 && arguments[59] !== undefined ? arguments[59] : null;\n let isLoudspeakerCalibration = arguments.length > 60 && arguments[60] !== undefined ? arguments[60] : true;\n _this._calibrateSoundBurstDownsample = calibrateSoundBurstDownsample;\n _this._calibrateSoundBurstPreSec = _calibrateSoundBurstPreSec;\n _this._calibrateSoundBurstRepeats = _calibrateSoundBurstRepeats;\n _this._calibrateSoundBurstSec = _calibrateSoundBurstSec;\n _this.micModelName = micModelName;\n _this.loudspeakerModelName = loudspeakerModelName;\n _this.language = language;\n _this.TAPER_SECS = _calibrateSoundTaperSec;\n _this.calibrateSoundLimit = calibrateSoundLimit;\n _this._calibrateSoundBurstDb = _calibrateSoundBurstDb;\n _this._calibrateSoundBurstFilteredExtraDb = _calibrateSoundBurstFilteredExtraDb;\n _this._calibrateSoundBurstLevelReTBool = _calibrateSoundBurstLevelReTBool;\n _this.CALIBRATION_TONE_DURATION = calibrateSound1000HzPreSec + calibrateSound1000HzSec + calibrateSound1000HzPostSec;\n _this.calibrateSound1000HzPreSec = calibrateSound1000HzPreSec;\n _this.calibrateSound1000HzSec = calibrateSound1000HzSec;\n _this.calibrateSound1000HzPostSec = calibrateSound1000HzPostSec;\n\n // Set simulation impulse responses\n _this.calibrateSoundSimulateMicrophone = calibrateSoundSimulateMicrophone;\n _this.calibrateSoundSimulateLoudspeaker = calibrateSoundSimulateLoudspeaker;\n _this.calibrateSoundSimulateMicrophoneFileName = calibrateSoundSimulateMicrophoneFileName;\n _this.calibrateSoundSimulateLoudspeakerFileName = calibrateSoundSimulateLoudspeakerFileName;\n const fMLS = _this.sourceSamplingRate / _this._calibrateSoundBurstDownsample;\n _this.iirLength = Math.floor(_calibrateSoundIIRSec * fMLS);\n _this.irLength = Math.floor(_calibrateSoundIRSec * fMLS);\n _this.calibrateSoundIIRPhase = _calibrateSoundIIRPhase;\n _this.num_mls_to_skip = Math.ceil(_calibrateSoundBurstPreSec / _calibrateSoundBurstSec);\n _this._calibrateSoundBurstPostSec = _calibrateSoundBurstPostSec;\n _this.numMLSPerCapture = _calibrateSoundBurstRepeats + _this.num_mls_to_skip;\n _this.desired_time_per_mls = _calibrateSoundBurstSec;\n _this.desired_sampling_rate = _calibrateSoundHz;\n _this._calibrateSoundBackgroundSecs = _calibrateSoundBackgroundSecs;\n _this._calibrateSoundSmoothOctaves = _calibrateSoundSmoothOctaves;\n _this._calibrateSoundSmoothMinBandwidthHz = _calibrateSoundSmoothMinBandwidthHz;\n _this._calibrateSoundPowerBinDesiredSec = _calibrateSoundPowerBinDesiredSec;\n _this._calibrateSoundBurstUses1000HzGainBool = _calibrateSoundBurstUses1000HzGainBool;\n _this._calibrateSoundPowerDbSDToleratedDb = _calibrateSoundPowerDbSDToleratedDb;\n _this._calibrateSoundBurstNormalizeBy1000HzGainBool = _calibrateSoundBurstNormalizeBy1000HzGainBool;\n _this._calibrateSoundBurstScalarDB = _calibrateSoundBurstScalarDB;\n _this.webAudioDeviceNames = webAudioDeviceNames;\n _this.calibrateSoundSamplingDesiredBits = calibrateSoundSamplingDesiredBits;\n _this.phrases = phrases;\n _this.soundSubtitleId = soundSubtitleId;\n const simulationEnabled = _this.calibrateSoundSimulateMicrophone !== null && _this.calibrateSoundSimulateLoudspeaker !== null;\n //pre + repeats * sec + post\n const allHzDuation = _this._calibrateSoundBurstPreSec + _this._calibrateSoundBurstRepeats * _this._calibrateSoundBurstSec + _this._calibrateSoundBurstPostSec;\n\n //feed calibration goal here\n _this._calibrateSoundCheck = _calibrateSoundCheck;\n _this.calibrateSound1000HzMaxSD_dB = calibrateSound1000HzMaxSD_dB;\n _this.calibrateSound1000HzMaxTries = calibrateSound1000HzMaxTries;\n _this._calibrateSoundBurstMaxSD_dB = _calibrateSoundBurstMaxSD_dB;\n _this.simulatedMicrophoneIR = null;\n _this.simulatedLoudspeakerIR = null;\n //check if a componentIR was given to the system, if it isn't check for the microphone. using dummy data here bc we need to\n //check the db based on the microphone currently connected\n\n //new lCalib found at top of calibration files *1000hz, make sure to correct\n //based on zeroing of 1000hz, search for \"*1000Hz\"\n const ID = isSmartPhone ? micModelNumber : micSerialNumber;\n const OEM = isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'minidsp' : _this.deviceInfo.OEM ? _this.deviceInfo.OEM.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('');\n // const ID = \"712-5669\";\n // const OEM = \"minidsp\";\n const micInfo = {\n micModelName: isSmartPhone ? micModelName : microphoneName,\n OEM: isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'miniDSP' : _this.deviceInfo.OEM : micManufacturer,\n ID: ID,\n createDate: new Date(),\n DateText: (0,_utils__WEBPACK_IMPORTED_MODULE_8__.getCurrentTimeString)(),\n HardwareName: isSmartPhone ? _this.deviceInfo.hardwarename : microphoneName,\n hardwareFamily: isSmartPhone ? _this.deviceInfo.hardwarefamily : microphoneName,\n HardwareModel: isSmartPhone ? _this.deviceInfo.hardwaremodel : microphoneName,\n PlatformName: isSmartPhone ? _this.deviceInfo.platformname : 'N/A',\n PlatformVersion: isSmartPhone ? _this.deviceInfo.platformversion : 'N/A',\n DeviceType: isSmartPhone ? _this.deviceInfo.devicetype : 'N/A',\n ID_from_51Degrees: isSmartPhone ? _this.deviceInfo.DeviceId : 'N/A',\n calibrateMicrophonesBool: calibrateMicrophonesBool,\n screenHeight: (_this$deviceInfo = _this.deviceInfo) === null || _this$deviceInfo === void 0 ? void 0 : _this$deviceInfo.screenHeight,\n screenWidth: (_this$deviceInfo2 = _this.deviceInfo) === null || _this$deviceInfo2 === void 0 ? void 0 : _this$deviceInfo2.screenWidth,\n webAudioDeviceNames: {\n loudspeaker: _this.webAudioDeviceNames.loudspeaker,\n microphone: _this.webAudioDeviceNames.microphone\n },\n userIDs: userIDs,\n lowercaseOEM: OEM ? OEM.toLowerCase().split(' ').join('') : ''\n };\n if (calibrateMicrophonesBool) {\n micInfo['authorEmails'] = authorEmails;\n }\n // if undefined in micInfo, set to empty string\n for (const [key, value] of Object.entries(micInfo)) {\n if (value === undefined) {\n micInfo[key] = '';\n }\n }\n\n // this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, 'default');\n // this.addMicrophoneInfo(ID, OEM, micInfo);\n if (!simulationEnabled) {\n if (componentIR == null) {\n //mode 'ir'\n //global variable this.componentIR must be set\n await _this.readFrqGainFromFirestore(ID, OEM, true).then(data => {\n if (data !== null) {\n _this.componentIR = data.ir;\n micInfo['parentTimestamp'] = data.createDate ? data.createDate : new Date();\n micInfo['parentFilenameJSON'] = data.jsonFileName ? data.jsonFileName : '';\n }\n });\n\n // await this.readFrqGain(ID, OEM).then(data => {\n // return data;\n // });\n\n // lCalib = await this.readGainat1000Hz(ID, OEM);\n lCalib = await _this.readGainat1000HzFromFirestore(ID, OEM, true);\n micInfo['gainDBSPL'] = lCalib;\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n //TODO: if this call to database is unknown, cannot perform experiment => return false\n if (_this.componentIR == null) {\n _this.status = \"Microphone (\".concat(OEM, \",\").concat(ID, \") is not found in the database. Please add it to the database.\").toString();\n _this.emit('update', {\n message: _this.status\n });\n return false;\n }\n } else {\n _this.transducerType = 'Microphone';\n _this.componentIR = componentIR;\n lCalib = _this.findGainatFrequency(_this.componentIR.Freq, _this.componentIR.Gain, 1000);\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n // await this.writeIsSmartPhone(ID, isSmartPhone, OEM);\n }\n } else {\n //simulation.\n if (calibrateSoundSimulateMicrophoneType === 'impulseResponse') {\n const frequencyResponse = await _this.pyServerAPI.getFrequencyResponseFromImpulseResponse({\n impulseResponse: _this.calibrateSoundSimulateMicrophone,\n sampleRate: _this.sourceSamplingRate,\n timeArray: calibrateSoundSimulateMicrophoneTime,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n _this.calibrateSoundSimulateMicrophone = frequencyResponse.impulse_response;\n _this.calibrateSoundSimulateMicrophone1000Hz = frequencyResponse.impulse_response_1000hz;\n _this.simulatedMicrophoneIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n if (isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n _this.componentGainDBSPL = frequencyResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n micInfo['gainDBSPL'] = lCalib;\n }\n } else {\n const impulseResponse = await _this.pyServerAPI.getImpulseResponseFromFrequencyResponse({\n frequencies: calibrateSoundSimulateMicrophoneFrequencies,\n gains: _this.calibrateSoundSimulateMicrophone,\n sample_rate: _this.sourceSamplingRate,\n iir_length: _this.iirLength,\n calibrateSoundIIRPhase: _this.calibrateSoundIIRPhase,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n if (isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.componentGainDBSPL = impulseResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n micInfo['gainDBSPL'] = lCalib;\n }\n _this.simulatedMicrophoneIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.calibrateSoundSimulateMicrophone = impulseResponse.impulse_response;\n _this.calibrateSoundSimulateMicrophone1000Hz = impulseResponse.impulse_response_1000hz;\n }\n if (calibrateSoundSimulateLoudspeakerType === 'impulseResponse') {\n const frequencyResponse = await _this.pyServerAPI.getFrequencyResponseFromImpulseResponse({\n impulseResponse: _this.calibrateSoundSimulateLoudspeaker,\n sampleRate: _this.sourceSamplingRate,\n timeArray: calibrateSoundSimulateLoudspeakerTime,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n if (!isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n _this.componentGainDBSPL = frequencyResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n }\n _this.calibrateSoundSimulateLoudspeaker = frequencyResponse.impulse_response;\n _this.calibrateSoundSimulateLoudspeaker1000Hz = frequencyResponse.impulse_response_1000hz;\n _this.simulatedLoudspeakerIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n } else {\n const impulseResponse = await _this.pyServerAPI.getImpulseResponseFromFrequencyResponse({\n frequencies: calibrateSoundSimulateLoudspeakerFrequencies,\n gains: _this.calibrateSoundSimulateLoudspeaker,\n sample_rate: _this.sourceSamplingRate,\n iir_length: _this.iirLength,\n calibrateSoundIIRPhase: _this.calibrateSoundIIRPhase,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n _this.simulatedLoudspeakerIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n if (!isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.componentGainDBSPL = impulseResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n }\n _this.calibrateSoundSimulateLoudspeaker = impulseResponse.impulse_response;\n _this.calibrateSoundSimulateLoudspeaker1000Hz = impulseResponse.impulse_response_1000hz;\n }\n }\n _this.oldComponentIR = JSON.parse(JSON.stringify(_this.componentIR));\n return await new Promise(async (resolve, reject) => {\n // add event listner to params.restartButton to resolve the promise with a string: 'restart'\n\n if (reminder) {\n reminder.style.display = '';\n }\n if (restartButton) {\n restartButton.style.display = '';\n restartButton.addEventListener('click', () => {\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n restartButton.style.display = 'none';\n if (reminder) {\n reminder.style.display = 'none';\n }\n _this.emit('update', {\n message: 'Restarting calibration...'\n });\n resolve('restart');\n });\n }\n await _this.pyServerAPI.checkMemory();\n // calibrate volume\n\n let volumeResults = await _this.startCalibrationVolume(stream, gainValues, lCalib, _this.componentGainDBSPL);\n if (!volumeResults) return;\n _this.T = volumeResults['parameters']['T'];\n _this.gainDBSPL = volumeResults['parameters']['gainDBSPL'];\n\n // end calibrate volume\n\n let impulseResponseResults = await _this.startCalibrationImpulseResponse(stream);\n if (!impulseResponseResults) return;\n impulseResponseResults['background_noise'] = _this.background_noise;\n impulseResponseResults['system']['background_noise'] = _this.background_noise;\n impulseResponseResults['component']['background_noise'] = _this.background_noise;\n\n //attenuate system background noise\n if (_this.systemAttenuatorGainDB != 0 && impulseResponseResults['system']['background_noise']['recording'] && impulseResponseResults['system']['background_noise']['x_background'] && impulseResponseResults['system']['background_noise']['y_background']) {\n let linearScaleAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 10);\n impulseResponseResults['system']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['system']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['system']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n //attenuate component background noise\n if (_this.componentAttentuatorGainDB != 0 && impulseResponseResults['component']['background_noise']['recording'] && impulseResponseResults['component']['background_noise']['x_background'] && impulseResponseResults['component']['background_noise']['y_background']) {\n let linearScaleAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 10);\n impulseResponseResults['component']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['component']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['component']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n impulseResponseResults['system']['attenuatorGainDB'] = _this.systemAttenuatorGainDB;\n impulseResponseResults['component']['attenuatorGainDB'] = _this.componentAttenuatorGainDB;\n impulseResponseResults['system']['fMaxHz'] = _this.systemFMaxHz;\n impulseResponseResults['component']['fMaxHz'] = _this.componentFMaxHz;\n impulseResponseResults['L_new_n'] = _this.L_new_n;\n impulseResponseResults['fs2'] = _this.fs2;\n impulseResponseResults['fMLS'] = _this.sourceSamplingRate / _this._calibrateSoundBurstDownsample;\n if (componentIR != null) {\n var _impulseResponseResul;\n // I corrected microphone/loudpeaker IR scale in easyeyes,\n // but since we write microphone IR to firestore here\n // we need to correct microphone IR here\n let correctGain = Math.round((volumeResults.parameters.gainDBSPL - _this.componentGainDBSPL) * 10) / 10;\n let IrFreq = impulseResponseResults === null || impulseResponseResults === void 0 ? void 0 : impulseResponseResults.component.ir.Freq.map(freq => Math.round(freq));\n let IrGain = impulseResponseResults === null || impulseResponseResults === void 0 || (_impulseResponseResul = impulseResponseResults.component) === null || _impulseResponseResul === void 0 ? void 0 : _impulseResponseResul.ir.Gain;\n const IrGainAt1000Hz = IrGain[IrFreq.findIndex(freq => freq === 1000)];\n const difference = Math.round(10 * (IrGainAt1000Hz - correctGain)) / 10;\n IrGain = IrGain.map(gain => gain - difference);\n micInfo['mls'] = Number(_this.SDofFilteredRange['mls']);\n micInfo['systemCorrectionSD'] = Number(_this.SDofFilteredRange['system']);\n micInfo['componentCorrectionSD'] = Number(_this.SDofFilteredRange['component']);\n console.log(typeof micInfo['componentCorrectionSD']);\n // const id = await this.writeIsSmartPhoneToFirestore(ID, isSmartPhone, OEM);\n // await this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, id);\n // await this.writeFrqGainToFirestore(ID, IrFreq, IrGain, OEM, id);\n // micInfo['gainDBSPL'] = impulseResponseResults.component.gainDBSPL;\n // await this.writeGainat1000HzToFirestore(ID, micInfo['gainDBSPL'], OEM, id);\n // await this.writeGainat1000Hz(ID, micInfo['gainDBSPL'], OEM);\n }\n const total_results = {\n ...volumeResults,\n ...impulseResponseResults\n };\n total_results['filteredMLSRange'] = _this.filteredMLSRange;\n total_results['filteredMLSAttenuation'] = _this.filteredMLSAttenuation;\n total_results['micInfo'] = micInfo;\n total_results['audioInfo'] = {};\n total_results['audioInfo']['sinkSampleRate'] = _this.sinkSamplingRate;\n total_results['audioInfo']['sourceSampleRate'] = _this.sourceSamplingRate;\n total_results['audioInfo']['bitsPerSample'] = _this.sampleSize;\n const timeStampresult = [..._this.timeStamp].join('\\n');\n total_results['timeStamps'] = timeStampresult;\n total_results['recordingChecks'] = _this.recordingChecks;\n total_results['waveforms'] = _this.waveforms;\n total_results['component']['phase'] = _this.componentIRPhase;\n total_results['system']['phase'] = _this.systemIRPhase;\n total_results['qualityMetrics'] = _this.SDofFilteredRange;\n total_results['flags'] = _this.flags;\n total_results['permissionStatus'] = _this.permissionStatus;\n total_results['simulatedMicrophoneIR'] = _this.simulatedMicrophoneIR;\n total_results['simulatedLoudspeakerIR'] = _this.simulatedLoudspeakerIR;\n console.log('total results');\n console.log(total_results);\n console.log('Time Stamps');\n console.log(timeStampresult);\n _this.stopCalibrationAudio();\n resolve(total_results);\n });\n });\n _defineProperty(this, \"generateCalibrationToneSignal\", gainValue => {\n // Generate a 1000Hz sine wave at the specified gain value\n const duration = this.CALIBRATION_TONE_DURATION; // in seconds\n const frequency = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // 1000Hz\n const sampleRate = this.sourceSamplingRate;\n const numSamples = duration * sampleRate;\n const signal = new Array(numSamples);\n for (let i = 0; i < numSamples; i++) {\n const t = i / sampleRate;\n\n // Base sine wave at specified frequency; scale by sqrt(2) so RMS matches requested dB\n let value = Math.sin(2 * Math.PI * frequency * t) * gainValue * Math.SQRT2;\n\n // Apply taper at beginning and end\n if (t < this.TAPER_SECS) {\n const onsetCurve = Math.pow(Math.sin(Math.PI * t / (2 * this.TAPER_SECS)), 2);\n value *= onsetCurve;\n } else if (t > duration - this.TAPER_SECS) {\n const offsetTime = t - (duration - this.TAPER_SECS);\n const offsetCurve = Math.pow(Math.cos(Math.PI * offsetTime / (2 * this.TAPER_SECS)), 2);\n value *= offsetCurve;\n }\n signal[i] = value;\n }\n return signal;\n });\n _classPrivateFieldSet(_mlsOrder, this, parseInt(mlsOrder, 10));\n _classPrivateFieldSet(_P, this, 2 ** mlsOrder - 1);\n _classPrivateFieldSet(_download, this, download);\n _classPrivateFieldSet(_mls, this, []);\n _classPrivateFieldSet(_lowHz, this, _lowHz2);\n _classPrivateFieldSet(_highHz, this, _highHz2);\n }\n // Function to perform linear interpolation between two points\n interpolate(x, x0, y0, x1, y1) {\n return y0 + (x - x0) * (y1 - y0) / (x1 - x0);\n }\n}\n_defineProperty(Combination, \"createInverseSCurveBuffer\", (length, phase) => {\n const curve = new Float32Array(length);\n let i;\n let j = length - 1;\n for (i = 0; i < length; i += 1) {\n // scale the curve to be between 0-1\n curve[i] = Math.sin(Math.PI * j / length - phase) / 2 + 0.5;\n j -= 1;\n }\n return curve;\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Combination);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/combination/combination.js?");
183
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array-buffer.slice.js */ \"./node_modules/core-js/modules/es.array-buffer.slice.js\");\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.float32-array.js */ \"./node_modules/core-js/modules/es.typed-array.float32-array.js\");\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.typed-array.fill.js */ \"./node_modules/core-js/modules/es.typed-array.fill.js\");\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.typed-array.set.js */ \"./node_modules/core-js/modules/es.typed-array.set.js\");\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.typed-array.sort.js */ \"./node_modules/core-js/modules/es.typed-array.sort.js\");\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../audioCalibrator */ \"./src/tasks/audioCalibrator.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils */ \"./src/utils.js\");\n/* harmony import */ var _powerCheck__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../powerCheck */ \"./src/powerCheck.js\");\n/* harmony import */ var _config_firebase__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../config/firebase */ \"./src/config/firebase.js\");\n/* harmony import */ var firebase_database__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! firebase/database */ \"./node_modules/firebase/database/dist/esm/index.esm.js\");\n/* harmony import */ var firebase_firestore__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! firebase/firestore */ \"./node_modules/firebase/firestore/dist/esm/index.esm.js\");\n\n\n\n\n\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import { phrases } from '../../../dist/example/i18n';\n\n/**\r\n *\r\n */\nvar _download = /*#__PURE__*/new WeakMap();\nvar _mlsGenInterface = /*#__PURE__*/new WeakMap();\nvar _mlsBufferView = /*#__PURE__*/new WeakMap();\nvar _mlsOrder = /*#__PURE__*/new WeakMap();\nvar _lowHz = /*#__PURE__*/new WeakMap();\nvar _highHz = /*#__PURE__*/new WeakMap();\nvar _mls = /*#__PURE__*/new WeakMap();\nvar _P = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_FREQUENCY = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_TYPE = /*#__PURE__*/new WeakMap();\nvar _currentConvolution = /*#__PURE__*/new WeakMap();\nvar _awaitDesiredMLSLength = /*#__PURE__*/new WeakMap();\nvar _awaitBackgroundNoiseRecording = /*#__PURE__*/new WeakMap();\nvar _awaitSignalOnset = /*#__PURE__*/new WeakMap();\nvar _afterMLSRecord = /*#__PURE__*/new WeakMap();\nvar _afterMLSwIIRRecord = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNodeFromBuffer = /*#__PURE__*/new WeakMap();\nvar _setCalibrationNodesFromBuffer = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudio = /*#__PURE__*/new WeakMap();\nvar _getTruncatedSignal = /*#__PURE__*/new WeakMap();\nvar _createCalibrationToneWithGainValue = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNode = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudioVolume = /*#__PURE__*/new WeakMap();\nvar _sendToServerForProcessing = /*#__PURE__*/new WeakMap();\nclass Combination extends _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__[\"default\"] {\n /**\r\n * Default constructor. Creates an instance with any number of paramters passed or the default parameters defined here.\r\n *\r\n * @param {Object<boolean, number, number, number>} calibratorParams - paramter object\r\n * @param {boolean} [calibratorParams.download = false] - boolean flag to download captures\r\n * @param {number} [calibratorParams.mlsOrder = 18] - order of the MLS to be generated\r\n * @param {number} [calibratorParams.numCaptures = 5] - number of captures to perform\r\n * @param {number} [calibratorParams.numMLSPerCapture = 2] - number of bursts of MLS per capture\r\n */\n constructor(_ref) {\n var _this;\n let {\n download = false,\n mlsOrder = 18,\n numCaptures = 3,\n numMLSPerCapture = 2,\n lowHz: _lowHz2 = 20,\n highHz: _highHz2 = 10000\n } = _ref;\n super(numCaptures, numMLSPerCapture);\n _this = this;\n /** @private */\n _defineProperty(this, \"stepNum\", 0);\n /** @private */\n _defineProperty(this, \"totalSteps\", 25);\n /** @private */\n _classPrivateFieldInitSpec(this, _download, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsGenInterface, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsBufferView, void 0);\n /** @private */\n _defineProperty(this, \"componentInvertedImpulseResponse\", null);\n /** @private */\n _defineProperty(this, \"systemInvertedImpulseResponse\", null);\n //averaged and subtracted ir returned from calibration used to calculated iir\n /** @private */\n _defineProperty(this, \"ir\", null);\n /** @private */\n _defineProperty(this, \"impulseResponses\", []);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsOrder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _lowHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _highHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mls, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _P, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _defineProperty(this, \"offsetGainNode\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolutionNoBandpass\", void 0);\n /** @private */\n _defineProperty(this, \"componentIROrigin\", {\n Freq: [],\n Gain: []\n });\n /** @private */\n _defineProperty(this, \"systemConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"systemConvolutionNoBandpass\", void 0);\n ////////////////////////volume\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_FREQUENCY, 1000);\n // Hz\n\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_TYPE, 'sine');\n _defineProperty(this, \"CALIBRATION_TONE_DURATION\", 5);\n // seconds\n _defineProperty(this, \"calibrateSound1000HzPreSec\", 3.5);\n _defineProperty(this, \"calibrateSound1000HzSec\", 1.0);\n _defineProperty(this, \"calibrateSound1000HzPostSec\", 0.5);\n /** @private */\n _defineProperty(this, \"outDBSPL\", null);\n _defineProperty(this, \"THD\", null);\n _defineProperty(this, \"outDBSPL1000\", null);\n /** @private */\n _defineProperty(this, \"TAPER_SECS\", 0.01);\n // seconds\n /** @private */\n _defineProperty(this, \"status_denominator\", 8);\n /** @private */\n _defineProperty(this, \"status_numerator\", 0);\n /** @private */\n _defineProperty(this, \"percent_complete\", 0);\n /** @private */\n _defineProperty(this, \"status\", \"\");\n /**@private */\n _defineProperty(this, \"status_literal\", \"<div style=\\\"display: flex; justify-content: center;\\\"><div style=\\\"width: 200px; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\"));\n /**@private */\n _defineProperty(this, \"componentIR\", null);\n /**@private */\n _defineProperty(this, \"oldComponentIR\", null);\n /**@private */\n _defineProperty(this, \"systemIR\", null);\n /**@private */\n _defineProperty(this, \"_calibrateSoundCheck\", '');\n _defineProperty(this, \"deviceType\", null);\n _defineProperty(this, \"deviceName\", null);\n _defineProperty(this, \"deviceInfo\", null);\n _defineProperty(this, \"desired_time_per_mls\", 0);\n _defineProperty(this, \"num_mls_to_skip\", 0);\n _defineProperty(this, \"desired_sampling_rate\", 0);\n _classPrivateFieldInitSpec(this, _currentConvolution, []);\n _defineProperty(this, \"mode\", 'unfiltered');\n _defineProperty(this, \"sourceNode\", void 0);\n _defineProperty(this, \"autocorrelations\", []);\n _defineProperty(this, \"iirLength\", 0);\n _defineProperty(this, \"irLength\", 0);\n _defineProperty(this, \"calibrateSoundIIRPhase\", 'linear');\n _defineProperty(this, \"componentInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"componentIRInTimeDomain\", []);\n _defineProperty(this, \"systemInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"_calibrateSoundBackgroundSecs\", void 0);\n _defineProperty(this, \"_calibrateSoundSmoothOctaves\", void 0);\n _defineProperty(this, \"background_noise\", {});\n _defineProperty(this, \"numSuccessfulBackgroundCaptured\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstFilteredExtraDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstLevelReTBool\", void 0);\n _defineProperty(this, \"SDofFilteredRange\", {\n mls: undefined,\n component: undefined,\n system: undefined\n });\n _defineProperty(this, \"transducerType\", 'Loudspeaker');\n _defineProperty(this, \"componentIRPhase\", []);\n _defineProperty(this, \"systemIRPhase\", []);\n _defineProperty(this, \"webAudioDeviceNames\", {\n loudspeaker: '',\n microphone: '',\n loudspeakerText: '',\n microphoneText: ''\n });\n _defineProperty(this, \"waveforms\", {\n volume: {}\n });\n _defineProperty(this, \"recordingChecks\", {\n volume: {},\n unfiltered: [],\n system: [],\n component: [],\n warnings: []\n });\n _defineProperty(this, \"inDB\", void 0);\n _defineProperty(this, \"soundCheck\", '');\n _defineProperty(this, \"filteredMLSRange\", {\n component: {\n Min: null,\n Max: null\n },\n system: {\n Min: null,\n Max: null\n }\n });\n /** @private */\n _defineProperty(this, \"timeStamp\", []);\n _defineProperty(this, \"restartCalibration\", false);\n _defineProperty(this, \"calibrateSoundLimit\", 1);\n _defineProperty(this, \"filteredMLSAttenuation\", {\n component: 1,\n system: 1,\n maxAbsSystem: 1,\n maxAbsComponent: 1\n });\n // Generate a signal for the MLS sequence\n _defineProperty(this, \"generateMLSSignal\", (mls, burstDownsample) => {\n // Generate a signal using the MLS sequence, upsampling if needed\n if (burstDownsample > 1) {\n return this.upsampleSignal(mls, burstDownsample);\n }\n return mls;\n });\n // Simulate MLS calibration by convolving with impulse responses\n _defineProperty(this, \"simulatedMLSCalibration\", async (mlsSignal, loudspeakerIR, microphoneIR) => {\n console.log('[SIMULATION] Running MLS impulse response calibration simulation');\n const duration = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n // Convolve MLS with loudspeaker IR and microphone IR\n const simulatedRecording = await this.pyServerAPI.irConvolution({\n input_signal: mlsSignal,\n microphone_ir: microphoneIR,\n loudspeaker_ir: loudspeakerIR,\n duration: duration,\n sample_rate: this.sourceSamplingRate / this._calibrateSoundBurstDownsample\n }).then(res => {\n return res['output_signal'];\n });\n // Save the simulated recording using proper method\n await this.saveUnfilteredRecording(simulatedRecording);\n console.log('simulatedRecording', simulatedRecording.length, this.getAllUnfilteredRecordedSignals().length, microphoneIR.length, loudspeakerIR.length, mlsSignal.length);\n // Process the recording\n await this.sendRecordingToServerForProcessing();\n return simulatedRecording;\n });\n //parameter result from volume calibration\n _defineProperty(this, \"T\", 0);\n //gainDBSPL result from volume calibration\n _defineProperty(this, \"gainDBSPL\", 0);\n //not always just using _calibrateSoundBurstDb for MLS so created a new parameter\n _defineProperty(this, \"power_dB\", 0);\n //system\n _defineProperty(this, \"systemAttenuatorGainDB\", 0);\n _defineProperty(this, \"systemFMaxHz\", 0);\n //component\n _defineProperty(this, \"componentAttentuatorGainDB\", 0);\n _defineProperty(this, \"componentFMaxHz\", 0);\n _defineProperty(this, \"dL_n\", void 0);\n _defineProperty(this, \"L_new_n\", void 0);\n _defineProperty(this, \"fs2\", void 0);\n _defineProperty(this, \"icapture\", 0);\n _defineProperty(this, \"permissionStatus\", null);\n //impulse responses for simulated loudspeaker and microphone\n _defineProperty(this, \"calibrateSoundSimulateMicrophone\", null);\n _defineProperty(this, \"calibrateSoundSimulateLoudspeaker\", null);\n /**generate string template that gets reevaluated as variable increases */\n _defineProperty(this, \"generateTemplate\", status => {\n if (this.isCalibrating) {\n return '';\n }\n if (this.percent_complete > 100) {\n this.percent_complete = 100;\n }\n let MLSsd = '';\n let componentSD = '';\n let systemSD = '';\n let flags = '';\n const soundSubtitle = document.getElementById(this.soundSubtitleId);\n if (soundSubtitle) {\n const reportWebAudioNames = \"\".concat(this.webAudioDeviceNames.loudspeakerText, \"<br/> \").concat(this.webAudioDeviceNames.microphoneText);\n soundSubtitle.innerHTML = reportWebAudioNames;\n }\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n const simulateText = simulationEnabled ? \"\\n Simulating Loudspeaker: \".concat(this.calibrateSoundSimulateLoudspeakerFileName, \", Microphone: \").concat(this.calibrateSoundSimulateMicrophoneFileName, \"\\n <br>\") : '';\n const samplingParamText = this.phrases.RC_SamplingHzBits[this.language].replace('[[N11]]', this.sourceSamplingRate).replace('[[N22]]', this.sinkSamplingRate).replace('[[N33]]', this.calibrateSoundSamplingDesiredBits);\n const reportParameters = \"\".concat(simulateText).concat(samplingParamText, \" \\u2193\").concat(this._calibrateSoundBurstDownsample, \":1\");\n if (this.flags) {\n flags = \"<br> autoGainControl: \".concat(this.flags.autoGainControl, \", echoCancellation: \").concat(this.flags.echoCancellation, \", noiseSuppression: \").concat(this.flags.noiseSuppression);\n }\n if (this.SDofFilteredRange['mls']) {\n MLSsd = \"<br> Record MLS power SD: \".concat(this.SDofFilteredRange['mls'], \" dB\");\n }\n if (this.SDofFilteredRange['system']) {\n systemSD = \"<br> Loudspeaker+Microphone correction SD: \".concat(this.SDofFilteredRange['system'], \" dB\");\n }\n if (this.SDofFilteredRange['component']) {\n componentSD = \"<br> \".concat(this.transducerType, \" correction SD: \").concat(this.SDofFilteredRange['component'], \" dB\");\n }\n const template = \"<div style=\\\"display: flex; justify-content: flex-start; margin-top: 0.4rem;\\\"><div style=\\\"width: 100%; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\");\n return \"\\n \".concat(reportParameters, \" \\n \").concat(MLSsd, \"\\n \").concat(systemSD, \"\\n \").concat(componentSD, \"\\n \").concat(flags, \"\\n <br>\").concat(status, \"\\n \").concat(template);\n });\n /** increment numerator and percent for status bar */\n _defineProperty(this, \"incrementStatusBar\", () => {\n this.status_numerator += 1;\n this.percent_complete = this.status_numerator / this.status_denominator * 100;\n });\n _defineProperty(this, \"setDeviceType\", deviceType => {\n this.deviceType = deviceType;\n });\n _defineProperty(this, \"setDeviceName\", deviceName => {\n this.deviceName = deviceName;\n });\n _defineProperty(this, \"setDeviceInfo\", deviceInfo => {\n this.deviceInfo = deviceInfo;\n });\n _defineProperty(this, \"setPermissionStatus\", permissionStatus => {\n this.permissionStatus = permissionStatus;\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendSystemImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute speaker+mic IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n }); //log any errors that are found in this step\n console.log('filteredComputedIRs', filteredComputedIRs);\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this); //gain of 1 below cutoff, need gain of 0\n const highHz = _classPrivateFieldGet(_highHz, this); //check error for anything other than 10 kHz\n const iirLength = this.iirLength;\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n // const payload_downsampled = filteredComputedIRs_slice.map(ir =>\n // this.downsampleSignal(ir, this._calibrateSoundBurstDownsample)\n // );\n return await this.pyServerAPI.getSystemInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs_slice,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.systemInvertedImpulseResponse = res['iir'];\n this.systemIR = res['ir'];\n this.systemInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.systemAttenuatorGainDB = res['attenuatorGain_dB'];\n this.systemFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.systemInvertedImpulseResponse,\n inverse_response_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.systemAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log(result);\n this.systemConvolution = result['convolution'];\n this.systemConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n\n // attenuate the system convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of system convolution\n\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.systemConvolution);\n this.filteredMLSAttenuation.system = this.systemConvolution.reduce((a, b) => a + b ** 2, 0) / this.systemConvolution.length;\n this.filteredMLSAttenuation.maxAbsSystem = max;\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendComponentImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute speaker or mic IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n });\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n // const payload_downsampled = filteredComputedIRs_slice.map(ir =>\n // this.downsampleSignal(ir, this._calibrateSoundBurstDownsample)\n // );\n let componentIRGains = this.componentIR['Gain'];\n const componentIRFreqs = this.componentIR['Freq'];\n //normalize the component IR gains\n componentIRGains = componentIRGains.map(value => {\n return value - this._calibrateSoundBurstScalarDB - this._calibrateSoundBurstDb;\n });\n if (this._calibrateSoundBurstNormalizeBy1000HzGainBool) {\n const sineGainAt1000Hz_dB = this.gainDBSPL;\n componentIRGains = componentIRGains.map(value => {\n return value - sineGainAt1000Hz_dB;\n });\n }\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this);\n const iirLength = this.iirLength;\n const irLength = this.irLength;\n const highHz = _classPrivateFieldGet(_highHz, this);\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return this.pyServerAPI.getComponentInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs_slice,\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n irLength,\n calibrateSoundSmoothOctaves: this._calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz: this._calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.componentInvertedImpulseResponse = res['iir'];\n this.componentInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.componentIR['Gain'] = res['ir'];\n this.componentIR['Freq'] = res['frequencies'];\n this.componentIRPhase = res['component_angle'];\n this.systemIRPhase = res['system_angle'];\n this.componentIROrigin['Freq'] = res['frequencies'];\n this.componentIROrigin['Gain'] = res['irOrigin'];\n this.componentIRInTimeDomain = res['irTime'];\n this.componentAttenuatorGainDB = res['attenuatorGain_dB'];\n this.componentFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.componentInvertedImpulseResponse,\n inverse_response_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.componentAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log('result', result);\n this.componentConvolution = result['convolution'];\n this.componentConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n // attenuate the component convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of component convolution\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.componentConvolution);\n // if (max > this.calibrateSoundLimit) {\n // const gain = this.calibrateSoundLimit / max;\n // // apply gain to component convolution\n // this.componentConvolution = this.componentConvolution.map(value => value * gain);\n // this.filteredMLSAttenuation.component = gain;\n // }\n this.filteredMLSAttenuation.component = this.componentConvolution.reduce((a, b) => a + b ** 2, 0) / this.componentConvolution.length;\n this.filteredMLSAttenuation.maxAbsComponent = max;\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n });\n /**\r\n * Upsamples a signal by repeating each sample N times\r\n * @param {Array<number>} signal - The input signal to upsample\r\n * @param {number} N - The upsampling factor\r\n * @returns {Array<number>} - The upsampled signal\r\n */\n _defineProperty(this, \"upsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n\n //if signal is an array of arrays, upsample each array individually\n try {\n if (Array.isArray(signal[0])) {\n return signal.map(arr => this.upsampleSignal(arr, N));\n }\n } catch (err) {\n console.error(err);\n return signal;\n }\n const result = [];\n for (let sample of signal) {\n // Repeat each sample N times\n for (let i = 0; i < N; i++) {\n result.push(sample);\n }\n }\n return result;\n });\n /**\r\n * Downsamples a signal by averaging groups of N samples\r\n * @param {Array<number>} signal - The input signal to downsample\r\n * @param {number} N - The downsampling factor\r\n * @returns {Array<number>} - The downsampled signal\r\n */\n _defineProperty(this, \"downsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n\n //if signal is an array of arrays, downsample each array individually\n try {\n if (Array.isArray(signal[0])) {\n return signal.map(arr => this.downsampleSignal(arr, N));\n }\n } catch (err) {\n console.error(err);\n return signal;\n }\n const result = [];\n for (let i = 0; i < signal.length; i += N) {\n const chunk = signal.slice(i, Math.min(i + N, signal.length));\n // Calculate average of the chunk\n const avg = chunk.reduce((sum, val) => sum + val, 0) / chunk.length;\n result.push(avg);\n }\n return result;\n });\n _defineProperty(this, \"sendBackgroundRecording\", () => {\n const allSignals = this.getAllBackgroundRecordings();\n const numSignals = allSignals.length;\n const background_rec_whole = allSignals[numSignals - 1];\n const fraction = 0.5 / (this._calibrateSoundBackgroundSecs + 0.5);\n // Calculate the starting index for slicing the array\n const startIndex = Math.round(fraction * background_rec_whole.length);\n // Slice the array from the calculated start index to the end of the array\n const background_rec = background_rec_whole.slice(startIndex);\n console.log('Sending background recording to server for processing');\n let backgroundSec = this._calibrateSoundBackgroundSecs + 0.5;\n this.addTimeStamp(\"Record \".concat(backgroundSec.toFixed(1), \" s of background.\"));\n const fBackground = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const background_rec_downsampled = this.downsampleSignal(background_rec, this._calibrateSoundBurstDownsample);\n this.pyServerAPI.getBackgroundNoisePSDWithRetry({\n background_rec: background_rec_downsampled,\n sampleRate: fBackground\n }).then(res => {\n if (this.numSuccessfulBackgroundCaptured < 1) {\n this.numSuccessfulBackgroundCaptured += 1;\n //storing all background data in background_psd object\n this.background_noise['x_background'] = res['x_background'];\n this.background_noise['y_background'] = res['y_background'];\n this.background_noise['recording'] = background_rec;\n }\n this.addTimeStamp('Compute spectrum of background');\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends the recorded signal, or a given csv string of a signal, to the back end server for processing\r\n *\r\n * @param {<array>String} signalCsv - Optional csv string of a previously recorded signal, if given, this signal will be processed\r\n * @example\r\n */\n _defineProperty(this, \"sendRecordingToServerForProcessing\", async signalCsv => {\n const allSignals = this.getAllUnfilteredRecordedSignals();\n console.log('Obtaining last all hz unfiltered recording from #allHzUnfilteredRecordings to send to server for processing');\n const numSignals = allSignals.length;\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const payload = signalCsv && signalCsv.length > 0 ? (0,_utils__WEBPACK_IMPORTED_MODULE_8__.csvToArray)(signalCsv) : allSignals[numSignals - 1];\n console.log('sending rec');\n this.stepNum += 1;\n console.log('send rec ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration Step: computing the IR of the last recording...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const payload_downsampled = this.downsampleSignal(payload, this._calibrateSoundBurstDownsample);\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n await this.pyServerAPI.allHzPowerCheck({\n payload: payload_downsampled,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this._calibrateSoundBurstRepeats,\n warmUp: this._calibrateSoundBurstPreSec,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0 && !simulationEnabled) {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"(\".concat(pre.toFixed(1), \" + \").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \" + \").concat(post.toFixed(1), \" s) of MLS ver.\") + \" \".concat(this.icapture, \". SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB));\n this.recordingChecks['unfiltered'].push(result);\n this.recordingChecks['warnings'].push(\"All Hz. Re-record because SD \".concat(result['sd'], \" >\\n \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording because SD \".concat(result['sd'], \" >\\n \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.clearLastUnfilteredRecordedSignals();\n this.numSuccessfulCaptured += 1;\n } else {\n if (result['sd'] <= this._calibrateSoundBurstMaxSD_dB) {\n console.log('SD: ' + result['sd'] + ', less than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"=\".concat(pre.toFixed(1), \"+\").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \"+\").concat(post.toFixed(1), \" s of MLS ver.\") + \" \".concat(this.icapture, \". SD = \").concat(result['sd'], \" <= \").concat(this._calibrateSoundBurstMaxSD_dB));\n } else {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"=\".concat(pre.toFixed(1), \"+\").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \"+\").concat(post.toFixed(1), \" s\") + \"of MLS ver. \".concat(this.icapture, \". SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB));\n }\n if (this.numSuccessfulCaptured == 1) {\n console.log('pop last unfiltered mls volume check');\n this.recordingChecks['unfiltered'].pop();\n }\n this.recordingChecks['unfiltered'].push(result);\n console.log('start calculate impulse response');\n // const usedPeriodStart = this._calibrateSoundBurstPreSec * this.sourceSamplingRate;\n const usedPeriodStart = this.num_mls_to_skip * this.sourceSamplingRate;\n const usedPeriodEnd = (this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec) * this.sourceSamplingRate;\n // const payload_skipped_warmUp = payload.slice(usedPeriodStart, usedPeriodEnd);\n const payload_skipped_warmUp = payload.slice(usedPeriodStart);\n console.log('payload.length', payload.length);\n console.log('usedPeriodStart', usedPeriodStart);\n console.log('usedPeriodEnd', usedPeriodEnd);\n console.log('payload_skipped_warmUp.length', payload_skipped_warmUp.length);\n const payload_skipped_warmUp_downsampled = this.downsampleSignal(payload_skipped_warmUp, this._calibrateSoundBurstDownsample);\n console.log('payload_skipped_warmUp_downsampled', payload_skipped_warmUp_downsampled.length);\n // console.log('usedPeriodStart', usedPeriodStart);\n // console.log('payload', payload);\n // console.log('payload_skipped_warmUp', payload_skipped_warmUp);\n // console.log('payload_skipped_warmUp_downsampled', payload_skipped_warmUp_downsampled);\n const factor = 1;\n //simulationEnabled ? this._calibrateSoundBurstDownsample : 1;\n await this.pyServerAPI.getAutocorrelation({\n mls: mls,\n payload: payload_skipped_warmUp_downsampled,\n sampleRate: fMLS,\n numPeriods: this._calibrateSoundBurstRepeats / factor,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.autocorrelations.push(res['autocorrelation']);\n this.fs2 = res['fs2'];\n this.L_new_n = res['L_new_n'];\n this.dL_n = res['dL_n'];\n this.impulseResponses.push(await this.pyServerAPI.getImpulseResponse({\n mls,\n sampleRate: fMLS,\n numPeriods: this._calibrateSoundBurstRepeats / factor,\n sig: payload_skipped_warmUp_downsampled,\n fs2: this.fs2,\n L_new_n: this.L_new_n,\n dL_n: this.dL_n,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \"/\").concat(this.numCaptures, \" IRs computed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res['ir'];\n }).catch(err => {\n console.error(err);\n }));\n });\n }\n console.log('number of unfiltered recording checks:' + this.recordingChecks['unfiltered'].length);\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /**\r\n * Passed to the calibration steps function, awaits the desired amount of seconds to capture the desired number\r\n * of MLS periods defined in the constructor.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitDesiredMLSLength, async () => {\n // seconds per MLS = P / SR\n // await N * P / SR\n this.stepNum += 1;\n console.log('await desired length ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the calibration signal...\".toString() + \"\\niteration \".concat(this.stepNum));\n this.emit('update', {\n message: this.status\n });\n let time_to_wait = 0;\n if (this.mode === 'unfiltered') {\n //unfiltered\n //should be: pre + (burst * repeats) + post\n // time_to_wait = (this.#mls[0].length / this.sourceSamplingRate) * this.numMLSPerCapture;\n // time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n time_to_wait = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstSec * this._calibrateSoundBurstRepeats + this._calibrateSoundBurstPostSec;\n } else if (this.mode === 'filtered') {\n //filtered\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (this.numMLSPerCapture / (this.num_mls_to_skip + this.numMLSPerCapture));\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) * this.numMLSPerCapture;\n // time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n time_to_wait = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstSec * this._calibrateSoundBurstRepeats + this._calibrateSoundBurstPostSec;\n } else {\n throw new Error('Mode broke in awaitDesiredMLSLength');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /**\r\n * Passed to the background noise recording function, awaits the desired amount of seconds to capture the desired number\r\n * of seconds of background noise\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitBackgroundNoiseRecording, async () => {\n console.log('Waiting ' + this._calibrateSoundBackgroundSecs + ' second(s) to record background noise');\n let time_to_wait = this._calibrateSoundBackgroundSecs + 0.5;\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /** .\r\n * .\r\n * .\r\n * Passed to the calibration steps function, awaits the onset of the signal to ensure a steady state\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitSignalOnset, async () => {\n this.stepNum += 1;\n console.log('await signal onset ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: waiting for the signal to stabilize...\".toString());\n this.emit('update', {\n message: this.status\n });\n let number_of_bursts_to_skip = 0;\n let time_to_sleep = 0;\n if (this.mode === 'unfiltered') {\n time_to_sleep = this._calibrateSoundBurstPreSec;\n } else if (this.mode === 'filtered') {\n console.log(_classPrivateFieldGet(_currentConvolution, this).length);\n // time_to_sleep =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (number_of_bursts_to_skip / (number_of_bursts_to_skip + this.numMLSPerCapture));\n time_to_sleep = _classPrivateFieldGet(_currentConvolution, this).length / this.sourceSamplingRate * number_of_bursts_to_skip;\n } else {\n throw new Error('Mode broke in awaitSignalOnset');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_sleep);\n });\n /**\r\n * Called immediately after a recording is captured. Used to process the resulting signal\r\n * whether by sending the result to a server or by computing a result locally.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _afterMLSRecord, async () => {\n console.log('after record');\n await this.sendRecordingToServerForProcessing();\n });\n _classPrivateFieldInitSpec(this, _afterMLSwIIRRecord, async () => {\n await this.checkPowerVariation();\n });\n /** .\r\n * .\r\n * .\r\n * Created an S Curver Buffer to taper the signal onset\r\n *\r\n * @param {*} onSetBool\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"createSCurveBuffer\", function () {\n let onSetBool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n const curve = new Float32Array(_this.TAPER_SECS * _this.sourceSamplingRate + 1);\n const frequency = 1 / (4 * _this.TAPER_SECS);\n let j = 0;\n for (let i = 0; i < _this.TAPER_SECS * _this.sourceSamplingRate + 1; i += 1) {\n const phase = 2 * Math.PI * frequency * j;\n const onsetTaper = Math.pow(Math.sin(phase), 2);\n const offsetTaper = Math.pow(Math.cos(phase), 2);\n curve[i] = onSetBool ? onsetTaper : offsetTaper;\n j += 1 / _this.sourceSamplingRate;\n }\n return curve;\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @param dataBuffer\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNodeFromBuffer, dataBuffer => {\n const mlsSignal = dataBuffer;\n // reorderMLS(\n // dataBuffer,\n // this.calibrateSound1000HzPreSec,\n // this.sourceSamplingRate\n // );\n console.log('length databuffer');\n console.log(mlsSignal.length);\n if (!this.sourceAudioContext) {\n this.makeNewSourceAudioContext();\n }\n const buffer = this.sourceAudioContext.createBuffer(1,\n // number of channels\n mlsSignal.length, this.sourceAudioContext.sampleRate // sample rate\n );\n const data = buffer.getChannelData(0); // get data\n\n // fill the buffer with our data\n try {\n for (let i = 0; i < mlsSignal.length; i += 1) {\n data[i] = mlsSignal[i];\n }\n } catch (error) {\n console.error(error);\n }\n this.sourceNode = this.sourceAudioContext.createBufferSource();\n this.sourceNode.buffer = buffer;\n if (this.mode === 'filtered') {\n //used to not loop filtered\n this.sourceNode.loop = true;\n } else {\n this.sourceNode.loop = true;\n }\n this.sourceNode.connect(this.sourceAudioContext.destination);\n this.addCalibrationNode(this.sourceNode);\n });\n /**\r\n * Given a data buffer, creates the required calibration node\r\n *\r\n * @param {*} dataBufferArray\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setCalibrationNodesFromBuffer, function () {\n let dataBufferArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [_classPrivateFieldGet(_mlsBufferView, _this)[_this.icapture]];\n if (dataBufferArray.length === 1) {\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, _this).call(_this, dataBufferArray[0]);\n } else {\n throw new Error('The length of the data buffer array must be 1');\n }\n });\n /**\r\n * Creates an audio context and plays it for a few seconds.\r\n *\r\n * @private\r\n * @returns - Resolves when the audio is done playing.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _playCalibrationAudio, () => {\n this.calibrationNodes[0].start(0);\n this.status = \"\";\n if (this.mode === 'unfiltered') {\n console.log('play calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: playing the calibration tone...\".toString()).toString();\n } else if (this.mode === 'filtered') {\n console.log('play convolved audio ' + this.stepNum);\n this.status = this.generateTemplate().toString(\"All Hz Calibration: playing the convolved calibration tone...\".toString());\n } else {\n throw new Error('Mode is incorrect');\n }\n this.emit('update', {\n message: this.status\n });\n this.stepNum += 1;\n console.log('sink sampling rate');\n console.log(this.sinkSamplingRate);\n console.log('source sampling rate');\n console.log(this.sourceSamplingRate);\n console.log('sample size');\n console.log(this.sampleSize);\n });\n /** .\r\n * .\r\n * .\r\n * Stops the audio with tapered offset\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"stopCalibrationAudio\", () => {\n if (this.calibrationNodes.length === 0) {\n return;\n }\n this.calibrationNodes[0].stop(0);\n this.calibrationNodes = [];\n if (this.sourceNode) this.sourceNode.disconnect();\n this.stepNum += 1;\n console.log('stop calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: stopping the calibration tone...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"playMLSwithIIR\", async (stream, convolution) => {\n let checkRec = false;\n this.mode = 'filtered';\n console.log('play mls with iir');\n //this.invertedImpulseResponse = iir\n\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, convolution),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2, _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSwIIRRecord, this),\n // after record\n this.mode, checkRec);\n });\n /**\r\n * Simulates playing convolved MLS with IIR and recording the result\r\n * @param {Array<number>} convolution - The convolved MLS signal\r\n * @param {Array<number>} loudspeakerIR - The loudspeaker impulse response\r\n * @param {Array<number>} microphoneIR - The microphone impulse response\r\n * @returns {Promise<void>}\r\n */\n _defineProperty(this, \"simulatePlayMLSwithIIR\", async (convolution, loudspeakerIR, microphoneIR) => {\n console.log('[SIMULATION] Simulate playing MLS with IIR');\n this.mode = 'filtered';\n const duration = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n // Further convolve with loudspeaker and microphone IRs to simulate recording\n const simulatedRecording = await this.pyServerAPI.irConvolution({\n input_signal: convolution,\n loudspeaker_ir: loudspeakerIR,\n microphone_ir: microphoneIR,\n duration: duration,\n sample_rate: this.sourceSamplingRate / this._calibrateSoundBurstDownsample\n }).then(res => {\n return res['output_signal'];\n });\n\n // Save the simulated recording\n await this.saveFilteredRecording(simulatedRecording);\n this.numSuccessfulCaptured = 2; // Mark as successfully captured to avoid retries\n\n // Process the recording\n await this.checkPowerVariation();\n this.stepNum += 1;\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration [SIMULATION]: Filtered recording processed...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"bothSoundCheck\", async stream => {\n let iir_ir_and_plots;\n\n // Check if simulation is enabled\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode for component check\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let component_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n component_conv_recs = component_conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let return_component_conv_rec = component_conv_recs[component_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n this.numSuccessfulCaptured = 0;\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'speakerAndMic';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode for system check\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let system_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n system_conv_recs = system_conv_recs.map(rec => {\n return rec.map(value => value / linearScaleAttenuation);\n });\n }\n let return_system_conv_rec = system_conv_recs[system_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n if (simulationEnabled) {\n console.log('[SIMULATION] Processing simulated recordings');\n } else {\n this.sourceAudioContext.close();\n }\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = component_conv_recs[component_conv_recs.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n //psd of component\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute spectrum of MLS recording');\n if (this.isCalibrating) return null;\n let component_unconv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered recording (speaker or mic)');\n if (this.isCalibrating) return null;\n let component_conv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.componentFMaxHz);\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n conv_rec = system_conv_recs[system_conv_recs.length - 1];\n //psd of system\n this.addTimeStamp('Compute spectrum of filtered recording (speaker+mic) and unfiltered recording');\n if (this.isCalibrating) return null;\n let system_recs_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls_psd', this.SDofFilteredRange['mls']);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd. done\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[0], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker+mic)');\n if (this.isCalibrating) return null;\n let system_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let system_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker or mic)');\n if (this.isCalibrating) return null;\n let component_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let component_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n filtered_recording: {\n component: return_component_conv_rec,\n system: return_system_conv_rec\n },\n unfiltered_recording: this.getAllUnfilteredRecordedSignals()[0],\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: system_filtered_mls_psd['x_mls'],\n y: system_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: system_no_bandpass_filtered_mls_psd['x_mls'],\n y: system_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: system_recs_psd['x_unconv'],\n y: system_recs_psd['y_unconv']\n },\n conv: {\n x: system_recs_psd['x_conv'],\n y: system_recs_psd['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: component_filtered_mls_psd['x_mls'],\n y: component_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: component_no_bandpass_filtered_mls_psd['x_mls'],\n y: component_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: component_unconv_rec_psd['x'],\n y: component_unconv_rec_psd['y']\n },\n conv: {\n x: component_conv_rec_psd['x'],\n y: component_conv_rec_psd['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n return iir_ir_and_plots;\n });\n _defineProperty(this, \"singleSoundCheck\", async stream => {\n let iir_ir_and_plots;\n\n // Check if simulation is enabled\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (this._calibrateSoundCheck != 'speakerAndMic') {\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n } else {\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n _classPrivateFieldSet(_currentConvolution, this, this.upsampleSignal(_classPrivateFieldGet(_currentConvolution, this), this._calibrateSoundBurstDownsample));\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'speakerAndMic';\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n // Use simulation mode\n await this.simulatePlayMLSwithIIR(_classPrivateFieldGet(_currentConvolution, this), this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n } else {\n // Use actual recording mode\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n }\n let conv_recs = this.getAllFilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'speakerOrMic') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'speakerOrMic') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttenuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n this.clearAllFilteredRecordedSignals();\n console.log('Obtaining unfiltered recording from #allHzUnfilteredRecordings to calculate spectrum');\n console.log('Obtaining filtered recording from #allHzFilteredRecordings to calculate spectrum');\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = conv_recs[conv_recs.length - 1];\n let return_conv_rec = conv_rec;\n if (simulationEnabled) {\n console.log('[SIMULATION] Processing simulated recordings');\n } else {\n this.sourceAudioContext.close();\n }\n if (this._calibrateSoundCheck != 'speakerAndMic') {\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute spectrum of MLS recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let unconv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n console.log(res);\n let mls_psd = res.y.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls sd', this.SDofFilteredRange['mls']);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the spectrum graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker+mic IIR-filtered MLS recording');\n if (this.isCalibrating) return null;\n let conv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= _classPrivateFieldGet(_highHz, this));\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker or mic');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: unconv_results['x'],\n y: unconv_results['y']\n },\n conv: {\n x: conv_results['x'],\n y: conv_results['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n } else {\n this.addTimeStamp('Compute spectrum of filtered recording (speaker+mic) and unfiltered recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let results = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of filtered MLS (speaker+mic)');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolutionNoBandpass,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: results['x_unconv'],\n y: results['y_unconv']\n },\n conv: {\n x: results['x_conv'],\n y: results['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n }\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n this.downloadSingleUnfilteredRecording();\n this.downloadSingleFilteredRecording();\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n return iir_ir_and_plots;\n });\n /**\r\n * Public method to start the calibration process. Objects intialized from webassembly allocate new memory\r\n * and must be manually freed. This function is responsible for intializing the MlsGenInterface,\r\n * and wrapping the calibration steps with a garbage collection safe gaurd.\r\n *\r\n * @public\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startCalibrationImpulseResponse\", async stream => {\n let desired_time = this.desired_time_per_mls;\n let checkRec = 'allhz';\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n console.log('MLS sequence should be of length: ' + fMLS * desired_time);\n length = fMLS * desired_time;\n this.power_dB = 0;\n if (!this._calibrateSoundBurstLevelReTBool) {\n this.power_dB = this._calibrateSoundBurstDb;\n } else {\n this.power_dB = this._calibrateSoundBurstDb + (this.T - this.gainDBSPL);\n }\n const amplitude = Math.pow(10, this.power_dB / 20);\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getMLSWithRetry({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions: this.numCaptures,\n calibrateSoundBurstDownsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n console.log(res);\n _classPrivateFieldSet(_mlsBufferView, this, this.upsampleSignal(res['mls'], this._calibrateSoundBurstDownsample));\n _classPrivateFieldSet(_mls, this, this.upsampleSignal(res['unscaledMLS'], this._calibrateSoundBurstDownsample));\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute MLS sequence');\n this.numSuccessfulBackgroundCaptured = 0;\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (this._calibrateSoundBackgroundSecs > 0 && !simulationEnabled) {\n this.mode = 'background';\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the background noise...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n await this.recordBackground(stream,\n //stream\n () => this.numSuccessfulBackgroundCaptured < 1,\n //loop condition\n _classPrivateFieldGet(_awaitBackgroundNoiseRecording, this),\n //sleep to record\n this.sendBackgroundRecording,\n //send to get PSD\n this.mode, checkRec);\n this.incrementStatusBar();\n }\n this.mode = 'unfiltered';\n this.numSuccessfulCaptured = 0;\n if (this.isCalibrating) return null;\n if (simulationEnabled) {\n console.log('[SIMULATION] Using simulation mode for MLS calibration');\n\n // Run simulation for each capture\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n if (this.isCalibrating) return null;\n // From Denis July 20th, 2025:\n // Imagine playing the 10 s MLS, repeatedly, forever, and we record part of it. That piece should be\n // 2.5+10+10+1 second long. To synthesize this, the pre-interval should be the final 2.5 sec of MLS.\n // Followed by two whole MLS. Followed by the initial 1 sec of MLS. Again, all the pieces together\n // should be one contiguous piece cut out from an infinitely repeating MLS.\n // Get the MLS signal for this capture\n const mlsSignal = _classPrivateFieldGet(_mlsBufferView, this)[this.icapture];\n // reorderMLS(\n // this.#mlsBufferView[this.icapture],\n // this.calibrateSound1000HzPreSec,\n // this.sourceSamplingRate\n // );\n\n // Run the simulation\n await this.simulatedMLSCalibration(mlsSignal, this.calibrateSoundSimulateLoudspeaker, this.calibrateSoundSimulateMicrophone);\n this.stepNum += 1;\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration [SIMULATION]: \".concat(i + 1, \"/\").concat(this.numCaptures, \" simulated captures processed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n } else {\n // Use actual recording mode\n\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, _classPrivateFieldGet(_mlsBufferView, this)[this.icapture]),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2,\n // loop while true\n _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSRecord, this),\n // after record\n this.mode, checkRec);\n this.stopCalibrationAudio();\n }\n }\n checkRec = false;\n\n // at this stage we've captured all the required signals,\n // and have received IRs for each one\n // so let's send all the IRs to the server to be converted to a single IIR\n if (this.isCalibrating) return null;\n await this.sendSystemImpulseResponsesToServerForProcessing();\n await this.pyServerAPI.checkMemory();\n if (this.isCalibrating) return null;\n await this.sendComponentImpulseResponsesToServerForProcessing();\n this.numSuccessfulCaptured = 0;\n let iir_ir_and_plots;\n if (this._calibrateSoundCheck != 'none') {\n //do single check\n if (this._calibrateSoundCheck == 'speakerOrMic' || this._calibrateSoundCheck == 'speakerAndMic') {\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.singleSoundCheck(stream);\n if (this.isCalibrating) return null;\n } else {\n //both\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.bothSoundCheck(stream);\n if (this.isCalibrating) return null;\n }\n\n // } else {\n // let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n // let conv_rec = this.componentInvertedImpulseResponse;\n // if (this.isCalibrating) return null;\n // let component_iir_psd = await this.pyServerAPI\n // .getPSDWithRetry({\n // unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n // conv_rec: this.componentInvertedImpulseResponse,\n // sampleRate: fMLS,\n // downsample: this._calibrateSoundBurstDownsample,\n // })\n // .then(res => {\n // this.incrementStatusBar();\n // this.status = this.generateTemplate(\n // `All Hz Calibration: done computing the PSD graphs...`.toString()\n // ).toString();\n // this.emit('update', {message: this.status});\n // return res;\n // })\n // .catch(err => {\n // console.error(err);\n // });\n // unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n // conv_rec = this.systemInvertedImpulseResponse;\n // if (this.isCalibrating) return null;\n // let system_iir_psd = await this.pyServerAPI\n // .getPSDWithRetry({\n // unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n // conv_rec: this.systemInvertedImpulseResponse,\n // sampleRate: fMLS,\n // downsample: this._calibrateSoundBurstDownsample,\n // })\n // .then(res => {\n // this.incrementStatusBar();\n // this.status = this.generateTemplate(\n // `All Hz Calibration: done computing the PSD graphs...`.toString()\n // ).toString();\n // this.emit('update', {message: this.status});\n // return res;\n // })\n // .catch(err => {\n // console.error(err);\n // });\n\n // let gainValue = this.getGainDBSPL();\n // let return_unconv_rec = unconv_rec;\n // let return_conv_rec = conv_rec;\n // iir_ir_and_plots = {\n // unfiltered_recording: return_unconv_rec,\n // filtered_recording: return_conv_rec,\n // system: {\n // iir: this.systemInvertedImpulseResponse,\n // iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n // ir: this.systemIR,\n // iir_psd: {\n // y: system_iir_psd['y_conv'],\n // x: system_iir_psd['y_conv'],\n // y_no_bandpass: system_iir_psd['y_unconv'],\n // x_no_bandpass: system_iir_psd['x_unconv'],\n // },\n // filtered_recording: [],\n // convolution: this.systemConvolution,\n // convolutionNoBandpass: this.systemConvolutionNoBandpass,\n // psd: {\n // unconv: {\n // x: [],\n // y: [],\n // },\n // conv: {\n // x: [],\n // y: [],\n // },\n // },\n // },\n // component: {\n // iir: this.componentInvertedImpulseResponse,\n // iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n // ir: this.componentIR,\n // ir_in_time_domain: this.componentIRInTimeDomain,\n // iir_psd: {\n // y: component_iir_psd['y_conv'],\n // x: component_iir_psd['x_conv'],\n // y_no_bandpass: component_iir_psd['y_unconv'],\n // x_no_bandpass: component_iir_psd['x_unconv'],\n // },\n // convolution: this.componentConvolution,\n // convolutionNoBandpass: this.componentConvolutionNoBandpass,\n // psd: {\n // unconv: {\n // x: [],\n // y: [],\n // },\n // conv: {\n // x: [],\n // y: [],\n // },\n // },\n // gainDBSPL: gainValue,\n // },\n // mls: this.#mlsBufferView,\n // autocorrelations: this.autocorrelations,\n // impulseResponses: [],\n // };\n // if (this.isCalibrating) return null;\n // await Promise.all(this.impulseResponses).then(res => {\n // for (let i = 0; i < res.length; i++) {\n // if (res[i] != undefined) {\n // iir_ir_and_plots['impulseResponses'].push(res[i]);\n // }\n // }\n // });\n\n // if (this.#download) {\n // saveToCSV(this.#mls, 'MLS.csv');\n // saveToCSV(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n // saveToCSV(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n // saveToCSV(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n // saveToCSV(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n // for (let i = 0; i < this.autocorrelations.length; i++) {\n // saveToCSV(this.autocorrelations[i], `autocorrelation_${i}`);\n // }\n // const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n // for (let i = 0; i < res.length; i++) {\n // if (res[i] != undefined) {\n // saveToCSV(res[i], `IR_${i}`);\n // }\n // }\n // });\n // }\n // }\n } else {\n let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n let conv_rec = this.componentInvertedImpulseResponse;\n let return_unconv_rec = unconv_rec;\n let return_conv_rec = conv_rec;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n this.addTimeStamp('Compute spectrum of speaker or mic IIR and speaker or mic IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.componentInvertedImpulseResponseNoBandpass,\n conv_rec: this.componentInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\").toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute spectrum of speaker+mic IIR and speaker+mic IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.systemInvertedImpulseResponseNoBandpass,\n conv_rec: this.systemInvertedImpulseResponse,\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\").toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n autocorrelations: this.autocorrelations,\n impulseResponses: [] // filled below\n };\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(resArray => {\n for (let i = 0; i < resArray.length; i++) {\n if (resArray[i] != undefined) {\n iir_ir_and_plots.impulseResponses.push(resArray[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n await Promise.all(this.impulseResponses).then(resArray => {\n for (let i = 0; i < resArray.length; i++) {\n if (resArray[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(resArray[i], \"IR_\".concat(i));\n }\n }\n });\n }\n }\n if (this.isCalibrating) return null;\n this.percent_complete = 100;\n this.status = this.generateTemplate(\"All Hz Calibration: Finished\".toString()).toString();\n this.addTimeStamp('Plot results');\n this.emit('update', {\n message: this.status\n });\n console.log('irr_ir_and_plots for none: ', iir_ir_and_plots);\n return iir_ir_and_plots;\n });\n //////////////////////volume\n _defineProperty(this, \"handleIncomingData\", data => {\n console.log('Received data: ', data);\n if (data.type === 'soundGainDBSPL') {\n this.soundGainDBSPL = data.value;\n } else {\n throw new Error(\"Unknown data type: \".concat(data.type));\n }\n });\n _classPrivateFieldInitSpec(this, _getTruncatedSignal, function () {\n let left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3.5;\n let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4.5;\n const start = Math.floor(left * _this.sourceSamplingRate);\n const end = Math.floor(right * _this.sourceSamplingRate);\n const result = Array.from(_this.getLastVolumeRecordedSignal().slice(start, end));\n console.log('Obtaining last 1000 hz recording from #allVolumeRecordings to send for processing');\n /**\r\n * function to check that capture was properly made\r\n * @param {*} list\r\n */\n const checkResult = list => {\n const setItem = new Set(list);\n if (setItem.size === 1 && setItem.has(0)) {\n console.warn('The last capture failed, all recorded signal is zero', _this.getAllVolumeRecordedSignals());\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n if (setItem.size === 0) {\n console.warn('The last capture failed, no recorded signal');\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n };\n checkResult(result);\n return result;\n });\n /** \r\n * \r\n * \r\n Construct a calibration Node with the calibration parameters and given gain value\r\n * @param {*} gainValue\r\n * */\n _classPrivateFieldInitSpec(this, _createCalibrationToneWithGainValue, gainValue => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n const taperGainNode = audioContext.createGain();\n const offsetGainNode = audioContext.createGain();\n const totalDuration = this.CALIBRATION_TONE_DURATION;\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n // Multiply by sqrt(2) so that requested dB (based on RMS) maps to oscillator peak\n gainNode.gain.value = gainValue * Math.SQRT2;\n oscilator.connect(gainNode);\n gainNode.connect(taperGainNode);\n const onsetCurve = this.createSCurveBuffer();\n taperGainNode.gain.setValueCurveAtTime(onsetCurve, 0, this.TAPER_SECS);\n taperGainNode.connect(offsetGainNode);\n const offsetCurve = this.createSCurveBuffer(false);\n offsetGainNode.gain.setValueCurveAtTime(offsetCurve, totalDuration - this.TAPER_SECS, this.TAPER_SECS);\n offsetGainNode.connect(audioContext.destination);\n const gainValuesOverTime = [];\n const sampleRate = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // Number of samples per second\n const interval = 1 / sampleRate; // Time between samples\n\n for (let t = 0; t <= totalDuration; t += interval) {\n let gainValueAtTime = gainValue;\n\n // Apply the onset curve\n if (t < this.TAPER_SECS) {\n const onsetIndex = Math.floor(t / this.TAPER_SECS * onsetCurve.length);\n gainValueAtTime *= onsetCurve[onsetIndex];\n }\n\n // Apply the offset curve\n if (t > totalDuration - this.TAPER_SECS) {\n const offsetTime = t - (totalDuration - this.TAPER_SECS);\n const offsetIndex = Math.floor(offsetTime / this.TAPER_SECS * offsetCurve.length);\n gainValueAtTime *= offsetCurve[offsetIndex];\n }\n gainValuesOverTime.push(gainValueAtTime);\n }\n this.waveforms['volume'][this.inDB] = gainValuesOverTime;\n this.addCalibrationNode(oscilator);\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNode, () => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = 0.04;\n oscilator.connect(gainNode);\n gainNode.connect(audioContext.destination);\n this.addCalibrationNode(oscilator);\n });\n _classPrivateFieldInitSpec(this, _playCalibrationAudioVolume, async () => {\n if (this.numCalibratingRoundsCompleted == 1) {\n this.recordingChecks['warnings'].push(\"1000Hz. Re-record \".concat(this.inDB, \" dB because SD \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\"));\n const currentStatus = \"1000 Hz: Re-recording at \".concat(this.inDB, \" dB because SD \\n \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \\n \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\").toString();\n this.status = this.generateTemplate(currentStatus).toString();\n this.emit('update', {\n message: this.status\n });\n }\n const totalDuration = this.CALIBRATION_TONE_DURATION;\n console.log('this.calibrationNodes', this.calibrationNodes);\n this.calibrationNodes[0].start(0);\n this.calibrationNodes[0].stop(totalDuration);\n console.log(\"Playing a buffer of \".concat(this.CALIBRATION_TONE_DURATION, \" seconds of audio\"));\n console.log(\"Waiting a total of \".concat(totalDuration, \" seconds\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(totalDuration);\n });\n _defineProperty(this, \"stopCalibrationAudioVolume\", () => {\n if (this.calibrationNodes.length > 0) {\n this.calibrationNodes[0].stop();\n }\n this.calibrationNodes = [];\n });\n _classPrivateFieldInitSpec(this, _sendToServerForProcessing, async lCalib => {\n console.log('Sending data to server');\n let left = this.calibrateSound1000HzPreSec;\n let right = this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec;\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getVolumeCalibration({\n sampleRate: this.sourceSamplingRate,\n payload: _classPrivateFieldGet(_getTruncatedSignal, this).call(this, left, right),\n lCalib: lCalib\n }).then(res => {\n //if res is undefined, throw an error\n if (res === undefined) {\n throw new Error('No response from server in getVolumeCalibration function. Please try again.');\n }\n console.log('res', res);\n if (this.outDBSPL === null) {\n this.incrementStatusBar();\n this.outDBSPL = res['outDbSPL'];\n this.outDBSPL1000 = res['outDbSPL1000'];\n this.THD = res['thd'];\n }\n }).catch(err => {\n console.warn(err);\n });\n const rec = this.getLastVolumeRecordedSignal();\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(0, this.calibrateSound1000HzPreSec * this.sourceSamplingRate)).toFixed(1));\n console.log('used period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(this.calibrateSound1000HzPreSec * this.sourceSamplingRate, (this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n console.log('post period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice((this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n const res = (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.volumePowerCheck)(rec, this.sourceSamplingRate || 96000, this.calibrateSound1000HzPreSec, this.calibrateSound1000HzSec, this._calibrateSoundPowerBinDesiredSec, this.calibrateSound1000HzPostSec);\n console.log(res);\n this.recordingChecks['volume'][this.inDB] = res;\n console.log('Recording checks in sendToServer', this.recordingChecks['volume']);\n const getSD = () => this.recordingChecks['volume'][this.inDB]['sd'];\n // const getSDMessage = () => {\n // //SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB. SD = 1.3 dB\n // // And reporting each rejected recording as\n // // SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB, SD = 19.7 > 4 dB.\n\n // if (this.numCalibratingRoundsCompleted == 1)\n // return `. SD = ${getSD()} > ${this.calibrateSound1000HzMaxSD_dB} dB.`;\n // return `. SD = ${getSD()} dB`;\n // };\n // const total_dur =\n // this.calibrateSound1000HzPreSec +\n // this.calibrateSound1000HzSec +\n // this.calibrateSound1000HzPostSec;\n\n // this.addTimeStamp(\n // `${this.calibrateSound1000HzPreSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzPostSec.toFixed(1)} s.` +\n // `1000 Hz at ${this.inDB} dB${getSDMessage()}`\n // );\n });\n _defineProperty(this, \"startCalibrationVolume\", async (stream, gainValues, lCalib, componentGainDBSPL) => {\n if (this.isCalibrating) return null;\n const trialIterations = gainValues.length;\n this.status_denominator += trialIterations;\n const thdValues = [];\n const inDBValues = [];\n let inDB = 0;\n const outDBSPLValues = [];\n const outDBSPL1000Values = [];\n let checkRec = 'loudest';\n // do one calibration that will be discarded\n const soundLevelToDiscard = -60;\n const gainToDiscard = Math.pow(10, soundLevelToDiscard / 20);\n this.inDB = soundLevelToDiscard;\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(soundLevelToDiscard, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.startTime = new Date().getTime();\n this.calibrationNodes = [];\n\n // Check if simulation is enabled (both impulse responses are available)\n const simulationEnabled = this.calibrateSoundSimulateMicrophone !== null && this.calibrateSoundSimulateLoudspeaker !== null;\n if (simulationEnabled) {\n console.log('Using simulation mode with provided impulse responses');\n // Generate the calibration tone signal for simulation\n const calibrationToneSignal = this.generateCalibrationToneSignal(gainToDiscard);\n\n // Run the simulation for initial calibration\n await this.simulatedVolumeCalibrationSteps(calibrationToneSignal, this.calibrateSoundSimulateLoudspeaker1000Hz, this.calibrateSoundSimulateMicrophone1000Hz, _classPrivateFieldGet(_sendToServerForProcessing, this), lCalib, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } else {\n // Use actual recording mode\n do {\n console.log('while loop');\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainToDiscard, lCalib,\n //todo make this a class parameter\n checkRec, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n }\n\n //reset the values\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n\n // run the calibration at different gain values provided by the user\n for (let i = 0; i < trialIterations; i++) {\n //convert gain to DB and add to inDB\n if (i == trialIterations - 1) {\n checkRec = 'loudest';\n }\n inDB = Math.log10(gainValues[i]) * 20;\n // precision to 1 decimal place\n inDB = Math.round(inDB * 10) / 10;\n this.inDB = inDB;\n inDBValues.push(inDB);\n console.log('next update');\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(inDB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (simulationEnabled) {\n console.log('simulationEnabled', gainValues[i]);\n // Generate the calibration tone signal for current gain value\n const calibrationToneSignal = this.generateCalibrationToneSignal(gainValues[i]);\n\n // Run the simulation for this gain value\n await this.simulatedVolumeCalibrationSteps(calibrationToneSignal, this.calibrateSoundSimulateLoudspeaker1000Hz, this.calibrateSoundSimulateMicrophone1000Hz, _classPrivateFieldGet(_sendToServerForProcessing, this), lCalib, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } else {\n // Use actual recording mode\n do {\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainValues[i], lCalib,\n //todo make this a class parameter\n checkRec, () => {\n var _this$recordingChecks;\n return ((_this$recordingChecks = this.recordingChecks) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks['volume']) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks[this.inDB]) === null || _this$recordingChecks === void 0 ? void 0 : _this$recordingChecks['sd']) || 0;\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n }\n outDBSPL1000Values.push(this.outDBSPL1000);\n thdValues.push(this.THD);\n outDBSPLValues.push(this.outDBSPL);\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n }\n if (this.isCalibrating) return null;\n // get the volume calibration parameters from the server\n this.addTimeStamp('Compute 1000 Hz calibration parameters');\n console.log('inDBValues', inDBValues);\n console.log('outDBSPL1000Values', outDBSPL1000Values);\n console.log('lCalib', lCalib);\n console.log('componentGainDBSPL', componentGainDBSPL);\n const parameters = await this.pyServerAPI.getVolumeCalibrationParameters({\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPL1000Values,\n lCalib: lCalib,\n componentGainDBSPL\n }).then(res => {\n this.incrementStatusBar();\n return res;\n }).catch(err => {\n throw err;\n });\n if (this.isCalibrating) return null;\n const result = {\n parameters: parameters,\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPLValues,\n outDBSPL1000Values: outDBSPL1000Values,\n thdValues: thdValues\n };\n return result;\n });\n _defineProperty(this, \"writeFrqGainToFirestore\", async (speakerID, frq, gain, OEM, documentID) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n // const sampledFrq = [];\n // const sampledGain = [];\n // for (let i = 0; i < frq.length; i += 100) {\n // sampledFrq.push(frq[i]);\n // sampledGain.push(gain[i]);\n // }\n\n const data = {\n Freq: frq,\n Gain: gain\n };\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n linear: data\n });\n\n // divide frq and gain into smaller chunks and write to firestore one chunk at a time\n // use arrayUnion to append to the array\n // const chunkSize = 600;\n // const chunkedFrq = [];\n // const chunkedGain = [];\n // for (let i = 0; i < frq.length; i += chunkSize) {\n // chunkedFrq.push(frq.slice(i, i + chunkSize));\n // chunkedGain.push(gain.slice(i, i + chunkSize));\n // }\n // const docRef = doc(database, 'Microphones', documentID);\n // for (let i = 0; i < chunkedFrq.length; i++) {\n // await updateDoc(docRef, {\n // linear: {\n // Freq: arrayUnion(...chunkedFrq[i]),\n // Gain: arrayUnion(...chunkedGain[i]),\n // },\n // });\n // }\n });\n // function to write frq and gain to firebase database given speakerID\n _defineProperty(this, \"writeFrqGain\", async (speakerID, frq, gain, OEM) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n\n const sampledFrq = [];\n const sampledGain = [];\n for (let i = 0; i < frq.length; i += 100) {\n sampledFrq.push(frq[i]);\n sampledGain.push(gain[i]);\n }\n const data = {\n Freq: sampledFrq,\n Gain: sampledGain\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")), data);\n });\n // Function to Read frq and gain from firebase database given speakerID\n // returns an array of frq and gain if speakerID exists, returns null otherwise\n _defineProperty(this, \"readFrqGainFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the linear field of the first document\n if (querySnapshot.size > 0) {\n const timestamp = new firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.Timestamp(querySnapshot.docs[0].data().createDate.seconds, querySnapshot.docs[0].data().createDate.nanoseconds);\n return {\n ir: querySnapshot.docs[0].data().linear,\n createDate: timestamp.toDate(),\n jsonFileName: querySnapshot.docs[0].data().jsonFileName\n };\n }\n return null;\n });\n _defineProperty(this, \"readFrqGain\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000HzFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the Gain1000 field of the first document\n if (querySnapshot.size > 0) {\n return querySnapshot.docs[0].data().Gain1000;\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000Hz\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"writeGainat1000HzToFirestore\", async (speakerID, gain, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n Gain1000: gain\n });\n });\n _defineProperty(this, \"writeGainat1000Hz\", async (speakerID, gain, OEM) => {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")), gain);\n });\n _defineProperty(this, \"writeIsSmartPhoneToFirestore\", async (speakerID, isSmartPhone, OEM) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', true));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n if (querySnapshot.size > 0) {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: false\n });\n return docRef.id;\n } else {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: true\n });\n return docRef.id;\n }\n });\n _defineProperty(this, \"writeIsSmartPhone\", async (speakerID, isSmartPhone, OEM) => {\n const data = {\n isSmartPhone: isSmartPhone\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/isSmartPhone\")), isSmartPhone);\n });\n _defineProperty(this, \"writeMicrophoneInfoToFirestore\", async (speakerID, micInfo, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.setDoc)(docRef, micInfo, {\n merge: true\n });\n });\n _defineProperty(this, \"doesMicrophoneExistInFirestore\", async (speakerID, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphone', OEM, speakerID, documentID);\n const docSnap = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDoc)(docRef);\n if (docSnap.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"doesMicrophoneExist\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID)));\n if (snapshot.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"addMicrophoneInfo\", async (speakerID, OEM, micInfo) => {\n // add to database if /info does not exist\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")));\n if (!snapshot.exists()) {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")), micInfo);\n }\n });\n _defineProperty(this, \"convertToDB\", gain => {\n return Math.log10(gain) * 20;\n });\n _defineProperty(this, \"findGainatFrequency\", (frequencies, gains, targetFrequency) => {\n // Find the index of the first frequency in the array greater than the target frequency\n let index = 0;\n while (index < frequencies.length && frequencies[index] < targetFrequency) {\n index++;\n }\n\n // Handle cases when the target frequency is outside the range of the given data\n if (index === 0) {\n return gains[0];\n } else if (index === frequencies.length) {\n return gains[gains.length - 1];\n } else {\n // Interpolate the gain based on the surrounding frequencies\n const x0 = frequencies[index - 1];\n const y0 = gains[index - 1];\n const x1 = frequencies[index];\n const y1 = gains[index];\n return this.interpolate(targetFrequency, x0, y0, x1, y1);\n }\n });\n _defineProperty(this, \"checkPowerVariation\", async () => {\n let recordings = this.getAllFilteredRecordedSignals();\n // remove filteredMLSAttenuation from the recordings\n\n // recordings = recordings.map(recording => {\n // if (this.soundCheck == 'component') {\n // return recording.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return recording.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n const rec = recordings[recordings.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const payload_downsampled = this.downsampleSignal(rec, this._calibrateSoundBurstDownsample);\n await this.pyServerAPI.allHzPowerCheck({\n payload: payload_downsampled,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this._calibrateSoundBurstRepeats,\n warmUp: this._calibrateSoundBurstPreSec,\n downsample: this._calibrateSoundBurstDownsample\n }).then(result => {\n if (result) {\n const total_dur = this._calibrateSoundBurstPreSec + this._calibrateSoundBurstRepeats * this._calibrateSoundBurstSec + this._calibrateSoundBurstPostSec;\n let soundCheckLabel;\n if (this.soundCheck === 'component') {\n soundCheckLabel = 'speaker or mic';\n } else if (this.soundCheck === 'speakerAndMic') {\n soundCheckLabel = 'speaker+mic';\n } else {\n soundCheckLabel = this.soundCheck;\n }\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(soundCheckLabel, \" IIR. SD = \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.recordingChecks['warnings'].push(\"All Hz. Re-record \".concat(this.inDB, \" because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n // numSuccessfulCaptured no longer to count number of successful capture but count attemps\n // is sd below _calibrateSoundBurstMaxSD_dB then count two attemps\n // else count one attemp\n this.numSuccessfulCaptured += 1;\n } else {\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(soundCheckLabel, \" IIR. SD = \").concat(result['sd'], \" \").concat(result['sd'] > this._calibrateSoundBurstMaxSD_dB ? '>' : '<=', \" \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n console.log('this.recordingChecks: ', this.recordingChecks);\n console.log('this.soundCheck: ', this.soundCheck);\n if (this.recordingChecks[this.soundCheck]) {\n this.recordingChecks[this.soundCheck].push(result);\n } else {\n this.recordingChecks[this.soundCheck] = [result];\n }\n // Now we do at most 2 attempts if sd > _calibrateSoundBurstMaxSD_dB\n // Second attempt is the final\n if (this.numSuccessfulCaptured < 2) {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n this.incrementStatusBar();\n console.log('after mls w iir record for some reason add numSucc capt ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \" recording of convolved MLS captured\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n }\n }\n });\n });\n _defineProperty(this, \"getGainDBSPL\", () => {\n var freqIndex = this.componentIR.Freq.indexOf(1000);\n\n // If freqIndex is not -1 (meaning 1000 is found in the freq array)\n if (freqIndex !== -1) {\n // Get the corresponding gain value using the index\n var gainValue = this.componentIR.Gain[freqIndex];\n return gainValue;\n } else {\n console.log('Freq 1000 not found in the array.');\n return null;\n }\n });\n // Example of how to use the writeFrqGain and readFrqGain functions\n // writeFrqGain('speaker1', [1, 2, 3], [4, 5, 6]);\n // Speaker1 is the speakerID you want to write to in the database\n // readFrqGain('MiniDSPUMIK_1').then(data => console.log(data));\n // MiniDSPUMIK_1 is the speakerID with some Data in the database\n //adding gainDBSPL\n _defineProperty(this, \"startCalibration\", async function (stream, gainValues) {\n var _this$deviceInfo, _this$deviceInfo2;\n let lCalib = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 104.92978421490648;\n let componentIR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n let microphoneName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'MiniDSP-UMIK1-711-4754-vertical';\n let _calibrateSoundCheck = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'speakerOrMic';\n let isSmartPhone = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;\n let _calibrateSoundBurstDb = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : -18;\n let _calibrateSoundBurstFilteredExtraDb = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 6;\n let _calibrateSoundBurstLevelReTBool = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;\n let _calibrateSoundBurstUses1000HzGainBool = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let _calibrateSoundBurstRepeats = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : 3;\n let _calibrateSoundBurstSec = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : 1;\n let _calibrateSoundBurstPreSec = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : 1;\n let _calibrateSoundBurstPostSec = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : 1;\n let _calibrateSoundHz = arguments.length > 15 && arguments[15] !== undefined ? arguments[15] : 48000;\n let _calibrateSoundIRSec = arguments.length > 16 && arguments[16] !== undefined ? arguments[16] : 0.2;\n let _calibrateSoundIIRSec = arguments.length > 17 && arguments[17] !== undefined ? arguments[17] : 0.2;\n let _calibrateSoundIIRPhase = arguments.length > 18 && arguments[18] !== undefined ? arguments[18] : 'linear';\n let calibrateSound1000HzPreSec = arguments.length > 19 && arguments[19] !== undefined ? arguments[19] : 0.5;\n let calibrateSound1000HzSec = arguments.length > 20 && arguments[20] !== undefined ? arguments[20] : 0.5;\n let calibrateSound1000HzPostSec = arguments.length > 21 && arguments[21] !== undefined ? arguments[21] : 0.5;\n let _calibrateSoundBackgroundSecs = arguments.length > 22 && arguments[22] !== undefined ? arguments[22] : 0;\n let _calibrateSoundSmoothOctaves = arguments.length > 23 && arguments[23] !== undefined ? arguments[23] : 0.33;\n let _calibrateSoundSmoothMinBandwidthHz = arguments.length > 24 && arguments[24] !== undefined ? arguments[24] : 200;\n let _calibrateSoundPowerBinDesiredSec = arguments.length > 25 && arguments[25] !== undefined ? arguments[25] : 0.2;\n let _calibrateSoundPowerDbSDToleratedDb = arguments.length > 26 && arguments[26] !== undefined ? arguments[26] : 1;\n let _calibrateSoundTaperSec = arguments.length > 27 && arguments[27] !== undefined ? arguments[27] : 0.01;\n let micManufacturer = arguments.length > 28 && arguments[28] !== undefined ? arguments[28] : '';\n let micSerialNumber = arguments.length > 29 && arguments[29] !== undefined ? arguments[29] : '';\n let micModelNumber = arguments.length > 30 && arguments[30] !== undefined ? arguments[30] : '';\n let micModelName = arguments.length > 31 && arguments[31] !== undefined ? arguments[31] : '';\n let calibrateMicrophonesBool = arguments.length > 32 ? arguments[32] : undefined;\n let authorEmails = arguments.length > 33 ? arguments[33] : undefined;\n let webAudioDeviceNames = arguments.length > 34 && arguments[34] !== undefined ? arguments[34] : {\n loudspeaker: 'loudspeaker',\n microphone: 'microphone',\n microphoneText: 'xxx XXX'\n };\n let userIDs = arguments.length > 35 ? arguments[35] : undefined;\n let restartButton = arguments.length > 36 ? arguments[36] : undefined;\n let reminder = arguments.length > 37 ? arguments[37] : undefined;\n let calibrateSoundLimit = arguments.length > 38 ? arguments[38] : undefined;\n let _calibrateSoundBurstNormalizeBy1000HzGainBool = arguments.length > 39 && arguments[39] !== undefined ? arguments[39] : false;\n let _calibrateSoundBurstScalarDB = arguments.length > 40 && arguments[40] !== undefined ? arguments[40] : 71;\n let calibrateSound1000HzMaxSD_dB = arguments.length > 41 && arguments[41] !== undefined ? arguments[41] : 4;\n let calibrateSound1000HzMaxTries = arguments.length > 42 && arguments[42] !== undefined ? arguments[42] : 4;\n let _calibrateSoundBurstMaxSD_dB = arguments.length > 43 && arguments[43] !== undefined ? arguments[43] : 4;\n let calibrateSoundSamplingDesiredBits = arguments.length > 44 && arguments[44] !== undefined ? arguments[44] : 24;\n let language = arguments.length > 45 ? arguments[45] : undefined;\n let loudspeakerModelName = arguments.length > 46 && arguments[46] !== undefined ? arguments[46] : '';\n let phrases = arguments.length > 47 ? arguments[47] : undefined;\n let soundSubtitleId = arguments.length > 48 ? arguments[48] : undefined;\n let calibrateSoundBurstDownsample = arguments.length > 49 && arguments[49] !== undefined ? arguments[49] : 1;\n let calibrateSoundSimulateMicrophone = arguments.length > 50 && arguments[50] !== undefined ? arguments[50] : null;\n let calibrateSoundSimulateMicrophoneTime = arguments.length > 51 && arguments[51] !== undefined ? arguments[51] : null;\n let calibrateSoundSimulateLoudspeaker = arguments.length > 52 && arguments[52] !== undefined ? arguments[52] : null;\n let calibrateSoundSimulateLoudspeakerTime = arguments.length > 53 && arguments[53] !== undefined ? arguments[53] : null;\n let calibrateSoundSimulateMicrophoneFrequencies = arguments.length > 54 && arguments[54] !== undefined ? arguments[54] : null;\n let calibrateSoundSimulateLoudspeakerFrequencies = arguments.length > 55 && arguments[55] !== undefined ? arguments[55] : null;\n let calibrateSoundSimulateMicrophoneType = arguments.length > 56 && arguments[56] !== undefined ? arguments[56] : 'impulseResponse';\n let calibrateSoundSimulateLoudspeakerType = arguments.length > 57 && arguments[57] !== undefined ? arguments[57] : 'impulseResponse';\n let calibrateSoundSimulateMicrophoneFileName = arguments.length > 58 && arguments[58] !== undefined ? arguments[58] : null;\n let calibrateSoundSimulateLoudspeakerFileName = arguments.length > 59 && arguments[59] !== undefined ? arguments[59] : null;\n let isLoudspeakerCalibration = arguments.length > 60 && arguments[60] !== undefined ? arguments[60] : true;\n _this._calibrateSoundBurstDownsample = calibrateSoundBurstDownsample;\n _this._calibrateSoundBurstPreSec = _calibrateSoundBurstPreSec;\n _this._calibrateSoundBurstRepeats = _calibrateSoundBurstRepeats;\n _this._calibrateSoundBurstSec = _calibrateSoundBurstSec;\n _this.micModelName = micModelName;\n _this.loudspeakerModelName = loudspeakerModelName;\n _this.language = language;\n _this.TAPER_SECS = _calibrateSoundTaperSec;\n _this.calibrateSoundLimit = calibrateSoundLimit;\n _this._calibrateSoundBurstDb = _calibrateSoundBurstDb;\n _this._calibrateSoundBurstFilteredExtraDb = _calibrateSoundBurstFilteredExtraDb;\n _this._calibrateSoundBurstLevelReTBool = _calibrateSoundBurstLevelReTBool;\n _this.CALIBRATION_TONE_DURATION = calibrateSound1000HzPreSec + calibrateSound1000HzSec + calibrateSound1000HzPostSec;\n _this.calibrateSound1000HzPreSec = calibrateSound1000HzPreSec;\n _this.calibrateSound1000HzSec = calibrateSound1000HzSec;\n _this.calibrateSound1000HzPostSec = calibrateSound1000HzPostSec;\n\n // Set simulation impulse responses\n _this.calibrateSoundSimulateMicrophone = calibrateSoundSimulateMicrophone;\n _this.calibrateSoundSimulateLoudspeaker = calibrateSoundSimulateLoudspeaker;\n _this.calibrateSoundSimulateMicrophoneFileName = calibrateSoundSimulateMicrophoneFileName;\n _this.calibrateSoundSimulateLoudspeakerFileName = calibrateSoundSimulateLoudspeakerFileName;\n const fMLS = _this.sourceSamplingRate / _this._calibrateSoundBurstDownsample;\n _this.iirLength = Math.floor(_calibrateSoundIIRSec * fMLS);\n _this.irLength = Math.floor(_calibrateSoundIRSec * fMLS);\n _this.calibrateSoundIIRPhase = _calibrateSoundIIRPhase;\n _this.num_mls_to_skip = Math.ceil(_calibrateSoundBurstPreSec / _calibrateSoundBurstSec);\n _this._calibrateSoundBurstPostSec = _calibrateSoundBurstPostSec;\n _this.numMLSPerCapture = _calibrateSoundBurstRepeats + _this.num_mls_to_skip;\n _this.desired_time_per_mls = _calibrateSoundBurstSec;\n _this.desired_sampling_rate = _calibrateSoundHz;\n _this._calibrateSoundBackgroundSecs = _calibrateSoundBackgroundSecs;\n _this._calibrateSoundSmoothOctaves = _calibrateSoundSmoothOctaves;\n _this._calibrateSoundSmoothMinBandwidthHz = _calibrateSoundSmoothMinBandwidthHz;\n _this._calibrateSoundPowerBinDesiredSec = _calibrateSoundPowerBinDesiredSec;\n _this._calibrateSoundBurstUses1000HzGainBool = _calibrateSoundBurstUses1000HzGainBool;\n _this._calibrateSoundPowerDbSDToleratedDb = _calibrateSoundPowerDbSDToleratedDb;\n _this._calibrateSoundBurstNormalizeBy1000HzGainBool = _calibrateSoundBurstNormalizeBy1000HzGainBool;\n _this._calibrateSoundBurstScalarDB = _calibrateSoundBurstScalarDB;\n _this.webAudioDeviceNames = webAudioDeviceNames;\n _this.calibrateSoundSamplingDesiredBits = calibrateSoundSamplingDesiredBits;\n _this.phrases = phrases;\n _this.soundSubtitleId = soundSubtitleId;\n const simulationEnabled = _this.calibrateSoundSimulateMicrophone !== null && _this.calibrateSoundSimulateLoudspeaker !== null;\n //pre + repeats * sec + post\n const allHzDuation = _this._calibrateSoundBurstPreSec + _this._calibrateSoundBurstRepeats * _this._calibrateSoundBurstSec + _this._calibrateSoundBurstPostSec;\n\n //feed calibration goal here\n _this._calibrateSoundCheck = _calibrateSoundCheck;\n _this.calibrateSound1000HzMaxSD_dB = calibrateSound1000HzMaxSD_dB;\n _this.calibrateSound1000HzMaxTries = calibrateSound1000HzMaxTries;\n _this._calibrateSoundBurstMaxSD_dB = _calibrateSoundBurstMaxSD_dB;\n _this.simulatedMicrophoneIR = null;\n _this.simulatedLoudspeakerIR = null;\n //check if a componentIR was given to the system, if it isn't check for the microphone. using dummy data here bc we need to\n //check the db based on the microphone currently connected\n\n //new lCalib found at top of calibration files *1000hz, make sure to correct\n //based on zeroing of 1000hz, search for \"*1000Hz\"\n const ID = isSmartPhone ? micModelNumber : micSerialNumber;\n const OEM = isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'minidsp' : _this.deviceInfo.OEM ? _this.deviceInfo.OEM.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('');\n // const ID = \"712-5669\";\n // const OEM = \"minidsp\";\n const micInfo = {\n micModelName: isSmartPhone ? micModelName : microphoneName,\n OEM: isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'miniDSP' : _this.deviceInfo.OEM : micManufacturer,\n ID: ID,\n createDate: new Date(),\n DateText: (0,_utils__WEBPACK_IMPORTED_MODULE_8__.getCurrentTimeString)(),\n HardwareName: isSmartPhone ? _this.deviceInfo.hardwarename : microphoneName,\n hardwareFamily: isSmartPhone ? _this.deviceInfo.hardwarefamily : microphoneName,\n HardwareModel: isSmartPhone ? _this.deviceInfo.hardwaremodel : microphoneName,\n PlatformName: isSmartPhone ? _this.deviceInfo.platformname : 'N/A',\n PlatformVersion: isSmartPhone ? _this.deviceInfo.platformversion : 'N/A',\n DeviceType: isSmartPhone ? _this.deviceInfo.devicetype : 'N/A',\n ID_from_51Degrees: isSmartPhone ? _this.deviceInfo.DeviceId : 'N/A',\n calibrateMicrophonesBool: calibrateMicrophonesBool,\n screenHeight: (_this$deviceInfo = _this.deviceInfo) === null || _this$deviceInfo === void 0 ? void 0 : _this$deviceInfo.screenHeight,\n screenWidth: (_this$deviceInfo2 = _this.deviceInfo) === null || _this$deviceInfo2 === void 0 ? void 0 : _this$deviceInfo2.screenWidth,\n webAudioDeviceNames: {\n loudspeaker: _this.webAudioDeviceNames.loudspeaker,\n microphone: _this.webAudioDeviceNames.microphone\n },\n userIDs: userIDs,\n lowercaseOEM: OEM ? OEM.toLowerCase().split(' ').join('') : ''\n };\n if (calibrateMicrophonesBool) {\n micInfo['authorEmails'] = authorEmails;\n }\n // if undefined in micInfo, set to empty string\n for (const [key, value] of Object.entries(micInfo)) {\n if (value === undefined) {\n micInfo[key] = '';\n }\n }\n\n // this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, 'default');\n // this.addMicrophoneInfo(ID, OEM, micInfo);\n if (!simulationEnabled) {\n if (componentIR == null) {\n //mode 'ir'\n //global variable this.componentIR must be set\n await _this.readFrqGainFromFirestore(ID, OEM, true).then(data => {\n if (data !== null) {\n _this.componentIR = data.ir;\n micInfo['parentTimestamp'] = data.createDate ? data.createDate : new Date();\n micInfo['parentFilenameJSON'] = data.jsonFileName ? data.jsonFileName : '';\n }\n });\n\n // await this.readFrqGain(ID, OEM).then(data => {\n // return data;\n // });\n\n // lCalib = await this.readGainat1000Hz(ID, OEM);\n lCalib = await _this.readGainat1000HzFromFirestore(ID, OEM, true);\n micInfo['gainDBSPL'] = lCalib;\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n //TODO: if this call to database is unknown, cannot perform experiment => return false\n if (_this.componentIR == null) {\n _this.status = \"Microphone (\".concat(OEM, \",\").concat(ID, \") is not found in the database. Please add it to the database.\").toString();\n _this.emit('update', {\n message: _this.status\n });\n return false;\n }\n } else {\n _this.transducerType = 'Microphone';\n _this.componentIR = componentIR;\n lCalib = _this.findGainatFrequency(_this.componentIR.Freq, _this.componentIR.Gain, 1000);\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n // await this.writeIsSmartPhone(ID, isSmartPhone, OEM);\n }\n } else {\n //simulation.\n if (calibrateSoundSimulateMicrophoneType === 'impulseResponse') {\n const frequencyResponse = await _this.pyServerAPI.getFrequencyResponseFromImpulseResponse({\n impulseResponse: _this.calibrateSoundSimulateMicrophone,\n sampleRate: _this.sourceSamplingRate,\n timeArray: calibrateSoundSimulateMicrophoneTime,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n _this.calibrateSoundSimulateMicrophone = frequencyResponse.impulse_response;\n _this.calibrateSoundSimulateMicrophone1000Hz = frequencyResponse.impulse_response_1000hz;\n _this.simulatedMicrophoneIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n if (isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n _this.componentGainDBSPL = frequencyResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n micInfo['gainDBSPL'] = lCalib;\n }\n } else {\n const impulseResponse = await _this.pyServerAPI.getImpulseResponseFromFrequencyResponse({\n frequencies: calibrateSoundSimulateMicrophoneFrequencies,\n gains: _this.calibrateSoundSimulateMicrophone,\n sample_rate: _this.sourceSamplingRate,\n iir_length: _this.iirLength,\n calibrateSoundIIRPhase: _this.calibrateSoundIIRPhase,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n if (isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.componentGainDBSPL = impulseResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n micInfo['gainDBSPL'] = lCalib;\n }\n _this.simulatedMicrophoneIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.calibrateSoundSimulateMicrophone = impulseResponse.impulse_response;\n _this.calibrateSoundSimulateMicrophone1000Hz = impulseResponse.impulse_response_1000hz;\n }\n if (calibrateSoundSimulateLoudspeakerType === 'impulseResponse') {\n const frequencyResponse = await _this.pyServerAPI.getFrequencyResponseFromImpulseResponse({\n impulseResponse: _this.calibrateSoundSimulateLoudspeaker,\n sampleRate: _this.sourceSamplingRate,\n timeArray: calibrateSoundSimulateLoudspeakerTime,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n if (!isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n _this.componentGainDBSPL = frequencyResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n }\n _this.calibrateSoundSimulateLoudspeaker = frequencyResponse.impulse_response;\n _this.calibrateSoundSimulateLoudspeaker1000Hz = frequencyResponse.impulse_response_1000hz;\n _this.simulatedLoudspeakerIR = {\n Freq: frequencyResponse.frequencies,\n Gain: frequencyResponse.gains\n };\n } else {\n const impulseResponse = await _this.pyServerAPI.getImpulseResponseFromFrequencyResponse({\n frequencies: calibrateSoundSimulateLoudspeakerFrequencies,\n gains: _this.calibrateSoundSimulateLoudspeaker,\n sample_rate: _this.sourceSamplingRate,\n iir_length: _this.iirLength,\n calibrateSoundIIRPhase: _this.calibrateSoundIIRPhase,\n totalDuration: allHzDuation,\n totalDuration1000Hz: _this.CALIBRATION_TONE_DURATION\n });\n _this.simulatedLoudspeakerIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n if (!isLoudspeakerCalibration) {\n _this.componentIR = {\n Freq: impulseResponse.frequencies,\n Gain: impulseResponse.gains\n };\n _this.componentGainDBSPL = impulseResponse.gain_at_1000hz;\n lCalib = _this.componentGainDBSPL;\n }\n _this.calibrateSoundSimulateLoudspeaker = impulseResponse.impulse_response;\n _this.calibrateSoundSimulateLoudspeaker1000Hz = impulseResponse.impulse_response_1000hz;\n }\n }\n _this.oldComponentIR = JSON.parse(JSON.stringify(_this.componentIR));\n return await new Promise(async (resolve, reject) => {\n // add event listner to params.restartButton to resolve the promise with a string: 'restart'\n\n if (reminder) {\n reminder.style.display = '';\n }\n if (restartButton) {\n restartButton.style.display = '';\n restartButton.addEventListener('click', () => {\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n restartButton.style.display = 'none';\n if (reminder) {\n reminder.style.display = 'none';\n }\n _this.emit('update', {\n message: 'Restarting calibration...'\n });\n resolve('restart');\n });\n }\n await _this.pyServerAPI.checkMemory();\n // calibrate volume\n\n let volumeResults = await _this.startCalibrationVolume(stream, gainValues, lCalib, _this.componentGainDBSPL);\n if (!volumeResults) return;\n _this.T = volumeResults['parameters']['T'];\n _this.gainDBSPL = volumeResults['parameters']['gainDBSPL'];\n\n // end calibrate volume\n\n let impulseResponseResults = await _this.startCalibrationImpulseResponse(stream);\n if (!impulseResponseResults) return;\n impulseResponseResults['background_noise'] = _this.background_noise;\n impulseResponseResults['system']['background_noise'] = _this.background_noise;\n impulseResponseResults['component']['background_noise'] = _this.background_noise;\n\n //attenuate system background noise\n if (_this.systemAttenuatorGainDB != 0 && impulseResponseResults['system']['background_noise']['recording'] && impulseResponseResults['system']['background_noise']['x_background'] && impulseResponseResults['system']['background_noise']['y_background']) {\n let linearScaleAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 10);\n impulseResponseResults['system']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['system']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['system']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n //attenuate component background noise\n if (_this.componentAttentuatorGainDB != 0 && impulseResponseResults['component']['background_noise']['recording'] && impulseResponseResults['component']['background_noise']['x_background'] && impulseResponseResults['component']['background_noise']['y_background']) {\n let linearScaleAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 10);\n impulseResponseResults['component']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['component']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['component']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n impulseResponseResults['system']['attenuatorGainDB'] = _this.systemAttenuatorGainDB;\n impulseResponseResults['component']['attenuatorGainDB'] = _this.componentAttenuatorGainDB;\n impulseResponseResults['system']['fMaxHz'] = _this.systemFMaxHz;\n impulseResponseResults['component']['fMaxHz'] = _this.componentFMaxHz;\n impulseResponseResults['L_new_n'] = _this.L_new_n;\n impulseResponseResults['fs2'] = _this.fs2;\n impulseResponseResults['fMLS'] = _this.sourceSamplingRate / _this._calibrateSoundBurstDownsample;\n if (componentIR != null) {\n var _impulseResponseResul;\n // I corrected microphone/loudpeaker IR scale in easyeyes,\n // but since we write microphone IR to firestore here\n // we need to correct microphone IR here\n let correctGain = Math.round((volumeResults.parameters.gainDBSPL - _this.componentGainDBSPL) * 10) / 10;\n let IrFreq = impulseResponseResults === null || impulseResponseResults === void 0 ? void 0 : impulseResponseResults.component.ir.Freq.map(freq => Math.round(freq));\n let IrGain = impulseResponseResults === null || impulseResponseResults === void 0 || (_impulseResponseResul = impulseResponseResults.component) === null || _impulseResponseResul === void 0 ? void 0 : _impulseResponseResul.ir.Gain;\n const IrGainAt1000Hz = IrGain[IrFreq.findIndex(freq => freq === 1000)];\n const difference = Math.round(10 * (IrGainAt1000Hz - correctGain)) / 10;\n IrGain = IrGain.map(gain => gain - difference);\n micInfo['mls'] = Number(_this.SDofFilteredRange['mls']);\n micInfo['systemCorrectionSD'] = Number(_this.SDofFilteredRange['system']);\n micInfo['componentCorrectionSD'] = Number(_this.SDofFilteredRange['component']);\n console.log(typeof micInfo['componentCorrectionSD']);\n // const id = await this.writeIsSmartPhoneToFirestore(ID, isSmartPhone, OEM);\n // await this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, id);\n // await this.writeFrqGainToFirestore(ID, IrFreq, IrGain, OEM, id);\n // micInfo['gainDBSPL'] = impulseResponseResults.component.gainDBSPL;\n // await this.writeGainat1000HzToFirestore(ID, micInfo['gainDBSPL'], OEM, id);\n // await this.writeGainat1000Hz(ID, micInfo['gainDBSPL'], OEM);\n }\n const total_results = {\n ...volumeResults,\n ...impulseResponseResults\n };\n total_results['filteredMLSRange'] = _this.filteredMLSRange;\n total_results['filteredMLSAttenuation'] = _this.filteredMLSAttenuation;\n total_results['micInfo'] = micInfo;\n total_results['audioInfo'] = {};\n total_results['audioInfo']['sinkSampleRate'] = _this.sinkSamplingRate;\n total_results['audioInfo']['sourceSampleRate'] = _this.sourceSamplingRate;\n total_results['audioInfo']['bitsPerSample'] = _this.sampleSize;\n const timeStampresult = [..._this.timeStamp].join('\\n');\n total_results['timeStamps'] = timeStampresult;\n total_results['recordingChecks'] = _this.recordingChecks;\n total_results['waveforms'] = _this.waveforms;\n total_results['component']['phase'] = _this.componentIRPhase;\n total_results['system']['phase'] = _this.systemIRPhase;\n total_results['qualityMetrics'] = _this.SDofFilteredRange;\n total_results['flags'] = _this.flags;\n total_results['permissionStatus'] = _this.permissionStatus;\n total_results['simulatedMicrophoneIR'] = _this.simulatedMicrophoneIR;\n total_results['simulatedLoudspeakerIR'] = _this.simulatedLoudspeakerIR;\n console.log('total results');\n console.log(total_results);\n console.log('Time Stamps');\n console.log(timeStampresult);\n _this.stopCalibrationAudio();\n resolve(total_results);\n });\n });\n _defineProperty(this, \"generateCalibrationToneSignal\", gainValue => {\n // Generate a 1000Hz sine wave at the specified gain value\n const duration = this.CALIBRATION_TONE_DURATION; // in seconds\n const frequency = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // 1000Hz\n const sampleRate = this.sourceSamplingRate;\n const numSamples = duration * sampleRate;\n const signal = new Array(numSamples);\n for (let i = 0; i < numSamples; i++) {\n const t = i / sampleRate;\n\n // Base sine wave at specified frequency; scale by sqrt(2) so RMS matches requested dB\n let value = Math.sin(2 * Math.PI * frequency * t) * gainValue * Math.SQRT2;\n\n // Apply taper at beginning and end\n if (t < this.TAPER_SECS) {\n const onsetCurve = Math.pow(Math.sin(Math.PI * t / (2 * this.TAPER_SECS)), 2);\n value *= onsetCurve;\n } else if (t > duration - this.TAPER_SECS) {\n const offsetTime = t - (duration - this.TAPER_SECS);\n const offsetCurve = Math.pow(Math.cos(Math.PI * offsetTime / (2 * this.TAPER_SECS)), 2);\n value *= offsetCurve;\n }\n signal[i] = value;\n }\n return signal;\n });\n _classPrivateFieldSet(_mlsOrder, this, parseInt(mlsOrder, 10));\n _classPrivateFieldSet(_P, this, 2 ** mlsOrder - 1);\n _classPrivateFieldSet(_download, this, download);\n _classPrivateFieldSet(_mls, this, []);\n _classPrivateFieldSet(_lowHz, this, _lowHz2);\n _classPrivateFieldSet(_highHz, this, _highHz2);\n }\n // Function to perform linear interpolation between two points\n interpolate(x, x0, y0, x1, y1) {\n return y0 + (x - x0) * (y1 - y0) / (x1 - x0);\n }\n}\n_defineProperty(Combination, \"createInverseSCurveBuffer\", (length, phase) => {\n const curve = new Float32Array(length);\n let i;\n let j = length - 1;\n for (i = 0; i < length; i += 1) {\n // scale the curve to be between 0-1\n curve[i] = Math.sin(Math.PI * j / length - phase) / 2 + 0.5;\n j -= 1;\n }\n return curve;\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Combination);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/combination/combination.js?");
184
184
 
185
185
  /***/ }),
186
186