Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 25 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /webaudio/the-audio-api/the-audioparam-interface/k-rate-constant-source.html - WPT Dashboard Interop Dashboard
<!doctype html>
<html>
<head>
<title>Test k-rate AudioParam of ConstantSourceNode</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="automation-rate-testing.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
audit.define('ConstantSource k-rate offset', (task, should) => {
// Arbitrary sample rate and duration.
let sampleRate = 8000;
// Only new a few render quanta to verify things are working.
let testDuration = 4 * 128 / sampleRate;
let context = new OfflineAudioContext({
numberOfChannels: 3,
sampleRate: sampleRate,
length: testDuration * sampleRate
});
doTest(context, should, {
sourceNodeName: 'none',
verifyPieceWiseConstant: true,
nodeName: 'ConstantSourceNode',
prefix: 'k-rate offset',
rateSettings: [{name: 'offset', value: 'k-rate'}],
automations: [{
name: 'offset',
methods: [
{name: 'setValueAtTime', options: [0, 0]}, {
name: 'linearRampToValueAtTime',
options: [10, testDuration]
}
]
}]
}).then(() => task.done());
});
// Parameters for the For the following tests.
// Must be power of two to eliminate round-off
const sampleRate8k = 8192;
// Arbitrary duration that doesn't need to be too long to verify k-rate
// automations. Probably should be at least a few render quanta.
const testDuration = 8 * RENDER_QUANTUM_FRAMES / sampleRate8k;
// Basic test that k-rate ConstantSourceNode.offset is k-rate. This is
// the basis for all of the following tests, so make sure it's right.
audit.define(
{
label: 'ConstantSourceNode.offset k-rate automation',
description:
'Explicitly test ConstantSourceNode.offset k-rate automation is k-rate'
},
(task, should) => {
let context = new OfflineAudioContext({
numberOfChannels: 2,
sampleRate: sampleRate8k,
length: testDuration * sampleRate8k
});
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
merger.connect(context.destination);
// k-rate ConstantSource.offset using a linear ramp starting at 0
// and incrementing by 1 for each frame.
let src = new ConstantSourceNode(context, {offset: 0});
src.offset.automationRate = 'k-rate';
src.offset.setValueAtTime(0, 0);
src.offset.linearRampToValueAtTime(context.length, testDuration);
src.connect(merger, 0, 0);
src.start();
// a-rate ConstantSource using the same ramp as above.
let refSrc = new ConstantSourceNode(context, {offset: 0});
refSrc.offset.setValueAtTime(0, 0);
refSrc.offset.linearRampToValueAtTime(context.length, testDuration);
refSrc.connect(merger, 0, 1);
refSrc.start();
context.startRendering()
.then(buffer => {
let actual = buffer.getChannelData(0);
let expected = buffer.getChannelData(1);
for (let k = 0; k < actual.length;
k += RENDER_QUANTUM_FRAMES) {
// Verify that the k-rate output is constant over the render
// and that it matches the value of the a-rate value at the
// beginning of the render.
should(
actual.slice(k, k + RENDER_QUANTUM_FRAMES),
`k-rate ConstantSource.offset: output[${k}:${
k + RENDER_QUANTUM_FRAMES}]`)
.beConstantValueOf(expected[k]);
}
})
.then(() => task.done());
});
// This test verifies that a k-rate input to the ConstantSourceNode.offset
// works just as if we set the AudioParam to be k-rate. This is the basis
// of the following tests, so make sure it works.
audit.define(
{
label: 'ConstantSource.offset',
description: 'Verify k-rate automation matches k-rate input'
},
(task, should) => {
let context = new OfflineAudioContext({
numberOfChannels: 2,
sampleRate: sampleRate8k,
length: testDuration * sampleRate8k
});
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
merger.connect(context.destination);
let tstSrc = new ConstantSourceNode(context);
let tstMod = new ConstantSourceNode(context);
tstSrc.offset.automationRate = 'k-rate';
tstMod.offset.linearRampToValueAtTime(context.length, testDuration);
tstMod.connect(tstSrc.offset)
tstSrc.connect(merger, 0, 0);
let refSrc = new ConstantSourceNode(context);
let refMod = new ConstantSourceNode(context);
refMod.offset.linearRampToValueAtTime(context.length, testDuration);
refMod.offset.automationRate = 'k-rate';
refMod.connect(refSrc.offset);
refSrc.connect(merger, 0, 1);
tstSrc.start();
tstMod.start();
refSrc.start();
refMod.start();
context.startRendering()
.then(buffer => {
let actual = buffer.getChannelData(0);
let expected = buffer.getChannelData(1);
for (let k = 0; k < context.length;
k += RENDER_QUANTUM_FRAMES) {
should(
actual.slice(k, k + RENDER_QUANTUM_FRAMES),
`ConstantSource.offset k-rate input: output[${k}:${
k + RENDER_QUANTUM_FRAMES}]`)
.beConstantValueOf(expected[k]);
}
})
.then(() => task.done());
});
audit.run();
</script>
</body>
</html>