blob: fcf66f2e3ef79438f412848ee64b9e73ab06554a [file] [log] [blame]
<!doctype html>
<html>
<head>
<title>k-rate AudioParams with inputs for DelayNode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit.js"></script>
<script src="/webaudio/resources/audit-util.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
// Power-of-two to eliminate round-off in computing time and frames, but
// is otherwise arbitrary.
const sampleRate = 8192;
// Arbitrary duration except it must be greater than or equal to 1.
const testDuration = 1.5;
audit.define(
{label: 'delayTime', description: `DelayNode delayTime k-rate input`},
async (task, should) => {
// Two channels: 0 = test result, 1 = expected result.
let context = new OfflineAudioContext({
numberOfChannels: 2,
sampleRate: sampleRate,
length: testDuration * sampleRate
});
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
merger.connect(context.destination);
// Test the DelayNode by having a reference node (refNode) that uses
// k-rate automations of delayTime. The test node (testNode) sets
// delayTime to k-rate with a connected input that has the same
// automation vlaues as the reference node. The test passes if the
// output from each node is identical to each other.
// Just some non-constant source.
let src = new OscillatorNode(context);
// The end value and time for the linear ramp. These values are
// chosen so that the delay advances faster than real time.
let endValue = 1.125;
let endTime = 1;
let refNode;
should(
() => refNode = new DelayNode(context),
`refNode = new DelayNode(context)`)
.notThrow();
should(
() => refNode.delayTime.automationRate = 'k-rate',
`refNode.delayTime.automationRate = 'k-rate'`)
.notThrow();
should(
() => refNode.delayTime.setValueAtTime(0, 0),
`refNode.delayTime.setValueAtTime(0, 0)`)
.notThrow();
should(
() => refNode.delayTime.linearRampToValueAtTime(
endValue, endTime),
`refNode.delayTime.linearRampToValueAtTime(${endValue}, ${
endTime})`)
.notThrow();
let testNode;
should(
() => testNode = new DelayNode(context),
`testNode = new DelayNode(context)`)
.notThrow();
should(
() => testNode.delayTime.automationRate = 'k-rate',
`testNode.delayTime.automationRate = 'k-rate'`)
.notThrow();
let testMod;
should(
() => testMod = new ConstantSourceNode(context),
`testMod = new ConstantSourceNode(context)`)
.notThrow();
should(
() => testMod.offset.setValueAtTime(0, 0),
`testMod.offset.setValueAtTime(0, 0)`)
.notThrow();
should(
() => testMod.offset.linearRampToValueAtTime(endValue, endTime),
`testMod.offset.linearRampToValueAtTime(${endValue}, ${
endTime})`)
.notThrow();
should(
() => testMod.connect(testNode.delayTime),
`testMod.connect(testNode.delayTime)`)
.notThrow();
// Connect up everything and go!
src.connect(testNode).connect(merger, 0, 0);
src.connect(refNode).connect(merger, 0, 1);
src.start();
testMod.start();
const buffer = await context.startRendering();
let expected = buffer.getChannelData(0);
let actual = buffer.getChannelData(1);
// Quick sanity check that output isn't zero. This means we messed
// up the connections or automations or the buffer source.
should(expected, `Expected k-rate delayTime AudioParam with input`)
.notBeConstantValueOf(0);
should(actual, `Actual k-rate delayTime AudioParam with input`)
.notBeConstantValueOf(0);
// Quick sanity check. The amount of delay after one render is
// endValue * 128 / sampleRate. But after 1 render, time has
// advanced 128/sampleRate. Hence, the delay exceeds the time by
// (endValue - 1)*128/sampleRate sec or (endValue - 1)*128 frames.
// This means the output must be EXACTLY zero for this many frames
// in the second render.
let zeroFrames = (endValue - 1) * RENDER_QUANTUM_FRAMES;
should(
actual.slice(
RENDER_QUANTUM_FRAMES, RENDER_QUANTUM_FRAMES + zeroFrames),
`output[${RENDER_QUANTUM_FRAMES}, ${
RENDER_QUANTUM_FRAMES + zeroFrames - 1}]`)
.beConstantValueOf(0);
should(
actual.slice(
RENDER_QUANTUM_FRAMES + zeroFrames,
2 * RENDER_QUANTUM_FRAMES),
`output[${RENDER_QUANTUM_FRAMES + zeroFrames}, ${
2 * RENDER_QUANTUM_FRAMES - 1}]`)
.notBeConstantValueOf(0);
// The expected and actual results must be EXACTLY the same.
should(actual, `k-rate delayTime AudioParam with input`)
.beCloseToArray(expected, {absoluteThreshold: 0});
});
audit.run();
</script>
</body>
</html>