Commit 6295da93 authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

Move AudioBufferSourceNode tests to WPT

These tests basically pass on Firefox.  If they don't, it's because
Firefox is incorrect and issues have been filed for these.

During the testing, we discovered that an incorrect assumption was made
that calling start() would always work.  Because of test failures in Firefox,
this assumption is incorrect.

Updated audit.js to latest Chrome version (to get loadFileFromURL) and
add wpt lint exception for a console message in audit.js.

Needed to update audiocontext-getoutputtimestamp.html to make bots happy
because the AudioContext is running now on the bots, so time is
progressing, so the time stamps aren't always zero.

Bug: 745778
Change-Id: I5f9ee01498678db0feb57051f682772ca7bd9fbb
Reviewed-on: https://chromium-review.googlesource.com/1040865Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570890}
parent b4205309
...@@ -318,6 +318,8 @@ external/wpt/web-animations/timing-model/animation-effects/active-time.html ...@@ -318,6 +318,8 @@ external/wpt/web-animations/timing-model/animation-effects/active-time.html
external/wpt/web-animations/timing-model/animations/finishing-an-animation.html external/wpt/web-animations/timing-model/animations/finishing-an-animation.html
external/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html external/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html
external/wpt/web-animations/timing-model/time-transformations/transformed-progress.html external/wpt/web-animations/timing-model/time-transformations/transformed-progress.html
external/wpt/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-ended.html
external/wpt/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-playbackrate-zero.html
external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html external/wpt/webaudio/the-audio-api/the-audionode-interface/channel-mode-interp-basic.html
external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html
external/wpt/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html external/wpt/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html
...@@ -999,8 +1001,6 @@ virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen.htm ...@@ -999,8 +1001,6 @@ virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen.htm
virtual/without-smil/svg/animations/exposed/effect.html virtual/without-smil/svg/animations/exposed/effect.html
wake_lock/wakelock-api.html wake_lock/wakelock-api.html
wake_lock/wakelock-in-nested-frame.html wake_lock/wakelock-in-nested-frame.html
webaudio/AudioBufferSource/audiobuffersource-ended.html
webaudio/AudioBufferSource/audiobuffersource-playbackrate-zero.html
webaudio/AudioParam/audioparam-setValueCurve-duration.html webaudio/AudioParam/audioparam-setValueCurve-duration.html
webaudio/codec-tests/flac/flac-decode.html webaudio/codec-tests/flac/flac-decode.html
webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html webaudio/codec-tests/vorbis/vbr-128kbps-44khz.html
......
...@@ -111,6 +111,7 @@ CONSOLE: service-workers/service-worker/resources/navigation-redirect-other-orig ...@@ -111,6 +111,7 @@ CONSOLE: service-workers/service-worker/resources/navigation-redirect-other-orig
CONSOLE: service-workers/service-worker/navigation-redirect.https.html CONSOLE: service-workers/service-worker/navigation-redirect.https.html
CONSOLE: service-workers/service-worker/resources/clients-get-other-origin.html CONSOLE: service-workers/service-worker/resources/clients-get-other-origin.html
CONSOLE: webrtc/tools/* CONSOLE: webrtc/tools/*
CONSOLE: webaudio/resources/audit.js:39
# use of console in a public library - annotation-model ensures # use of console in a public library - annotation-model ensures
# it is not actually used # it is not actually used
......
function createTestBuffer(context, sampleFrameLength) {
let audioBuffer =
context.createBuffer(1, sampleFrameLength, context.sampleRate);
let channelData = audioBuffer.getChannelData(0);
// Create a simple linear ramp starting at zero, with each value in the buffer
// equal to its index position.
for (let i = 0; i < sampleFrameLength; ++i)
channelData[i] = i;
return audioBuffer;
}
function checkSingleTest(renderedBuffer, i, should) {
let renderedData = renderedBuffer.getChannelData(0);
let offsetFrame = i * testSpacingFrames;
let test = tests[i];
let expected = test.expected;
let description;
if (test.description) {
description = test.description;
} else {
// No description given, so create a basic one from the given test
// parameters.
description =
'loop from ' + test.loopStartFrame + ' -> ' + test.loopEndFrame;
if (test.offsetFrame)
description += ' with offset ' + test.offsetFrame;
if (test.playbackRate && test.playbackRate != 1)
description += ' with playbackRate of ' + test.playbackRate;
}
let framesToTest;
if (test.renderFrames)
framesToTest = test.renderFrames;
else if (test.durationFrames)
framesToTest = test.durationFrames;
// Verify that the output matches
let prefix = 'Case ' + i + ': ';
should(
renderedData.slice(offsetFrame, offsetFrame + framesToTest),
prefix + description)
.beEqualToArray(expected);
// Verify that we get all zeroes after the buffer (or duration) has passed.
should(
renderedData.slice(
offsetFrame + framesToTest, offsetFrame + testSpacingFrames),
prefix + description + ': tail')
.beConstantValueOf(0);
}
function checkAllTests(renderedBuffer, should) {
for (let i = 0; i < tests.length; ++i)
checkSingleTest(renderedBuffer, i, should);
}
// Create the actual result by modulating playbackRate or detune AudioParam of
// ABSN. |modTarget| is a string of AudioParam name, |modOffset| is the offset
// (anchor) point of modulation, and |modRange| is the range of modulation.
//
// createSawtoothWithModulation(context, 'detune', 440, 1200);
//
// The above will perform a modulation on detune within the range of
// [1200, -1200] around the sawtooth waveform on 440Hz.
function createSawtoothWithModulation(context, modTarget, modOffset, modRange) {
let lfo = context.createOscillator();
let amp = context.createGain();
// Create a sawtooth generator with the signal range of [0, 1].
let phasor = context.createBufferSource();
let phasorBuffer = context.createBuffer(1, sampleRate, sampleRate);
let phasorArray = phasorBuffer.getChannelData(0);
let phase = 0, phaseStep = 1 / sampleRate;
for (let i = 0; i < phasorArray.length; i++) {
phasorArray[i] = phase % 1.0;
phase += phaseStep;
}
phasor.buffer = phasorBuffer;
phasor.loop = true;
// 1Hz for audible (human-perceivable) parameter modulation by LFO.
lfo.frequency.value = 1.0;
amp.gain.value = modRange;
phasor.playbackRate.value = modOffset;
// The oscillator output should be amplified accordingly to drive the
// modulation within the desired range.
lfo.connect(amp);
amp.connect(phasor[modTarget]);
phasor.connect(context.destination);
lfo.start();
phasor.start();
}
...@@ -33,6 +33,12 @@ window.Audit = (function() { ...@@ -33,6 +33,12 @@ window.Audit = (function() {
'use strict'; 'use strict';
// NOTE: Moving this method (or any other code above) will change the location
// of 'CONSOLE ERROR...' message in the expected text files.
function _logError(message) {
console.error('[audit.js] ' + message);
}
function _logPassed(message) { function _logPassed(message) {
test(function(arg) { test(function(arg) {
assert_true(true); assert_true(true);
...@@ -70,13 +76,9 @@ window.Audit = (function() { ...@@ -70,13 +76,9 @@ window.Audit = (function() {
String(target.slice(0, options.numberOfArrayElements)) + '...'; String(target.slice(0, options.numberOfArrayElements)) + '...';
targetString = '[' + arrayElements + ']'; targetString = '[' + arrayElements + ']';
} else if (target === null) { } else if (target === null) {
// null is an object, so we need to handle this specially.
targetString = String(target); targetString = String(target);
} else { } else {
// We're expecting String() to return something like "[object Foo]", targetString = '' + String(target).split(/[\s\]]/)[1];
// so we split the string to get the object type "Foo". This is
// pretty fragile.
targetString = '' + String(targetString).split(/[\s\]]/)[1];
} }
break; break;
default: default:
...@@ -350,7 +352,7 @@ window.Audit = (function() { ...@@ -350,7 +352,7 @@ window.Audit = (function() {
* *
* @example * @example
* should('My promise', promise).beResolve().then((result) => { * should('My promise', promise).beResolve().then((result) => {
* // log(result); * log(result);
* }); * });
* *
* @result * @result
...@@ -1288,6 +1290,56 @@ window.Audit = (function() { ...@@ -1288,6 +1290,56 @@ window.Audit = (function() {
} }
} }
/**
* Load file from a given URL and pass ArrayBuffer to the following promise.
* @param {String} fileUrl file URL.
* @return {Promise}
*
* @example
* Audit.loadFileFromUrl('resources/my-sound.ogg').then((response) => {
* audioContext.decodeAudioData(response).then((audioBuffer) => {
* // Do something with AudioBuffer.
* });
* });
*/
function loadFileFromUrl(fileUrl) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', fileUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
// |status = 0| is a workaround for the run_web_test.py server. We are
// speculating the server quits the transaction prematurely without
// completing the request.
if (xhr.status === 200 || xhr.status === 0) {
resolve(xhr.response);
} else {
let errorMessage = 'loadFile: Request failed when loading ' +
fileUrl + '. ' + xhr.statusText + '. (status = ' + xhr.status +
')';
if (reject) {
reject(errorMessage);
} else {
new Error(errorMessage);
}
}
};
xhr.onerror = (event) => {
let errorMessage =
'loadFile: Network failure when loading ' + fileUrl + '.';
if (reject) {
reject(errorMessage);
} else {
new Error(errorMessage);
}
};
xhr.send();
});
}
/** /**
* @class Audit * @class Audit
* @description A WebAudio layout test task manager. * @description A WebAudio layout test task manager.
...@@ -1313,12 +1365,18 @@ window.Audit = (function() { ...@@ -1313,12 +1365,18 @@ window.Audit = (function() {
if (options && options.requireResultFile == true) { if (options && options.requireResultFile == true) {
_logError( _logError(
'this test requires the explicit comparison with the ' + 'this test requires the explicit comparison with the ' +
'expected result when it runs with run-webkit-tests.'); 'expected result when it runs with run_web_tests.py.');
} }
return new TaskRunner(); return new TaskRunner();
}, },
/**
* Load file from a given URL and pass ArrayBuffer to the following promise.
* See |loadFileFromUrl| method for the detail.
*/
loadFileFromUrl: loadFileFromUrl
}; };
})(); })();
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
Basic Test of AudioBufferSourceNode Basic Test of AudioBufferSourceNode
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/start-stop-exceptions.js"></script> <script src="/webaudio/resources/start-stop-exceptions.js"></script>
</head> </head>
<script id="layout-test-code"> <script id="layout-test-code">
let sampleRate = 44100; let sampleRate = 44100;
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<title> <title>
audiobuffersource-channels.html audiobuffersource-channels.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
audiobuffersource-ended.html audiobuffersource-ended.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/audiobuffersource-testing.js"></script> <script src="/webaudio/resources/audiobuffersource-testing.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<title> <title>
Test Start Grain with Delayed Buffer Setting Test Start Grain with Delayed Buffer Setting
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -7,11 +7,11 @@ Test AudioBufferSourceNode supports 5.1 channel. ...@@ -7,11 +7,11 @@ Test AudioBufferSourceNode supports 5.1 channel.
<title> <title>
audiobuffersource-multi-channels.html audiobuffersource-multi-channels.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/mix-testing.js"></script> <script src="/webaudio/resources/mix-testing.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
...@@ -33,12 +33,11 @@ Test AudioBufferSourceNode supports 5.1 channel. ...@@ -33,12 +33,11 @@ Test AudioBufferSourceNode supports 5.1 channel.
.then(arrayBuffer => { .then(arrayBuffer => {
context.decodeAudioData(arrayBuffer).then(audioBuffer => { context.decodeAudioData(arrayBuffer).then(audioBuffer => {
expectedAudio = audioBuffer; expectedAudio = audioBuffer;
task.done();
}); });
}), }),
'Fetching expected audio') 'Fetching expected audio')
.beResolved() .beResolved();
.then(() => task.done());
}); });
audit.define( audit.define(
...@@ -61,7 +60,6 @@ Test AudioBufferSourceNode supports 5.1 channel. ...@@ -61,7 +60,6 @@ Test AudioBufferSourceNode supports 5.1 channel.
// the wave file are +/- 32768. // the wave file are +/- 32768.
let maxUlp = 1; let maxUlp = 1;
let threshold = maxUlp / 32768; let threshold = maxUlp / 32768;
for (let k = 0; k < renderedAudio.numberOfChannels; ++k) { for (let k = 0; k < renderedAudio.numberOfChannels; ++k) {
should( should(
renderedAudio.getChannelData(k), renderedAudio.getChannelData(k),
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<title> <title>
Test AudioBufferSourceNode With Looping a Single-Sample Buffer Test AudioBufferSourceNode With Looping a Single-Sample Buffer
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<title> <title>
audiobuffersource-playbackrate-zero.html audiobuffersource-playbackrate-zero.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
audiobuffersource-start.html audiobuffersource-start.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/audiobuffersource-testing.js"></script> <script src="/webaudio/resources/audiobuffersource-testing.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<title> <title>
Test Onended Event Listener Test Onended Event Listener
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
Test Scheduled Sources with Huge Time Limits Test Scheduled Sources with Huge Time Limits
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/audioparam-testing.js"></script> <script src="/webaudio/resources/audioparam-testing.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
note-grain-on-play.html note-grain-on-play.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/note-grain-on-testing.js"></script> <script src="/webaudio/resources/note-grain-on-testing.js"></script>
</head> </head>
<body> <body>
<div id="description"></div> <div id="description"></div>
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
<title> <title>
note-grain-on-timing.html note-grain-on-timing.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/note-grain-on-testing.js"></script> <script src="/webaudio/resources/note-grain-on-testing.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -8,11 +8,11 @@ We use an impulse so we can tell exactly where the rendering is happening. ...@@ -8,11 +8,11 @@ We use an impulse so we can tell exactly where the rendering is happening.
<title> <title>
sample-accurate-scheduling.html sample-accurate-scheduling.html
</title> </title>
<script src="../../resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script> <script src="/webaudio/resources/audit-util.js"></script>
<script src="../resources/audit.js"></script> <script src="/webaudio/resources/audit.js"></script>
<script src="../resources/buffer-loader.js"></script> <script src="/webaudio/resources/buffer-loader.js"></script>
</head> </head>
<body> <body>
<script id="layout-test-code"> <script id="layout-test-code">
......
...@@ -19,9 +19,10 @@ ...@@ -19,9 +19,10 @@
should(timestamp.contextTime, 'timestamp.contextTime').exist(); should(timestamp.contextTime, 'timestamp.contextTime').exist();
should(timestamp.performanceTime, 'timestamp.performanceTime').exist(); should(timestamp.performanceTime, 'timestamp.performanceTime').exist();
should(timestamp.contextTime, 'timestamp.contextTime').beEqualTo(0); should(timestamp.contextTime, 'timestamp.contextTime')
.beGreaterThanOrEqualTo(0);
should(timestamp.performanceTime, 'timestamp.performanceTime') should(timestamp.performanceTime, 'timestamp.performanceTime')
.beEqualTo(0); .beGreaterThanOrEqualTo(0);
task.done(); task.done();
}); });
......
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