haikuwebkit/LayoutTests/webaudio/AudioParam/audioparam-update-value-att...

183 lines
7.1 KiB
HTML
Raw Permalink Normal View History

Import AudioContext / AudioListener / AudioNode / AudioParam layout tests from Blink https://bugs.webkit.org/show_bug.cgi?id=216706 Reviewed by Eric Carlson. Import AudioContext / AudioListener / AudioNode / AudioParam layout tests from Blink. * webaudio/AudioContext/audiocontext-close-basic-expected.txt: Added. * webaudio/AudioContext/audiocontext-close-basic.html: Added. * webaudio/AudioContext/audiocontext-listener-should-not-crash-expected.txt: Added. * webaudio/AudioContext/audiocontext-listener-should-not-crash.html: Added. * webaudio/AudioListener/audiolistener-automation-position-expected.txt: Added. * webaudio/AudioListener/audiolistener-automation-position.html: Added. * webaudio/AudioListener/audiolistener-set-position-expected.txt: Added. * webaudio/AudioListener/audiolistener-set-position.html: Added. * webaudio/AudioNode/tail-connections-expected.txt: Added. * webaudio/AudioNode/tail-connections.html: Added. * webaudio/AudioNode/tail-processing-expected.txt: Added. * webaudio/AudioNode/tail-processing.html: Added. * webaudio/AudioParam/audioparam-automation-clamping-expected.txt: Added. * webaudio/AudioParam/audioparam-automation-clamping.html: Added. * webaudio/AudioParam/audioparam-cancel-and-hold-expected.txt: Renamed from LayoutTests/webaudio/audioparam-cancel-and-hold-expected.txt. * webaudio/AudioParam/audioparam-cancel-and-hold.html: Renamed from LayoutTests/webaudio/audioparam-cancel-and-hold.html. * webaudio/AudioParam/audioparam-clamp-time-to-current-time-expected.txt: Added. * webaudio/AudioParam/audioparam-clamp-time-to-current-time.html: Added. * webaudio/AudioParam/audioparam-initial-event-expected.txt: Added. * webaudio/AudioParam/audioparam-initial-event.html: Added. * webaudio/AudioParam/audioparam-k-rate-expected.txt: Added. * webaudio/AudioParam/audioparam-k-rate.html: Added. * webaudio/AudioParam/audioparam-linearRamp-value-attribute-expected.txt: Added. * webaudio/AudioParam/audioparam-linearRamp-value-attribute.html: Added. * webaudio/AudioParam/audioparam-negative-exponentialRamp-expected.txt: Added. * webaudio/AudioParam/audioparam-negative-exponentialRamp.html: Added. * webaudio/AudioParam/audioparam-nominal-range-expected.txt: Renamed from LayoutTests/webaudio/audioparam-nominal-range-expected.txt. * webaudio/AudioParam/audioparam-nominal-range.html: Renamed from LayoutTests/webaudio/audioparam-nominal-range.html. * webaudio/AudioParam/audioparam-processing-expected.txt: Added. * webaudio/AudioParam/audioparam-processing.html: Added. * webaudio/AudioParam/audioparam-sampling-expected.txt: Added. * webaudio/AudioParam/audioparam-sampling.html: Added. * webaudio/AudioParam/audioparam-setTarget-timeConstant-0-expected.txt: Added. * webaudio/AudioParam/audioparam-setTarget-timeConstant-0.html: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-continuous-expected.txt: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-continuous.html: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-limit-expected.txt: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-limit.html: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-sampling-expected.txt: Added. * webaudio/AudioParam/audioparam-setTargetAtTime-sampling.html: Added. * webaudio/AudioParam/audioparam-setValueCurve-copy-expected.txt: Added. * webaudio/AudioParam/audioparam-setValueCurve-copy.html: Added. * webaudio/AudioParam/audioparam-setValueCurve-duration-expected.txt: Added. * webaudio/AudioParam/audioparam-setValueCurve-duration.html: Added. * webaudio/AudioParam/audioparam-setValueCurve-end-expected.txt: Added. * webaudio/AudioParam/audioparam-setValueCurve-end.html: Added. * webaudio/AudioParam/audioparam-setValueCurve-exceptions-expected.txt: Added. * webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation-expected.txt: Added. * webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html: Added. * webaudio/AudioParam/audioparam-update-value-attribute-expected.txt: Added. * webaudio/AudioParam/audioparam-update-value-attribute.html: Added. * webaudio/AudioParam/audioparam-value-setter-error-expected.txt: Added. * webaudio/AudioParam/audioparam-value-setter-error.html: Added. * webaudio/AudioParam/cancel-values-crash-913217-expected.txt: Added. * webaudio/AudioParam/cancel-values-crash-913217.html: Added. * webaudio/AudioParam/value-setter-warnings-expected.txt: Added. * webaudio/AudioParam/value-setter-warnings.html: Added. * webaudio/AudioParam/worklet-warnings-expected.txt: Added. * webaudio/AudioParam/worklet-warnings.html: Added. * webaudio/audioparam-exponentialRampToValueAtTime.html: * webaudio/audioparam-linearRampToValueAtTime.html: * webaudio/audioparam-setValueAtTime.html: * webaudio/resources/audioparam-testing-legacy.js: Copied from LayoutTests/webaudio/resources/audioparam-testing.js. (renderLength): (createConstantBuffer): (createConstantArray): (createLinearRampArray): (createExponentialRampArray): (discreteTimeConstantForSampleRate): (createExponentialApproachArray): (createSineWaveArray): (endValueDelta): (valueUpdate): (comparePartialSignals): (verifyDiscontinuities): (compareSignals): (checkResultFunction): (doAutomation): (createAudioGraphAndTest): * webaudio/resources/audioparam-testing.js: (renderLength): (createConstantArray): (getStartEndFrames): (createLinearRampArray): (createExponentialRampArray): (discreteTimeConstantForSampleRate): (createExponentialApproachArray): (createReferenceSineArray): (createSineWaveArray): (endValueDelta): (relativeErrorMetric): (differenceErrorMetric): (valueUpdate): (comparePartialSignals): (verifyDiscontinuities): (compareSignals): (checkResultFunction): (doAutomation): (createAudioGraphAndTest): * webaudio/resources/set-position-vs-curve-test.js: Added. (testPositionSetterVsCurve): Canonical link: https://commits.webkit.org/229512@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-18 19:18:42 +00:00
<!DOCTYPE html>
<html>
<head>
<title>
Updating of Value Attribute from Timeline
</title>
<script src="../../imported/w3c/web-platform-tests/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/audio-param.js"></script>
</head>
<body>
<script id="layout-test-code">
// This should be a power of two so that all time computations have no
// round-off errors.
let sampleRate = 32768;
let renderQuantumSize = 128;
// How many tests to run.
let renderLoops = 20;
let renderFrames = renderLoops * renderQuantumSize;
let renderDuration = renderFrames / sampleRate;
let audit = Audit.createTaskRunner();
audit.define('linear', (task, should) => {
// Test the value attribute from a linearRamp event
runTest(should, function(g, v0, t0, v1, t1) {
g.gain.linearRampToValueAtTime(v1, t1);
return {
expectedValue: function(testTime) {
return audioParamLinearRamp(testTime, v0, t0, v1, t1);
},
message: 'linearRamp(' + v1 + ', ' + t1 + ')',
errorThreshold: 1.1650e-6
};
}).then(() => task.done());
});
audit.define('exponential', (task, should) => {
// Test the value attribute from an exponentialRamp event
runTest(should, function(g, v0, t0, v1, t1) {
g.gain.exponentialRampToValueAtTime(v1, t1);
return {
expectedValue: function(testTime) {
return audioParamExponentialRamp(testTime, v0, t0, v1, t1);
},
message: 'exponentialRamp(' + v1 + ', ' + t1 + ')',
errorThreshold: 7.4601e-7
};
}).then(() => task.done());
});
audit.define('setTarget', (task, should) => {
// Test the value attribute from a setTargetAtTime event
runTest(should, function(g, v0, t0, v1, t1) {
let timeConstant = 0.1;
let vFinal = 0;
g.gain.setTargetAtTime(vFinal, t0, timeConstant);
return {
expectedValue: function(testTime) {
return audioParamSetTarget(
testTime, v0, t0, vFinal, timeConstant);
},
message: 'setTargetAtTime(' + vFinal + ', ' + t0 + ', ' +
timeConstant + ')',
errorThreshold: 2.2599e-6
};
}).then(() => task.done());
});
audit.define('setValueCurve', (task, should) => {
// Test the value attribute from a setValueCurve event
runTest(should, function(g, v0, t0, v1, t1) {
let curve = [1, 1.5, 4];
let duration = t1 - t0;
g.gain.setValueCurveAtTime(Float32Array.from(curve), t0, duration);
return {
expectedValue: function(testTime) {
return audioParamSetValueCurve(testTime, curve, t0, duration);
},
message: 'setValueCurveAtTime([' + curve + '], ' + t0 + ', ' +
duration + ')',
errorThreshold: 7.9577e-8
};
}).then(() => task.done());
});
audit.run();
// Test that the .value getter has the correct value when a timeline is
// running. The |testFunction| is the underlying test to be run.
function runTest(should, testFunction) {
// Create a simple graph consisting of a constant source and a gain node
// where the automations are run. A setValueAtTime event starts things
// off.
let context = new OfflineAudioContext(1, renderFrames, sampleRate);
let source = context.createBufferSource();
source.buffer = createConstantBuffer(context, 1, 1);
source.loop = true;
let gain = context.createGain();
source.connect(gain);
gain.connect(context.destination);
// Start the timeline with setValueAtTime(v0, t0).
let v0 = 0.25;
let t0 = 0;
// End value and time, for those that need it. The end time is less
// than the rendering duration so we can test that the final values of
// the automation (if any) are also correct.
let v1 = 100;
let t1 = renderDuration - 5 * renderQuantumSize / sampleRate;
gain.gain.setValueAtTime(v0, t0);
// Run the desired automation test. The test function returns a
// dictionary consisting of the following properties:
//
// |message| an informative message about the automation being
// tested. |errorThreshold| error threshold to determine if the test
// passes or not. |expectedValue| a function that compute the expected
// value at time |t|.
let test = testFunction(gain, v0, t0, v1, t1);
// Print an informative message about the test being run.
// testPassed("Initialize " + test.message + " with setValueAtTime(" +
// v0 + ", " + t0 + ").");
should(true, 'Initialize')
.message(
test.message + ' with setValueAtTime(' + v0 + ', ' + t0 + ')',
'');
let success = true;
// Max relative error found for this test. This is printed if the test
// fails so that setting the thresholds is easier.
let maxError = 0;
// For every rendering quantum (except the first), suspend the context
// so the we can inspect the value attribute and compare it with the
// expected value.
for (let k = 1; k < renderLoops; ++k) {
let time = k * renderQuantumSize / sampleRate;
context.suspend(time)
.then(function() {
// The context is supsended at time |time|, which is just before
// the rendering quantum starts. Thus, the value of the
// attribute is actually 1 frame before the current context
// time.
let sampleTime = context.currentTime - 1 / sampleRate;
// Compute the max relative error
let expected = test.expectedValue(sampleTime);
let relError =
Math.abs(expected - gain.gain.value) / Math.abs(expected);
maxError = Math.max(relError, maxError);
success =
should(
gain.gain.value,
test.message + ' at frame ' + (sampleRate * sampleTime))
.beCloseTo(
expected, {threshold: test.errorThreshold || 0});
})
.then(context.resume.bind(context));
}
source.start();
return context.startRendering().then(function(resultBuffer) {
// Just print a final pass (or fail) message.
should(success, 'Gain .value attribute for ' + test.message)
.message(
'correctly updated during automation',
'not correctly updated during automation; max error = ' +
maxError);
});
}
</script>
</body>
</html>