tor-browser

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

audionode-disconnect-audioparam.html (8347B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <title>
      5      audionode-disconnect-audioparam.html
      6    </title>
      7    <script src="/resources/testharness.js"></script>
      8    <script src="/resources/testharnessreport.js"></script>
      9    <script src="/webaudio/resources/audit-util.js"></script>
     10    <script src="/webaudio/resources/audit.js"></script>
     11  </head>
     12  <body>
     13    <script id="layout-test-code">
     14      let renderQuantum = 128;
     15 
     16      let sampleRate = 44100;
     17      let renderDuration = 0.5;
     18      let disconnectTime = 0.5 * renderDuration;
     19 
     20      let audit = Audit.createTaskRunner();
     21 
     22      // Calculate the index for disconnection.
     23      function getDisconnectIndex(disconnectTime) {
     24        let disconnectIndex = disconnectTime * sampleRate;
     25        disconnectIndex = renderQuantum *
     26            Math.floor((disconnectIndex + renderQuantum - 1) / renderQuantum);
     27        return disconnectIndex;
     28      }
     29 
     30      // Get the index of value change.
     31      function getValueChangeIndex(array, targetValue) {
     32        return array.findIndex(function(element, index) {
     33          if (element === targetValue)
     34            return true;
     35        });
     36      }
     37 
     38      // Task 1: test disconnect(AudioParam) method.
     39      audit.define('disconnect(AudioParam)', (task, should) => {
     40        // Creates a buffer source with value [1] and then connect it to two
     41        // gain nodes in series. The output of the buffer source is lowered by
     42        // half
     43        // (* 0.5) and then connected to two |.gain| AudioParams in each gain
     44        // node.
     45        //
     46        //  (1) bufferSource => gain1 => gain2
     47        //  (2) bufferSource => half => gain1.gain
     48        //  (3) half => gain2.gain
     49        //
     50        // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After
     51        // disconnecting (3), it should produce 1.5.
     52        let context =
     53            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
     54        let source = context.createBufferSource();
     55        let buffer1ch = createConstantBuffer(context, 1, 1);
     56        let half = context.createGain();
     57        let gain1 = context.createGain();
     58        let gain2 = context.createGain();
     59 
     60        source.buffer = buffer1ch;
     61        source.loop = true;
     62        half.gain.value = 0.5;
     63 
     64        source.connect(gain1);
     65        gain1.connect(gain2);
     66        gain2.connect(context.destination);
     67        source.connect(half);
     68 
     69        // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the
     70        // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the
     71        // signal by 1.5 (= 1.0 + 0.5).
     72        half.connect(gain1.gain);
     73        half.connect(gain2.gain);
     74 
     75        source.start();
     76 
     77        // Schedule the disconnection at the half of render duration.
     78        context.suspend(disconnectTime).then(function() {
     79          half.disconnect(gain2.gain);
     80          context.resume();
     81        });
     82 
     83        context.startRendering()
     84            .then(function(buffer) {
     85              let channelData = buffer.getChannelData(0);
     86              let disconnectIndex = getDisconnectIndex(disconnectTime);
     87              let valueChangeIndex = getValueChangeIndex(channelData, 1.5);
     88 
     89              // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5]
     90              should(channelData, 'Channel #0').containValues([2.25, 1.5]);
     91              should(valueChangeIndex, 'The index of value change')
     92                  .beEqualTo(disconnectIndex);
     93            })
     94            .then(() => task.done());
     95      });
     96 
     97      // Task 2: test disconnect(AudioParam, output) method.
     98      audit.define('disconnect(AudioParam, output)', (task, should) => {
     99        // Create a 2-channel buffer source with [1, 2] in each channel and
    100        // make a serial connection through gain1 and gain 2. The make the
    101        // buffer source half with a gain node and connect it to a 2-output
    102        // splitter. Connect each output to 2 gain AudioParams respectively.
    103        //
    104        //    (1) bufferSource => gain1 => gain2
    105        //    (2) bufferSource => half => splitter(2)
    106        //    (3) splitter#0 => gain1.gain
    107        //    (4) splitter#1 => gain2.gain
    108        //
    109        // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for
    110        // each channel. After disconnecting (4), it should output 1.5 and 3.
    111        let context =
    112            new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate);
    113        let source = context.createBufferSource();
    114        let buffer2ch = createConstantBuffer(context, 1, [1, 2]);
    115        let splitter = context.createChannelSplitter(2);
    116        let half = context.createGain();
    117        let gain1 = context.createGain();
    118        let gain2 = context.createGain();
    119 
    120        source.buffer = buffer2ch;
    121        source.loop = true;
    122        half.gain.value = 0.5;
    123 
    124        source.connect(gain1);
    125        gain1.connect(gain2);
    126        gain2.connect(context.destination);
    127 
    128        // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain.
    129        // Each splitter's output will be applied to |gain1.gain| and
    130        // |gain2.gain| respectively in an additive fashion.
    131        source.connect(half);
    132        half.connect(splitter);
    133 
    134        // This amplifies the signal by 1.5. (= 1.0 + 0.5)
    135        splitter.connect(gain1.gain, 0);
    136 
    137        // This amplifies the signal by 2. (= 1.0 + 1.0)
    138        splitter.connect(gain2.gain, 1);
    139 
    140        source.start();
    141 
    142        // Schedule the disconnection at the half of render duration.
    143        context.suspend(disconnectTime).then(function() {
    144          splitter.disconnect(gain2.gain, 1);
    145          context.resume();
    146        });
    147 
    148        context.startRendering()
    149            .then(function(buffer) {
    150              let channelData0 = buffer.getChannelData(0);
    151              let channelData1 = buffer.getChannelData(1);
    152 
    153              let disconnectIndex = getDisconnectIndex(disconnectTime);
    154              let valueChangeIndexCh0 = getValueChangeIndex(channelData0, 1.5);
    155              let valueChangeIndexCh1 = getValueChangeIndex(channelData1, 3);
    156 
    157              // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5]
    158              should(channelData0, 'Channel #0').containValues([3, 1.5]);
    159              should(
    160                  valueChangeIndexCh0,
    161                  'The index of value change in channel #0')
    162                  .beEqualTo(disconnectIndex);
    163 
    164              // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3]
    165              should(channelData1, 'Channel #1').containValues([6, 3]);
    166              should(
    167                  valueChangeIndexCh1,
    168                  'The index of value change in channel #1')
    169                  .beEqualTo(disconnectIndex);
    170            })
    171            .then(() => task.done());
    172      });
    173 
    174      // Task 3: exception checks.
    175      audit.define('exceptions', (task, should) => {
    176        let context = new AudioContext();
    177        let gain1 = context.createGain();
    178        let splitter = context.createChannelSplitter(2);
    179        let gain2 = context.createGain();
    180        let gain3 = context.createGain();
    181 
    182        // Connect a splitter to gain nodes and merger so we can test the
    183        // possible ways of disconnecting the nodes to verify that appropriate
    184        // exceptions are thrown.
    185        gain1.connect(splitter);
    186        splitter.connect(gain2.gain, 0);
    187        splitter.connect(gain3.gain, 1);
    188        gain2.connect(gain3);
    189        gain3.connect(context.destination);
    190 
    191        // gain1 is not connected to gain3.gain. Exception should be thrown.
    192        should(
    193            function() {
    194              gain1.disconnect(gain3.gain);
    195            },
    196            'gain1.disconnect(gain3.gain)')
    197            .throw(DOMException, 'InvalidAccessError');
    198 
    199        // When the output index is good but the destination is invalid.
    200        should(
    201            function() {
    202              splitter.disconnect(gain1.gain, 1);
    203            },
    204            'splitter.disconnect(gain1.gain, 1)')
    205            .throw(DOMException, 'InvalidAccessError');
    206 
    207        // When both arguments are wrong, throw IndexSizeError first.
    208        should(
    209            function() {
    210              splitter.disconnect(gain1.gain, 2);
    211            },
    212            'splitter.disconnect(gain1.gain, 2)')
    213            .throw(DOMException, 'IndexSizeError');
    214 
    215        task.done();
    216      });
    217 
    218      audit.run();
    219    </script>
    220  </body>
    221 </html>