tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test-analyser-resume-after-suspended.html (3108B)


      1 <!doctype html>
      2 <meta name="timeout" content="long">
      3 <title>AnalyzerNode resumed after suspended</title>
      4 <script src=/resources/testharness.js></script>
      5 <script src=/resources/testharnessreport.js></script>
      6 <script>
      7 
      8 function areFloat32ArraysEqual(arr1, arr2) {
      9  if (arr1.length !== arr2.length) {
     10    return false;
     11  }
     12 
     13  for (let i = 0; i < arr1.length; i++) {
     14    if (arr1[i] !== arr2[i]) {
     15      return false;
     16    }
     17  }
     18 
     19  return true;
     20 }
     21 
     22 // This test ensures that calling suspend() does not clear or reset
     23 // the AnalyserNode, and that after resuming the AudioContext,
     24 // it continues retrieving valid data without any interruptions.
     25 promise_test(async () => {
     26  function runTest(resolve) {
     27    const context = new AudioContext();
     28    context.suspend();
     29 
     30    const oscillator = new OscillatorNode(context);
     31    oscillator.connect(context.destination);
     32    oscillator.start();
     33 
     34    const analyser = new AnalyserNode(context);
     35    oscillator.connect(analyser);
     36 
     37    let analyserReadCount = 0;
     38    let lastTime = 0;
     39    // Time between checks in milliseconds.
     40    const interval = 300;
     41 
     42    let previousTimeDomainDataArray =
     43        new Float32Array(analyser.frequencyBinCount);
     44 
     45    // The analyser.getFloatTimeDomainData() is called every 300 ms under
     46    // suspended or resumed state. If it is a suspended state, the value
     47    // from the function should be the same as the previous value. If
     48    // it is a resumed state, the value should be different.
     49    async function readAnalyserData(timestamp) {
     50      if (lastTime === 0) {
     51        lastTime = timestamp;
     52      }
     53 
     54      const elapsed = timestamp - lastTime;
     55 
     56      // Only run the readAnalyserData every 300ms in order to give enough time
     57      // for context to pull the data.
     58      if (elapsed >= interval) {
     59        analyserReadCount++;
     60 
     61        let shouldSkipAsserts = false;
     62        switch (analyserReadCount) {
     63          case 1:
     64            shouldSkipAsserts = true;
     65            break;
     66          case 10:
     67            await context.suspend();
     68            shouldSkipAsserts = true;
     69            break;
     70          case 5:
     71          case 15:
     72            await context.resume();
     73            shouldSkipAsserts = true;
     74            break;
     75          case 20:
     76            oscillator.stop();
     77            resolve();
     78            break;
     79          default:
     80            break;
     81        }
     82 
     83        const timeDomainDataArray =
     84            new Float32Array(analyser.frequencyBinCount);
     85        analyser.getFloatTimeDomainData(timeDomainDataArray);
     86 
     87        if (!shouldSkipAsserts) {
     88          let result = areFloat32ArraysEqual(timeDomainDataArray,
     89                                  previousTimeDomainDataArray);
     90          context.state === 'suspended' ? assert_true(result)
     91                                        : assert_false(result);
     92        }
     93 
     94        previousTimeDomainDataArray.set(timeDomainDataArray);
     95        lastTime = timestamp;
     96      }
     97 
     98      requestAnimationFrame(readAnalyserData);
     99    }
    100 
    101    requestAnimationFrame(readAnalyserData);
    102  }
    103 
    104  return new Promise((resolve) => runTest(resolve));
    105 }, 'AnalyserNode resume after suspended');
    106 </script>