automation-changes.html (4678B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>Panner Node Automation</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="../../resources/audit-util.js"></script> 8 </head> 9 10 <body> 11 <script> 12 // Use a power-of-two to eliminate some round-off; otherwise, this isn't 13 // really important. 14 const sampleRate = 16384; 15 16 // Render enough for the test; we don't need a lot. 17 const renderFrames = 2048; 18 19 // Initial panner positionX and final positionX for listener. 20 const positionX = 2000; 21 22 // Create the basic graph for testing which consists of an 23 // oscillator node connected to a panner node. 24 function createGraph(context) { 25 const listener = context.listener; 26 27 listener.positionX.value = 0; 28 listener.positionY.value = 0; 29 listener.positionZ.value = 0; 30 31 const src = new OscillatorNode(context); 32 33 const panner = new PannerNode(context, { 34 distanceModel: 'linear', 35 refDistance: 1, 36 maxDistance: 3000, 37 positionX: positionX, 38 positionY: 0, 39 positionZ: 0 40 }); 41 src.connect(panner).connect(context.destination); 42 43 src.start(); 44 } 45 46 47 // Verify the output from the panner is correct. 48 function verifyOutput(context, moveFrame, prefix) { 49 return context.startRendering().then(resultBuffer => { 50 // Get the outputs (left and right) 51 const c0 = resultBuffer.getChannelData(0); 52 const c1 = resultBuffer.getChannelData(1); 53 54 // The src/listener set up is such that audio should only come 55 // from the right for until |moveFrame|. Hence the left channel 56 // should be 0 (or very nearly 0). 57 const zero = new Float32Array(moveFrame); 58 59 assert_array_equal_within_eps( 60 c0.slice(0, moveFrame), 61 zero, 62 {absoluteThreshold: 1e-16}, 63 `${prefix}: output0[0:${moveFrame - 1}]`); 64 assert_not_constant_value( 65 c1.slice(0, moveFrame), 66 0, 67 `${prefix}: output1[0:${moveFrame - 1}]`); 68 69 // At |moveFrame| and beyond, the listener and source are at the 70 // same position, so the outputs from the left and right should be 71 // identical, and the left channel should not be 0 anymore. 72 assert_not_constant_value( 73 c0.slice(moveFrame), 74 0, 75 `${prefix}: output0[${moveFrame}:]`); 76 assert_array_equal_within_eps( 77 c1.slice(moveFrame), 78 c0.slice(moveFrame), 79 0, 80 `${prefix}: output1[${moveFrame}:]`); 81 }); 82 } 83 84 // Test that listener.positionX.value setter does the right thing. 85 promise_test(async t => { 86 const context = new OfflineAudioContext(2, renderFrames, sampleRate); 87 createGraph(context); 88 89 // Frame at which the listener instantaneously moves to a new location. 90 const moveFrame = 512; 91 92 // Schedule a suspend; when it trips, set the value and resume. 93 context.suspend(moveFrame / context.sampleRate).then(() => { 94 context.listener.positionX.value = positionX; 95 context.resume(); 96 }); 97 98 await verifyOutput(context, moveFrame, 'listener.positionX.value'); 99 }, 'Set Listener.positionX.value'); 100 101 // Test that listener.positionX.setValueAtTime() does the right thing. 102 promise_test(async t => { 103 const context = new OfflineAudioContext(2, renderFrames, sampleRate); 104 createGraph(context); 105 106 // Frame at which the listener instantaneously moves to a new location. 107 const moveFrame = 512; 108 109 context.listener.positionX.setValueAtTime( 110 positionX, moveFrame / context.sampleRate); 111 112 await verifyOutput( 113 context, moveFrame, 'listener.positionX.setValueAtTime'); 114 }, 'Listener.positionX.setValue'); 115 116 // Test that listener.setPosition() does the right thing. 117 promise_test(async t => { 118 const context = new OfflineAudioContext(2, renderFrames, sampleRate); 119 createGraph(context); 120 121 // Frame at which the listener instantaneously moves to a new location. 122 const moveFrame = 512; 123 124 context.suspend(moveFrame / context.sampleRate).then(() => { 125 context.listener.setPosition(positionX, 0, 0); 126 context.resume(); 127 }); 128 129 await verifyOutput( 130 context, moveFrame, 'listener.setPosition'); 131 }, 'Listener.setPosition'); 132 </script> 133 </body> 134 </html>