async audioFrequencyCheck()

in integration/js/pages/MeetingReadinessCheckerPage.js [106:195]


  async audioFrequencyCheck() {
    let res = undefined;
    try {
      res = await this.driver.executeAsyncScript(async () => {
        let logs = [];
        let callback = arguments[arguments.length - 1];
        const sleep = (milliseconds) => {
          return new Promise(resolve => setTimeout(resolve, milliseconds))
        };

        let successfulToneChecks = 0;
        let totalToneChecks = 0;
        let audioContext = new (window.AudioContext || window.webkitAudioContext)();
        let minToneError = Infinity;
        let maxToneError = -Infinity;
        try {
          let stream = document.getElementById("speaker-test-audio-element").srcObject;
          let source = audioContext.createMediaStreamSource(stream);
          let analyser = audioContext.createAnalyser();
          source.connect(analyser);
          let byteFrequencyData = new Uint8Array(analyser.frequencyBinCount);
          let floatFrequencyData = new Float32Array(analyser.frequencyBinCount);

          await sleep(5000);

          const checkFrequency = (targetReceiveFrequency) => {
            analyser.getFloatFrequencyData(floatFrequencyData);
            let maxBinDb = -Infinity;
            let hotBinFrequency = 0;
            const binSize = audioContext.sampleRate / analyser.fftSize; // default fftSize is 2048
            for (let i = 0; i < floatFrequencyData.length; i++) {
              const v = floatFrequencyData[i];
              if (v > maxBinDb) {
                maxBinDb = v;
                hotBinFrequency = i * binSize;
              }
            }
            const error = Math.abs(hotBinFrequency - targetReceiveFrequency);
            if (maxBinDb > -Infinity) {
              if (error < minToneError) {
                minToneError = error;
              }
              if (error > maxToneError) {
                maxToneError = error;
              }
            }
            if (error <= 2 * binSize) {
              successfulToneChecks++;
            }
            totalToneChecks++;
            return hotBinFrequency
          };

          const checkFrequencyFor = async (runCount, freq) => {
            let i = 0;
            for (i = 0; i < runCount; i++) {
              const testFrequency = checkFrequency(freq);
              logs.push(`Resulting Frequency ${testFrequency}`);
              i++;
              await sleep(100)
            }
          };

          await checkFrequencyFor(50, 440);
        } catch (e) {
          logs.push(`${e}`)
        } finally {
          logs.push(`Frequency check completed`);
          await audioContext.close();
          callback({
            percentage: successfulToneChecks / totalToneChecks,
            logs
          });
        }
      });
    } catch (e) {
      this.logger(`Audio output check failed ${e}`)
    } finally {
      if (res) {
        res.logs.forEach(l => {
          this.logger(l)
        })
      }
    }
    this.logger(`Audio output check success rate: ${res.percentage * 100}%`);
    if (res.percentage >= 0.75) {
      return true
    }
    return false
  }