tor-browser

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

audioparam-close.html (5870B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <title>Test AudioParam events very close in time</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  <body>
     10    <script>
     11      // Largest sample rate that is required to be supported and is a power of
     12      // two, to eliminate round-off as much as possible.
     13      const sampleRate = 65536;
     14 
     15      // Only need one render quantum for testing.
     16      const testFrames = 128;
     17 
     18      // Largest representable single-float number
     19      const floatMax = Math.fround(3.4028234663852886e38);
     20 
     21      // epspos is the smallest x such that 1 + x != 1
     22      const epspos = 1.1102230246251568e-16;
     23      // epsneg is the smallest x such that 1 - x != 1
     24      const epsneg = 5.551115123125784e-17;
     25 
     26      promise_test(async t => {
     27        const context = new OfflineAudioContext({
     28          numberOfChannels: 1,
     29          sampleRate,
     30          length: testFrames
     31        });
     32 
     33        const src0 = new ConstantSourceNode(context, {offset: 0});
     34 
     35        // This should always succeed.  We just want to print out a message
     36        // that |src0| is a constant source node for the following
     37        // processing.
     38        assert_equals(
     39            src0, src0,
     40            'src0 = new ConstantSourceNode(context, {offset: 0}) ' +
     41                'should succeed');
     42 
     43        src0.connect(context.destination);
     44 
     45        // Values for the first event (setValue).  |time1| MUST be 0.
     46        const time1 = 0;
     47        const value1 = 10;
     48 
     49        // Values for the second event (linearRamp).  |value2| must be huge,
     50        // and |time2| must be small enough that 1/|time2| overflows a
     51        // single float. This value is the least positive single float.
     52        const time2 = 1.401298464324817e-45;
     53        const value2 = floatMax;
     54 
     55        // These should always succeed; the messages are just informational
     56        // to show the events that we scheduled.
     57        assert_equals(
     58            src0.offset.setValueAtTime(value1, time1),
     59            src0.offset,
     60            `src0.offset.setValueAtTime(${value1}, ${time1}) should ` +
     61                `return AudioParam`);
     62        assert_equals(
     63            src0.offset.linearRampToValueAtTime(value2, time2),
     64            src0.offset,
     65            `src0.offset.linearRampToValueAtTime(${value2}, ${time2}) should ` +
     66                `return AudioParam`);
     67 
     68        src0.start();
     69 
     70        const renderedBuffer = await context.startRendering();
     71        const output = renderedBuffer.getChannelData(0);
     72 
     73        // Since time1 = 0, the output at frame 0 MUST be value1.
     74        assert_equals(
     75            output[0], value1, 'Frame 0 should equal initial value set');
     76 
     77        // Since time2 < 1, output from frame 1 and later must be a
     78        // constant.
     79        assert_array_constant_value(
     80            output.slice(1),
     81            value2,
     82            'Frames 1+ should equal ramp target value');
     83      }, 'NaN should not occur during extreme linearRampToValueAtTime events');
     84 
     85      promise_test(async t => {
     86        const context = new OfflineAudioContext({
     87          numberOfChannels: 1,
     88          sampleRate,
     89          length: testFrames
     90        });
     91 
     92        const src1 = new ConstantSourceNode(context, {offset: 0});
     93 
     94        // This should always succeed.  We just want to print out a message
     95        // that |src1| is a constant source node for the following
     96        // processing.
     97        assert_equals(
     98            src1, src1,
     99            'src1 = new ConstantSourceNode(context, {offset: 0}) ' +
    100                'should succeed');
    101 
    102        src1.connect(context.destination);
    103 
    104        const frameIndex = 1;
    105 
    106        // These time values are arranged so that time1 < frame/sampleRate <
    107        // time2.  This means we need to interpolate to get a value at given
    108        // frame.
    109        //
    110        // The values are not so important, but |value2| should be huge.
    111        const time1 = frameIndex * (1 - epsneg) / context.sampleRate;
    112        const value1 = 1e15;
    113 
    114        const time2 = frameIndex * (1 + epspos) / context.sampleRate;
    115        const value2 = floatMax;
    116 
    117        assert_equals(
    118            src1.offset.setValueAtTime(value1, time1),
    119            src1.offset,
    120            `src1.offset.setValueAtTime(${value1}, ${time1}) should ` +
    121                `return AudioParam`);
    122        assert_equals(
    123            src1.offset.linearRampToValueAtTime(value2, time2),
    124            src1.offset,
    125            `src1.offset.linearRampToValueAtTime(${value2}, ${time2}) should ` +
    126                `return AudioParam`);
    127 
    128        src1.start();
    129 
    130        const renderedBuffer = await context.startRendering();
    131        const output = renderedBuffer.getChannelData(0);
    132 
    133        // Sanity check
    134        assert_not_equals(
    135            time2 - time1, 0,
    136            'Sanity check: time1 and time2 should not be equal');
    137        // Because 0 < time1 < 1, output must be 0 at time 0.
    138        assert_equals(
    139            output[0], 0, 'output[0] should be 0 before any automation');
    140 
    141        // Because time1 < 1/sampleRate < time2, we need to
    142        // interpolate the value between these times to determine the
    143        // output at frame 1.
    144        const sampleTime = frameIndex / context.sampleRate;
    145        const interpolated =
    146            value1 + (value2 - value1) * (sampleTime - time1) / (time2 - time1);
    147        assert_approx_equals(
    148            output[1],
    149            interpolated, 0,
    150            'Interpolated value at frame 1 should match ramp');
    151 
    152        // Because 1 < time2 < 2, the output at frame 2 and higher is
    153        // constant.
    154        assert_array_constant_value(
    155            output.slice(2), value2, 'output[2:] should be constant at value2');
    156      }, 'Interpolation of linear ramp between very close time values');
    157    </script>
    158  </body>
    159 </html>