| OLD | NEW |
| 1 <!doctype html> | 1 <!doctype html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>Test Processing Of AudioParams of Disconnected AudioNodes</title> | 4 <title>Test Processing Of AudioParams of Disconnected AudioNodes</title> |
| 5 <script src="../../resources/testharness.js"></script> | 5 <script src="../../resources/testharness.js"></script> |
| 6 <script src="../../resources/testharnessreport.js"></script> | 6 <script src="../../resources/testharnessreport.js"></script> |
| 7 <script src="../resources/audio-testing.js"></script> | 7 <script src="../resources/audit.js"></script> |
| 8 </head> | 8 </head> |
| 9 | 9 |
| 10 <body> | 10 <body> |
| 11 <script> | 11 <script> |
| 12 // Arbitrary sample rate. | 12 // Arbitrary sample rate. |
| 13 var sampleRate = 8000; | 13 var sampleRate = 8000; |
| 14 | 14 |
| 15 // Arbitrary number of frames for the test, except it must be greater than | 15 // Arbitrary number of frames for the test, except it must be greater than |
| 16 // |automationEndFrame|. | 16 // |automationEndFrame|. |
| 17 var renderFrames = 1024; | 17 var renderFrames = 1024; |
| 18 | 18 |
| 19 // The linear ramp automation ends at this frame. Arbitrary, except it | 19 // The linear ramp automation ends at this frame. Arbitrary, except it |
| 20 // must be strictly less than the render length. | 20 // must be strictly less than the render length. |
| 21 var automationEndFrame = 128; | 21 var automationEndFrame = 128; |
| 22 | 22 |
| 23 var audit = Audit.createTaskRunner(); | 23 var audit = Audit.createTaskRunner(); |
| 24 | 24 |
| 25 // There should be a test for every single node which has an AudioParam. | 25 // There should be a test for every single node which has an AudioParam. |
| 26 // Source nodes are not included in this because the AudioParams for the | 26 // Source nodes are not included in this because the AudioParams for the |
| 27 // source nodes only process when the node has been started. | 27 // source nodes only process when the node has been started. |
| 28 | 28 |
| 29 audit.defineTask("BiquadFilterNode", function (taskDone) { | 29 audit.define("BiquadFilterNode", (task, should) => { |
| 30 var nodeName = "BiquadFilterNode" | 30 var nodeName = "BiquadFilterNode" |
| 31 Promise.all([ | 31 Promise.all([ |
| 32 testParamAutomation({ | 32 testParamAutomation(should, { |
| 33 nodeName: nodeName, | 33 nodeName: nodeName, |
| 34 paramName: "Q", | 34 paramName: "Q", |
| 35 initialValue: 2, | 35 initialValue: 2, |
| 36 rampFinalValue: 5 | 36 rampFinalValue: 5 |
| 37 }), | 37 }), |
| 38 testParamAutomation({ | 38 testParamAutomation(should, { |
| 39 nodeName: nodeName, | 39 nodeName: nodeName, |
| 40 paramName: "detune", | 40 paramName: "detune", |
| 41 initialValue: 1, | 41 initialValue: 1, |
| 42 rampFinalValue: 0.5 | 42 rampFinalValue: 0.5 |
| 43 }), | 43 }), |
| 44 testParamAutomation({ | 44 testParamAutomation(should, { |
| 45 nodeName: nodeName, | 45 nodeName: nodeName, |
| 46 paramName: "frequency", | 46 paramName: "frequency", |
| 47 initialValue: 1000, | 47 initialValue: 1000, |
| 48 rampFinalValue: 100 | 48 rampFinalValue: 100 |
| 49 }), | 49 }), |
| 50 testParamAutomation({ | 50 testParamAutomation(should, { |
| 51 nodeName: nodeName, | 51 nodeName: nodeName, |
| 52 paramName: "gain", | 52 paramName: "gain", |
| 53 initialValue: -3, | 53 initialValue: -3, |
| 54 rampFinalValue: 3 | 54 rampFinalValue: 3 |
| 55 }), | 55 }), |
| 56 ]).then(taskDone); | 56 ]).then(() => task.done()); |
| 57 }); | 57 }); |
| 58 | 58 |
| 59 audit.defineTask("DelayNode", function (taskDone) { | 59 audit.define("DelayNode", (task, should) => { |
| 60 testParamAutomation({ | 60 testParamAutomation(should, { |
| 61 nodeName: "DelayNode", | 61 nodeName: "DelayNode", |
| 62 paramName: "delayTime", | 62 paramName: "delayTime", |
| 63 initialValue: 0.25, | 63 initialValue: 0.25, |
| 64 rampFinalValue: 0.5 | 64 rampFinalValue: 0.5 |
| 65 }).then(taskDone); | 65 }).then(() => task.done()); |
| 66 }); | 66 }); |
| 67 | 67 |
| 68 audit.defineTask("DynamicsCompressorNode", function (taskDone) { | 68 audit.define("DynamicsCompressorNode", (task, should) => { |
| 69 var nodeName = "DynamicsCompressorNode"; | 69 var nodeName = "DynamicsCompressorNode"; |
| 70 Promise.all([ | 70 Promise.all([ |
| 71 testParamAutomation({ | 71 testParamAutomation(should, { |
| 72 nodeName: nodeName, | 72 nodeName: nodeName, |
| 73 paramName: "attack", | 73 paramName: "attack", |
| 74 initialValue: 0.1, | 74 initialValue: 0.1, |
| 75 rampFinalValue: 0.5 | 75 rampFinalValue: 0.5 |
| 76 }), | 76 }), |
| 77 testParamAutomation({ | 77 testParamAutomation(should, { |
| 78 nodeName: nodeName, | 78 nodeName: nodeName, |
| 79 paramName: "knee", | 79 paramName: "knee", |
| 80 initialValue: 0, | 80 initialValue: 0, |
| 81 rampFinalValue: 25 | 81 rampFinalValue: 25 |
| 82 }), | 82 }), |
| 83 testParamAutomation({ | 83 testParamAutomation(should, { |
| 84 nodeName: nodeName, | 84 nodeName: nodeName, |
| 85 paramName: "ratio", | 85 paramName: "ratio", |
| 86 initialValue: 1, | 86 initialValue: 1, |
| 87 rampFinalValue: 15 | 87 rampFinalValue: 15 |
| 88 }), | 88 }), |
| 89 testParamAutomation({ | 89 testParamAutomation(should, { |
| 90 nodeName: nodeName, | 90 nodeName: nodeName, |
| 91 paramName: "release", | 91 paramName: "release", |
| 92 initialValue: 0, | 92 initialValue: 0, |
| 93 rampFinalValue: 0.75 | 93 rampFinalValue: 0.75 |
| 94 }), | 94 }), |
| 95 testParamAutomation({ | 95 testParamAutomation(should, { |
| 96 nodeName: nodeName, | 96 nodeName: nodeName, |
| 97 paramName: "threshold", | 97 paramName: "threshold", |
| 98 initialValue: -50, | 98 initialValue: -50, |
| 99 rampFinalValue: -10 | 99 rampFinalValue: -10 |
| 100 }) | 100 }) |
| 101 ]).then(taskDone); | 101 ]).then(() => task.done()); |
| 102 }); | 102 }); |
| 103 | 103 |
| 104 audit.defineTask("GainNode", function (taskDone) { | 104 audit.define("GainNode", (task, should) => { |
| 105 testParamAutomation({ | 105 testParamAutomation(should, { |
| 106 nodeName: "GainNode", | 106 nodeName: "GainNode", |
| 107 paramName: "gain", | 107 paramName: "gain", |
| 108 initialValue: 1, | 108 initialValue: 1, |
| 109 rampFinalValue: 0.5 | 109 rampFinalValue: 0.5 |
| 110 }).then(taskDone); | 110 }).then(() => task.done()); |
| 111 }); | 111 }); |
| 112 | 112 |
| 113 audit.defineTask("PannerNode", function (taskDone) { | 113 audit.define("PannerNode", (task, should) => { |
| 114 var nodeName = "PannerNode"; | 114 var nodeName = "PannerNode"; |
| 115 Promise.all([ | 115 Promise.all([ |
| 116 testParamAutomation({ | 116 testParamAutomation(should, { |
| 117 nodeName: nodeName, | 117 nodeName: nodeName, |
| 118 paramName: "positionX", | 118 paramName: "positionX", |
| 119 initialValue: 0.1, | 119 initialValue: 0.1, |
| 120 rampFinalValue: 0.5 | 120 rampFinalValue: 0.5 |
| 121 }), | 121 }), |
| 122 testParamAutomation({ | 122 testParamAutomation(should, { |
| 123 nodeName: nodeName, | 123 nodeName: nodeName, |
| 124 paramName: "positionY", | 124 paramName: "positionY", |
| 125 initialValue: 2, | 125 initialValue: 2, |
| 126 rampFinalValue: 30 | 126 rampFinalValue: 30 |
| 127 }), | 127 }), |
| 128 testParamAutomation({ | 128 testParamAutomation(should, { |
| 129 nodeName: nodeName, | 129 nodeName: nodeName, |
| 130 paramName: "positionZ", | 130 paramName: "positionZ", |
| 131 initialValue: 1, | 131 initialValue: 1, |
| 132 rampFinalValue: 15 | 132 rampFinalValue: 15 |
| 133 }), | 133 }), |
| 134 testParamAutomation({ | 134 testParamAutomation(should, { |
| 135 nodeName: nodeName, | 135 nodeName: nodeName, |
| 136 paramName: "orientationX", | 136 paramName: "orientationX", |
| 137 initialValue: 0.1, | 137 initialValue: 0.1, |
| 138 rampFinalValue: 0.5 | 138 rampFinalValue: 0.5 |
| 139 }), | 139 }), |
| 140 testParamAutomation({ | 140 testParamAutomation(should, { |
| 141 nodeName: nodeName, | 141 nodeName: nodeName, |
| 142 paramName: "orientationY", | 142 paramName: "orientationY", |
| 143 initialValue: 2, | 143 initialValue: 2, |
| 144 rampFinalValue: 30 | 144 rampFinalValue: 30 |
| 145 }), | 145 }), |
| 146 testParamAutomation({ | 146 testParamAutomation(should, { |
| 147 nodeName: nodeName, | 147 nodeName: nodeName, |
| 148 paramName: "orientationZ", | 148 paramName: "orientationZ", |
| 149 initialValue: 1, | 149 initialValue: 1, |
| 150 rampFinalValue: 15 | 150 rampFinalValue: 15 |
| 151 }), | 151 }), |
| 152 ]).then(taskDone); | 152 ]).then(() => task.done()); |
| 153 }); | 153 }); |
| 154 | 154 |
| 155 audit.defineTask("StereoPannerNode", function (taskDone) { | 155 audit.define("StereoPannerNode", (task, should) => { |
| 156 testParamAutomation({ | 156 testParamAutomation(should, { |
| 157 nodeName: "StereoPannerNode", | 157 nodeName: "StereoPannerNode", |
| 158 paramName: "pan", | 158 paramName: "pan", |
| 159 initialValue: 1, | 159 initialValue: 1, |
| 160 rampFinalValue: 0.5 | 160 rampFinalValue: 0.5 |
| 161 }).then(taskDone); | 161 }).then(() => task.done()); |
| 162 }); | 162 }); |
| 163 | 163 |
| 164 audit.defineTask("AudioListener", function (taskDone) { | 164 audit.define("AudioListener", (task, should) => { |
| 165 Promise.all([ | 165 Promise.all([ |
| 166 testAudioListener({ | 166 testAudioListener(should, { |
| 167 paramName: "positionX", | 167 paramName: "positionX", |
| 168 initialValue: 1, | 168 initialValue: 1, |
| 169 rampFinalValue: 100 | 169 rampFinalValue: 100 |
| 170 }), | 170 }), |
| 171 testAudioListener({ | 171 testAudioListener(should, { |
| 172 paramName: "positionY", | 172 paramName: "positionY", |
| 173 initialValue: 1, | 173 initialValue: 1, |
| 174 rampFinalValue: 200 | 174 rampFinalValue: 200 |
| 175 }), | 175 }), |
| 176 testAudioListener({ | 176 testAudioListener(should, { |
| 177 paramName: "positionZ", | 177 paramName: "positionZ", |
| 178 initialValue: 1, | 178 initialValue: 1, |
| 179 rampFinalValue: 300 | 179 rampFinalValue: 300 |
| 180 }), | 180 }), |
| 181 testAudioListener({ | 181 testAudioListener(should, { |
| 182 paramName: "forwardX", | 182 paramName: "forwardX", |
| 183 initialValue: 1, | 183 initialValue: 1, |
| 184 rampFinalValue: -100 | 184 rampFinalValue: -100 |
| 185 }), | 185 }), |
| 186 testAudioListener({ | 186 testAudioListener(should, { |
| 187 paramName: "forwardY", | 187 paramName: "forwardY", |
| 188 initialValue: 1, | 188 initialValue: 1, |
| 189 rampFinalValue: -200 | 189 rampFinalValue: -200 |
| 190 }), | 190 }), |
| 191 testAudioListener({ | 191 testAudioListener(should, { |
| 192 paramName: "forwardZ", | 192 paramName: "forwardZ", |
| 193 initialValue: 1, | 193 initialValue: 1, |
| 194 rampFinalValue: -300 | 194 rampFinalValue: -300 |
| 195 }), | 195 }), |
| 196 testAudioListener({ | 196 testAudioListener(should, { |
| 197 paramName: "upX", | 197 paramName: "upX", |
| 198 initialValue: 1, | 198 initialValue: 1, |
| 199 rampFinalValue: 99 | 199 rampFinalValue: 99 |
| 200 }), | 200 }), |
| 201 testAudioListener({ | 201 testAudioListener(should, { |
| 202 paramName: "upY", | 202 paramName: "upY", |
| 203 initialValue: 1, | 203 initialValue: 1, |
| 204 rampFinalValue: 42 | 204 rampFinalValue: 42 |
| 205 }), | 205 }), |
| 206 testAudioListener({ | 206 testAudioListener(should, { |
| 207 paramName: "upZ", | 207 paramName: "upZ", |
| 208 initialValue: 1, | 208 initialValue: 1, |
| 209 rampFinalValue: 137 | 209 rampFinalValue: 137 |
| 210 }), | 210 }), |
| 211 ]).then(taskDone); | 211 ]).then(() => task.done()); |
| 212 }); | 212 }); |
| 213 | 213 |
| 214 // Run test of automation processing. |options| is a dictionary that | 214 // Run test of automation processing. |options| is a dictionary that |
| 215 // describes the node to test, the AudioParams to be tested and the values | 215 // describes the node to test, the AudioParams to be tested and the values |
| 216 // for the AudioParam. The members of the dictionary are: | 216 // for the AudioParam. The members of the dictionary are: |
| 217 // | 217 // |
| 218 // nodeName - name of the node (constructor name) | 218 // nodeName - name of the node (constructor name) |
| 219 // paramName - name of the AudioParam to be tested | 219 // paramName - name of the AudioParam to be tested |
| 220 // initialValue - starting value for linear ramp | 220 // initialValue - starting value for linear ramp |
| 221 // rampFinalValue - finale value for linear ramp | 221 // rampFinalValue - finale value for linear ramp |
| 222 // | 222 // |
| 223 // The test is considered to have succeeded if the |.value| of the AudioPa
ram | 223 // The test is considered to have succeeded if the |.value| of the AudioPa
ram |
| 224 // is the final value. | 224 // is the final value. |
| 225 // | 225 // |
| 226 // A simple graph is created containing the node to be tested, connected | 226 // A simple graph is created containing the node to be tested, connected |
| 227 // to the destination. A linear ramp automation is scheduled for the | 227 // to the destination. A linear ramp automation is scheduled for the |
| 228 // specified AudioParam, starting and ending at the values given. | 228 // specified AudioParam, starting and ending at the values given. |
| 229 // | 229 // |
| 230 // Processing is started and after some number of frames, the |.value| of | 230 // Processing is started and after some number of frames, the |.value| of |
| 231 // the AudioParam is obtained and compared against the final value. These | 231 // the AudioParam is obtained and compared against the final value. These |
| 232 // should match exactly. | 232 // should match exactly. |
| 233 function testParamAutomation(options) { | 233 function testParamAutomation(should, options) { |
| 234 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | 234 var context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| 235 | 235 |
| 236 // Create the node to be tested | 236 // Create the node to be tested |
| 237 var node = new window[options.nodeName](context); | 237 var node = new window[options.nodeName](context); |
| 238 node.connect(context.destination); | 238 node.connect(context.destination); |
| 239 | 239 |
| 240 // A linear ramp starting at frame 0 to frame |automationEndFrame| is | 240 // A linear ramp starting at frame 0 to frame |automationEndFrame| is |
| 241 // used for the test. This value is fairly arbitrary, but it should be | 241 // used for the test. This value is fairly arbitrary, but it should be |
| 242 // less than the total render frames. | 242 // less than the total render frames. |
| 243 | 243 |
| 244 node[options.paramName].setValueAtTime(options.initialValue, 0); | 244 node[options.paramName].setValueAtTime(options.initialValue, 0); |
| 245 node[options.paramName].linearRampToValueAtTime(options.rampFinalValue, | 245 node[options.paramName].linearRampToValueAtTime(options.rampFinalValue, |
| 246 automationEndFrame / context.sampleRate); | 246 automationEndFrame / context.sampleRate); |
| 247 | 247 |
| 248 return context.startRendering() | 248 return context.startRendering() |
| 249 .then(function (resultBuffer) { | 249 .then(function (resultBuffer) { |
| 250 // Sanity check: the given ramp final value must not be the default | 250 // Sanity check: the given ramp final value must not be the default |
| 251 // value, otherwise we can't easily tell if the automation was | 251 // value, otherwise we can't easily tell if the automation was |
| 252 // actually run. | 252 // actually run. |
| 253 Should(options.nodeName + "." + options.paramName + " ramp final val
ue", | 253 should(options.rampFinalValue, |
| 254 options.rampFinalValue) | 254 options.nodeName + "." + options.paramName + " ramp final value") |
| 255 .notBeEqualTo(node[options.paramName].defaultValue); | 255 .notBeEqualTo(node[options.paramName].defaultValue); |
| 256 | 256 |
| 257 // The actual AudioParam value should be the rampe final value. | 257 // The actual AudioParam value should be the rampe final value. |
| 258 Should(options.nodeName + "." + options.paramName + | 258 should(node[options.paramName].value, |
| 259 ".value", | 259 options.nodeName + "." + options.paramName + ".value") |
| 260 node[options.paramName].value) | |
| 261 .beEqualTo(options.rampFinalValue); | 260 .beEqualTo(options.rampFinalValue); |
| 262 }); | 261 }); |
| 263 } | 262 } |
| 264 | 263 |
| 265 function testAudioListener(options) { | 264 function testAudioListener(should, options) { |
| 266 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | 265 var context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| 267 | 266 |
| 268 // Create the node to be tested | 267 // Create the node to be tested |
| 269 var node = new PannerNode(context); | 268 var node = new PannerNode(context); |
| 270 node.connect(context.destination); | 269 node.connect(context.destination); |
| 271 | 270 |
| 272 // A linear ramp starting at frame 0 to frame |automationEndFrame| is | 271 // A linear ramp starting at frame 0 to frame |automationEndFrame| is |
| 273 // used for the test. This value is fairly arbitrary, but it should be | 272 // used for the test. This value is fairly arbitrary, but it should be |
| 274 // less than the total render frames. | 273 // less than the total render frames. |
| 275 | 274 |
| 276 context.listener[options.paramName].setValueAtTime(options.initialValue,
0); | 275 context.listener[options.paramName].setValueAtTime(options.initialValue,
0); |
| 277 context.listener[options.paramName].linearRampToValueAtTime(options.ramp
FinalValue, | 276 context.listener[options.paramName].linearRampToValueAtTime(options.ramp
FinalValue, |
| 278 automationEndFrame / context.sampleRate); | 277 automationEndFrame / context.sampleRate); |
| 279 | 278 |
| 280 return context.startRendering() | 279 return context.startRendering() |
| 281 .then(function (resultBuffer) { | 280 .then(function (resultBuffer) { |
| 282 // Sanity check: the given ramp final value must not be the default | 281 // Sanity check: the given ramp final value must not be the default |
| 283 // value, otherwise we can't easily tell if the automation was | 282 // value, otherwise we can't easily tell if the automation was |
| 284 // actually run. | 283 // actually run. |
| 285 Should("AudioListener." + options.paramName + " ramp final value", | 284 should(options.rampFinalValue, |
| 286 options.rampFinalValue) | 285 "AudioListener." + options.paramName + " ramp final value") |
| 287 .notBeEqualTo(context.listener[options.paramName].defaultValue); | 286 .notBeEqualTo(context.listener[options.paramName].defaultValue); |
| 288 | 287 |
| 289 // The actual AudioParam value should be the rampe final value. | 288 // The actual AudioParam value should be the rampe final value. |
| 290 Should("AudioListener." + options.paramName + | 289 should(context.listener[options.paramName].value, |
| 291 ".value", | 290 "AudioListener." + options.paramName + ".value") |
| 292 context.listener[options.paramName].value) | |
| 293 .beEqualTo(options.rampFinalValue); | 291 .beEqualTo(options.rampFinalValue); |
| 294 }); | 292 }); |
| 295 } | 293 } |
| 296 | 294 |
| 297 audit.runTasks(); | 295 audit.run(); |
| 298 </script> | 296 </script> |
| 299 </body> | 297 </body> |
| 300 </html> | 298 </html> |
| OLD | NEW |