Bug 1438319 [wpt PR 9524] - Fix timeouts in WPT AudioParam tests, a=testonly

Automatic update from web-platform-testsFix timeouts in WPT AudioParam tests

Replace the tests that are using ScriptProcessor and online contexts
with an offline context and verify all the output values instead of
just one.

This change exposed a couple of issues:
  - setTargetAtTime wasn't actually testing setTargetAtTime because a
    linearRampToValueAtTime event was called at the same time,
    effectively replacing the setTargetAtTime event
  - linearRampToValue and exponentialRampToValue tests expose bugs in
    Chrome's implementation of these when the event is scheduled in
    the past, and there is no preceding event.

Bug: 812285, 626703
Change-Id: Iad3f54dd4373411431c019de44d4c3bad07587ff
Reviewed-on: https://chromium-review.googlesource.com/919151
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537311}

wpt-commits: 81ada4212ece1e2f5c6cc560d6b2f45593679e93
wpt-pr: 9524
wpt-commits: 81ada4212ece1e2f5c6cc560d6b2f45593679e93
wpt-pr: 9524
This commit is contained in:
Raymond Toy 2018-03-26 12:22:47 +00:00 коммит произвёл James Graham
Родитель c5582233ef
Коммит 04f728145f
7 изменённых файлов: 356 добавлений и 213 удалений

Просмотреть файл

@ -293336,6 +293336,11 @@
{}
]
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-test.js": [
[
{}
]
],
"webaudio/the-audio-api/the-audioprocessingevent-interface/.gitkeep": [
[
{}
@ -596445,25 +596450,29 @@
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-exponentialRampToValueAtTime.html": [
"53a2c031fd3c51cd401c1d192b09b745dd6b9260",
"12e1f35dca3f0b28d421ab39bdb2a98dc18abb3d",
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-linearRampToValueAtTime.html": [
"ebd5ea3d866634ff0958eb2fda96bf58cbbea6ad",
"30b41f51caaf643c1acd746be3a7ce19d2498ca1",
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-setTargetAtTime.html": [
"2fc8054f87b7d622b4cb5801e9f3a2083dbc23a4",
"2a012bfbd59445aa14789d80b94f514726e819f0",
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-setValueAtTime.html": [
"30bcf53f72c13690f606b1c27584e9bb937017ef",
"7558fec8601a9aa3a6fc8fc93c7e978a6bf50a9e",
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-setValueCurveAtTime.html": [
"fd40dc7cc8aca8ab829852dbabda3b00bcec5817",
"db939616369e2ce66b717d47512141e6f28e4c14",
"testharness"
],
"webaudio/the-audio-api/the-audioparam-interface/retrospective-test.js": [
"aeb2213183f2fd26848c507e030de3e5f7f01fee",
"support"
],
"webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html": [
"3e54f9a98e7488223e6c40929268ddec3c8b5961",
"testharness"

Просмотреть файл

@ -1,51 +1,70 @@
<!doctype html>
<meta charset=utf-8>
<title>Test exponentialRampToValue with end time in the past</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
function do_test(t, context) {
var source = context.createConstantSource();
<html>
<head>
<title>Test exponentialRampToValue with end time in the past</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>
<script src="retrospective-test.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
audit.define(
{
label: 'test',
description: 'Test exponentialRampToValue with end time in the past'
},
(task, should) => {
let {context, source, test, reference} = setupRetrospectiveGraph();
// Suspend the context at this frame so we can synchronously set up
// automations.
const suspendFrame = 128;
context.suspend(suspendFrame / context.sampleRate)
.then(() => {
// Call setTargetAtTime with a time in the past
test.gain.exponentialRampToValueAtTime(
0.1, 0.5 * context.currentTime);
test.gain.exponentialRampToValueAtTime(0.9, 1.0);
reference.gain.exponentialRampToValueAtTime(
0.1, context.currentTime);
reference.gain.exponentialRampToValueAtTime(0.9, 1.0);
})
.then(() => context.resume());
source.start();
var test = context.createGain();
test.gain.exponentialRampToValueAtTime(0.1, 0.5*context.currentTime);
test.gain.exponentialRampToValueAtTime(0.9, 2.0);
context.startRendering()
.then(resultBuffer => {
let testValue = resultBuffer.getChannelData(0);
let referenceValue = resultBuffer.getChannelData(1);
var reference = context.createGain();
reference.gain.exponentialRampToValueAtTime(0.1, context.currentTime);
reference.gain.exponentialRampToValueAtTime(0.9, 2.0);
// Until the suspendFrame, both should be exactly equal to 1.
should(
testValue.slice(0, suspendFrame),
`Test[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
should(
referenceValue.slice(0, suspendFrame),
`Reference[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
source.connect(test);
source.connect(reference);
var merger = context.createChannelMerger();
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
var processor = context.createScriptProcessor(0, 2, 0);
merger.connect(processor);
processor.onaudioprocess =
t.step_func_done((e) => {
source.stop();
processor.onaudioprocess = null;
var testValue = e.inputBuffer.getChannelData(0)[0];
var referenceValue = e.inputBuffer.getChannelData(1)[0];
assert_equals(testValue, referenceValue,
"value matches expected");
// After the suspendFrame, both should be equal (and not
// constant)
should(
testValue.slice(suspendFrame), `Test[${suspendFrame}:]`)
.beEqualToArray(referenceValue.slice(suspendFrame));
})
.then(() => task.done());
});
}
async_test(function(t) {
var context = new AudioContext;
(function waitForTimeAdvance() {
if (context.currentTime == 0) {
t.step_timeout(waitForTimeAdvance, 0);
} else {
do_test(t, context);
}
})();
});
</script>
audit.run();
</script>
</body>
</html>

Просмотреть файл

@ -1,51 +1,70 @@
<!doctype html>
<meta charset=utf-8>
<title>Test linearRampToValue with end time in the past</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
function do_test(t, context) {
var source = context.createConstantSource();
<html>
<head>
<title>Test linearRampToValue with end time in the past</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>
<script src="retrospective-test.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
audit.define(
{
label: 'test',
description: 'Test linearRampToValue with end time in the past'
},
(task, should) => {
let {context, source, test, reference} = setupRetrospectiveGraph();
// Suspend the context at this frame so we can synchronously set up
// automations.
const suspendFrame = 128;
context.suspend(suspendFrame / context.sampleRate)
.then(() => {
// Call setTargetAtTime with a time in the past
test.gain.linearRampToValueAtTime(
0.1, 0.5 * context.currentTime);
test.gain.linearRampToValueAtTime(0.9, 1.0);
reference.gain.linearRampToValueAtTime(
0.1, context.currentTime);
reference.gain.linearRampToValueAtTime(0.9, 1.0);
})
.then(() => context.resume());
source.start();
var test = context.createGain();
test.gain.linearRampToValueAtTime(0.1, 0.5*context.currentTime);
test.gain.linearRampToValueAtTime(0.9, 2.0);
context.startRendering()
.then(resultBuffer => {
let testValue = resultBuffer.getChannelData(0);
let referenceValue = resultBuffer.getChannelData(1);
var reference = context.createGain();
reference.gain.linearRampToValueAtTime(0.1, context.currentTime);
reference.gain.linearRampToValueAtTime(0.9, 2.0);
// Until the suspendFrame, both should be exactly equal to 1.
should(
testValue.slice(0, suspendFrame),
`Test[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
should(
referenceValue.slice(0, suspendFrame),
`Reference[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
source.connect(test);
source.connect(reference);
var merger = context.createChannelMerger();
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
var processor = context.createScriptProcessor(0, 2, 0);
merger.connect(processor);
processor.onaudioprocess =
t.step_func_done((e) => {
source.stop();
processor.onaudioprocess = null;
var testValue = e.inputBuffer.getChannelData(0)[0];
var referenceValue = e.inputBuffer.getChannelData(1)[0];
assert_equals(testValue, referenceValue,
"value matches expected");
// After the suspendFrame, both should be equal (and not
// constant)
should(
testValue.slice(suspendFrame), `Test[${suspendFrame}:]`)
.beEqualToArray(referenceValue.slice(suspendFrame));
})
.then(() => task.done());
});
}
async_test(function(t) {
var context = new AudioContext;
(function waitForTimeAdvance() {
if (context.currentTime == 0) {
t.step_timeout(waitForTimeAdvance, 0);
} else {
do_test(t, context);
}
})();
});
</script>
audit.run();
</script>
</body>
</html>

Просмотреть файл

@ -1,51 +1,80 @@
<!doctype html>
<meta charset=utf-8>
<title>Test setTargetAtTime with start time in the past</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
function do_test(t, context) {
var source = context.createConstantSource();
source.start();
<html>
<head>
<title>Test setTargetAtTime with start time in the past</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>
let audit = Audit.createTaskRunner();
var test = context.createGain();
test.gain.setTargetAtTime(0.1, 0.5*context.currentTime, 0.1);
test.gain.linearRampToValueAtTime(0.9, 2.0);
audit.define(
{
label: 'test',
description: 'Test setTargetAtTime with start time in the past'
},
(task, should) => {
// Use a sample rate that is a power of two to eliminate round-off
// in computing the currentTime.
let context = new OfflineAudioContext(2, 16384, 16384);
let source = new ConstantSourceNode(context);
var reference = context.createGain();
reference.gain.setTargetAtTime(0.1, context.currentTime, 0.1);
reference.gain.linearRampToValueAtTime(0.9, 2.0);
// Suspend the context at this frame so we can synchronously set up
// automations.
const suspendFrame = 128;
let test = new GainNode(context);
let reference = new GainNode(context);
source.connect(test);
source.connect(reference);
var merger = context.createChannelMerger();
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
var processor = context.createScriptProcessor(0, 2, 0);
merger.connect(processor);
processor.onaudioprocess =
t.step_func_done((e) => {
source.stop();
processor.onaudioprocess = null;
merger.connect(context.destination);
var testValue = e.inputBuffer.getChannelData(0)[0];
var referenceValue = e.inputBuffer.getChannelData(1)[0];
context.suspend(suspendFrame / context.sampleRate)
.then(() => {
// Call setTargetAtTime with a time in the past
test.gain.setTargetAtTime(0.1, 0.5*context.currentTime, 0.1);
reference.gain.setTargetAtTime(0.1, context.currentTime, 0.1);
})
.then(() => context.resume());
assert_equals(testValue, referenceValue,
"value matches expected");
source.start();
context.startRendering()
.then(resultBuffer => {
let testValue = resultBuffer.getChannelData(0);
let referenceValue = resultBuffer.getChannelData(1);
// Until the suspendFrame, both should be exactly equal to 1.
should(
testValue.slice(0, suspendFrame),
`Test[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
should(
referenceValue.slice(0, suspendFrame),
`Reference[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
// After the suspendFrame, both should be equal (and not
// constant)
should(
testValue.slice(suspendFrame), `Test[${suspendFrame}:]`)
.beEqualToArray(referenceValue.slice(suspendFrame));
})
.then(() => task.done());
});
}
async_test(function(t) {
var context = new AudioContext;
(function waitForTimeAdvance() {
if (context.currentTime == 0) {
t.step_timeout(waitForTimeAdvance, 0);
} else {
do_test(t, context);
}
})();
});
</script>
audit.run();
</script>
</body>
</html>

Просмотреть файл

@ -1,54 +1,74 @@
<!DOCTYPE html>
<title>Test setValueAtTime with startTime in the past</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function do_test(t, context) {
var source = context.createConstantSource();
source.start();
<html>
<head>
<title>Test setValueAtTime with startTime in the past</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>
<script src="retrospective-test.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
// Use a ramp of slope 1/sample to measure time.
// The end value is the extent of exact precision in single precision float.
const rampEnd = Math.pow(2, 24);
const rampEndSeconds = rampEnd / context.sampleRate;
var test = context.createGain();
test.gain.setValueAtTime(0.0, 0.5*context.currentTime);
audit.define(
{
label: 'test',
description: 'Test setValueAtTime with startTime in the past'
},
(task, should) => {
let {context, source, test, reference} = setupRetrospectiveGraph();
// Suspend the context at this frame so we can synchronously set up
// automations.
const suspendFrame = 128;
// Use a ramp of slope 1 per frame to measure time.
// The end value is the extent of exact precision in single
// precision float.
const rampEnd = context.length - suspendFrame;
const rampEndSeconds = context.length / context.sampleRate;
context.suspend(suspendFrame / context.sampleRate)
.then(() => {
// Call setValueAtTime with a time in the past
test.gain.setValueAtTime(0.0, 0.5 * context.currentTime);
test.gain.linearRampToValueAtTime(rampEnd, rampEndSeconds);
var reference = context.createGain();
reference.gain.setValueAtTime(0.0, context.currentTime);
reference.gain.linearRampToValueAtTime(rampEnd, rampEndSeconds);
reference.gain.linearRampToValueAtTime(
rampEnd, rampEndSeconds);
})
.then(() => context.resume());
source.connect(test);
source.connect(reference);
source.start();
var merger = context.createChannelMerger();
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
context.startRendering()
.then(resultBuffer => {
let testValue = resultBuffer.getChannelData(0);
let referenceValue = resultBuffer.getChannelData(1);
var processor = context.createScriptProcessor(0, 2, 0);
merger.connect(processor);
processor.onaudioprocess =
t.step_func_done((e) => {
source.stop();
processor.onaudioprocess = null;
// Until the suspendFrame, both should be exactly equal to 1.
should(
testValue.slice(0, suspendFrame),
`Test[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
should(
referenceValue.slice(0, suspendFrame),
`Reference[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
var testValue = e.inputBuffer.getChannelData(0)[0];
var referenceValue = e.inputBuffer.getChannelData(1)[0];
assert_equals(testValue, referenceValue,
"ramp value matches expected");
// After the suspendFrame, both should be equal (and not
// constant)
should(
testValue.slice(suspendFrame), `Test[${suspendFrame}:]`)
.beEqualToArray(referenceValue.slice(suspendFrame));
})
.then(() => task.done());
});
}
async_test(function(t) {
var context = new AudioContext;
(function waitForTimeAdvance() {
if (context.currentTime == 0) {
t.step_timeout(waitForTimeAdvance, 0);
} else {
do_test(t, context);
}
})();
});
</script>
audit.run();
</script>
</body>
</html>

Просмотреть файл

@ -1,49 +1,67 @@
<!doctype html>
<meta charset=utf-8>
<title>Test SetValueCurve with start time in the past</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
function do_test(t, context) {
var source = context.createConstantSource();
<html>
<head>
<title>Test SetValueCurve with start time in the past</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>
<script src="retrospective-test.js"></script>
</head>
</body>
<script>
let audit = Audit.createTaskRunner();
audit.define(
{
label: 'test',
description: 'Test SetValueCurve with start time in the past'
},
(task, should) => {
let {context, source, test, reference} = setupRetrospectiveGraph();
// Suspend the context at this frame so we can synchronously set up
// automations.
const suspendFrame = 128;
context.suspend(suspendFrame / context.sampleRate)
.then(() => {
// Call setValueAtTime with a time in the past
test.gain.setValueCurveAtTime(
new Float32Array([1.0, 0.1]), 0.5 * context.currentTime,
1.0);
reference.gain.setValueCurveAtTime(
new Float32Array([1.0, 0.1]), context.currentTime, 1.0);
})
.then(() => context.resume());
source.start();
var test = context.createGain();
test.gain.setValueCurveAtTime(new Float32Array([1.0, 0.1]), 0.0, 1.0);
context.startRendering()
.then(resultBuffer => {
let testValue = resultBuffer.getChannelData(0);
let referenceValue = resultBuffer.getChannelData(1);
var reference = context.createGain();
reference.gain.setValueCurveAtTime(new Float32Array([1.0, 0.1]), 0.5*context.currentTime, 1.0);
// Until the suspendFrame, both should be exactly equal to 1.
should(
testValue.slice(0, suspendFrame),
`Test[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
should(
referenceValue.slice(0, suspendFrame),
`Reference[0:${suspendFrame - 1}]`)
.beConstantValueOf(1);
source.connect(test);
source.connect(reference);
var merger = context.createChannelMerger();
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
var processor = context.createScriptProcessor(0, 2, 0);
merger.connect(processor);
processor.onaudioprocess =
t.step_func_done((e) => {
source.stop();
processor.onaudioprocess = null;
var testValue = e.inputBuffer.getChannelData(0)[0];
var referenceValue = e.inputBuffer.getChannelData(1)[0];
assert_equals(testValue, referenceValue,
"value matches expected");
// After the suspendFrame, both should be equal (and not
// constant)
should(
testValue.slice(suspendFrame), `Test[${suspendFrame}:]`)
.beEqualToArray(referenceValue.slice(suspendFrame));
})
.then(() => task.done());
});
}
async_test(function(t) {
var context = new AudioContext;
(function waitForTimeAdvance() {
if (context.currentTime == 0) {
t.step_timeout(waitForTimeAdvance, 0);
} else {
do_test(t, context);
}
})();
});
</script>
audit.run();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,29 @@
// Create an audio graph on an offline context that consists of a
// constant source and two gain nodes. One of the nodes is the node te
// be tested and the other is the reference node. The output from the
// test node is in channel 0 of the offline context; the reference
// node is in channel 1.
//
// Returns a dictionary with the context, source node, the test node,
// and the reference node.
function setupRetrospectiveGraph() {
// Use a sample rate that is a power of two to eliminate round-off
// in computing the currentTime.
let context = new OfflineAudioContext(2, 16384, 16384);
let source = new ConstantSourceNode(context);
let test = new GainNode(context);
let reference = new GainNode(context);
source.connect(test);
source.connect(reference);
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
test.connect(merger, 0, 0);
reference.connect(merger, 0, 1);
merger.connect(context.destination);
return {context: context, source: source, test: test, reference: reference};
}