Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 41 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /webaudio/the-audio-api/the-audioparam-interface/automation-rate.html - WPT Dashboard Interop Dashboard
<!doctype html>
<html>
<head>
<title>AudioParam.automationRate tests</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>
</head>
<body>
<script>
// For each node that has an AudioParam, verify that the default
// |automationRate| has the expected value and that we can change it or
// throw an error if it can't be changed.
// Any valid sample rate is fine; we don't actually render anything in the
// tests.
let sampleRate = 8000;
let audit = Audit.createTaskRunner();
// Array of tests. Each test is a dictonary consisting of the name of the
// node and an array specifying the AudioParam's of the node. This array
// in turn gives the name of the AudioParam, the default value for the
// |automationRate|, and whether it is fixed (isFixed).
const tests = [
{
nodeName: 'AudioBufferSourceNode',
audioParams: [
{name: 'detune', defaultRate: 'k-rate', isFixed: true},
{name: 'playbackRate', defaultRate: 'k-rate', isFixed: true}
]
},
{
nodeName: 'BiquadFilterNode',
audioParams: [
{name: 'frequency', defaultRate: 'a-rate', isFixed: false},
{name: 'detune', defaultRate: 'a-rate', isFixed: false},
{name: 'Q', defaultRate: 'a-rate', isFixed: false},
{name: 'gain', defaultRate: 'a-rate', isFixed: false},
]
},
{
nodeName: 'ConstantSourceNode',
audioParams: [{name: 'offset', defaultRate: 'a-rate', isFixed: false}]
},
{
nodeName: 'DelayNode',
audioParams:
[{name: 'delayTime', defaultRate: 'a-rate', isFixed: false}]
},
{
nodeName: 'DynamicsCompressorNode',
audioParams: [
{name: 'threshold', defaultRate: 'k-rate', isFixed: true},
{name: 'knee', defaultRate: 'k-rate', isFixed: true},
{name: 'ratio', defaultRate: 'k-rate', isFixed: true},
{name: 'attack', defaultRate: 'k-rate', isFixed: true},
{name: 'release', defaultRate: 'k-rate', isFixed: true}
]
},
{
nodeName: 'GainNode',
audioParams: [{name: 'gain', defaultRate: 'a-rate', isFixed: false}]
},
{
nodeName: 'OscillatorNode',
audioParams: [
{name: 'frequency', defaultRate: 'a-rate', isFixed: false},
{name: 'detune', defaultRate: 'a-rate', isFixed: false}
]
},
{
nodeName: 'PannerNode',
audioParams: [
{name: 'positionX', defaultRate: 'a-rate', isFixed: false},
{name: 'positionY', defaultRate: 'a-rate', isFixed: false},
{name: 'positionZ', defaultRate: 'a-rate', isFixed: false},
{name: 'orientationX', defaultRate: 'a-rate', isFixed: false},
{name: 'orientationY', defaultRate: 'a-rate', isFixed: false},
{name: 'orientationZ', defaultRate: 'a-rate', isFixed: false},
]
},
{
nodeName: 'StereoPannerNode',
audioParams: [{name: 'pan', defaultRate: 'a-rate', isFixed: false}]
},
];
tests.forEach(test => {
// Define a separate test for each test entry.
audit.define(test.nodeName, (task, should) => {
let context = new OfflineAudioContext(
{length: sampleRate, sampleRate: sampleRate});
// Construct the node and test each AudioParam of the node.
let node = new window[test.nodeName](context);
test.audioParams.forEach(param => {
testAudioParam(
should, {nodeName: test.nodeName, node: node, param: param});
});
task.done();
});
});
// AudioListener needs it's own special test since it's not a node.
audit.define('AudioListener', (task, should) => {
let context = new OfflineAudioContext(
{length: sampleRate, sampleRate: sampleRate});
[{name: 'positionX', defaultRate: 'a-rate', isFixed: false},
{name: 'positionY', defaultRate: 'a-rate', isFixed: false},
{name: 'positionZ', defaultRate: 'a-rate', isFixed: false},
{name: 'forwardX', defaultRate: 'a-rate', isFixed: false},
{name: 'forwardY', defaultRate: 'a-rate', isFixed: false},
{name: 'forwardZ', defaultRate: 'a-rate', isFixed: false},
{name: 'upX', defaultRate: 'a-rate', isFixed: false},
{name: 'upY', defaultRate: 'a-rate', isFixed: false},
{name: 'upZ', defaultRate: 'a-rate', isFixed: false},
].forEach(param => {
testAudioParam(should, {
nodeName: 'AudioListener',
node: context.listener,
param: param
});
});
task.done();
});
audit.run();
function testAudioParam(should, options) {
let param = options.param;
let audioParam = options.node[param.name];
let defaultRate = param.defaultRate;
// Verify that the default value is correct.
should(
audioParam.automationRate,
`Default ${options.nodeName}.${param.name}.automationRate`)
.beEqualTo(defaultRate);
// Try setting the rate to a different rate. If the |automationRate|
// is fixed, expect an error. Otherwise, expect no error and expect
// the value is changed to the new value.
let newRate = defaultRate === 'a-rate' ? 'k-rate' : 'a-rate';
let setMessage = `Set ${
options.nodeName
}.${param.name}.automationRate to "${newRate}"`
if (param.isFixed) {
should(() => audioParam.automationRate = newRate, setMessage)
.throw(DOMException, 'InvalidStateError');
}
else {
should(() => audioParam.automationRate = newRate, setMessage)
.notThrow();
should(
audioParam.automationRate,
`${options.nodeName}.${param.name}.automationRate`)
.beEqualTo(newRate);
}
}
</script>
</body>
</html>