test_pannerNodeAtZeroDistance.html (3732B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test PannerNode produces output even when the even when the distance is from the listener is zero</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script type="text/javascript" src="webaudio.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 <pre id="test"> 11 <script class="testbody" type="text/javascript"> 12 13 const BUF_SIZE = 1024; 14 const sampleRate = 44100; 15 var types = [ 16 "equalpower", 17 "HRTF" 18 ] 19 20 async function testMono(panningModel) { 21 var ac = new OfflineAudioContext(2, BUF_SIZE, sampleRate); 22 23 // A sine to be used to fill the buffers 24 function sine(t) { 25 return Math.sin(440 * 2 * Math.PI * t / ac.sampleRate); 26 } 27 28 var monoBuffer = ac.createBuffer(1, BUF_SIZE, ac.sampleRate); 29 for (var i = 0; i < BUF_SIZE; ++i) { 30 monoBuffer.getChannelData(0)[i] = sine(i); 31 } 32 33 var monoSource = ac.createBufferSource(); 34 monoSource.buffer = monoBuffer; 35 monoSource.start(0); 36 37 var panner = new PannerNode(ac, { 38 panningModel, 39 distanceModel: "linear", 40 }); 41 monoSource.connect(panner); 42 43 var panner2 = new PannerNode(ac, { 44 panningModel, 45 distanceModel: "inverse", 46 }); 47 panner.connect(panner2); 48 49 var panner3 = new PannerNode(ac, { 50 panningModel, 51 distanceModel: "exponential" 52 }); 53 panner2.connect(panner3); 54 55 panner3.connect(ac.destination); 56 57 const buffer = await ac.startRendering(); 58 59 if (panningModel == "equalpower") { 60 // Use the input buffer to compare the output. According to the spec, 61 // mono input at zero distance will apply gain = cos(0.5 * Math.PI / 2) 62 // https://webaudio.github.io/web-audio-api/#Spatialzation-equal-power-panning 63 const gain = Math.cos(0.5 * Math.PI / 2); 64 for (var i = 0; i < BUF_SIZE; ++i) { 65 monoBuffer.getChannelData(0)[i] = gain * monoBuffer.getChannelData(0)[i]; 66 } 67 compareChannels(buffer.getChannelData(0), monoBuffer.getChannelData(0)); 68 } else { 69 ok(!isChannelSilent(buffer.getChannelData(0)), 70 "mono panning: expect non-zero left channel"); 71 } 72 // Check symmetry 73 compareChannels(buffer.getChannelData(0), buffer.getChannelData(1)); 74 } 75 76 async function testStereo(panningModel) { 77 var ac = new OfflineAudioContext(2, BUF_SIZE, sampleRate); 78 79 // A sine to be used to fill the buffers 80 function sine(t) { 81 return Math.sin(440 * 2 * Math.PI * t / ac.sampleRate); 82 } 83 84 var stereoBuffer = ac.createBuffer(2, BUF_SIZE, ac.sampleRate); 85 for (var i = 0; i < BUF_SIZE; ++i) { 86 stereoBuffer.getChannelData(0)[i] = sine(i); 87 stereoBuffer.getChannelData(1)[i] = sine(i); 88 } 89 90 var stereoSource = ac.createBufferSource(); 91 stereoSource.buffer = stereoBuffer; 92 stereoSource.start(0); 93 94 var panner = new PannerNode(ac, { 95 panningModel, 96 distanceModel: "linear", 97 }); 98 stereoSource.connect(panner); 99 100 var panner2 = new PannerNode(ac, { 101 panningModel, 102 distanceModel: "inverse", 103 }); 104 panner.connect(panner2); 105 106 var panner3 = new PannerNode(ac, { 107 panningModel, 108 distanceModel: "exponential", 109 }); 110 panner2.connect(panner3); 111 112 panner3.connect(ac.destination); 113 114 const buffer = await ac.startRendering(); 115 if (panningModel == "equalpower") { 116 compareBuffers(buffer, stereoBuffer); 117 } else { 118 ok(!isChannelSilent(buffer.getChannelData(0)), 119 "stereo panning: expect non-zero left channel"); 120 // Check symmetry 121 compareChannels(buffer.getChannelData(0), buffer.getChannelData(1)); 122 } 123 } 124 125 async function test(type) { 126 await promiseHRTFReady(sampleRate); 127 await testMono(type) 128 await testStereo(type); 129 } 130 131 add_task(async function() { 132 for (const panningModel of types) { 133 await test(panningModel); 134 } 135 }); 136 137 </script> 138 </pre> 139 </body> 140 </html>