forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Insert initial event if needed for linear or exponential ramp automation
When there is no event preceding the linear or exponential ramp, insert a new event (setValueAtTime) to give the starting point for the ramp. This fixes the unintuitive behavior where the ramp basically did nothing except cause a jump to the final value at the end time of the ramp. WebAudio issue: WebAudio/web-audio-api#130 Resolution: WebAudio/web-audio-api#659 BUG=552072 TEST=audioparam-initial-event.html Review URL: https://codereview.chromium.org/1432813003 Cr-Commit-Position: refs/heads/master@{#388242}
- Loading branch information
rtoy
authored and
Commit bot
committed
Apr 19, 2016
1 parent
862ec97
commit f8198c3
Showing
6 changed files
with
224 additions
and
16 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
third_party/WebKit/LayoutTests/webaudio/audioparam-initial-event-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Test Automation Ramps without Initial Event | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS Linear ramp equals [0.5,0.4998958333333333,0.4997916666666667,0.4996875,0.4995833333333333,0.49947916666666664,0.499375,0.49927083333333333,0.49916666666666665,0.4990625,0.49895833333333334,0.49885416666666665,0.49875,0.49864583333333334,0.49854166666666666,0.4984375,...] with an element-wise tolerance of 6.0003e-8. | ||
PASS Exponential ramp equals [0.5,0.5001444220542908,0.5002889037132263,0.5004333853721619,0.5005779266357422,0.5007225275039673,0.5008671879768372,0.501011848449707,0.5011565685272217,0.5013013482093811,0.5014461278915405,0.5015909671783447,0.5017358660697937,0.5018808245658875,0.5020257830619812,0.5021708011627197,...] with an element-wise tolerance of 0.0000023842. | ||
PASS Delayed linear ramp equals [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,...] with an element-wise tolerance of 9.87968e-8. | ||
PASS Delayed exponential ramp equals [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,...] with an element-wise tolerance of 0.000013948. | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
|
175 changes: 175 additions & 0 deletions
175
third_party/WebKit/LayoutTests/webaudio/audioparam-initial-event.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<!doctype html> | ||
<html> | ||
|
||
<head> | ||
<script src="../resources/js-test.js"></script> | ||
<script src="resources/compatibility.js"></script> | ||
<script src="resources/audio-testing.js"></script> | ||
<script src="resources/audioparam-testing.js"></script> | ||
<title>AudioParam Initial Events </title> | ||
</head> | ||
|
||
<body> | ||
<script> | ||
description("Test Automation Ramps without Initial Event"); | ||
window.jsTestIsAsync = true; | ||
|
||
var sampleRate = 48000; | ||
// Number of frames in a rendering quantum. | ||
var quantumFrames = 128; | ||
// Test doesn't need to run for very long. | ||
var renderDuration = 0.2; | ||
var renderFrames = renderDuration * sampleRate; | ||
var automationEndTime = 0.1; | ||
|
||
var audit = Audit.createTaskRunner(); | ||
|
||
// The following tests start a ramp automation without an initial event. This should cause an | ||
// initial event to be added implicitly to give a starting point. | ||
audit.defineTask("linear-ramp", function (done) { | ||
runTest("Linear ramp", { | ||
automationFunction: function (node, value, time) { | ||
node.gain.linearRampToValueAtTime(value, time); | ||
}, | ||
referenceFunction: linearRamp, | ||
// Experimentally determined threshold | ||
threshold: 6.0003e-8, | ||
// The starting value of the gain node | ||
v0: 0.5, | ||
// The target value of the automation | ||
v1: 0, | ||
}) | ||
.then(done); | ||
}); | ||
|
||
audit.defineTask("exponential-ramp", function (done) { | ||
runTest("Exponential ramp", { | ||
automationFunction: function (node, value, time) { | ||
node.gain.exponentialRampToValueAtTime(value, time); | ||
}, | ||
referenceFunction: exponentialRamp, | ||
threshold: 2.3842e-6, | ||
v0: 0.5, | ||
v1: 2, | ||
}) | ||
.then(done); | ||
}); | ||
|
||
// Same tests as above, but we delay the call to the automation function. This is to verify that | ||
// the we still do the right thing after the context has started. | ||
audit.defineTask("delayed-linear-ramp", function (done) { | ||
runTest("Delayed linear ramp", { | ||
automationFunction: function (node, value, time) { | ||
node.gain.linearRampToValueAtTime(value, time); | ||
}, | ||
referenceFunction: linearRamp, | ||
// Experimentally determined threshold | ||
threshold: 9.87968e-8, | ||
// The starting value of the gain node | ||
v0: 0.5, | ||
// The target value of the automation | ||
v1: 0, | ||
delay: quantumFrames / sampleRate | ||
}) | ||
.then(done); | ||
}); | ||
|
||
audit.defineTask("delayed-exponential-ramp", function (done) { | ||
runTest("Delayed exponential ramp", { | ||
automationFunction: function (node, value, time) { | ||
node.gain.exponentialRampToValueAtTime(value, time); | ||
}, | ||
referenceFunction: exponentialRamp, | ||
// Experimentally determined threshold | ||
threshold: 1.3948e-5, | ||
// The starting value of the gain node | ||
v0: 0.5, | ||
// The target value of the automation | ||
v1: 2, | ||
delay: quantumFrames / sampleRate | ||
}) | ||
.then(done); | ||
}); | ||
|
||
audit.defineTask("finish", function (done) { | ||
finishJSTest(); | ||
done(); | ||
}); | ||
|
||
audit.runTasks(); | ||
|
||
// Generate the expected waveform for a linear ramp starting from the value |v0|, ramping to | ||
// |v1| at time |endTime|. The time of |v0| is assumed to be 0. |nFrames| is how many frames | ||
// to generate. | ||
function linearRamp(v0, v1, startTime, endTime, nFrames) { | ||
var expected = createLinearRampArray(startTime, endTime, v0, v1, sampleRate); | ||
var preFiller = new Array(Math.floor(startTime * sampleRate)); | ||
var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | ||
preFiller.fill(v0); | ||
return preFiller.concat(expected.concat(postFiller.fill(v1))); | ||
} | ||
|
||
// Generate the expected waveform for an exponential ramp starting from the value |v0|, | ||
// ramping to |v1| at time |endTime|. The time of |v0| is assumed to be 0. |nFrames| is how | ||
// many frames to generate. | ||
function exponentialRamp(v0, v1, startTime, endTime, nFrames) { | ||
var expected = createExponentialRampArray(startTime, endTime, v0, v1, sampleRate); | ||
var preFiller = new Array(Math.floor(startTime * sampleRate)); | ||
preFiller.fill(v0); | ||
var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | ||
return preFiller.concat(expected.concat(postFiller.fill(v1))); | ||
} | ||
|
||
// Run an automation test. |message| is the message to use for printing the results. |options| | ||
// is a property bag containing the configuration of the test including the following: | ||
// | ||
// automationFunction - automation function to use, | ||
// referenceFunction - function generating the expected result | ||
// threshold - comparison threshold | ||
// v0 - starting value | ||
// v1 - end value for automation | ||
function runTest(message, options) { | ||
var automationFunction = options.automationFunction; | ||
var referenceFunction = options.referenceFunction; | ||
var threshold = options.threshold; | ||
var v0 = options.v0; | ||
var v1 = options.v1; | ||
var delay = options.delay; | ||
|
||
var context = new OfflineAudioContext(1, renderFrames, sampleRate); | ||
|
||
// A constant source of amplitude 1. | ||
var source = context.createBufferSource(); | ||
source.buffer = createConstantBuffer(context, 1, 1); | ||
source.loop = true; | ||
|
||
// Automation is applied to a gain node | ||
var gain = context.createGain(); | ||
gain.gain.value = v0; | ||
|
||
// Delay start of automation, if requested | ||
if (delay) { | ||
context.suspend(options.delay).then(function () { | ||
automationFunction(gain, v1, automationEndTime); | ||
context.resume(); | ||
}); | ||
} else { | ||
automationFunction(gain, v1, automationEndTime); | ||
} | ||
|
||
source.connect(gain); | ||
gain.connect(context.destination); | ||
|
||
source.start(); | ||
|
||
return context.startRendering() | ||
.then(function (resultBuffer) { | ||
var result = resultBuffer.getChannelData(0); | ||
var expected = referenceFunction(v0, v1, delay ? delay : 0, automationEndTime, renderFrames); | ||
Should(message, result).beCloseToArray(expected, threshold); | ||
}); | ||
} | ||
</script> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters