tor-browser

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

audioworkletprocessor-unconnected-outputs.https.window.js (4406B)


      1 'use strict';
      2 
      3 // This value is used to set the values in an AudioParam.
      4 const TestValue = 0.5;
      5 
      6 // Prepare 4 outputs; 2 outputs will be unconnected for testing.
      7 const WorkletNodeOptions =  {
      8  processorOptions: {testValue: TestValue},
      9  numberOfInputs: 0,
     10  numberOfOutputs: 4
     11 };
     12 
     13 // The code for the AWP definition in AudioWorkletGlobalScope.
     14 const processorCode = () => {
     15 
     16  // This processor sends the `outputs` array to the main thread at the first
     17  // process call - after filling its 2nd output with the test value.
     18  class OutputTestProcessor extends AudioWorkletProcessor {
     19 
     20    constructor(options) {
     21      super(options);
     22      this.testValue = options.processorOptions.testValue;
     23    }
     24 
     25    process(inputs, outputs) {
     26      // Fill the second output of this process with the `testValue`.
     27      const output = outputs[1];
     28      for (const channel of output) {
     29        channel.fill(this.testValue);
     30      }
     31 
     32      // Send the outputs array and stop rendering.
     33      this.port.postMessage({outputs});
     34      return false;
     35    }
     36  }
     37 
     38  registerProcessor('output-test-processor', OutputTestProcessor);
     39 
     40  // This process has an AudioParam and sends the `params` array to the main
     41  // thread at the first process call.
     42  class ParamTestProcessor extends AudioWorkletProcessor {
     43    static get parameterDescriptors() {
     44      return [
     45        {name: 'testParam', defaultValue: 0.0}
     46      ];
     47    }
     48 
     49    process(inputs, outputs, params) {
     50      // Send the params array and stop rendering.
     51      this.port.postMessage({paramValues: params.testParam});
     52      return false;
     53    }
     54  }
     55 
     56  registerProcessor('param-test-processor', ParamTestProcessor);
     57 }
     58 
     59 const initializeAudioContext = async () => {
     60  const context = new AudioContext();
     61  const moduleString = `(${processorCode.toString()})();`;
     62  const blobUrl = window.URL.createObjectURL(
     63      new Blob([moduleString], {type: 'text/javascript'}));
     64  await context.audioWorklet.addModule(blobUrl);
     65  context.suspend();
     66  return context;
     67 };
     68 
     69 // Test if unconnected outputs provides a non-zero length array for channels.
     70 promise_test(async () => {
     71  const context = await initializeAudioContext();
     72  const outputTester = new AudioWorkletNode(
     73      context, 'output-test-processor', WorkletNodeOptions);
     74  const testGain = new GainNode(context);
     75 
     76  // Connect the 2nd output of the tester to another node. Note that
     77  // `testGain` is not connected to the destination.
     78  outputTester.connect(testGain, 1);
     79 
     80  // Connect the 4th output of the tester to the destination node.
     81  outputTester.connect(context.destination, 3);
     82 
     83  return new Promise(resolve => {
     84    outputTester.port.onmessage = resolve;
     85    context.resume();
     86  }).then(event => {
     87    // The number of outputs should be 4, as specified above.
     88    const outputs = event.data.outputs;
     89    assert_equals(outputs.length, WorkletNodeOptions.numberOfOutputs);
     90    for (const output of outputs) {
     91      // Each output should have 1 channel of audio data per spec.
     92      assert_equals(output.length, 1);
     93      for (const channel of output) {
     94        // Each channel should have a non-zero length array.
     95        assert_true(channel.length > 0);
     96      }
     97    }
     98    context.close();
     99  });
    100 }, 'Test if unconnected outputs provides a non-zero length array for channels');
    101 
    102 // Test if outputs connected to AudioParam provides a non-zero length array for
    103 // channels.
    104 promise_test(async () => {
    105  const context = await initializeAudioContext();
    106  const outputTester = new AudioWorkletNode(
    107      context, 'output-test-processor', WorkletNodeOptions);
    108  const paramTester = new AudioWorkletNode(
    109      context, 'param-test-processor');
    110 
    111  // Connect the 2nd output of the tester to another node's AudioParam.
    112  outputTester.connect(paramTester.parameters.get('testParam'), 1);
    113 
    114  outputTester.connect(context.destination);
    115 
    116  return new Promise(resolve => {
    117    paramTester.port.onmessage = resolve;
    118    context.resume();
    119  }).then(event => {
    120    // The resulting values from AudioParam should be a non-zero length array
    121    // filled with `TestValue` above.
    122    const actualValues = event.data.paramValues;
    123    const expectedValues = (new Array(actualValues.length)).fill(TestValue);
    124    assert_true(actualValues.length > 0);
    125    assert_array_equals(actualValues, expectedValues);
    126    context.close();
    127  });
    128 }, 'Test if outputs connected to AudioParam provides a non-zero length array ' +
    129   'for channels');