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-audioparam-interface/audioparam-close.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-audioparam-interface/audioparam-close.html')
-rw-r--r-- | testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-close.html | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-close.html b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-close.html new file mode 100644 index 0000000000..b5555b0137 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-close.html @@ -0,0 +1,161 @@ +<!doctype html> +<html> + <head> + <title>Test AudioParam events very close in time</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> + </head> + + <body> + <script> + const audit = Audit.createTaskRunner(); + + // Largest sample rate that is required to be supported and is a power of + // two, to eliminate round-off as much as possible. + const sampleRate = 65536; + + // Only need one render quantum for testing. + const testFrames = 128; + + // Largest representable single-float number + const floatMax = Math.fround(3.4028234663852886e38); + + // epspos is the smallest x such that 1 + x != 1 + const epspos = 1.1102230246251568e-16; + // epsneg is the smallest x such that 1 - x != 1 + const epsneg = 5.551115123125784e-17; + + audit.define( + {label: 'no-nan', description: 'NaN does not occur'}, + (task, should) => { + const context = new OfflineAudioContext({ + numberOfChannels: 1, + sampleRate: sampleRate, + length: testFrames + }); + + const src0 = new ConstantSourceNode(context, {offset: 0}); + + // This should always succeed. We just want to print out a message + // that |src0| is a constant source node for the following + // processing. + should(src0, 'src0 = new ConstantSourceNode(context, {offset: 0})') + .beEqualTo(src0); + + src0.connect(context.destination); + + // Values for the first event (setValue). |time1| MUST be 0. + const time1 = 0; + const value1 = 10; + + // Values for the second event (linearRamp). |value2| must be huge, + // and |time2| must be small enough that 1/|time2| overflows a + // single float. This value is the least positive single float. + const value2 = floatMax; + const time2 = 1.401298464324817e-45; + + // These should always succeed; the messages are just informational + // to show the events that we scheduled. + should( + src0.offset.setValueAtTime(value1, time1), + `src0.offset.setValueAtTime(${value1}, ${time1})`) + .beEqualTo(src0.offset); + should( + src0.offset.linearRampToValueAtTime(value2, time2), + `src0.offset.linearRampToValueAtTime(${value2}, ${time2})`) + .beEqualTo(src0.offset); + + src0.start(); + + context.startRendering() + .then(buffer => { + const output = buffer.getChannelData(0); + + // Since time1 = 0, the output at frame 0 MUST be value1. + should(output[0], 'output[0]').beEqualTo(value1); + + // Since time2 < 1, output from frame 1 and later must be a + // constant. + should(output.slice(1), 'output[1]') + .beConstantValueOf(value2); + }) + .then(() => task.done()); + }); + + audit.define( + {label: 'interpolation', description: 'Interpolation of linear ramp'}, + (task, should) => { + const context = new OfflineAudioContext({ + numberOfChannels: 1, + sampleRate: sampleRate, + length: testFrames + }); + + const src1 = new ConstantSourceNode(context, {offset: 0}); + + // This should always succeed. We just want to print out a message + // that |src1| is a constant source node for the following + // processing. + should(src1, 'src1 = new ConstantSourceNode(context, {offset: 0})') + .beEqualTo(src1); + + src1.connect(context.destination); + + const frame = 1; + + // These time values are arranged so that time1 < frame/sampleRate < + // time2. This means we need to interpolate to get a value at given + // frame. + // + // The values are not so important, but |value2| should be huge. + const time1 = frame * (1 - epsneg) / context.sampleRate; + const value1 = 1e15; + + const time2 = frame * (1 + epspos) / context.sampleRate; + const value2 = floatMax; + + should( + src1.offset.setValueAtTime(value1, time1), + `src1.offset.setValueAtTime(${value1}, ${time1})`) + .beEqualTo(src1.offset); + should( + src1.offset.linearRampToValueAtTime(value2, time2), + `src1.offset.linearRampToValueAtTime(${value2}, ${time2})`) + .beEqualTo(src1.offset); + + src1.start(); + + context.startRendering() + .then(buffer => { + const output = buffer.getChannelData(0); + + // Sanity check + should(time2 - time1, 'Event time difference') + .notBeEqualTo(0); + + // Because 0 < time1 < 1, output must be 0 at time 0. + should(output[0], 'output[0]').beEqualTo(0); + + // Because time1 < 1/sampleRate < time2, we need to + // interpolate the value between these times to determine the + // output at frame 1. + const t = frame / context.sampleRate; + const v = value1 + + (value2 - value1) * (t - time1) / (time2 - time1); + + should(output[1], 'output[1]').beCloseTo(v, {threshold: 0}); + + // Because 1 < time2 < 2, the output at frame 2 and higher is + // constant. + should(output.slice(2), 'output[2:]') + .beConstantValueOf(value2); + }) + .then(() => task.done()); + }); + + audit.run(); + </script> + </body> +</html> |