tor-browser

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

audiobuffersource-playbackrate-zero.html (3788B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <title>audiobuffersource-playbackrate-zero.html</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      // Sample rate should be power of 128 to observe the change of AudioParam
     12      // at the beginning of rendering quantum. (playbackRate is k-rate) This is
     13      // the minimum sample rate in the valid sample rate range.
     14      const sampleRate = 8192;
     15 
     16      // The render duration in seconds, and the length in samples.
     17      const renderDuration = 1.0;
     18      const renderLength = renderDuration * sampleRate;
     19 
     20      const context = new OfflineAudioContext(1, renderLength, sampleRate);
     21 
     22      promise_test(async t => {
     23        const ramp = new AudioBufferSourceNode(context);
     24        const rampBuffer = createLinearRampBuffer(context, renderLength);
     25        ramp.buffer = rampBuffer;
     26 
     27        ramp.connect(context.destination);
     28        ramp.start();
     29 
     30        // Leave the playbackRate as 1 for the first half, then change it
     31        // to zero at the exact half. The zero playback rate should hold the
     32        // sample value of the buffer index at the moment. (sample-and-hold)
     33        ramp.playbackRate.setValueAtTime(1.0, 0.0);
     34        ramp.playbackRate.setValueAtTime(0.0, renderDuration / 2);
     35 
     36        const renderedBuffer = await context.startRendering();
     37 
     38        const data = renderedBuffer.getChannelData(0);
     39        const rampData = rampBuffer.getChannelData(0);
     40        const half = rampData.length / 2;
     41 
     42        let passed = true;
     43        let i;
     44 
     45        for (i = 1; i < rampData.length; i++) {
     46          if (i < half) {
     47            if (data[i] !== rampData[i]) {
     48              passed = false;
     49              break;
     50            }
     51          } else {
     52            if (data[i] !== rampData[half]) {
     53              passed = false;
     54              break;
     55            }
     56          }
     57        }
     58 
     59        assert_true(
     60            passed,
     61            `The zero playbackRate should hold the sample value. Expected` +
     62                `${rampData[half]} but got ${data[i]} at index ${i}`);
     63      }, 'Synthesize and verify sample-and-hold behavior when playbackRate ' +
     64          'is set to zero halfway');
     65 
     66      promise_test(async t => {
     67        const context = new OfflineAudioContext(1, renderLength, sampleRate);
     68        const rampBuffer = new AudioBuffer({
     69          length: renderLength,
     70          sampleRate: context.sampleRate
     71        });
     72 
     73        const data = new Float32Array(renderLength);
     74        const startValue = 5;
     75 
     76        for (let k = 0; k < data.length; ++k) {
     77          data[k] = k + startValue;
     78        }
     79 
     80        rampBuffer.copyToChannel(data, 0);
     81 
     82        const src = new AudioBufferSourceNode(context, {
     83          buffer: rampBuffer,
     84          playbackRate: 0
     85        });
     86 
     87        src.connect(context.destination);
     88 
     89        // Purposely start the source between frame boundaries
     90        const startFrame = 27.3;
     91        src.start(startFrame / context.sampleRate);
     92 
     93        const audioBuffer = await context.startRendering();
     94        const actualStartFrame = Math.ceil(startFrame);
     95        const audio = audioBuffer.getChannelData(0);
     96 
     97        assert_constant_value(
     98            audio.slice(0, actualStartFrame),
     99            0,
    100            'output before startFrame should be silence: ');
    101        assert_constant_value(
    102            audio.slice(actualStartFrame),
    103            startValue,
    104            `output after startFrame (starting at index ${actualStartFrame}) ` +
    105                `should match start value: `);
    106      }, 'Subsample start with playbackRate 0 should produce sample-and-hold ' +
    107          'from exact start frame');
    108    </script>
    109  </body>
    110 </html>