Files
sousa-gecko/testing/web-platform/tests/webaudio/the-audio-api/rendersizehint-smoke-tests.https.html
T
Hongchan Choi e39a225aff Bug 2041976 [wpt PR 60128] - [WebAudio] Add custom renderSizeHint integration and smoke tests, a=testonly
Automatic update from web-platform-tests
[WebAudio] Add custom renderSizeHint integration and smoke tests

This CL adds comprehensive verification for custom render quantum sizes.

Specifically, this change:
- Adds integration tests verifying block size propagation for both
  MediaStreamAudioSourceNode and MediaStreamAudioDestinationNode
  across a parameter matrix: power-of-two (256), 10ms at 48kHz (480),
  10ms at 44.1kHz (441), and arbitrary non-power-of-two (500) sizes.
- Replaces slow JS loops in WPT smoke tests with fast, native
  Float32Array includes() checks to ensure all output samples are
  finite.

Bug: 499036414, 502311300
Test: external/wpt/webaudio/the-audio-api/rendersizehint-smoke-tests.https.html, webaudio/MediaStreamAudioDestination/mediastreamaudiodestinationnode-rendersizehint.https.html
Change-Id: I262a320bf3a2b55cc2a66cecbb4b70a49b5a76ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7871927
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1636329}

--

wpt-commits: 39c4da44b6836cb9d6f4fe87333ed1b9f1a4295c
wpt-pr: 60128
2026-05-29 15:59:59 +00:00

124 lines
4.5 KiB
HTML

<!DOCTYPE html>
<title>Smoke tests for standard nodes with renderSizeHint</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const TEST_CONFIGS = [
// Stress test very low rate & tiny block sizes.
{sampleRate: 3000, renderSizeHint: 1, length: 128},
// Stress test very high rate & massive block sizes.
{sampleRate: 768000, renderSizeHint: 4608000, length: 4608000},
// Standard baseline verification.
{sampleRate: 48000, renderSizeHint: 128, length: 128},
// Non-power-of-two block size verification.
{sampleRate: 48000, renderSizeHint: 100, length: 200}
];
const createTestContext = config => new OfflineAudioContext({
length: config.length,
sampleRate: config.sampleRate,
renderSizeHint: config.renderSizeHint
});
const createEmptyBuffer = context => new AudioBuffer({
length: 128,
sampleRate: context.sampleRate
});
/**
* Runs smoke tests for a given AudioNode source type across multiple
* combinations of sampleRate and renderSizeHint.
*
* @param {string} nodeName The name of the node being tested.
* @param {function(OfflineAudioContext): AudioNode} createNodeFn A factory
* function to create the node.
*/
const runSourceNodeTest = (nodeName, createNodeFn) => {
for (const config of TEST_CONFIGS) {
const {sampleRate, renderSizeHint} = config;
promise_test(async () => {
const context = createTestContext(config);
const node = createNodeFn(context);
node.connect(context.destination);
node.start();
const renderedBuffer = await context.startRendering();
const data = renderedBuffer.getChannelData(0);
assert_false(
data.includes(NaN), 'Output should not contain NaN');
assert_false(
data.includes(Infinity), 'Output should not contain Infinity');
assert_false(
data.includes(-Infinity), 'Output should not contain -Infinity');
}, `${nodeName} smoke test at ${sampleRate}Hz & hint ` +
`${renderSizeHint}`);
}
};
const SOURCE_NODE_TESTS = {
'OscillatorNode': context => new OscillatorNode(context),
'AudioBufferSourceNode': context => new AudioBufferSourceNode(context, {
buffer: createEmptyBuffer(context)
}),
'ConstantSourceNode': context => new ConstantSourceNode(context)
};
for (const name in SOURCE_NODE_TESTS) {
runSourceNodeTest(name, SOURCE_NODE_TESTS[name]);
}
/**
* Runs smoke tests for a given AudioNode processor/router type across multiple
* combinations of sampleRate and renderSizeHint.
*
* @param {string} nodeName The name of the node being tested.
* @param {function(OfflineAudioContext): AudioNode} createNodeFn A factory
* function to create the node.
*/
const runProcessorNodeTest = (nodeName, createNodeFn) => {
for (const config of TEST_CONFIGS) {
const {sampleRate, renderSizeHint} = config;
promise_test(async () => {
const context = createTestContext(config);
const source = new ConstantSourceNode(context);
const node = createNodeFn(context);
source.connect(node).connect(context.destination);
source.start();
const renderedBuffer = await context.startRendering();
const data = renderedBuffer.getChannelData(0);
assert_false(
data.includes(NaN), 'Output should not contain NaN');
assert_false(
data.includes(Infinity), 'Output should not contain Infinity');
assert_false(
data.includes(-Infinity), 'Output should not contain -Infinity');
}, `${nodeName} smoke test at ${sampleRate}Hz & hint ` +
`${renderSizeHint}`);
}
};
const PROCESSOR_NODE_TESTS = {
'GainNode': context => new GainNode(context),
'BiquadFilterNode': context => new BiquadFilterNode(context),
'DelayNode': context => new DelayNode(context),
'DynamicsCompressorNode': context => new DynamicsCompressorNode(context),
'WaveShaperNode': context => new WaveShaperNode(context),
'PannerNode': context => new PannerNode(context),
'StereoPannerNode': context => new StereoPannerNode(context),
'AnalyserNode': context => new AnalyserNode(context),
'IIRFilterNode': context => new IIRFilterNode(context, {
feedforward: [1],
feedback: [1, -0.5]
}),
'ConvolverNode': context => new ConvolverNode(context, {
buffer: createEmptyBuffer(context)
}),
'ChannelMergerNode': context => new ChannelMergerNode(context),
'ChannelSplitterNode': context => new ChannelSplitterNode(context)
};
for (const [name, fn] of Object.entries(PROCESSOR_NODE_TESTS)) {
runProcessorNodeTest(name, fn);
}
</script>