Index: third_party/WebKit/LayoutTests/webaudio/StereoPanner/stereopannernode-no-glitch.html |
diff --git a/third_party/WebKit/LayoutTests/webaudio/StereoPanner/stereopannernode-no-glitch.html b/third_party/WebKit/LayoutTests/webaudio/StereoPanner/stereopannernode-no-glitch.html |
index 6708c3d57c7d90f6ff748703d6aa0143d95db4aa..01d69da5f9bdc8573069ebb40cecdee5d64a2dd9 100644 |
--- a/third_party/WebKit/LayoutTests/webaudio/StereoPanner/stereopannernode-no-glitch.html |
+++ b/third_party/WebKit/LayoutTests/webaudio/StereoPanner/stereopannernode-no-glitch.html |
@@ -1,176 +1,183 @@ |
<!DOCTYPE html> |
<html> |
- |
-<head> |
- <script src="../../resources/testharness.js"></script> |
- <script src="../../resources/testharnessreport.js"></script> |
- <script src="../resources/audit-util.js"></script> |
- <script src="../resources/audit.js"></script> |
-</head> |
- |
-<body> |
- <script> |
- var sampleRate = 44100; |
- var renderDuration = 0.5; |
- |
- // The threshold for glitch detection. This was experimentally determined. |
- var GLITCH_THRESHOLD = 0.0005; |
- |
- // The maximum threshold for the error between the actual and the expected |
- // sample values. Experimentally determined. |
- var MAX_ERROR_ALLOWED = 0.0000001; |
- |
- // Option for |Should| test util. The number of array elements to be printed |
- // out is arbitrary. |
- var SHOULD_OPTS = { |
- numberOfArrayLog: 2 |
- }; |
- |
- var audit = Audit.createTaskRunner(); |
- |
- // Extract a transitional region from the AudioBuffer. If no transition |
- // found, fail this test. |
- function extractPanningTransition(should, input, prefix) { |
- var chanL = input.getChannelData(0); |
- var chanR = input.getChannelData(1); |
- var start, end; |
- var index = 1; |
- |
- // Find transition by comparing two consecutive samples. If two consecutive |
- // samples are identical, the transition has not started. |
- while (chanL[index-1] === chanL[index] || chanR[index-1] === chanR[index]) { |
- if (++index >= input.length) { |
- should(false, prefix + ': Transition in the channel data') |
- .summarize('found', 'not found'); |
- return null; |
+ <head> |
+ <title> |
+ stereopannernode-no-glitch.html |
+ </title> |
+ <script src="../../resources/testharness.js"></script> |
+ <script src="../../resources/testharnessreport.js"></script> |
+ <script src="../resources/audit-util.js"></script> |
+ <script src="../resources/audit.js"></script> |
+ </head> |
+ <body> |
+ <script id="layout-test-code"> |
+ let sampleRate = 44100; |
+ let renderDuration = 0.5; |
+ |
+ // The threshold for glitch detection. This was experimentally determined. |
+ let GLITCH_THRESHOLD = 0.0005; |
+ |
+ // The maximum threshold for the error between the actual and the expected |
+ // sample values. Experimentally determined. |
+ let MAX_ERROR_ALLOWED = 0.0000001; |
+ |
+ // Option for |Should| test util. The number of array elements to be |
+ // printed out is arbitrary. |
+ let SHOULD_OPTS = {numberOfArrayLog: 2}; |
+ |
+ let audit = Audit.createTaskRunner(); |
+ |
+ // Extract a transitional region from the AudioBuffer. If no transition |
+ // found, fail this test. |
+ function extractPanningTransition(should, input, prefix) { |
+ let chanL = input.getChannelData(0); |
+ let chanR = input.getChannelData(1); |
+ let start, end; |
+ let index = 1; |
+ |
+ // Find transition by comparing two consecutive samples. If two |
+ // consecutive samples are identical, the transition has not started. |
+ while (chanL[index - 1] === chanL[index] || |
+ chanR[index - 1] === chanR[index]) { |
+ if (++index >= input.length) { |
+ should(false, prefix + ': Transition in the channel data') |
+ .summarize('found', 'not found'); |
+ return null; |
+ } |
} |
- } |
- start = index - 1; |
- |
- // Find the end of transition. If two consecutive samples are not equal, |
- // the transition is still ongoing. |
- while (chanL[index-1] !== chanL[index] || chanR[index-1] !== chanR[index]) { |
- if (++index >= input.length) { |
- should(false, 'Transition found') |
- .summarize('', 'but the buffer ended prematurely'); |
- return null; |
+ start = index - 1; |
+ |
+ // Find the end of transition. If two consecutive samples are not equal, |
+ // the transition is still ongoing. |
+ while (chanL[index - 1] !== chanL[index] || |
+ chanR[index - 1] !== chanR[index]) { |
+ if (++index >= input.length) { |
+ should(false, 'Transition found') |
+ .summarize('', 'but the buffer ended prematurely'); |
+ return null; |
+ } |
} |
+ end = index; |
+ |
+ return { |
+ left: chanL.subarray(start, end), |
+ right: chanR.subarray(start, end), |
+ length: end - start |
+ }; |
} |
- end = index; |
- |
- return { |
- left: chanL.subarray(start, end), |
- right: chanR.subarray(start, end), |
- length: end - start |
- }; |
- } |
- |
- // JS implementation of stereo equal power panning. |
- function panStereoEqualPower(pan, inputL, inputR) { |
- pan = Math.min(1.0, Math.max(-1.0, pan)); |
- var output = []; |
- var panRadian; |
- if (!inputR) { // mono case. |
- panRadian = (pan * 0.5 + 0.5) * Math.PI / 2; |
- output[0] = inputL * Math.cos(panRadian); |
- output[1] = inputR * Math.sin(panRadian); |
- } else { // stereo case. |
- panRadian = (pan <= 0 ? pan + 1 : pan) * Math.PI / 2; |
- var gainL = Math.cos(panRadian); |
- var gainR = Math.sin(panRadian); |
- if (pan <= 0) { |
- output[0] = inputL + inputR * gainL; |
- output[1] = inputR * gainR; |
- } else { |
- output[0] = inputL * gainL; |
- output[1] = inputR + inputL * gainR; |
+ |
+ // JS implementation of stereo equal power panning. |
+ function panStereoEqualPower(pan, inputL, inputR) { |
+ pan = Math.min(1.0, Math.max(-1.0, pan)); |
+ let output = []; |
+ let panRadian; |
+ if (!inputR) { // mono case. |
+ panRadian = (pan * 0.5 + 0.5) * Math.PI / 2; |
+ output[0] = inputL * Math.cos(panRadian); |
+ output[1] = inputR * Math.sin(panRadian); |
+ } else { // stereo case. |
+ panRadian = (pan <= 0 ? pan + 1 : pan) * Math.PI / 2; |
+ let gainL = Math.cos(panRadian); |
+ let gainR = Math.sin(panRadian); |
+ if (pan <= 0) { |
+ output[0] = inputL + inputR * gainL; |
+ output[1] = inputR * gainR; |
+ } else { |
+ output[0] = inputL * gainL; |
+ output[1] = inputR + inputL * gainR; |
+ } |
} |
- } |
- return output; |
- } |
- |
- // Generate the expected result of stereo equal panning. |input| is an |
- // AudioBuffer to be panned. |
- function generateStereoEqualPanningResult(input, startPan, endPan, length) { |
- |
- // Smoothing constant time is 0.05 second. |
- var smoothingConstant = 1 - Math.exp(-1 / (sampleRate * 0.05)); |
- |
- var inputL = input.getChannelData(0); |
- var inputR = input.getChannelData(1); |
- var pan = startPan; |
- var outputL = [], outputR = []; |
- |
- for (var i = 0; i < length; i++) { |
- var samples = panStereoEqualPower(pan, inputL[i], inputR[i]); |
- outputL[i] = samples[0]; |
- outputR[i] = samples[1]; |
- pan += (endPan - pan) * smoothingConstant; |
+ return output; |
} |
- return { |
- left: outputL, |
- right: outputR |
- }; |
- } |
- |
- // Build audio graph and render. Change the pan parameter in the middle of |
- // rendering. |
- function panAndVerify(should, options) { |
- var context = new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); |
- var source = context.createBufferSource(); |
- var panner = context.createStereoPanner(); |
- var stereoBuffer = createConstantBuffer(context, renderDuration * sampleRate, [1.0, 1.0]); |
- |
- source.buffer = stereoBuffer; |
- |
- panner.pan.value = options.startPanValue; |
- |
- source.connect(panner); |
- panner.connect(context.destination); |
- source.start(); |
- |
- // Schedule the parameter transition by the setter at 1/10 of the render |
- // duration. |
- context.suspend(0.1 * renderDuration).then(function () { |
- panner.pan.value = options.endPanValue; |
- context.resume(); |
- }); |
+ // Generate the expected result of stereo equal panning. |input| is an |
+ // AudioBuffer to be panned. |
+ function generateStereoEqualPanningResult( |
+ input, startPan, endPan, length) { |
+ // Smoothing constant time is 0.05 second. |
+ let smoothingConstant = 1 - Math.exp(-1 / (sampleRate * 0.05)); |
+ |
+ let inputL = input.getChannelData(0); |
+ let inputR = input.getChannelData(1); |
+ let pan = startPan; |
+ let outputL = [], outputR = []; |
+ |
+ for (let i = 0; i < length; i++) { |
+ let samples = panStereoEqualPower(pan, inputL[i], inputR[i]); |
+ outputL[i] = samples[0]; |
+ outputR[i] = samples[1]; |
+ pan += (endPan - pan) * smoothingConstant; |
+ } |
- return context.startRendering().then(function (buffer) { |
- var actual = extractPanningTransition(should, buffer, options.message); |
- var expected = generateStereoEqualPanningResult(stereoBuffer, |
- options.startPanValue, options.endPanValue, actual.length); |
+ return {left: outputL, right: outputR}; |
+ } |
- // |notGlitch| tests are redundant if the actual and expected results |
- // match and if the expected results themselves don't glitch. |
- should(actual.left, options.message + ': Channel #0').notGlitch(GLITCH_THRESHOLD); |
- should(actual.right, options.message + ': Channel #1').notGlitch(GLITCH_THRESHOLD); |
+ // Build audio graph and render. Change the pan parameter in the middle of |
+ // rendering. |
+ function panAndVerify(should, options) { |
+ let context = |
+ new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); |
+ let source = context.createBufferSource(); |
+ let panner = context.createStereoPanner(); |
+ let stereoBuffer = createConstantBuffer( |
+ context, renderDuration * sampleRate, [1.0, 1.0]); |
+ |
+ source.buffer = stereoBuffer; |
+ |
+ panner.pan.value = options.startPanValue; |
+ |
+ source.connect(panner); |
+ panner.connect(context.destination); |
+ source.start(); |
+ |
+ // Schedule the parameter transition by the setter at 1/10 of the render |
+ // duration. |
+ context.suspend(0.1 * renderDuration).then(function() { |
+ panner.pan.value = options.endPanValue; |
+ context.resume(); |
+ }); |
+ |
+ return context.startRendering().then(function(buffer) { |
+ let actual = |
+ extractPanningTransition(should, buffer, options.message); |
+ let expected = generateStereoEqualPanningResult( |
+ stereoBuffer, options.startPanValue, options.endPanValue, |
+ actual.length); |
+ |
+ // |notGlitch| tests are redundant if the actual and expected results |
+ // match and if the expected results themselves don't glitch. |
+ should(actual.left, options.message + ': Channel #0') |
+ .notGlitch(GLITCH_THRESHOLD); |
+ should(actual.right, options.message + ': Channel #1') |
+ .notGlitch(GLITCH_THRESHOLD); |
+ |
+ should(actual.left, options.message + ': Channel #0', SHOULD_OPTS) |
+ .beCloseToArray( |
+ expected.left, {absoluteThreshold: MAX_ERROR_ALLOWED}); |
+ should(actual.right, options.message + ': Channel #1', SHOULD_OPTS) |
+ .beCloseToArray( |
+ expected.right, {absoluteThreshold: MAX_ERROR_ALLOWED}); |
+ }); |
+ } |
- should(actual.left, options.message + ': Channel #0', SHOULD_OPTS) |
- .beCloseToArray(expected.left, {absoluteThreshold: MAX_ERROR_ALLOWED}); |
- should(actual.right, options.message + ': Channel #1', SHOULD_OPTS) |
- .beCloseToArray(expected.right, {absoluteThreshold: MAX_ERROR_ALLOWED}); |
+ // Task: move pan from negative (-0.1) to positive (0.1) value to check if |
+ // there is a glitch during the transition. See crbug.com/470559. |
+ audit.define('negative-to-positive', (task, should) => { |
+ panAndVerify( |
+ should, {startPanValue: -0.1, endPanValue: 0.1, message: 'L->R'}) |
+ .then(() => task.done()); |
}); |
- } |
- // Task: move pan from negative (-0.1) to positive (0.1) value to check if |
- // there is a glitch during the transition. See crbug.com/470559. |
- audit.define('negative-to-positive', (task, should) => { |
- panAndVerify(should, { startPanValue: -0.1, endPanValue: 0.1, message: "L->R" }) |
- .then(() => task.done()); |
- }); |
+ // Task: move pan from positive (0.1) to negative (-0.1) value to check if |
+ // there is a glitch during the transition. |
+ audit.define('positive-to-negative', (task, should) => { |
+ panAndVerify( |
+ should, {startPanValue: 0.1, endPanValue: -0.1, message: 'R->L'}) |
+ .then(() => task.done()); |
+ }); |
- // Task: move pan from positive (0.1) to negative (-0.1) value to check if |
- // there is a glitch during the transition. |
- audit.define('positive-to-negative', (task, should) => { |
- panAndVerify(should, { startPanValue: 0.1, endPanValue: -0.1, message: "R->L" }) |
- .then(() => task.done()); |
- }); |
- |
- audit.run(); |
- </script> |
-</body> |
- |
+ audit.run(); |
+ </script> |
+ </body> |
</html> |