Commit 57df4e50 authored by rtoy@chromium.org's avatar rtoy@chromium.org

Rebase oscillator sine test result.

Manually compared this new result against the linux result and they
differ by about 2 units, which is expected. The old result appears
to have a completely incorrect frequency sweep.

Also added a new test for oscillator that uses SNR and max difference to compare the expected and actual result. This is a bit more robust with different numerical results and makes it easier to tell if something is totally wrong or just slightly wrong for the oscillator-sine test.

Removed oscillator-sine; it seems very sensitive to numerics of the platform, and I think the new osc-sine-sweep-snr test is robust enough to catch errors

The other oscillator tests are just updated to match the change in api in oscillator-testing.js to support passing in the context so different check routines can be used for the test.

BUG=425744, 431688, 309197
TESTS=osc-sine-sweep-snr.html

Review URL: https://codereview.chromium.org/670863002

git-svn-id: svn://svn.chromium.org/blink/trunk@185249 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent fed881ca
......@@ -1264,8 +1264,6 @@ crbug.com/357437 [ Release Mavericks ] web-animations-api/change-in-animation-fr
crbug.com/357437 [ Release Win7 ] web-animations-api/change-in-animation-frame.html [ Failure Pass ]
crbug.com/357437 [ Debug Win7 ] web-animations-api/change-in-animation-frame.html [ Failure Pass ]
crbug.com/357437 [ Release XP ] web-animations-api/change-in-animation-frame.html [ Failure Pass ]
Bug(gardener) [ Release Linux ] webaudio/oscillator-sine.html [ Failure Pass ]
Bug(gardener) [ Debug Linux ] webaudio/oscillator-sine.html [ Failure Pass ]
crbug.com/392095 [ Release Linux ] webaudio/realtimeanalyser-fft-scaling.html [ Failure Pass ]
crbug.com/392095 [ Debug Linux ] webaudio/realtimeanalyser-fft-scaling.html [ Failure Pass ]
Bug(gardener) [ Debug Win7 ] webaudio/up-mixing-mono-51.html [ Pass Timeout ]
......
......@@ -774,7 +774,6 @@ crbug.com/347365 [ Linux ] dom/xhtml/level3/core/canonicalform08.xhtml [ Crash P
crbug.com/347365 [ Linux ] dom/xhtml/level3/core/canonicalform09.xhtml [ Crash Pass ]
crbug.com/309197 [ Win Debug ] webaudio/oscillator-custom.html [ Skip ]
crbug.com/309197 [ Win Debug ] webaudio/oscillator-sine.html [ Skip ]
crbug.com/309197 [ Win Debug ] webaudio/oscillator-square.html [ Skip ]
crbug.com/356777 http/tests/history/frameset-repeated-name.html [ Pass Failure ]
......@@ -1374,6 +1373,5 @@ crbug.com/384723 accessibility/chromium-only-roles.html [ Failure ]
crbug.com/385014 accessibility/canvas-fallback-content-2.html [ Failure ]
crbug.com/431152 inspector/audits/audits-panel-functional.html [ Pass Failure ]
crbug.com/431688 [ Win Release ] webaudio/oscillator-sine.html [ Failure ]
crbug.com/431778 [ Win7 Linux Debug ] http/tests/security/shape-image-cors.html [ Pass Crash ]
crbug.com/431643 [ Win ] http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_redirect_chain_allow_timing.html [ Pass Failure ]
PASS Exceeded SNR threshold of 86.58 dB
PASS Maximum difference below threshold of 2.9 ulp (16-bits)
PASS Number of differences between actual and expected result is less than 5850
PASS successfullyParsed is true
TEST COMPLETE
<!doctype html>
<html>
<head>
<title>Test Oscillator Node: sine</title>
<script src="resources/compatibility.js"></script>
<script src="resources/buffer-loader.js"></script>
<script src="../resources/js-test.js"></script>
<script src="resources/oscillator-testing.js"></script>
</head>
<body>
<script>
// See oscillator-sine.html for more info on the actual wave shape.
//
// This test is a partial duplicate of oscillator-sine but is designed to be less sensitive
// to the actual output versus the reference. Instead of requiring an exact match, we check
// several criteria to pass the test. The SNR between the actual and expected signals must
// be large enough. The maximum difference must be below a threshold, and the actual number
// of points that are different must be below a threshold.
var sampleRate = 44100.0;
var nyquist = 0.5 * sampleRate;
var lengthInSeconds = 4;
var lowFrequency = 10;
var highFrequency = nyquist + 2000; // go slightly higher than nyquist to make sure we generate silence there
var context = 0;
var reference = 0;
var renderedData = 0;
var signalPower = 0;
var noisePower = 0;
// Scaling factor for converting the 16-bit WAV data to float (and vice-versa).
var waveScaleFactor = 32768;
// Thresholds for verifying the test passes. The thresholds are experimentally determined.
// SNR must be greater than this to pass the test.
// Q: Why is the SNR threshold not infinity?
// A: The reference result is a 16-bit WAV file, so it won't compare exactly with the
// floating point result.
var thresholdSNR = 86.58;
// Max diff must be less than this to pass the test.
var thresholdDiff = 2.9 / waveScaleFactor;
// Count the number of differences between the expected and actual result. The tests passes
// if the count is less than this threshold.
var thresholdDiffCount = 5850;
function db(sPower, nPower)
{
if (nPower == 0 && sPower > 0) {
return 1000;
}
return 10 * Math.log10(sPower / nPower);
}
function checkResult (event) {
renderedData = event.renderedBuffer.getChannelData(0);
// Compute signal to noise ratio between the result and the reference. Also keep track
// of the max difference (and position).
var maxError = -1;
var errorPosition = -1;
var diffCount = 0;
for (var k = 0; k < renderedData.length; ++k) {
var diff = renderedData[k] - reference[k];
noisePower += diff * diff;
signalPower += reference[k] * reference[k];
if (Math.abs(diff) > maxError) {
maxError = Math.abs(diff);
errorPosition = k;
}
// The reference file is a 16-bit WAV file, so we will never get an exact match
// between it and the actual floating-point result.
if (diff > 1/waveScaleFactor) {
diffCount++;
}
}
var snr = db(signalPower, noisePower);
if (snr < thresholdSNR) {
testFailed("Expected SNR of " + thresholdSNR + " dB, but actual SNR is " + snr + " dB");
} else {
testPassed("Exceeded SNR threshold of " + thresholdSNR + " dB");
}
if (maxError > thresholdDiff) {
testFailed("Maximum difference of " + (maxError * waveScaleFactor) + " at "
+ errorPosition + " exceeded threshold of " + (thresholdDiff * waveScaleFactor)
+ " ulp (16-bits)");
} else {
testPassed("Maximum difference below threshold of "
+ (thresholdDiff * waveScaleFactor) + " ulp (16-bits)");
}
if (diffCount > thresholdDiffCount) {
testFailed(diffCount + " differences found but expected no more than " + thresholdDiffCount);
} else {
testPassed("Number of differences between actual and expected result is less than " + thresholdDiffCount);
}
finishJSTest();
}
function finishedLoading(bufferList) {
reference = bufferList[0].getChannelData(0);
generateExponentialOscillatorSweep(context, "sine");
context.oncomplete = checkResult;
context.startRendering();
}
function runTest () {
window.jsTestIsAsync = true;
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
bufferLoader = new BufferLoader(
context,
[ "oscillator-sine-expected.wav" ],
finishedLoading);
bufferLoader.load();
}
runTest();
successfullyParsed = true;
</script>
</body>
</html>
......@@ -21,7 +21,14 @@ function init() {
if (!window.testRunner)
return;
generateExponentialOscillatorSweep("custom");
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
generateExponentialOscillatorSweep(context, "custom");
context.oncomplete = finishAudioTest;
context.startRendering();
testRunner.waitUntilDone();
}
</script>
......
......@@ -21,7 +21,14 @@ function init() {
if (!window.testRunner)
return;
generateExponentialOscillatorSweep(OSC.SAWTOOTH);
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
generateExponentialOscillatorSweep(context, "sawtooth");
context.oncomplete = finishAudioTest;
context.startRendering();
testRunner.waitUntilDone();
}
</script>
......
<!DOCTYPE html>
<!--
Create an oscillator of type SINE and generate a slow exponential tone sweep.
The result can be checked for the correct wave shape and for aliasing artifacts.
See oscillator-testing.js for details.
-->
<html>
<head>
<script type="text/javascript" src="resources/audio-testing.js"></script>
<script type="text/javascript" src="resources/oscillator-testing.js"></script>
</head>
<body>
<script>
window.onload = init;
function init() {
if (!window.testRunner)
return;
generateExponentialOscillatorSweep("sine");
}
</script>
</body>
</html>
......@@ -21,7 +21,14 @@ function init() {
if (!window.testRunner)
return;
generateExponentialOscillatorSweep("square");
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
generateExponentialOscillatorSweep(context, "square");
context.oncomplete = finishAudioTest;
context.startRendering();
testRunner.waitUntilDone();
}
</script>
......
......@@ -21,7 +21,14 @@ function init() {
if (!window.testRunner)
return;
generateExponentialOscillatorSweep("triangle");
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
generateExponentialOscillatorSweep(context, "triangle");
context.oncomplete = finishAudioTest;
context.startRendering();
testRunner.waitUntilDone();
}
</script>
......
......@@ -17,10 +17,7 @@ var lowFrequency = 10;
var highFrequency = nyquist + 2000; // go slightly higher than nyquist to make sure we generate silence there
var context = 0;
function generateExponentialOscillatorSweep(oscillatorType) {
// Create offline audio context.
context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, sampleRate);
function generateExponentialOscillatorSweep(context, oscillatorType) {
var osc = context.createOscillator();
if (oscillatorType == "custom") {
// Create a simple waveform with three Fourier coefficients.
......@@ -44,9 +41,4 @@ function generateExponentialOscillatorSweep(oscillatorType) {
var nyquist = 0.5 * sampleRate;
osc.frequency.setValueAtTime(10, 0);
osc.frequency.exponentialRampToValueAtTime(highFrequency, lengthInSeconds);
context.oncomplete = finishAudioTest;
context.startRendering();
testRunner.waitUntilDone();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment