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');