blob: fbe6e42e3178f84d108bfd1c62518a4d13eb2dff [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: AudioBuffer
</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="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
should(() => {
new AudioBuffer();
}, 'new AudioBuffer()').throw(TypeError);
should(() => {
new AudioBuffer(1);
}, 'new AudioBuffer(1)').throw(TypeError);
should(() => {
new AudioBuffer(Date, 42);
}, 'new AudioBuffer(Date, 42)').throw(TypeError);
task.done();
});
audit.define('required options', (task, should) => {
let buffer;
// The length and sampleRate attributes are required; all others are
// optional.
should(() => {
new AudioBuffer({});
}, 'buffer = new AudioBuffer({})').throw(TypeError);
should(() => {
new AudioBuffer({length: 1});
}, 'buffer = new AudioBuffer({length: 1})').throw(TypeError);
should(() => {
new AudioBuffer({sampleRate: 48000});
}, 'buffer = new AudioBuffer({sampleRate: 48000})').throw(TypeError);
should(() => {
buffer = new AudioBuffer({numberOfChannels: 1});
}, 'buffer = new AudioBuffer({numberOfChannels: 1}').throw(TypeError);
// Length and sampleRate are required, but others are optional.
should(
() => {
buffer =
new AudioBuffer({length: 21, sampleRate: context.sampleRate});
},
'buffer0 = new AudioBuffer({length: 21, sampleRate: ' +
context.sampleRate + '}')
.notThrow();
// Verify the buffer has the correct values.
should(buffer.numberOfChannels, 'buffer0.numberOfChannels')
.beEqualTo(1);
should(buffer.length, 'buffer0.length').beEqualTo(21);
should(buffer.sampleRate, 'buffer0.sampleRate')
.beEqualTo(context.sampleRate);
should(
() => {
buffer = new AudioBuffer(
{numberOfChannels: 3, length: 1, sampleRate: 48000});
},
'buffer1 = new AudioBuffer(' +
'{numberOfChannels: 3, length: 1, sampleRate: 48000})')
.notThrow();
// Verify the buffer has the correct values.
should(buffer.numberOfChannels, 'buffer1.numberOfChannels')
.beEqualTo(3);
should(buffer.length, 'buffer1.length').beEqualTo(1);
should(buffer.sampleRate, 'buffer1.sampleRate').beEqualTo(48000);
task.done();
});
audit.define('invalid option values', (task, should) => {
let options = {numberOfChannels: 0, length: 1, sampleRate: 16000};
should(
() => {
let buffer = new AudioBuffer(options);
},
'new AudioBuffer(' + JSON.stringify(options) + ')')
.throw(DOMException, 'NotSupportedError');
options = {numberOfChannels: 99, length: 0, sampleRate: 16000};
should(
() => {
let buffer = new AudioBuffer(options);
},
'new AudioBuffer(' + JSON.stringify(options) + ')')
.throw(DOMException, 'NotSupportedError');
options = {numberOfChannels: 1, length: 0, sampleRate: 16000};
should(
() => {
let buffer = new AudioBuffer(options);
},
'new AudioBuffer(' + JSON.stringify(options) + ')')
.throw(DOMException, 'NotSupportedError');
options = {numberOfChannels: 1, length: 1, sampleRate: 100};
should(
() => {
let buffer = new AudioBuffer(options);
},
'new AudioBuffer(' + JSON.stringify(options) + ')')
.throw(DOMException, 'NotSupportedError');
task.done();
});
audit.define('default constructor', (task, should) => {
let buffer;
let options = {numberOfChannels: 5, length: 17, sampleRate: 16000};
should(
() => {
buffer = new AudioBuffer(options);
},
'buffer = new AudioBuffer(' + JSON.stringify(options) + ')')
.notThrow();
should(buffer.numberOfChannels, 'buffer.numberOfChannels')
.beEqualTo(options.numberOfChannels);
should(buffer.length, 'buffer.length').beEqualTo(options.length);
should(buffer.sampleRate, 'buffer.sampleRate').beEqualTo(16000);
task.done();
});
audit.define('valid constructor', (task, should) => {
let buffer;
let options = {numberOfChannels: 3, length: 42, sampleRate: 54321};
let message = 'new AudioBuffer(' + JSON.stringify(options) + ')';
should(() => {
buffer = new AudioBuffer(options);
}, message).notThrow();
should(buffer.numberOfChannels, 'buffer.numberOfChannels')
.beEqualTo(options.numberOfChannels);
should(buffer.length, 'buffer.length').beEqualTo(options.length);
should(buffer.sampleRate, 'buffer.sampleRate')
.beEqualTo(options.sampleRate);
// Verify that we actually got the right number of channels
for (let k = 0; k < options.numberOfChannels; ++k) {
let data;
let message = 'buffer.getChannelData(' + k + ')';
should(() => {
data = buffer.getChannelData(k);
}, message).notThrow();
should(data.length, message + ' length').beEqualTo(options.length);
}
should(
() => {
buffer.getChannelData(options.numberOfChannels);
},
'buffer.getChannelData(' + options.numberOfChannels + ')')
.throw(DOMException, 'IndexSizeError');
task.done();
});
audit.define('multiple contexts', (task, should) => {
// Test that an AudioBuffer can be used for different contexts.
let buffer =
new AudioBuffer({length: 128, sampleRate: context.sampleRate});
// Don't use getChannelData here because we want to be able to use
// |data| to compare the final results of playing out this buffer. (If
// we did, |data| gets detached when the sources play.)
let data = new Float32Array(buffer.length);
for (let k = 0; k < data.length; ++k)
data[k] = 1 + k;
buffer.copyToChannel(data, 0);
let c1 = new OfflineAudioContext(1, 128, context.sampleRate);
let c2 = new OfflineAudioContext(1, 128, context.sampleRate);
let s1 = new AudioBufferSourceNode(c1, {buffer: buffer});
let s2 = new AudioBufferSourceNode(c2, {buffer: buffer});
s1.connect(c1.destination);
s2.connect(c2.destination);
s1.start();
s2.start();
Promise
.all([
c1.startRendering().then(function(resultBuffer) {
return resultBuffer;
}),
c2.startRendering().then(function(resultBuffer) {
return resultBuffer;
}),
])
.then(resultBuffers => {
let c1ResultValue = should(resultBuffers[0].getChannelData(0), 'c1 result')
.beEqualToArray(data);
let c2ResultValue = should(resultBuffers[1].getChannelData(0), 'c2 result')
.beEqualToArray(data);
should(
c1ResultValue && c2ResultValue,
'AudioBuffer shared between two different contexts')
.message('correctly', 'incorrectly');
task.done();
});
});
audit.run();
</script>
</body>
</html>