Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 <!doctype html> | |
| 2 <html> | |
| 3 <head> | |
| 4 <script src="../resources/js-test.js"></script> | |
| 5 <script src="resources/compatibility.js"></script> | |
| 6 <script src="resources/audio-testing.js"></script> | |
| 7 <script src="resources/panner-formulas.js"></script> | |
| 8 <title>Test Basic Panner Position Properties</title> | |
| 9 </head> | |
| 10 | |
| 11 <body> | |
| 12 <script> | |
| 13 description("Test Basic SpatialPannerNode Properties."); | |
| 14 window.jsTestIsAsync = true; | |
| 15 | |
| 16 var sampleRate = 48000; | |
| 17 | |
| 18 // These tests are quite slow, so don't run for many frames. 256 frames s hould be enough to | |
| 19 // demonstrate that automations are working. | |
| 20 var renderFrames = 256; | |
| 21 var renderDuration = renderFrames / sampleRate; | |
| 22 | |
| 23 var audit = Audit.createTaskRunner(); | |
| 24 | |
| 25 audit.defineTask("panner position x-setter", function (done) { | |
| 26 var nodes = createGraph(); | |
| 27 var { | |
| 28 context, source, panner | |
| 29 } = nodes; | |
|
hongchan
2016/05/03 18:15:01
How about:
var nodes = { context, source, panner
Raymond Toy
2016/05/03 20:32:21
No problems with this, but js-beautify wants to in
hongchan
2016/05/03 20:38:58
That's perhaps because js-beautify doesn't know ab
Raymond Toy
2016/05/03 20:46:47
Yes, js-beautify probably doesn't know. Isn't mul
Raymond Toy
2016/05/03 21:03:45
Done, except no multiple assignment.
| |
| 30 | |
| 31 testPositionSetter({ | |
| 32 nodes: nodes, | |
| 33 pannerSetter: panner.positionX, | |
| 34 message: "panner.positionX" | |
| 35 }).then(done); | |
| 36 }); | |
| 37 | |
| 38 audit.defineTask("panner position y-setter", function (done) { | |
| 39 var nodes = createGraph(); | |
| 40 var { | |
| 41 context, source, panner | |
| 42 } = nodes; | |
|
hongchan
2016/05/03 18:15:01
ditto.
Raymond Toy
2016/05/03 21:03:45
Done.
| |
| 43 | |
| 44 testPositionSetter({ | |
| 45 nodes: nodes, | |
| 46 pannerSetter: panner.positionY, | |
| 47 message: "panner.positionY" | |
| 48 }).then(done); | |
| 49 }); | |
| 50 | |
| 51 audit.defineTask("panner position z-setter", function (done) { | |
| 52 var nodes = createGraph(); | |
| 53 var { | |
| 54 context, source, panner | |
| 55 } = nodes; | |
|
hongchan
2016/05/03 18:15:01
ditto.
Raymond Toy
2016/05/03 21:03:45
Done.
| |
| 56 | |
| 57 testPositionSetter({ | |
| 58 nodes: nodes, | |
| 59 pannerSetter: panner.positionZ, | |
| 60 message: "panner.positionZ" | |
| 61 }).then(done); | |
| 62 }); | |
| 63 | |
| 64 // This test currently fails because of the dezippering of the distance an d cone gain that | |
| 65 // happens when setPosition is used. | |
| 66 audit.defineTask("setPosition", function (done) { | |
| 67 var { context, panner, source } = createGraph(); | |
| 68 | |
| 69 // Initialize source position (values don't really matter). | |
| 70 panner.setPosition(1,1,1); | |
| 71 | |
| 72 // After some (unimportant) time, move the panner to a (any) new locatio n. | |
| 73 var suspendFrame = 128; | |
| 74 context.suspend(suspendFrame / sampleRate).then(function () { | |
| 75 panner.setPosition(-100, 2000, 8000); | |
| 76 }).then(context.resume.bind(context)); | |
| 77 | |
| 78 context.startRendering().then(function (resultBuffer) { | |
| 79 verifyPannerOutputChanged(resultBuffer, {message: "setPosition", suspe ndFrame: suspendFrame}); | |
| 80 }).then(done); | |
| 81 }); | |
| 82 | |
| 83 audit.defineTask("orientation setter", function (done) { | |
| 84 var { context, panner, source } = createGraph(); | |
| 85 | |
| 86 // For orientation to matter, we need to make the source directional, an d also move away | |
| 87 // from the listener (because the default location is 0,0,0). | |
| 88 panner.setPosition(0,0,1); | |
| 89 panner.coneInnerAngle = 0; | |
| 90 panner.coneOuterAngle = 360; | |
| 91 panner.coneOuterGain = .001; | |
| 92 | |
| 93 // After some (unimportant) time, change the panner orientation to a new orientation. The | |
| 94 // only constraint is that the orientation changes from before. | |
| 95 var suspendFrame = 128; | |
| 96 context.suspend(suspendFrame / sampleRate).then(function () { | |
| 97 panner.orientationX.value = -100; | |
| 98 panner.orientationY.value = 2000; | |
| 99 panner.orientationZ.value = 8000; | |
| 100 }).then(context.resume.bind(context)); | |
| 101 | |
| 102 context.startRendering().then(function (resultBuffer) { | |
| 103 verifyPannerOutputChanged(resultBuffer, {message: "panner.orientation{ XYZ}", suspendFrame: suspendFrame}); | |
| 104 }).then(done); | |
| 105 }); | |
| 106 | |
| 107 | |
| 108 audit.defineTask("listener x-setter", function (done) { | |
| 109 var nodes = createGraph(); | |
| 110 var { | |
| 111 context, source, panner | |
| 112 } = nodes; | |
| 113 | |
| 114 panner.setPosition(1,0,1); | |
| 115 testPositionSetter({ | |
| 116 nodes: nodes, | |
| 117 pannerSetter: context.listener.positionX, | |
| 118 message: "listener.positionX" | |
| 119 }).then(done); | |
| 120 }); | |
| 121 | |
| 122 audit.defineTask("listener y-setter", function (done) { | |
| 123 var nodes = createGraph(); | |
| 124 var { | |
| 125 context, source, panner | |
| 126 } = nodes; | |
| 127 | |
| 128 panner.setPosition(1,0,1); | |
| 129 //panner.setOrientation(0, 0, -1); | |
| 130 testPositionSetter({ | |
| 131 nodes: nodes, | |
| 132 pannerSetter: context.listener.positionY, | |
| 133 message: "listener.positionY" | |
| 134 }).then(done); | |
| 135 }); | |
| 136 | |
| 137 audit.defineTask("listener z-setter", function (done) { | |
| 138 var nodes = createGraph(); | |
| 139 var { | |
| 140 context, source, panner | |
| 141 } = nodes; | |
| 142 | |
| 143 panner.setPosition(1,0,1); | |
| 144 //panner.setOrientation(0, 0, -1); | |
| 145 testPositionSetter({ | |
| 146 nodes: nodes, | |
| 147 pannerSetter: context.listener.positionZ, | |
| 148 message: "listener.positionZ" | |
| 149 }).then(done); | |
| 150 }); | |
| 151 | |
| 152 audit.defineTask("forward setter", function (done) { | |
| 153 var { context, panner, source } = createGraph(); | |
| 154 | |
| 155 // For orientation to matter, we need to make the source directional, an d also move away | |
| 156 // from the listener (because the default location is 0,0,0). | |
| 157 panner.setPosition(0,0,1); | |
| 158 panner.coneInnerAngle = 0; | |
| 159 panner.coneOuterAngle = 360; | |
| 160 panner.coneOuterGain = .001; | |
| 161 | |
| 162 // After some (unimportant) time, change the panner orientation to a new orientation. The | |
| 163 // only constraint is that the orientation changes from before. | |
| 164 var suspendFrame = 128; | |
| 165 context.suspend(suspendFrame / sampleRate).then(function () { | |
| 166 context.listener.forwardX.value = -100; | |
| 167 context.listener.forwardY.value = 2000; | |
| 168 context.listener.forwardZ.value = 8000; | |
| 169 }).then(context.resume.bind(context)); | |
| 170 | |
| 171 context.startRendering().then(function (resultBuffer) { | |
| 172 verifyPannerOutputChanged(resultBuffer, {message: "listener.forward{XY Z}", suspendFrame: suspendFrame}); | |
| 173 }).then(done); | |
| 174 }); | |
| 175 | |
| 176 audit.defineTask("up setter", function (done) { | |
| 177 var { context, panner, source } = createGraph(); | |
| 178 | |
| 179 // For orientation to matter, we need to make the source directional, an d also move away | |
| 180 // from the listener (because the default location is 0,0,0). | |
| 181 panner.setPosition(0,0,1); | |
| 182 panner.coneInnerAngle = 0; | |
| 183 panner.coneOuterAngle = 360; | |
| 184 panner.coneOuterGain = .001; | |
| 185 panner.setPosition(1,0,1); | |
| 186 | |
| 187 // After some (unimportant) time, change the panner orientation to a new orientation. The | |
| 188 // only constraint is that the orientation changes from before. | |
| 189 var suspendFrame = 128; | |
| 190 context.suspend(suspendFrame / sampleRate).then(function () { | |
| 191 context.listener.upX.value = 100; | |
| 192 context.listener.upY.value = 100; | |
| 193 context.listener.upZ.value = 100;; | |
| 194 }).then(context.resume.bind(context)); | |
| 195 | |
| 196 context.startRendering().then(function (resultBuffer) { | |
| 197 verifyPannerOutputChanged(resultBuffer, {message: "listener.up{XYZ}", suspendFrame: suspendFrame}); | |
| 198 }).then(done); | |
| 199 }); | |
| 200 | |
| 201 audit.defineTask("finish", function (done) { | |
| 202 finishJSTest(); | |
| 203 done(); | |
| 204 }); | |
| 205 | |
| 206 audit.runTasks( | |
| 207 //"setPosition", | |
| 208 //"finish" | |
|
hongchan
2016/05/03 18:15:01
I can accept this as a pattern. However, is this i
Raymond Toy
2016/05/03 20:32:21
No. A bit of debugging left over.
| |
| 209 ); | |
| 210 | |
| 211 function createGraph() { | |
| 212 var context = new OfflineAudioContext(2, renderFrames, sampleRate); | |
| 213 var panner = context.createPanner(); | |
| 214 var source = context.createBufferSource(); | |
| 215 source.buffer = createConstantBuffer(context, 1, 1); | |
| 216 source.loop = true; | |
| 217 | |
| 218 source.connect(panner); | |
| 219 panner.connect(context.destination); | |
| 220 | |
| 221 source.start(); | |
| 222 return { context: context, | |
|
hongchan
2016/05/03 18:15:01
Let's add a line break after {.
Raymond Toy
2016/05/03 21:03:45
Done.
| |
| 223 source: source, | |
| 224 panner: panner | |
| 225 }; | |
| 226 } | |
| 227 | |
| 228 function testPositionSetter(options) { | |
| 229 var { | |
| 230 nodes, pannerSetter, message | |
| 231 } = options; | |
|
hongchan
2016/05/03 18:15:01
ditto here - let's put them in a single line.
Raymond Toy
2016/05/03 21:03:45
Done.
| |
| 232 | |
| 233 var { | |
| 234 context, source, panner | |
| 235 } = nodes; | |
|
hongchan
2016/05/03 18:15:01
ditto.
Raymond Toy
2016/05/03 21:03:45
Done.
| |
| 236 | |
| 237 // Set panner x position. (Value doesn't matter); | |
| 238 pannerSetter.value = 1; | |
| 239 | |
| 240 // Wait a bit and set a new position. (Actual time and position doesn't matter). | |
| 241 var suspendFrame = 128; | |
| 242 context.suspend(suspendFrame / sampleRate).then(function () { | |
| 243 pannerSetter.value = 10000; | |
| 244 }).then(context.resume.bind(context)); | |
| 245 | |
| 246 return context.startRendering().then(function (resultBuffer) { | |
| 247 verifyPannerOutputChanged(resultBuffer, {message: message, suspendFram e: suspendFrame}); | |
| 248 }); | |
| 249 } | |
| 250 | |
| 251 function verifyPannerOutputChanged(resultBuffer, options) { | |
| 252 var { message, suspendFrame } = options; | |
| 253 // Verify that the first part of output is constant. (Doesn't matter w hat.) | |
| 254 var success = true; | |
| 255 var data0 = resultBuffer.getChannelData(0); | |
| 256 var data1 = resultBuffer.getChannelData(1); | |
| 257 | |
| 258 success = Should(message + ".value at frame 0 channel 0", data0.slice( 0, suspendFrame)) | |
| 259 .beConstantValueOf(data0[0]) && success; | |
| 260 success = Should(message + ".value at frame 0 channel 1", data1.slice( 0, suspendFrame)) | |
| 261 .beConstantValueOf(data1[0]) && success; | |
| 262 | |
| 263 // The rest after suspendTime should be constant and different from th e first part. | |
| 264 success = Should(message + ".value at frame " + suspendFrame + " chann el 0", | |
| 265 data0.slice(suspendFrame)) | |
| 266 .beConstantValueOf(data0[suspendFrame]) && success; | |
| 267 success = Should(message + ".value at frame " + suspendFrame + " chann el 0", | |
| 268 data1.slice(suspendFrame)) | |
| 269 .beConstantValueOf(data1[suspendFrame]) && success; | |
| 270 success = Should("Output at frame " + suspendFrame + " channel 0", dat a0[0]) | |
| 271 .notBeEqualTo(data0[suspendFrame]) && success; | |
| 272 success = Should("Output at frame " + suspendFrame + " channel 1", dat a1[0]) | |
| 273 .notBeEqualTo(data1[suspendFrame]) && success; | |
| 274 | |
| 275 var prefix = "Directly setting " + message + ".value"; | |
| 276 if (success) | |
| 277 testPassed(prefix + " worked.\n"); | |
| 278 else | |
| 279 testFailed(prefix + " failed.\n"); | |
| 280 } | |
| 281 </script> | |
| 282 </body> | |
| 283 </html> | |
| OLD | NEW |