ctor-audiobuffer.html (8222B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> 5 Test Constructor: AudioBuffer 6 </title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/webaudio/resources/audit-util.js"></script> 10 <script src="/webaudio/resources/audit.js"></script> 11 <script src="/webaudio/resources/audionodeoptions.js"></script> 12 </head> 13 <body> 14 <script id="layout-test-code"> 15 let context; 16 17 let audit = Audit.createTaskRunner(); 18 19 audit.define('initialize', (task, should) => { 20 context = initializeContext(should); 21 task.done(); 22 }); 23 24 audit.define('invalid constructor', (task, should) => { 25 should(() => { 26 new AudioBuffer(); 27 }, 'new AudioBuffer()').throw(TypeError); 28 should(() => { 29 new AudioBuffer(1); 30 }, 'new AudioBuffer(1)').throw(TypeError); 31 should(() => { 32 new AudioBuffer(Date, 42); 33 }, 'new AudioBuffer(Date, 42)').throw(TypeError); 34 35 task.done(); 36 }); 37 38 audit.define('required options', (task, should) => { 39 let buffer; 40 41 // The length and sampleRate attributes are required; all others are 42 // optional. 43 should(() => { 44 new AudioBuffer({}); 45 }, 'buffer = new AudioBuffer({})').throw(TypeError); 46 47 should(() => { 48 new AudioBuffer({length: 1}); 49 }, 'buffer = new AudioBuffer({length: 1})').throw(TypeError); 50 51 should(() => { 52 new AudioBuffer({sampleRate: 48000}); 53 }, 'buffer = new AudioBuffer({sampleRate: 48000})').throw(TypeError); 54 55 should(() => { 56 buffer = new AudioBuffer({numberOfChannels: 1}); 57 }, 'buffer = new AudioBuffer({numberOfChannels: 1}').throw(TypeError); 58 59 // Length and sampleRate are required, but others are optional. 60 should( 61 () => { 62 buffer = 63 new AudioBuffer({length: 21, sampleRate: context.sampleRate}); 64 }, 65 'buffer0 = new AudioBuffer({length: 21, sampleRate: ' + 66 context.sampleRate + '}') 67 .notThrow(); 68 // Verify the buffer has the correct values. 69 should(buffer.numberOfChannels, 'buffer0.numberOfChannels') 70 .beEqualTo(1); 71 should(buffer.length, 'buffer0.length').beEqualTo(21); 72 should(buffer.sampleRate, 'buffer0.sampleRate') 73 .beEqualTo(context.sampleRate); 74 75 should( 76 () => { 77 buffer = new AudioBuffer( 78 {numberOfChannels: 3, length: 1, sampleRate: 48000}); 79 }, 80 'buffer1 = new AudioBuffer(' + 81 '{numberOfChannels: 3, length: 1, sampleRate: 48000})') 82 .notThrow(); 83 // Verify the buffer has the correct values. 84 should(buffer.numberOfChannels, 'buffer1.numberOfChannels') 85 .beEqualTo(3); 86 should(buffer.length, 'buffer1.length').beEqualTo(1); 87 should(buffer.sampleRate, 'buffer1.sampleRate').beEqualTo(48000); 88 89 task.done(); 90 }); 91 92 audit.define('invalid option values', (task, should) => { 93 let options = {numberOfChannels: 0, length: 1, sampleRate: 16000}; 94 should( 95 () => { 96 let buffer = new AudioBuffer(options); 97 }, 98 'new AudioBuffer(' + JSON.stringify(options) + ')') 99 .throw(DOMException, 'NotSupportedError'); 100 101 options = {numberOfChannels: 99, length: 0, sampleRate: 16000}; 102 should( 103 () => { 104 let buffer = new AudioBuffer(options); 105 }, 106 'new AudioBuffer(' + JSON.stringify(options) + ')') 107 .throw(DOMException, 'NotSupportedError'); 108 109 options = {numberOfChannels: 1, length: 0, sampleRate: 16000}; 110 should( 111 () => { 112 let buffer = new AudioBuffer(options); 113 }, 114 'new AudioBuffer(' + JSON.stringify(options) + ')') 115 .throw(DOMException, 'NotSupportedError'); 116 117 options = {numberOfChannels: 1, length: 1, sampleRate: 100}; 118 should( 119 () => { 120 let buffer = new AudioBuffer(options); 121 }, 122 'new AudioBuffer(' + JSON.stringify(options) + ')') 123 .throw(DOMException, 'NotSupportedError'); 124 125 task.done(); 126 }); 127 128 audit.define('default constructor', (task, should) => { 129 let buffer; 130 131 let options = {numberOfChannels: 5, length: 17, sampleRate: 16000}; 132 should( 133 () => { 134 buffer = new AudioBuffer(options); 135 }, 136 'buffer = new AudioBuffer(' + JSON.stringify(options) + ')') 137 .notThrow(); 138 139 should(buffer.numberOfChannels, 'buffer.numberOfChannels') 140 .beEqualTo(options.numberOfChannels); 141 should(buffer.length, 'buffer.length').beEqualTo(options.length); 142 should(buffer.sampleRate, 'buffer.sampleRate').beEqualTo(16000); 143 144 task.done(); 145 }); 146 147 audit.define('valid constructor', (task, should) => { 148 let buffer; 149 150 let options = {numberOfChannels: 3, length: 42, sampleRate: 54321}; 151 152 let message = 'new AudioBuffer(' + JSON.stringify(options) + ')'; 153 should(() => { 154 buffer = new AudioBuffer(options); 155 }, message).notThrow(); 156 157 should(buffer.numberOfChannels, 'buffer.numberOfChannels') 158 .beEqualTo(options.numberOfChannels); 159 160 should(buffer.length, 'buffer.length').beEqualTo(options.length); 161 162 should(buffer.sampleRate, 'buffer.sampleRate') 163 .beEqualTo(options.sampleRate); 164 165 // Verify that we actually got the right number of channels 166 for (let k = 0; k < options.numberOfChannels; ++k) { 167 let data; 168 let message = 'buffer.getChannelData(' + k + ')'; 169 should(() => { 170 data = buffer.getChannelData(k); 171 }, message).notThrow(); 172 173 should(data.length, message + ' length').beEqualTo(options.length); 174 } 175 176 should( 177 () => { 178 buffer.getChannelData(options.numberOfChannels); 179 }, 180 'buffer.getChannelData(' + options.numberOfChannels + ')') 181 .throw(DOMException, 'IndexSizeError'); 182 183 task.done(); 184 }); 185 186 audit.define('multiple contexts', (task, should) => { 187 // Test that an AudioBuffer can be used for different contexts. 188 let buffer = 189 new AudioBuffer({length: 128, sampleRate: context.sampleRate}); 190 191 // Don't use getChannelData here because we want to be able to use 192 // |data| to compare the final results of playing out this buffer. (If 193 // we did, |data| gets detached when the sources play.) 194 let data = new Float32Array(buffer.length); 195 for (let k = 0; k < data.length; ++k) 196 data[k] = 1 + k; 197 buffer.copyToChannel(data, 0); 198 199 let c1 = new OfflineAudioContext(1, 128, context.sampleRate); 200 let c2 = new OfflineAudioContext(1, 128, context.sampleRate); 201 202 let s1 = new AudioBufferSourceNode(c1, {buffer: buffer}); 203 let s2 = new AudioBufferSourceNode(c2, {buffer: buffer}); 204 205 s1.connect(c1.destination); 206 s2.connect(c2.destination); 207 208 s1.start(); 209 s2.start(); 210 211 Promise 212 .all([ 213 c1.startRendering().then(function(resultBuffer) { 214 return resultBuffer; 215 }), 216 c2.startRendering().then(function(resultBuffer) { 217 return resultBuffer; 218 }), 219 ]) 220 .then(resultBuffers => { 221 let c1ResultValue = should(resultBuffers[0].getChannelData(0), 'c1 result') 222 .beEqualToArray(data); 223 let c2ResultValue = should(resultBuffers[1].getChannelData(0), 'c2 result') 224 .beEqualToArray(data); 225 should( 226 c1ResultValue && c2ResultValue, 227 'AudioBuffer shared between two different contexts') 228 .message('correctly', 'incorrectly'); 229 task.done(); 230 }); 231 }); 232 233 audit.run(); 234 </script> 235 </body> 236 </html>