<!DOCTYPE html>
<html>
<head>
<title>
audiobuffersource-playbackrate-modulated-impulse.html
</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script>
<script src="../resources/audit.js"></script>
</head>
<body>
<script id="layout-test-code">
let sampleRate = 44100;
// To get an observable change on playbackRate modulation, the minimum
// rendering length should greater than the rendering quantum.
let renderLength = 256;
let half = renderLength / 2;
// With the playbackRate of 1, the duration of impulse buffer should be 4
// samples (which means the interval between impulses is 4). Doubling
// playback speed decrease the interval to 2 samples.
let impulseLength = 4;
let context = new OfflineAudioContext(1, renderLength, sampleRate);
let impulseBuffer, dcOffsetBuffer;
let audit = Audit.createTaskRunner();
// Task: build an impulse and DC-offset buffers for testing.
audit.define('build-buffers', (task, should) => {
should(() => {
// 4-sample impulse sample.
impulseBuffer = createImpulseBuffer(context, impulseLength);
// Create a DC offset buffer with 2 values [0, 1] for modulating
// playbackRate. The first half of buffer is 0 and the rest is 1.
dcOffsetBuffer = context.createBuffer(1, renderLength, sampleRate);
let dcOffsetArray = dcOffsetBuffer.getChannelData(0);
for (i = 0; i < dcOffsetArray.length; i++) {
// Note that these values will be added to the playbackRate
// AudioParam value. For example, 0 DC offset value will result
// playbackRate of 1 because the default playbackRate value is 1.
dcOffsetArray[i] = i < half ? 0 : 1;
}
}, 'Build buffers').notThrow();
task.done();
});
// Task: Render the actual buffer and compare with the reference.
audit.define('synthesize-verify', (task, should) => {
let impulse = context.createBufferSource();
let dcOffset = context.createBufferSource();
impulse.buffer = impulseBuffer;
dcOffset.buffer = dcOffsetBuffer;
impulse.loop = true;
impulse.connect(context.destination);
dcOffset.connect(impulse.playbackRate);
impulse.start();
dcOffset.start();
context.startRendering()
.then(function(renderedBuffer) {
let data = renderedBuffer.getChannelData(0);
let passed = true, i = 0;
let nextImpulseIndex = 0;
while (i < renderLength) {
if (i === nextImpulseIndex && data[i] === 1) {
// From 0 to 127th element, the interval between impulses is
// 4. On the other hand, the interval is 2 between 128th and
// 255th element.
nextImpulseIndex +=
(i < half) ? impulseLength : impulseLength / 2;
} else if (data[i] !== 0) {
// If a value is neither 0 or 1, break the loop and fail the
// test.
passed = false;
break;
}
i++;
}
should(passed, 'Doubling playbackRate')
.message(
'decreased the interval between impulses to half',
'produced the incorrect result' +
'at the index ' + i)
})
.then(() => task.done());
});
audit.run();
successfullyParsed = true;
</script>
</body>
</html>