Bug 1526301 [wpt PR 15005] - Update cached azimuth/elevation/cone gain, a=testonly

Automatic update from web-platform-tests
Update cached azimuth/elevation/cone gain

Sample accurate panner automations need to update the cached value for
the azimuth, elevation, and cone gain at the end of each render in
case the automations end (because all automations are sufficiently far
in the past).  When this happens, the panner switches from a-rate
sample-accurate method to k-rate method that uses the cached values
when nothing is moving.  If the a-rate method doesn't update, then the
k-rate method uses the old values which are now incorrect.

Bug: 917757
Test: the-panner-node/automation-changes.html
Change-Id: I7289c278b1cc9dc31d9e3f5698ac467cb1474ca5
Reviewed-on: https://chromium-review.googlesource.com/c/1427795
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#627129}

--

wpt-commits: 48e44386b5c07758ddd22c8227701c37beebe76f
wpt-pr: 15005
This commit is contained in:
Raymond Toy 2019-02-12 13:49:51 +00:00 коммит произвёл moz-wptsync-bot
Родитель 2250799a7e
Коммит 6700f1ed95
1 изменённых файлов: 140 добавлений и 0 удалений

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

@ -0,0 +1,140 @@
<!doctype html>
<html>
<head>
<title>Panner Node Automation</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/audit-util.js"></script>
<script src="../../resources/audit.js"></script>
</head>
<body>
<script>
// Use a power-of-two to eliminate some round-off; otherwise, this isn't
// really important.
const sampleRate = 16384;
// Render enough for the test; we don't need a lot.
const renderFrames = 2048;
// Initial panner positionX and final positionX for listener.
const positionX = 2000;
const audit = Audit.createTaskRunner();
// Test that listener.positionX.value setter does the right thing.
audit.define('Set Listener.positionX.value', (task, should) => {
const context = new OfflineAudioContext(2, renderFrames, sampleRate);
createGraph(context);
// Frame at which the listener instantaneously moves to a new location.
const moveFrame = 512;
context.suspend(moveFrame / context.sampleRate)
.then(() => {
context.listener.positionX.value = positionX;
})
.then(() => context.resume());
verifyOutput(context, moveFrame, should, 'listenr.positionX.value')
.then(() => task.done());
});
// Test that listener.positionX.setValueAtTime() does the right thing.
audit.define('Listener.positionX.setValue', (task, should) => {
const context = new OfflineAudioContext(2, renderFrames, sampleRate);
createGraph(context);
// Frame at which the listener instantaneously moves to a new location.
const moveFrame = 512;
context.listener.positionX.setValueAtTime(
positionX, moveFrame / context.sampleRate);
verifyOutput(
context, moveFrame, should, 'listener.positionX.setValueATTime')
.then(() => task.done());
});
// Test that listener.setPosition() does the right thing.
audit.define('Listener.setPosition', (task, should) => {
const context = new OfflineAudioContext(2, renderFrames, sampleRate);
createGraph(context);
// Frame at which the listener instantaneously moves to a new location.
const moveFrame = 512;
context.suspend(moveFrame / context.sampleRate)
.then(() => {
context.listener.setPosition(positionX, 0, 0);
})
.then(() => context.resume());
verifyOutput(context, moveFrame, should, 'listener.setPostion')
.then(() => task.done());
});
audit.run();
// Create the basic graph for testing which consists of an oscillator node
// connected to a panner node.
function createGraph(context) {
const listener = context.listener;
listener.positionX.value = 0;
listener.positionY.value = 0;
listener.positionZ.value = 0;
const src = new OscillatorNode(context);
const panner = new PannerNode(context, {
distanceModel: 'linear',
refDistance: 1,
maxDistance: 3000,
positionX: positionX,
positionY: 0,
positionZ: 0
});
src.connect(panner).connect(context.destination);
src.start();
}
// Verify the output from the panner is correct.
function verifyOutput(context, moveFrame, should, prefix) {
return context.startRendering().then(resultBuffer => {
// Get the outputs (left and right)
const c0 = resultBuffer.getChannelData(0);
const c1 = resultBuffer.getChannelData(1);
// The src/listener set up is such that audio should only come
// from the right for until |moveFrame|. Hence the left channel
// should be 0 (or very nearly 0).
const zero = new Float32Array(moveFrame);
should(
c0.slice(0, moveFrame), `${prefix}: output0[0:${moveFrame - 1}]`)
.beCloseToArray(zero, {absoluteThreshold: 1e-16});
should(
c1.slice(0, moveFrame), `${prefix}: output1[0:${moveFrame - 1}]`)
.notBeConstantValueOf(0);
// At |moveFrame| and beyond, the listener and source are at the
// same position, so the outputs from the left and right should be
// identical, and the left channel should not be 0 anymore.
should(c0.slice(moveFrame), `${prefix}: output0[${moveFrame}:]`)
.notBeConstantValueOf(0);
should(c1.slice(moveFrame), `${prefix}: output1[${moveFrame}:]`)
.beCloseToArray(c0.slice(moveFrame));
});
}
</script>
</body>
</html>