tor-browser

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

constant-source-output.html (7962B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <title>
      5      Test ConstantSourceNode Output
      6    </title>
      7    <script src="/resources/testharness.js"></script>
      8    <script src="/resources/testharnessreport.js"></script>
      9    <script src="../../resources/audit-util.js"></script>
     10    <script src="../../resources/audit.js"></script>
     11    <script src="../../resources/audioparam-testing.js"></script>
     12  </head>
     13  <body>
     14    <script id="layout-test-code">
     15      let sampleRate = 48000;
     16      let renderDuration = 0.125;
     17      let renderFrames = sampleRate * renderDuration;
     18 
     19      let audit = Audit.createTaskRunner();
     20 
     21      audit.define('constant source', (task, should) => {
     22        // Verify a constant source outputs the correct (fixed) constant.
     23        let context = new OfflineAudioContext(1, renderFrames, sampleRate);
     24        let node = new ConstantSourceNode(context, {offset: 0.5});
     25        node.connect(context.destination);
     26        node.start();
     27 
     28        context.startRendering()
     29            .then(function(buffer) {
     30              let actual = buffer.getChannelData(0);
     31              let expected = new Float32Array(actual.length);
     32              expected.fill(node.offset.value);
     33 
     34              should(actual, 'Basic: ConstantSourceNode({offset: 0.5})')
     35                  .beEqualToArray(expected);
     36            })
     37            .then(() => task.done());
     38      });
     39 
     40      audit.define('stop before start', (task, should) => {
     41        let context = new OfflineAudioContext(1, renderFrames, sampleRate);
     42        let node = new ConstantSourceNode(context, {offset: 1});
     43        node.connect(context.destination);
     44        node.start(61 / context.sampleRate);
     45        node.stop(31 / context.sampleRate);
     46 
     47        context.startRendering()
     48            .then(function(buffer) {
     49                let actual = buffer.getChannelData(0);
     50                should(actual,
     51                       "ConstantSourceNode with stop before " +
     52                           "start must output silence")
     53                  .beConstantValueOf(0);
     54            })
     55            .then(() => task.done());
     56      });
     57 
     58      audit.define('stop equal to start', (task, should) => {
     59          let context = new OfflineAudioContext(1, renderFrames, sampleRate);
     60          let node = new ConstantSourceNode(context, {offset: 1});
     61          node.connect(context.destination);
     62          node.start(31 / context.sampleRate);
     63          node.stop(31 / context.sampleRate);
     64 
     65          context.startRendering()
     66              .then(function(buffer) {
     67                  let actual = buffer.getChannelData(0);
     68                  should(actual,
     69                         "ConstantSourceNode with stop equal to start " +
     70                             " must output silence")
     71                      .beConstantValueOf(0);
     72          })
     73          .then(() => task.done());
     74      });
     75 
     76      audit.define('start/stop', (task, should) => {
     77        // Verify a constant source starts and stops at the correct time and has
     78        // the correct (fixed) value.
     79        let context = new OfflineAudioContext(1, renderFrames, sampleRate);
     80        let node = new ConstantSourceNode(context, {offset: 1});
     81        node.connect(context.destination);
     82 
     83        let startFrame = 10;
     84        let stopFrame = 300;
     85 
     86        node.start(startFrame / context.sampleRate);
     87        node.stop(stopFrame / context.sampleRate);
     88 
     89        context.startRendering()
     90            .then(function(buffer) {
     91              let actual = buffer.getChannelData(0);
     92              let expected = new Float32Array(actual.length);
     93              // The expected output is all 1s from start to stop time.
     94              expected.fill(0);
     95 
     96              for (let k = startFrame; k < stopFrame; ++k) {
     97                expected[k] = node.offset.value;
     98              }
     99 
    100              let prefix = 'start/stop: ';
    101              should(actual.slice(0, startFrame),
    102                     prefix + 'ConstantSourceNode frames [0, ' +
    103                       startFrame + ')')
    104                  .beConstantValueOf(0);
    105 
    106              should(actual.slice(startFrame, stopFrame),
    107                     prefix + 'ConstantSourceNode frames [' +
    108                         startFrame + ', ' + stopFrame + ')')
    109                  .beConstantValueOf(1);
    110 
    111              should(
    112                  actual.slice(stopFrame),
    113                  prefix + 'ConstantSourceNode frames [' + stopFrame +
    114                      ', ' + renderFrames + ')')
    115                  .beConstantValueOf(0);
    116            })
    117            .then(() => task.done());
    118 
    119      });
    120 
    121      audit.define('basic automation', (task, should) => {
    122        // Verify that automation works as expected.
    123        let context = new OfflineAudioContext(1, renderFrames, sampleRate);
    124        let source = context.createConstantSource();
    125        source.connect(context.destination);
    126 
    127        let rampEndTime = renderDuration / 2;
    128        source.offset.setValueAtTime(0.5, 0);
    129        source.offset.linearRampToValueAtTime(1, rampEndTime);
    130 
    131        source.start();
    132 
    133        context.startRendering()
    134            .then(function(buffer) {
    135              let actual = buffer.getChannelData(0);
    136              let expected = createLinearRampArray(
    137                  0, rampEndTime, 0.5, 1, context.sampleRate);
    138 
    139              let rampEndFrame = Math.ceil(rampEndTime * context.sampleRate);
    140              let prefix = 'Automation: ';
    141 
    142              should(actual.slice(0, rampEndFrame),
    143                     prefix + 'ConstantSourceNode.linearRamp(1, 0.5)')
    144                  .beCloseToArray(expected, {
    145                    // Experimentally determined threshold.
    146                    relativeThreshold: 7.1610e-7
    147                  });
    148 
    149              should(actual.slice(rampEndFrame),
    150                     prefix + 'ConstantSourceNode after ramp')
    151                .beConstantValueOf(1);
    152            })
    153            .then(() => task.done());
    154      });
    155 
    156      audit.define('connected audioparam', (task, should) => {
    157        // Verify the constant source output with connected AudioParam produces
    158        // the correct output.
    159        let context = new OfflineAudioContext(2, renderFrames, sampleRate)
    160        context.destination.channelInterpretation = 'discrete';
    161        let source = new ConstantSourceNode(context, {offset: 1});
    162        let osc = context.createOscillator();
    163        let merger = context.createChannelMerger(2);
    164        merger.connect(context.destination);
    165 
    166        source.connect(merger, 0, 0);
    167        osc.connect(merger, 0, 1);
    168        osc.connect(source.offset);
    169 
    170        osc.start();
    171        let sourceStartFrame = 10;
    172        source.start(sourceStartFrame / context.sampleRate);
    173 
    174        context.startRendering()
    175            .then(function(buffer) {
    176              // Channel 0 and 1 should be identical, except channel 0 (the
    177              // source) is silent at the beginning.
    178              let actual = buffer.getChannelData(0);
    179              let expected = buffer.getChannelData(1);
    180              // The expected output should be oscillator + 1 because offset
    181              // is 1.
    182              expected = expected.map(x => 1 + x);
    183              let prefix = 'Connected param: ';
    184 
    185              // The initial part of the output should be silent because the
    186              // source node hasn't started yet.
    187              should(
    188                  actual.slice(0, sourceStartFrame),
    189                  prefix + 'ConstantSourceNode frames [0, ' + sourceStartFrame +
    190                      ')')
    191                  .beConstantValueOf(0);
    192              // The rest of the output should be the same as the oscillator (in
    193              // channel 1)
    194              should(
    195                  actual.slice(sourceStartFrame),
    196                  prefix + 'ConstantSourceNode frames [' + sourceStartFrame +
    197                      ', ' + renderFrames + ')')
    198                  .beCloseToArray(expected.slice(sourceStartFrame), 0);
    199 
    200            })
    201            .then(() => task.done());
    202      });
    203 
    204      audit.run();
    205    </script>
    206  </body>
    207 </html>