diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html')
-rw-r--r-- | testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html b/testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html new file mode 100644 index 0000000000..8bfa009b18 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/waveshaper.html @@ -0,0 +1,127 @@ +<!DOCTYPE html> +<html> + <head> + <title> + waveshaper.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> + <script src="../../resources/buffer-loader.js"></script> + </head> + <body> + <script id="layout-test-code"> + let audit = Audit.createTaskRunner(); + + let sampleRate = 44100; + let lengthInSeconds = 4; + let numberOfRenderFrames = sampleRate * lengthInSeconds; + let numberOfCurveFrames = 65536; + let inputBuffer; + let waveShapingCurve; + + let context; + + function generateInputBuffer() { + // Create mono input buffer. + let buffer = + context.createBuffer(1, numberOfRenderFrames, context.sampleRate); + let data = buffer.getChannelData(0); + + // Generate an input vector with values from -1 -> +1 over a duration of + // lengthInSeconds. This exercises the full nominal input range and will + // touch every point of the shaping curve. + for (let i = 0; i < numberOfRenderFrames; ++i) { + let x = i / numberOfRenderFrames; // 0 -> 1 + x = 2 * x - 1; // -1 -> +1 + data[i] = x; + } + + return buffer; + } + + // Generates a symmetric curve: Math.atan(5 * x) / (0.5 * Math.PI) + // (with x == 0 corresponding to the center of the array) + // This curve is arbitrary, but would be useful in the real-world. + // To some extent, the actual curve we choose is not important in this + // test, since the input vector walks through all possible curve values. + function generateWaveShapingCurve() { + let curve = new Float32Array(numberOfCurveFrames); + + let n = numberOfCurveFrames; + let n2 = n / 2; + + for (let i = 0; i < n; ++i) { + let x = (i - n2) / n2; + let y = Math.atan(5 * x) / (0.5 * Math.PI); + } + + return curve; + } + + function checkShapedCurve(buffer, should) { + let inputData = inputBuffer.getChannelData(0); + let outputData = buffer.getChannelData(0); + + let success = true; + + // Go through every sample and make sure it has been shaped exactly + // according to the shaping curve we gave it. + for (let i = 0; i < buffer.length; ++i) { + let input = inputData[i]; + + // Calculate an index based on input -1 -> +1 with 0 being at the + // center of the curve data. + let index = Math.floor(numberOfCurveFrames * 0.5 * (input + 1)); + + // Clip index to the input range of the curve. + // This takes care of input outside of nominal range -1 -> +1 + index = index < 0 ? 0 : index; + index = + index > numberOfCurveFrames - 1 ? numberOfCurveFrames - 1 : index; + + let expectedOutput = waveShapingCurve[index]; + + let output = outputData[i]; + + if (output != expectedOutput) { + success = false; + break; + } + } + + should( + success, 'WaveShaperNode applied non-linear distortion correctly') + .beTrue(); + } + + audit.define('test', function(task, should) { + // Create offline audio context. + context = new OfflineAudioContext(1, numberOfRenderFrames, sampleRate); + + // source -> waveshaper -> destination + let source = context.createBufferSource(); + let waveshaper = context.createWaveShaper(); + source.connect(waveshaper); + waveshaper.connect(context.destination); + + // Create an input test vector. + inputBuffer = generateInputBuffer(); + source.buffer = inputBuffer; + + // We'll apply non-linear distortion according to this shaping curve. + waveShapingCurve = generateWaveShapingCurve(); + waveshaper.curve = waveShapingCurve; + + source.start(0); + + context.startRendering() + .then(buffer => checkShapedCurve(buffer, should)) + .then(task.done.bind(task)); + }); + + audit.run(); + </script> + </body> +</html> |