| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 | |
| 3 <html> | |
| 4 <head> | |
| 5 <script src="../resources/js-test.js"></script> | |
| 6 <script src="resources/compatibility.js"></script> | |
| 7 <script src="resources/audit-util.js"></script> | |
| 8 <script src="resources/audio-testing.js"></script> | |
| 9 <script src="resources/audiobuffersource-testing.js"></script> | |
| 10 </head> | |
| 11 | |
| 12 <body> | |
| 13 <script> | |
| 14 description("Tests AudioBufferSourceNode looping with a variety of loop points."
); | |
| 15 | |
| 16 // The following test cases assume an AudioBuffer of length 8 whose PCM data is
a linear ramp, 0, 1, 2, 3,... | |
| 17 // |description| is optional and will be computed from the other parameters. |of
fsetFrame| is | |
| 18 // optional and defaults to 0. | |
| 19 | |
| 20 var tests = [ | |
| 21 | |
| 22 { description: "loop whole buffer by default with loopStart == loopEnd == 0", | |
| 23 loopStartFrame: 0, | |
| 24 loopEndFrame: 0, | |
| 25 renderFrames: 16, | |
| 26 playbackRate: 1, | |
| 27 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 28 | |
| 29 { description: "loop whole buffer explicitly", | |
| 30 loopStartFrame: 0, | |
| 31 loopEndFrame: 8, | |
| 32 renderFrames: 16, | |
| 33 playbackRate: 1, | |
| 34 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 35 | |
| 36 { description: "loop from middle to end of buffer", | |
| 37 loopStartFrame: 4, | |
| 38 loopEndFrame: 8, | |
| 39 renderFrames: 16, | |
| 40 playbackRate: 1, | |
| 41 expected: [0,1,2,3,4,5,6,7,4,5,6,7,4,5,6,7] }, | |
| 42 | |
| 43 { description: "loop from start to middle of buffer", | |
| 44 loopStartFrame: 0, | |
| 45 loopEndFrame: 4, | |
| 46 renderFrames: 16, | |
| 47 playbackRate: 1, | |
| 48 expected: [0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3] }, | |
| 49 | |
| 50 { loopStartFrame: 4, | |
| 51 loopEndFrame: 6, | |
| 52 renderFrames: 16, | |
| 53 playbackRate: 1, | |
| 54 expected: [0,1,2,3,4,5,4,5,4,5,4,5,4,5,4,5] }, | |
| 55 | |
| 56 { loopStartFrame: 3, | |
| 57 loopEndFrame: 7, | |
| 58 renderFrames: 16, | |
| 59 playbackRate: 1, | |
| 60 expected: [0,1,2,3,4,5,6,3,4,5,6,3,4,5,6,3] }, | |
| 61 | |
| 62 { loopStartFrame: 4, | |
| 63 loopEndFrame: 6, | |
| 64 renderFrames: 16, | |
| 65 playbackRate: 0.5, | |
| 66 expected: [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 4, 4.5, 5, 5.5] }, | |
| 67 | |
| 68 { loopStartFrame: 4, | |
| 69 loopEndFrame: 6, | |
| 70 renderFrames: 16, | |
| 71 playbackRate: 1.5, | |
| 72 expected: [0, 1.5, 3, 4.5, 4, 5.5, 5, 4.5, 4, 5.5, 5, 4.5, 4, 5.5, 5, 4.5] }, | |
| 73 | |
| 74 // Offset past loop end, so playback starts at loop start | |
| 75 { loopStartFrame: 2, | |
| 76 loopEndFrame: 5, | |
| 77 renderFrames: 16, | |
| 78 playbackRate: 1, | |
| 79 offsetFrame: 6, | |
| 80 expected: [2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2] }, | |
| 81 | |
| 82 // Offset before loop start, so start at offset and continue | |
| 83 { loopStartFrame: 3, | |
| 84 loopEndFrame: 6, | |
| 85 renderFrames: 16, | |
| 86 playbackRate: 1, | |
| 87 offsetFrame: 1, | |
| 88 expected: [1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4] }, | |
| 89 | |
| 90 // Offset between loop start and loop end, so start at offset and continue | |
| 91 { loopStartFrame: 3, | |
| 92 loopEndFrame: 6, | |
| 93 renderFrames: 16, | |
| 94 playbackRate: 1, | |
| 95 offsetFrame: 4, | |
| 96 expected: [4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4] }, | |
| 97 | |
| 98 { description: "illegal playbackRate of 47 greater than loop length", | |
| 99 loopStartFrame: 4, | |
| 100 loopEndFrame: 6, | |
| 101 renderFrames: 16, | |
| 102 playbackRate: 47, | |
| 103 expected: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }, | |
| 104 | |
| 105 // Try illegal loop-points - they should be ignored and we'll loop the whole buf
fer. | |
| 106 | |
| 107 { description: "illegal loop: loopStartFrame > loopEndFrame", | |
| 108 loopStartFrame: 7, | |
| 109 loopEndFrame: 3, | |
| 110 renderFrames: 16, | |
| 111 playbackRate: 1, | |
| 112 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 113 | |
| 114 { description: "illegal loop: loopStartFrame == loopEndFrame", | |
| 115 loopStartFrame: 3, | |
| 116 loopEndFrame: 3, | |
| 117 renderFrames: 16, | |
| 118 playbackRate: 1, | |
| 119 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 120 | |
| 121 { description: "illegal loop: loopStartFrame < 0", | |
| 122 loopStartFrame: -8, | |
| 123 loopEndFrame: 3, | |
| 124 renderFrames: 16, | |
| 125 playbackRate: 1, | |
| 126 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 127 | |
| 128 { description: "illegal loop: loopEndFrame > bufferLength", | |
| 129 loopStartFrame: 0, | |
| 130 loopEndFrame: 30000, | |
| 131 renderFrames: 16, | |
| 132 playbackRate: 1, | |
| 133 expected: [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] }, | |
| 134 | |
| 135 // Start a loop with a duration longer than the buffer. The output should be th
e data from frame 1 | |
| 136 // to 6, and then looping from 3 to 5 until 20 frames have been played. | |
| 137 { description: "loop from 3 -> 6 with offset 1 for 20 frames", | |
| 138 loopStartFrame: 3, | |
| 139 loopEndFrame: 6, | |
| 140 playbackRate: 1, | |
| 141 offsetFrame: 1, | |
| 142 renderFrames: 30, | |
| 143 durationFrames: 20, | |
| 144 expected: [1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0] }, | |
| 145 | |
| 146 // Start a loop with a duration less than the length of the looping frames. The
output should be | |
| 147 // the data from frame 1 to 3, and then stopping because duration = 3 | |
| 148 { description: "loop from 3 -> 8 with offset 1 for 3 frames", | |
| 149 loopStartFrame: 3, | |
| 150 loopEndFrame: 8, | |
| 151 playbackRate: 1, | |
| 152 offsetFrame: 1, | |
| 153 durationFrames: 3, | |
| 154 renderFrames: 30, | |
| 155 expected: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0] }, | |
| 156 | |
| 157 // Start a loop with a duration less than the length of the looping frames. The
output should be | |
| 158 // the data from frame 1 to 3, and then stopping because duration = 3 | |
| 159 { description: "loop from 3 -> 8 with offset 7 for 3 frames", | |
| 160 loopStartFrame: 3, | |
| 161 loopEndFrame: 8, | |
| 162 playbackRate: 1, | |
| 163 offsetFrame: 7, | |
| 164 durationFrames: 3, | |
| 165 renderFrames: 30, | |
| 166 expected: [7, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0] } | |
| 167 | |
| 168 ]; | |
| 169 | |
| 170 var sampleRate = 44100; | |
| 171 var buffer; | |
| 172 var bufferFrameLength = 8; | |
| 173 var testSpacingFrames = 32; | |
| 174 var testSpacingSeconds = testSpacingFrames / sampleRate; | |
| 175 var totalRenderLengthFrames = tests.length * testSpacingFrames; | |
| 176 | |
| 177 function runLoopTest(context, testNumber, test) { | |
| 178 var source = context.createBufferSource(); | |
| 179 | |
| 180 source.buffer = buffer; | |
| 181 source.playbackRate.value = test.playbackRate; | |
| 182 source.loop = true; | |
| 183 source.loopStart = test.loopStartFrame / context.sampleRate; | |
| 184 source.loopEnd = test.loopEndFrame / context.sampleRate; | |
| 185 | |
| 186 var offset = test.offsetFrame ? test.offsetFrame / context.sampleRate : 0; | |
| 187 | |
| 188 source.connect(context.destination); | |
| 189 | |
| 190 // Render each test one after the other, spaced apart by testSpacingSeconds. | |
| 191 var startTime = testNumber * testSpacingSeconds; | |
| 192 | |
| 193 // If durationFrames is given, run the test for the specified duration. | |
| 194 if (test.durationFrames) { | |
| 195 if (!test.renderFrames) { | |
| 196 testFailed("renderFrames is required for test " + testNumber + ": "
+ test.description); | |
| 197 } else { | |
| 198 if (test.durationFrames > testSpacingFrames || test.durationFrames <
0) { | |
| 199 testFailed("Test " + testNumber | |
| 200 + ": durationFrames (" + test.durationFrames + ") outside th
e range [0, " | |
| 201 + testSpacingFrames + "]"); | |
| 202 } | |
| 203 source.start(startTime, offset, test.durationFrames / context.sample
Rate); | |
| 204 } | |
| 205 } else if (test.renderFrames) { | |
| 206 var duration = test.renderFrames / context.sampleRate; | |
| 207 if (test.renderFrames > testSpacingFrames || test.renderFrames < 0) { | |
| 208 testFailed("Test " + testNumber | |
| 209 + ": renderFrames (" + test.renderFrames + ") outside the range
[0, " | |
| 210 + testSpacingFrames + "]"); | |
| 211 } | |
| 212 source.start(startTime, offset); | |
| 213 source.stop(startTime + duration); | |
| 214 } else { | |
| 215 testFailed("Test " + testNumber + " must specify renderFrames and possib
ly durationFrames"); | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 function runTest() { | |
| 220 window.jsTestIsAsync = true; | |
| 221 | |
| 222 // Create offline audio context. | |
| 223 var context = new OfflineAudioContext(1, totalRenderLengthFrames, sampleRate
); | |
| 224 buffer = createTestBuffer(context, bufferFrameLength); | |
| 225 | |
| 226 for (var i = 0; i < tests.length; ++i) | |
| 227 runLoopTest(context, i, tests[i]); | |
| 228 | |
| 229 context.oncomplete = checkAllTests; | |
| 230 context.startRendering(); | |
| 231 } | |
| 232 | |
| 233 runTest(); | |
| 234 successfullyParsed = true; | |
| 235 | |
| 236 </script> | |
| 237 | |
| 238 </body> | |
| 239 </html> | |
| OLD | NEW |