mirror of
https://github.com/servo/servo.git
synced 2025-10-04 02:29:12 +01:00
143 lines
5.3 KiB
HTML
143 lines
5.3 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>
|
|
audioparam-method-chaining.html
|
|
</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/webaudio/resources/audit-util.js"></script>
|
|
<script src="/webaudio/resources/audit.js"></script>
|
|
<script src="/webaudio/resources/audioparam-testing.js"></script>
|
|
</head>
|
|
<body>
|
|
<script id="layout-test-code">
|
|
let sampleRate = 8000;
|
|
|
|
// Create a dummy array for setValueCurveAtTime method.
|
|
let curveArray = new Float32Array([5.0, 6.0]);
|
|
|
|
// AudioNode dictionary with associated dummy arguments.
|
|
let methodDictionary = [
|
|
{name: 'setValueAtTime', args: [1.0, 0.0]},
|
|
{name: 'linearRampToValueAtTime', args: [2.0, 1.0]},
|
|
{name: 'exponentialRampToValueAtTime', args: [3.0, 2.0]},
|
|
{name: 'setTargetAtTime', args: [4.0, 2.0, 0.5]},
|
|
{name: 'setValueCurveAtTime', args: [curveArray, 5.0, 1.0]},
|
|
{name: 'cancelScheduledValues', args: [6.0]}
|
|
];
|
|
|
|
let audit = Audit.createTaskRunner();
|
|
|
|
// Task: testing entries from the dictionary.
|
|
audit.define('from-dictionary', (task, should) => {
|
|
let context = new AudioContext();
|
|
|
|
methodDictionary.forEach(function(method) {
|
|
let sourceParam = context.createGain().gain;
|
|
should(
|
|
sourceParam === sourceParam[method.name](...method.args),
|
|
'The return value of ' + sourceParam.constructor.name + '.' +
|
|
method.name + '()' +
|
|
' matches the source AudioParam')
|
|
.beEqualTo(true);
|
|
|
|
});
|
|
|
|
task.done();
|
|
});
|
|
|
|
// Task: test method chaining with invalid operation.
|
|
audit.define('invalid-operation', (task, should) => {
|
|
let context = new OfflineAudioContext(1, sampleRate, sampleRate);
|
|
let osc = context.createOscillator();
|
|
let amp1 = context.createGain();
|
|
let amp2 = context.createGain();
|
|
|
|
osc.connect(amp1);
|
|
osc.connect(amp2);
|
|
amp1.connect(context.destination);
|
|
amp2.connect(context.destination);
|
|
|
|
// The first operation fails with an exception, thus the second one
|
|
// should not have effect on the parameter value. Instead, it should
|
|
// maintain the default value of 1.0.
|
|
should(
|
|
function() {
|
|
amp1.gain.setValueAtTime(0.25, -1.0)
|
|
.linearRampToValueAtTime(2.0, 1.0);
|
|
},
|
|
'Calling setValueAtTime() with a negative end time')
|
|
.throw(RangeError);
|
|
|
|
// The first operation succeeds but the second fails due to zero target
|
|
// value for the exponential ramp. Thus only the first should have
|
|
// effect on the parameter value, setting the value to 0.5.
|
|
should(
|
|
function() {
|
|
amp2.gain.setValueAtTime(0.5, 0.0).exponentialRampToValueAtTime(
|
|
0.0, 1.0);
|
|
},
|
|
'Calling exponentialRampToValueAtTime() with a zero target value')
|
|
.throw(RangeError);
|
|
|
|
osc.start();
|
|
osc.stop(1.0);
|
|
|
|
context.startRendering()
|
|
.then(function(buffer) {
|
|
should(amp1.gain.value, 'The gain value of the first gain node')
|
|
.beEqualTo(1.0);
|
|
should(amp2.gain.value, 'The gain value of the second gain node')
|
|
.beEqualTo(0.5);
|
|
})
|
|
.then(() => task.done());
|
|
});
|
|
|
|
// Task: verify if the method chaining actually works. Create an arbitrary
|
|
// envelope and compare the result with the expected one created by JS
|
|
// code.
|
|
audit.define('verification', (task, should) => {
|
|
let context = new OfflineAudioContext(1, sampleRate * 4, sampleRate);
|
|
let constantBuffer = createConstantBuffer(context, 1, 1.0);
|
|
|
|
let source = context.createBufferSource();
|
|
source.buffer = constantBuffer;
|
|
source.loop = true;
|
|
|
|
let envelope = context.createGain();
|
|
|
|
source.connect(envelope);
|
|
envelope.connect(context.destination);
|
|
|
|
envelope.gain.setValueAtTime(0.0, 0.0)
|
|
.linearRampToValueAtTime(1.0, 1.0)
|
|
.exponentialRampToValueAtTime(0.5, 2.0)
|
|
.setTargetAtTime(0.001, 2.0, 0.5);
|
|
|
|
source.start();
|
|
|
|
context.startRendering()
|
|
.then(function(buffer) {
|
|
let expectedEnvelope =
|
|
createLinearRampArray(0.0, 1.0, 0.0, 1.0, sampleRate);
|
|
expectedEnvelope.push(...createExponentialRampArray(
|
|
1.0, 2.0, 1.0, 0.5, sampleRate));
|
|
expectedEnvelope.push(...createExponentialApproachArray(
|
|
2.0, 4.0, 0.5, 0.001, sampleRate, 0.5));
|
|
|
|
// There are slight differences between JS implementation of
|
|
// AudioParam envelope and the internal implementation. (i.e.
|
|
// double/float and rounding up) The error threshold is adjusted
|
|
// empirically through the local testing.
|
|
should(buffer.getChannelData(0), 'The rendered envelope')
|
|
.beCloseToArray(
|
|
expectedEnvelope, {absoluteThreshold: 4.0532e-6});
|
|
})
|
|
.then(() => task.done());
|
|
});
|
|
|
|
audit.run();
|
|
</script>
|
|
</body>
|
|
</html>
|