blob: f8aa9994e3e92a4947b7fcba8a8a31f2892f3d53 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>
Test Clamping of AudioParam Time
</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 id="layout-test-code">
// Fairly arbitrary sample rate and render frames.
let sampleRate = 24000;
let renderFrames = 1024;
let audit = Audit.createTaskRunner();
audit.define('setValue', (task, should) => {
let suspendFrame = 128;
createGraph({
suspendFrame: suspendFrame,
method: 'setValueAtTime',
initialGain: 0,
arg0: 1,
})
.then(function(resultBuffer) {
// Just verify that the cosine wave actually started at
// suspendFrame.
let result = resultBuffer.getChannelData(0);
should(
result.slice(0, suspendFrame),
'setValue: Output[0-' + (suspendFrame - 1) + ']')
.beConstantValueOf(0);
should(
result.slice(suspendFrame),
'setValue: Output[' + suspendFrame + '-' +
(renderFrames - 1) + ']')
.beConstantValueOf(1);
})
.then(() => task.done());
});
audit.define('linear', (task, should) => {
let suspendFrame = 128;
createGraph({
suspendFrame: suspendFrame,
method: 'linearRampToValueAtTime',
initialGain: 1,
arg0: 0.5
})
.then(function(resultBuffer) {
// Just verify that the cosine wave actually started at
// suspendFrame.
let result = resultBuffer.getChannelData(0);
should(
result.slice(0, suspendFrame),
'linear: Output[0-' + (suspendFrame - 1) + ']')
.beConstantValueOf(1);
should(
result.slice(suspendFrame),
'linear: Output[' + suspendFrame + '-' + (renderFrames - 1) +
']')
.beConstantValueOf(0.5);
})
.then(() => task.done());
});
audit.define('exponential', (task, should) => {
let suspendFrame = 128;
createGraph({
suspendFrame: suspendFrame,
method: 'exponentialRampToValueAtTime',
initialGain: 1,
arg0: 0.5
})
.then(function(resultBuffer) {
// Just verify that the cosine wave actually started at
// suspendFrame.
let result = resultBuffer.getChannelData(0);
should(
result.slice(0, suspendFrame),
'exponential: Output[0-' + (suspendFrame - 1) + ']')
.beConstantValueOf(1);
should(
result.slice(suspendFrame),
'exponential: Output[' + suspendFrame + '-' +
(renderFrames - 1) + ']')
.beConstantValueOf(0.5);
})
.then(() => task.done());
});
audit.define('setTarget', (task, should) => {
let suspendFrame = 128;
createGraph({
suspendFrame: suspendFrame,
method: 'setTargetAtTime',
initialGain: 1,
arg0: 0.5,
moreArgs: 0.1
})
.then(function(resultBuffer) {
// Just verify that the cosine wave actually started at
// suspendFrame.
let result = resultBuffer.getChannelData(0);
should(
result.slice(0, suspendFrame),
'setTarget: Output[0-' + (suspendFrame - 1) + ']')
.beConstantValueOf(1);
// For the samples past the suspend time, we only care that first
// value is 1 and that the rest are not zero.
should(
result[suspendFrame],
'setTarget: Output[' + suspendFrame + ']')
.beEqualTo(1);
let positive = result.slice(suspendFrame + 1).every(x => x > 0);
should(
positive,
'Output[' + (suspendFrame + 1) + '-' + (renderFrames - 1) +
'] contains only positive values')
.beEqualTo(true);
})
.then(() => task.done());
});
audit.define('setValueCurve', (task, should) => {
let suspendFrame = 128;
createGraph({
suspendFrame: suspendFrame,
method: 'setValueCurveAtTime',
initialGain: 1,
arg0: Float32Array.from([2, 3]),
moreArgs: 0.1
})
.then(function(resultBuffer) {
// Just verify that the cosine wave actually started at
// suspendFrame.
let result = resultBuffer.getChannelData(0);
should(
result.slice(0, suspendFrame),
'setValueCurve: Output[0-' + (suspendFrame - 1) + ']')
.beConstantValueOf(1);
// The selected curve contains values greater than or equal to 2.
// Just verify that all values are greater than or equal to 2.
let biggerThan2 = result.slice(suspendFrame).every(x => x >= 2);
should(
biggerThan2,
'setValueCurve: Output[' + suspendFrame + '-' +
(renderFrames - 1) + ']')
.beEqualTo(true);
})
.then(() => task.done());
});
// Create the test graph consisting of a constant source followed by a
// gain node. The gain node automations will be tested. |options|
// specifies the parameters for the test including
//
// suspendFrame: time at which we schedule the automation call
// method: the name of automation method to be tested
// initialGain: the initial gain at time 0 for the gain node
// arg0: the first argument to be supplied to the automation method.
// moreArgs: An array of any additional arguments for the automation
// method.
function createGraph(options) {
let context = new OfflineAudioContext(1, renderFrames, sampleRate);
let cosineWave = new PeriodicWave(context, {real: [0, 1]});
let src = new OscillatorNode(
context, {periodicWave: cosineWave, frequency: 0});
// The gain node whose automations we're testing.
let gain = new GainNode(context, {gain: 0});
src.connect(gain).connect(context.destination);
gain.gain.setValueAtTime(options.initialGain, 0);
// Suspend rendering so that we can call the automation method at the
// right time. |startTime| is the time for the automation method. It
// must be some time before the suspend time.
let suspendFrame = options.suspendFrame;
let startTime = (suspendFrame / 2) / context.sampleRate;
context.suspend(suspendFrame / context.sampleRate)
.then(function() {
// Call the appropriate automation method with the desired
// automation value, time, and any other arguments needed.
gain.gain[options.method](
...[options.arg0, startTime, options.moreArgs]);
})
.then(context.resume.bind(context));
// Start the source and begin rendering, returning the promise from
// rendering.
src.start();
return context.startRendering();
}
audit.run();
</script>
</body>
</html>