110 lines
3.7 KiB
HTML
110 lines
3.7 KiB
HTML
<!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>
|