blob: 7fd20e67a7079ab3c02d490e458cb762006e0ca0 [file] [log] [blame]
<!doctype html>
<html>
<head>
<title>Test ScriptProcessorNode</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>
// Arbitrary sample rate
const sampleRate = 48000;
let audit = Audit.createTaskRunner();
audit.define(
{
label: 'test',
description: 'ScriptProcessor with stopped input source'
},
(task, should) => {
// Two channels for testing. Channel 0 is the output of the
// scriptProcessor. Channel 1 is the oscillator so we can compare
// the outputs.
let context = new OfflineAudioContext({
numberOfChannels: 2,
length: sampleRate,
sampleRate: sampleRate
});
let merger = new ChannelMergerNode(
context, {numberOfChannels: context.destination.channelCount});
merger.connect(context.destination);
let src = new OscillatorNode(context);
// Arbitrary buffer size for the ScriptProcessorNode. Don't use 0;
// we need to know the actual size to know the latency of the node
// (easily).
const spnSize = 512;
let spn = context.createScriptProcessor(spnSize, 1, 1);
// Arrange for the ScriptProcessor to add |offset| to the input.
const offset = 1;
spn.onaudioprocess = (event) => {
let input = event.inputBuffer.getChannelData(0);
let output = event.outputBuffer.getChannelData(0);
for (let k = 0; k < output.length; ++k) {
output[k] = input[k] + offset;
}
};
src.connect(spn).connect(merger, 0, 0);
src.connect(merger, 0, 1);
// Start and stop the source. The stop time is fairly arbitrary,
// but use a render quantum boundary for simplicity.
const stopFrame = RENDER_QUANTUM_FRAMES;
src.start(0);
src.stop(stopFrame / context.sampleRate);
context.startRendering()
.then(buffer => {
let ch0 = buffer.getChannelData(0);
let ch1 = buffer.getChannelData(1);
let shifted = ch1.slice(0, stopFrame).map(x => x + offset);
// SPN has a basic latency of 2*|spnSize| fraems, so the
// beginning is silent.
should(
ch0.slice(0, 2 * spnSize - 1),
`ScriptProcessor output[0:${2 * spnSize - 1}]`)
.beConstantValueOf(0);
// For the middle section (after adding latency), the output
// should be the source shifted by |offset|.
should(
ch0.slice(2 * spnSize, 2 * spnSize + stopFrame),
`ScriptProcessor output[${2 * spnSize}:${
2 * spnSize + stopFrame - 1}]`)
.beCloseToArray(shifted, {absoluteThreshold: 0});
// Output should be constant after the source has stopped.
// Include the latency introduced by the node.
should(
ch0.slice(2 * spnSize + stopFrame),
`ScriptProcessor output[${2 * spnSize + stopFrame}:]`)
.beConstantValueOf(offset);
})
.then(() => task.done());
});
audit.run();
</script>
</body>
</html>