audioparam-summingjunction.html (4017B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> 5 audioparam-summingjunction.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/mix-testing.js"></script> 11 </head> 12 <body> 13 <script> 14 // Tests that multiple audio-rate signals (AudioNode outputs) 15 // can be connected to an AudioParam and that these signals 16 // are summed, along with the AudioParams intrinsic value. 17 const sampleRate = 44100.0; 18 const lengthInSeconds = 1; 19 20 // Buffers used by the two gain controlling sources. 21 let linearRampBuffer; 22 let toneBuffer; 23 const toneFrequency = 440; 24 // Arbitrary non-zero value. 25 const baselineGain = 5; 26 27 const maxAllowedError = 1e-6; 28 29 function checkResult(renderedBuffer) { 30 let renderedData = renderedBuffer.getChannelData(0); 31 32 // Get buffer data from the two sources used to control gain. 33 const linearRampData = linearRampBuffer.getChannelData(0); 34 const toneData = toneBuffer.getChannelData(0); 35 36 const n = renderedBuffer.length; 37 38 assert_equals(n, linearRampBuffer.length, 'Rendered signal length'); 39 40 // Check that the rendered result exactly matches the sum of the 41 // intrinsic gain plus the two sources used to control gain. This is 42 // because we're changing the gain of a signal having constant value 1. 43 let success = true; 44 for (let i = 0; i < n; ++i) { 45 const expectedValue = baselineGain + linearRampData[i] + toneData[i]; 46 const error = Math.abs(expectedValue - renderedData[i]); 47 48 if (error > maxAllowedError) { 49 success = false; 50 break; 51 } 52 } 53 54 assert_true( 55 success, 56 'Rendered signal matches sum of two audio-rate gain changing ' + 57 'signals plus baseline gain' 58 ); 59 } 60 61 promise_test(async t => { 62 const sampleFrameLength = sampleRate * lengthInSeconds; 63 64 const context = 65 new OfflineAudioContext(1, sampleFrameLength, sampleRate); 66 67 // Create buffer used by the source which will have its gain controlled. 68 const constantOneBuffer = 69 createConstantBuffer(context, sampleFrameLength, 1); 70 let constantSource = new AudioBufferSourceNode(context); 71 constantSource.buffer = constantOneBuffer; 72 73 // Create 1st buffer used to control gain (a linear ramp). 74 linearRampBuffer = createLinearRampBuffer(context, sampleFrameLength); 75 let gainSource1 = new AudioBufferSourceNode(context); 76 gainSource1.buffer = linearRampBuffer; 77 78 // Create 2st buffer used to control gain (a simple sine wave tone). 79 toneBuffer = 80 createToneBuffer(context, toneFrequency, lengthInSeconds, 1); 81 let gainSource2 = new AudioBufferSourceNode(context); 82 gainSource2.buffer = toneBuffer; 83 84 // Create a gain node controlling the gain of constantSource and make 85 // the connections. 86 let gainNode = new GainNode(context); 87 88 // Intrinsic baseline gain. 89 // This gain value should be summed with gainSource1 and gainSource2. 90 gainNode.gain.value = baselineGain; 91 92 constantSource.connect(gainNode); 93 gainNode.connect(context.destination); 94 95 // Connect two audio-rate signals to control the .gain AudioParam. 96 gainSource1.connect(gainNode.gain); 97 gainSource2.connect(gainNode.gain); 98 99 // Start all sources at time 0. 100 constantSource.start(0); 101 gainSource1.start(0); 102 gainSource2.start(0); 103 104 const renderedBuffer = await context.startRendering(); 105 checkResult(renderedBuffer); 106 }, 'Test summing junction behavior of AudioParam with multiple ' + 107 'audio-rate sources and intrinsic gain'); 108 </script> 109 </body> 110 </html>