| <!DOCTYPE html> |
| <html> |
| <head> |
| <title> |
| waveshaper-limits.html |
| </title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="../../resources/audit-util.js"></script> |
| <script src="../../resources/audit.js"></script> |
| </head> |
| <body> |
| <script id="layout-test-code"> |
| let audit = Audit.createTaskRunner(); |
| |
| let context; |
| let bufferData; |
| let outputData; |
| let reference; |
| |
| let sampleRate = 48000; |
| // Must be odd so we have an exact middle point. |
| let testFrames = 23; |
| let scale = 1 / ((testFrames - 1) / 2 - 1); |
| // Number of decimal digits to print |
| let decimals = 6; |
| // Required accuracy |
| let diffThreshold = Math.pow(10, -decimals); |
| |
| // Generate reference data |
| function generateReference() { |
| // The curve data is 0, 1, 0, and the input data is a ramp from -1+eps |
| // to 1+eps. Then the output is a ramp from 0 to 1 back to 0. |
| let ref = new Float32Array(testFrames); |
| let midPoint = (testFrames - 1) / 2; |
| // First sample is below -1 at -1-scale. |
| ref[0] = 0; |
| // Generate ramp up to the mid-point |
| for (let k = 0; k < midPoint; ++k) { |
| ref[k + 1] = k * scale; |
| } |
| // The value at the mid-point must be 1, from the curve |
| ref[midPoint] = 1; |
| // Generate a ramp from 1 down to 0 |
| for (let k = midPoint; k < testFrames - 1; ++k) { |
| ref[k + 1] = 2 - k * scale; |
| } |
| // The last sample is out of range at 1+scale |
| ref[testFrames - 1] = 0; |
| return ref; |
| } |
| |
| function checkResult(renderedBuffer, should) { |
| outputData = renderedBuffer.getChannelData(0); |
| reference = generateReference(); |
| let success = true; |
| // Verify that every output value matches our expected reference value. |
| for (let k = 0; k < outputData.length; ++k) { |
| let diff = outputData[k] - reference[k]; |
| should( |
| Math.abs(diff), |
| 'Max error mapping ' + bufferData[k].toFixed(decimals) + ' to ' + |
| outputData[k].toFixed(decimals)) |
| .beLessThanOrEqualTo(diffThreshold); |
| } |
| } |
| |
| audit.define( |
| { |
| label: 'test', |
| description: |
| 'WaveShaperNode including values outside the range of [-1,1]' |
| }, |
| function(task, should) { |
| context = new OfflineAudioContext(1, testFrames, sampleRate); |
| // Create input values between -1.1 and 1.1 |
| let buffer = |
| context.createBuffer(1, testFrames, context.sampleRate); |
| bufferData = new Float32Array(testFrames); |
| let start = -1 - scale; |
| for (let k = 0; k < testFrames; ++k) { |
| bufferData[k] = k * scale + start; |
| } |
| buffer.copyToChannel(bufferData, 0); |
| |
| let source = context.createBufferSource(); |
| source.buffer = buffer; |
| |
| // Create simple waveshaper. It should map -1 to 0, 0 to 1, and +1 |
| // to 0 and interpolate all points in between using a simple linear |
| // interpolator. |
| let shaper = context.createWaveShaper(); |
| let curve = new Float32Array(3); |
| curve[0] = 0; |
| curve[1] = 1; |
| curve[2] = 0; |
| shaper.curve = curve; |
| source.connect(shaper); |
| shaper.connect(context.destination); |
| |
| source.start(); |
| context.startRendering() |
| .then(buffer => checkResult(buffer, should)) |
| .then(() => task.done()); |
| }); |
| |
| audit.run(); |
| </script> |
| </body> |
| </html> |