test_convolverNodeNormalization.html (2856B)
1 <!DOCTYPE html> 2 <title>Test normalization of convolution buffers</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script> 6 // Constants from 7 // https://www.w3.org/TR/2015/WD-webaudio-20151208/#widl-ConvolverNode-normalize 8 const GainCalibration = 0.00125; 9 const GainCalibrationSampleRate = 44100; 10 11 const sampleRate = GainCalibrationSampleRate; 12 const LENGTH = 12800; 13 // tolerate 16-bit math. 14 const EPSILON = 1.0 / Math.pow(2, 15); 15 16 function test_normalization_via_response_concat() 17 { 18 var context = new OfflineAudioContext(1, LENGTH, sampleRate); 19 20 var impulse = context.createBuffer(1, 1, sampleRate); 21 impulse.getChannelData(0)[0] = 1.0; 22 var source = context.createBufferSource(); 23 source.buffer = impulse; 24 source.start(0); 25 26 // Construct a set of adjacent responses in such a way that, when each is 27 // convolved with the impulse, they can be merged to produce a constant. 28 29 // The 5/4 ratio provides a range of lengths with different offsets within 30 // blocks. 31 var i = 0; 32 for (var responseEnd = 1; 33 i < LENGTH; 34 responseEnd = Math.floor((5 * responseEnd) / 4) + 1) { 35 var responseBuffer = context.createBuffer(1, responseEnd, sampleRate); 36 var response = responseBuffer.getChannelData(0); 37 var responseStart = i; 38 // The values in the response should be normalized, and so the output 39 // should not be dependent on the value. Pick a changing value to test 40 // this. 41 var value = responseStart + 1; 42 for (; i < responseEnd; ++i) { 43 response[i] = value; 44 } 45 var convolver = context.createConvolver(); 46 convolver.normalize = true; 47 convolver.buffer = responseBuffer; 48 convolver.connect(context.destination); 49 // Undo the normalization calibration by scaling the impulse so as to 50 // expect unit pulse output from the convolver. 51 var gain = context.createGain(); 52 gain.gain.value = 53 Math.sqrt((responseEnd - responseStart) / responseEnd) / GainCalibration; 54 gain.connect(convolver); 55 source.connect(gain); 56 } 57 58 return context.startRendering(). 59 then((buffer) => { 60 var output = buffer.getChannelData(0); 61 var max = output[0]; 62 var maxIndex = 0; 63 var min = max; 64 var minIndex = 0; 65 for (var i = 1; i < buffer.length; ++i) { 66 if (output[i] > max) { 67 max = output[i]; 68 maxIndex = i; 69 } else if (output[i] < min) { 70 min = output[i]; 71 minIndex = i; 72 } 73 } 74 assert_approx_equals(output[maxIndex], 1.0, EPSILON, 75 "max output at " + maxIndex); 76 assert_approx_equals(output[minIndex], 1.0, EPSILON, 77 "min output at " + minIndex); 78 }); 79 } 80 81 promise_test(test_normalization_via_response_concat, 82 "via response concatenation"); 83 </script>