| <!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> |