moderate-exponentialRamp.html (1985B)
1 <!DOCTYPE html> 2 <title>Test exponentialRampToValueAtTime() with a moderate ratio of change</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script> 6 'use strict'; 7 8 promise_test(async function() { 9 const bufferSize = 128; 10 const sampleRate = 16384; 11 // 3 * 2^6, not a power of two, so that there is some rounding error in the 12 // exponent 13 const rampEndSample = 192; 14 // These values are chosen so that there is rounding error in 15 // (offset1/offset0)^(1/rampEndSample). 16 const offset0 = 4.; 17 const offset1 = 7.; 18 // 8 units in the last place (ulp) is a generous tolerance if single 19 // precision powf() is used. Math.pow(2, -23) ~ 1 ulp. 20 // A simple recurrence relation formulation with only single precision 21 // arithmetic applied across the whole rendering quantum would accumulate 22 // error up to 50 ulp, losing 5.6 of the 24 bits of precision. 23 const relativeTolerance = 8 * Math.pow(2, -23); 24 25 const context = new OfflineAudioContext(1, bufferSize, sampleRate); 26 27 const source = new ConstantSourceNode(context); 28 source.start(); 29 // Explicit event to work around 30 // https://bugzilla.mozilla.org/show_bug.cgi?id=1265393 31 source.offset.setValueAtTime(offset0, 0.); 32 source.offset.exponentialRampToValueAtTime(offset1, rampEndSample/sampleRate); 33 source.connect(context.destination); 34 35 const buffer = await context.startRendering(); 36 assert_equals(buffer.length, bufferSize, "output buffer length"); 37 const output = buffer.getChannelData(0); 38 const ratio = offset1 / offset0; 39 for (let i = 0; i < bufferSize; ++i) { 40 // Math.pow() uses double precision, while `output` has single precision, 41 // but `tolerance` is more than enough to accommodate differences. 42 const expected = offset0 * Math.pow(offset1/offset0, i/rampEndSample); 43 assert_approx_equals( 44 output[i], 45 expected, 46 relativeTolerance * expected, 47 "scheduled value at " + i); 48 } 49 }); 50 </script>