tor-browser

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

test_delaynode-channel-count-1.html (4581B)


      1 <!DOCTYPE html>
      2 <title>Test that DelayNode output channelCount matches that of the delayed input</title>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script>
      6 // See https://github.com/WebAudio/web-audio-api/issues/25
      7 
      8 // sampleRate is a power of two so that delay times are exact in base-2
      9 // floating point arithmetic.
     10 const SAMPLE_RATE = 32768;
     11 // Arbitrary delay time in frames (but this is assumed a multiple of block
     12 // size below):
     13 const DELAY_FRAMES = 3 * 128;
     14 // Implementations may apply interpolation to input samples, which can spread
     15 // the effect of input with larger channel counts over neighbouring blocks.
     16 // This test ignores enough neighbouring blocks to ignore the effects of
     17 // filter radius of up to this number of frames:
     18 const INTERPOLATION_GRACE = 128;
     19 // Number of frames of DelayNode output that are known to be stereo:
     20 const STEREO_FRAMES = 128;
     21 // The delay will be increased at this frame to switch DelayNode output back
     22 // to mono.
     23 const MONO_OUTPUT_START_FRAME =
     24  DELAY_FRAMES + INTERPOLATION_GRACE + STEREO_FRAMES;
     25 // Number of frames of output that are known to be mono after the known stereo
     26 // and interpolation grace.
     27 const MONO_FRAMES = 128;
     28 // Total length allows for interpolation after effects of stereo input are
     29 // finished and one block to test return to mono output:
     30 const TOTAL_LENGTH =
     31  MONO_OUTPUT_START_FRAME + INTERPOLATION_GRACE + MONO_FRAMES;
     32 // maxDelayTime, is a multiple of block size, because the Gecko implementation
     33 // once had a bug with delayTime = maxDelayTime in this situation:
     34 const MAX_DELAY_FRAMES = TOTAL_LENGTH + INTERPOLATION_GRACE;
     35 
     36 promise_test(() => {
     37  let context = new OfflineAudioContext({numberOfChannels: 1,
     38                                         length: TOTAL_LENGTH,
     39                                         sampleRate: SAMPLE_RATE});
     40 
     41  // Only channel 1 of the splitter is connected to the destination.
     42  let splitter = new ChannelSplitterNode(context, {numberOfOutputs: 2});
     43  splitter.connect(context.destination, 1);
     44 
     45  // A gain node has channelCountMode "max" and channelInterpretation
     46  // "speakers", and so will up-mix a mono input when there is stereo input.
     47  let gain = new GainNode(context);
     48  gain.connect(splitter);
     49 
     50  // The delay node initially outputs a single channel of silence, when it
     51  // does not have enough signal in its history to output what it has
     52  // previously received.  After the delay period, it will then output the
     53  // stereo signal it received.
     54  let delay =
     55      new DelayNode(context,
     56                    {maxDelayTime: MAX_DELAY_FRAMES / context.sampleRate,
     57                     delayTime: DELAY_FRAMES / context.sampleRate});
     58  // Schedule an increase in the delay to return to mono silent output from
     59  // the unfilled portion of the DelayNode's buffer.
     60  delay.delayTime.setValueAtTime(MAX_DELAY_FRAMES / context.sampleRate,
     61                                 MONO_OUTPUT_START_FRAME / context.sampleRate);
     62  delay.connect(gain);
     63 
     64  let stereoMerger = new ChannelMergerNode(context, {numberOfInputs: 2});
     65  stereoMerger.connect(delay);
     66 
     67  let leftOffset = 0.125;
     68  let rightOffset = 0.5;
     69  let leftSource = new ConstantSourceNode(context, {offset: leftOffset});
     70  let rightSource = new ConstantSourceNode(context, {offset: rightOffset});
     71  leftSource.start();
     72  rightSource.start();
     73  leftSource.connect(stereoMerger, 0, 0);
     74  rightSource.connect(stereoMerger, 0, 1);
     75  // Connect a mono source directly to the gain, so that even stereo silence
     76  // will be detected in channel 1 of the gain output because it will cause
     77  // the mono source to be up-mixed.
     78  let monoOffset = 0.25
     79  let monoSource = new ConstantSourceNode(context, {offset: monoOffset});
     80  monoSource.start();
     81  monoSource.connect(gain);
     82 
     83  return context.startRendering().
     84    then((buffer) => {
     85      let output = buffer.getChannelData(0);
     86 
     87      function assert_samples_equal(startIndex, length, expected, description)
     88      {
     89        for (let i = startIndex; i < startIndex + length; ++i) {
     90          assert_equals(output[i], expected, description + ` at ${i}`);
     91        }
     92      }
     93 
     94      assert_samples_equal(0, DELAY_FRAMES - INTERPOLATION_GRACE,
     95                           0, "Initial mono");
     96      assert_samples_equal(DELAY_FRAMES + INTERPOLATION_GRACE, STEREO_FRAMES,
     97                           monoOffset + rightOffset, "Stereo");
     98      assert_samples_equal(MONO_OUTPUT_START_FRAME + INTERPOLATION_GRACE,
     99                           MONO_FRAMES,
    100                           0, "Final mono");
    101    });
    102 });
    103 
    104 </script>