tor-browser

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

automation-changes.html (4678B)


      1 <!doctype html>
      2 <html>
      3  <head>
      4    <title>Panner Node Automation</title>
      5    <script src="/resources/testharness.js"></script>
      6    <script src="/resources/testharnessreport.js"></script>
      7    <script src="../../resources/audit-util.js"></script>
      8  </head>
      9 
     10  <body>
     11    <script>
     12      // Use a power-of-two to eliminate some round-off; otherwise, this isn't
     13      // really important.
     14      const sampleRate = 16384;
     15 
     16      // Render enough for the test; we don't need a lot.
     17      const renderFrames = 2048;
     18 
     19      // Initial panner positionX and final positionX for listener.
     20      const positionX = 2000;
     21 
     22      // Create the basic graph for testing which consists of an
     23      // oscillator node connected to a panner node.
     24      function createGraph(context) {
     25        const listener = context.listener;
     26 
     27        listener.positionX.value = 0;
     28        listener.positionY.value = 0;
     29        listener.positionZ.value = 0;
     30 
     31        const src = new OscillatorNode(context);
     32 
     33        const panner = new PannerNode(context, {
     34          distanceModel: 'linear',
     35          refDistance: 1,
     36          maxDistance: 3000,
     37          positionX: positionX,
     38          positionY: 0,
     39          positionZ: 0
     40        });
     41        src.connect(panner).connect(context.destination);
     42 
     43        src.start();
     44      }
     45 
     46 
     47      // Verify the output from the panner is correct.
     48      function verifyOutput(context, moveFrame, prefix) {
     49        return context.startRendering().then(resultBuffer => {
     50          // Get the outputs (left and right)
     51          const c0 = resultBuffer.getChannelData(0);
     52          const c1 = resultBuffer.getChannelData(1);
     53 
     54          // The src/listener set up is such that audio should only come
     55          // from the right for until |moveFrame|.  Hence the left channel
     56          // should be 0 (or very nearly 0).
     57          const zero = new Float32Array(moveFrame);
     58 
     59          assert_array_equal_within_eps(
     60              c0.slice(0, moveFrame),
     61              zero,
     62              {absoluteThreshold: 1e-16},
     63              `${prefix}: output0[0:${moveFrame - 1}]`);
     64          assert_not_constant_value(
     65              c1.slice(0, moveFrame),
     66              0,
     67              `${prefix}: output1[0:${moveFrame - 1}]`);
     68 
     69          // At |moveFrame| and beyond, the listener and source are at the
     70          // same position, so the outputs from the left and right should be
     71          // identical, and the left channel should not be 0 anymore.
     72          assert_not_constant_value(
     73              c0.slice(moveFrame),
     74              0,
     75              `${prefix}: output0[${moveFrame}:]`);
     76          assert_array_equal_within_eps(
     77              c1.slice(moveFrame),
     78              c0.slice(moveFrame),
     79              0,
     80              `${prefix}: output1[${moveFrame}:]`);
     81        });
     82      }
     83 
     84      // Test that listener.positionX.value setter does the right thing.
     85      promise_test(async t => {
     86        const context = new OfflineAudioContext(2, renderFrames, sampleRate);
     87        createGraph(context);
     88 
     89        // Frame at which the listener instantaneously moves to a new location.
     90        const moveFrame = 512;
     91 
     92        // Schedule a suspend; when it trips, set the value and resume.
     93        context.suspend(moveFrame / context.sampleRate).then(() => {
     94          context.listener.positionX.value = positionX;
     95          context.resume();
     96        });
     97 
     98        await verifyOutput(context, moveFrame, 'listener.positionX.value');
     99      }, 'Set Listener.positionX.value');
    100 
    101      // Test that listener.positionX.setValueAtTime() does the right thing.
    102      promise_test(async t => {
    103        const context = new OfflineAudioContext(2, renderFrames, sampleRate);
    104        createGraph(context);
    105 
    106        // Frame at which the listener instantaneously moves to a new location.
    107        const moveFrame = 512;
    108 
    109        context.listener.positionX.setValueAtTime(
    110            positionX, moveFrame / context.sampleRate);
    111 
    112        await verifyOutput(
    113            context, moveFrame, 'listener.positionX.setValueAtTime');
    114      }, 'Listener.positionX.setValue');
    115 
    116      // Test that listener.setPosition() does the right thing.
    117      promise_test(async t => {
    118        const context = new OfflineAudioContext(2, renderFrames, sampleRate);
    119        createGraph(context);
    120 
    121        // Frame at which the listener instantaneously moves to a new location.
    122        const moveFrame = 512;
    123 
    124        context.suspend(moveFrame / context.sampleRate).then(() => {
    125          context.listener.setPosition(positionX, 0, 0);
    126          context.resume();
    127        });
    128 
    129        await verifyOutput(
    130            context, moveFrame, 'listener.setPosition');
    131      }, 'Listener.setPosition');
    132    </script>
    133  </body>
    134 </html>