blob: c8715e5f4f4bfce6077debf4c11d5eeb9406f121 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>Test AudioBufferSourceNode looping without explicit duration</title>
<script src="../resources/js-test.js"></script>
<script src="resources/compatibility.js"></script>
<script src="resources/audio-testing.js"></script>
</head>
<body>
<script>
description("Test AudioBufferSourceNode looping without explicit duration");
window.jsTestIsAsync = true;
// Reasonably low sample rate for the optimum test speed.
var sampleRate = 4096;
var audit = Audit.createTaskRunner();
// Task: create a short linear ramp and enable looping. The test will
// verify that the ramp was looped the appropriate number of times.
audit.defineTask('loop-count', function (done) {
// How many loops of the source we want to render. Any whole number
// greater than 1 will work.
var loopCount = 4;
var sourceFrames = 8;
var renderFrames = sourceFrames * loopCount;
var context = new OfflineAudioContext(1, renderFrames, sampleRate);
var source = context.createBufferSource();
var linearRampBuffer = createLinearRampBuffer(context, sourceFrames);
source.buffer = linearRampBuffer;
source.connect(context.destination);
// Enable looping and start the source with an offset, but without a
// duration. In this case, the source should loop "forever".
// See crbug.com/457009.
source.loop = true;
source.start(0, 0);
context.startRendering().then(function (renderedBuffer) {
var badIndex = -1;
var success = true;
var actual = renderedBuffer.getChannelData(0);
var linearRamp = linearRampBuffer.getChannelData(0);
// Manually create a |loopCount| copies of linear ramps.
var expected = new Float32Array(linearRamp.length * loopCount);
for (var i = 0; i < loopCount; i++)
expected.set(linearRamp, linearRamp.length * i);
// The actual output should match the created loop.
Should('The output of actual and expected loops', actual)
.beEqualToArray(expected);
}).then(done);
});
// Task: Test that looping an AudioBufferSource works correctly if the
// source is started and the buffer is assigned later, but before the source
// would start.
audit.defineTask('delayed-start', function (done) {
var renderDuration = 2;
var context = new OfflineAudioContext(2, sampleRate * renderDuration, sampleRate);
var linearRampBuffer = createLinearRampBuffer(context, 128);
var normal = context.createBufferSource();
var delayed = context.createBufferSource();
var merger = context.createChannelMerger(2);
// Connect the normally started source to the left channel, and the
// delayed to the right channel.
normal.connect(merger, 0, 0);
delayed.connect(merger, 0, 1);
merger.connect(context.destination);
normal.buffer = linearRampBuffer;
normal.loop = true;
delayed.loop = true;
normal.start(1, 0);
delayed.start(1, 0);
// Assign the buffer to the delayed source node at 0.5 second.
context.suspend(0.5).then(function () {
delayed.buffer = linearRampBuffer;
context.resume();
});
context.startRendering().then(function (buffer) {
// The left and right channel must match regardless of the timing
// of buffer assignment.
Should('The content of the left and right channel',
buffer.getChannelData(0)).beEqualToArray(buffer.getChannelData(1));
}).then(done);
});
audit.defineTask('finish', function (done) {
finishJSTest();
done();
});
audit.runTasks(
'loop-count',
'delayed-start',
'finish'
);
successfullyParsed = true;
</script>
</body>
</html>