tor-browser

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

k-rate-delay-connections.html (4403B)


      1 <!doctype html>
      2 <html>
      3  <head>
      4    <title>DelayNode delayTime with k-rate input should match automation</title>
      5    <script src="/resources/testharness.js"></script>
      6    <script src="/resources/testharnessreport.js"></script>
      7    <script src="/webaudio/resources/audit-util.js"></script>
      8  </head>
      9 
     10  <body>
     11    <script>
     12      // Power-of-two sample rate to eliminate round-off errors.
     13      const sampleRate = 8192;
     14 
     15      // Arbitrary test duration (must be ≥ 1s).
     16      const testDurationSeconds = 1.5;
     17 
     18      // Total number of frames based on sample rate and duration.
     19      const totalFrames = sampleRate * testDurationSeconds;
     20 
     21      promise_test(async t => {
     22        // Two channels:  0 = test result, 1 = expected result.
     23        const context = new OfflineAudioContext({
     24          numberOfChannels: 2,
     25          sampleRate: sampleRate,
     26          length: totalFrames
     27        });
     28 
     29        const merger = new ChannelMergerNode(context, {
     30          numberOfInputs: context.destination.channelCount
     31        });
     32        merger.connect(context.destination);
     33 
     34        // Test the DelayNode by having a reference node (refNode) that uses
     35        // k-rate automations of delayTime. The test node (testNode) sets
     36        // delayTime to k-rate with a connected input that has the same
     37        // automation vlaues as the reference node.  The test passes if the
     38        // output from each node is identical to each other.
     39 
     40        const oscillator = new OscillatorNode(context);
     41 
     42        // The end value and time for the linear ramp.  These values are
     43        // chosen so that the delay advances faster than real time.
     44        const rampEndValue = 1.125;
     45        const rampEndTime = 1;
     46 
     47        const refNode = new DelayNode(context);
     48        refNode.delayTime.automationRate = 'k-rate';
     49        refNode.delayTime.setValueAtTime(0, 0);
     50        refNode.delayTime.linearRampToValueAtTime(rampEndValue, rampEndTime);
     51 
     52        const testNode = new DelayNode(context);
     53        testNode.delayTime.automationRate = 'k-rate';
     54 
     55        const modulator = new ConstantSourceNode(context);
     56        modulator.offset.setValueAtTime(0, 0);
     57        modulator.offset.linearRampToValueAtTime(rampEndValue, rampEndTime);
     58        modulator.connect(testNode.delayTime);
     59 
     60        oscillator.connect(testNode).connect(merger, 0, 0);
     61        oscillator.connect(refNode).connect(merger, 0, 1);
     62 
     63        oscillator.start();
     64        modulator.start();
     65 
     66        const renderedBuffer = await context.startRendering();
     67        const actual = renderedBuffer.getChannelData(0);
     68        const expected = renderedBuffer.getChannelData(1);
     69 
     70        // Quick sanity check that output isn't zero.  This means we messed
     71        // up the connections or automations or the buffer source.
     72        assert_not_constant_value(
     73            expected, 0, 'Expected output should not be constant zero');
     74        assert_not_constant_value(
     75            actual, 0, 'Actual output should not be constant zero');
     76 
     77        // Quick sanity check.  The amount of delay after one render is
     78        // endValue * 128 / sampleRate.  But after 1 render, time has
     79        // advanced 128/sampleRate.  Hence, the delay exceeds the time by
     80        // (endValue - 1)*128/sampleRate sec or (endValue - 1)*128 frames.
     81        // This means the output must be EXACTLY zero for this many frames
     82        // in the second render.
     83        const silentFrames = (rampEndValue - 1) * RENDER_QUANTUM_FRAMES;
     84 
     85        assert_strict_constant_value(
     86            actual.slice(
     87                RENDER_QUANTUM_FRAMES, RENDER_QUANTUM_FRAMES + silentFrames),
     88            0,
     89            `output[${RENDER_QUANTUM_FRAMES}` +
     90                `..${RENDER_QUANTUM_FRAMES + silentFrames - 1}] must be silent`
     91        );
     92 
     93        // Next quantum should NOT be silent
     94        assert_not_constant_value(
     95            actual.slice(
     96                RENDER_QUANTUM_FRAMES + silentFrames,
     97                2 * RENDER_QUANTUM_FRAMES),
     98            0,
     99            `output[${RENDER_QUANTUM_FRAMES + silentFrames}` +
    100                `..${2 * RENDER_QUANTUM_FRAMES - 1}] must have signal`
    101        );
    102 
    103        // Compare actual vs expected output
    104        assert_array_equals_exact(
    105            actual,
    106            expected,
    107            'Output from testNode should exactly match reference');
    108      }, 'k-rate DelayNode.delayTime with input matches automation behavior');
    109    </script>
    110  </body>
    111 </html>