OLD | NEW |
---|---|
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
3 | 3 |
4 <head> | 4 <head> |
5 <script src="../resources/js-test.js"></script> | 5 <script src="../resources/js-test.js"></script> |
6 <script src="resources/compatibility.js"></script> | 6 <script src="resources/compatibility.js"></script> |
7 <script src="resources/audio-testing.js"></script> | 7 <script src="resources/audio-testing.js"></script> |
8 </head> | 8 </head> |
9 | 9 |
10 <body> | 10 <body> |
11 <script> | 11 <script> |
12 description('Test if StereoPannerNode producing glitches by crossing zero.') ; | 12 description('Test if StereoPannerNode producing glitches by crossing zero.') ; |
13 window.jsTestIsAsync = true; | 13 window.jsTestIsAsync = true; |
14 | 14 |
15 var audit = Audit.createTaskRunner(); | |
16 | |
17 var sampleRate = 44100; | 15 var sampleRate = 44100; |
18 | 16 var renderDuration = 0.5; |
19 // Note that this layout test requires rather large render duration because | |
20 // we need enough time to do something useful in the |onstatechange| event | |
21 // before rendering finishes. | |
22 var renderDuration = 20; | |
23 | 17 |
24 // The threshold for glitch detection. This was experimentally determined. | 18 // The threshold for glitch detection. This was experimentally determined. |
25 var GLITCH_THRESHOLD = 0.0005; | 19 var GLITCH_THRESHOLD = 0.0005; |
26 | 20 |
27 // The maximum threshold for the error between the actual and the expected | 21 // The maximum threshold for the error between the actual and the expected |
28 // sample values. Experimentally determined. | 22 // sample values. Experimentally determined. |
29 var MAX_ERROR_ALLOWED = 0.0000001; | 23 var MAX_ERROR_ALLOWED = 0.0000001; |
30 | 24 |
31 // Option for |Should| test util. The number of array elements to be printed | 25 // Option for |Should| test util. The number of array elements to be printed |
32 // out is arbitrary. | 26 // out is arbitrary. |
33 var SHOULD_OPTS = { | 27 var SHOULD_OPTS = { |
34 numberOfArrayLog: 2 | 28 numberOfArrayLog: 2 |
35 }; | 29 }; |
36 | 30 |
31 var audit = Audit.createTaskRunner(); | |
37 | 32 |
38 // Extract a transitional region from the AudioBuffer. If no transition | 33 // Extract a transitional region from the AudioBuffer. If no transition |
39 // found, fail this test. | 34 // found, fail this test. |
40 function extractPanningTransition(input) { | 35 function extractPanningTransition(input) { |
41 var chanL = input.getChannelData(0); | 36 var chanL = input.getChannelData(0); |
42 var chanR = input.getChannelData(1); | 37 var chanR = input.getChannelData(1); |
43 var start, end; | 38 var start, end; |
44 var index = 1; | 39 var index = 1; |
45 | 40 |
46 // Find transition by comparing two consecutive samples. If two consecutiv e | 41 // Find transition by comparing two consecutive samples. If two consecutiv e |
47 // samples are identical, the transition has not started. | 42 // samples are identical, the transition has not started. |
48 while (chanL[index-1] === chanL[index] || chanR[index-1] === chanR[index]) { | 43 while (chanL[index-1] === chanL[index] || chanR[index-1] === chanR[index]) { |
49 if (++index >= input.length) { | 44 if (++index >= input.length) { |
50 testFailed('No transition found in the channel data.'); | 45 testFailed('No transition found in the channel data.'); |
51 return null; | 46 return null; |
52 } | 47 } |
53 } | 48 } |
54 start = index - 1; | 49 start = index - 1; |
55 | 50 |
56 // Find the end of transition. If two consecutive samples are not equal, | 51 // Find the end of transition. If two consecutive samples are not equal, |
57 // the transition is still ongoing. | 52 // the transition is still ongoing. |
58 while (chanL[index-1] !== chanL[index] || chanR[index-1] !== chanR[index]) { | 53 while (chanL[index-1] !== chanL[index] || chanR[index-1] !== chanR[index]) { |
59 if (++index >= input.length) { | 54 if (++index >= input.length) { |
60 testFailed('A transition found but the buffer ended prematurely.'); | 55 testFailed('A transition found but the buffer ended prematurely.'); |
61 return null; | 56 return null; |
62 } | 57 } |
63 } | 58 } |
64 end = index; | 59 end = index; |
65 | 60 |
66 testPassed('Transition found. (length = ' + (end - start) + ')'); | 61 testPassed('Transition found between sample #' + start + ' and #' + end + '.'); |
Raymond Toy
2015/12/02 19:33:41
I know this isn't part of this CL, but is there an
hongchan
2015/12/03 19:28:31
1. This extractPanningTransition() method is actua
Raymond Toy
2015/12/03 19:50:54
Well, the test always passes so it seems not reall
| |
67 | 62 |
68 return { | 63 return { |
69 left: chanL.subarray(start, end), | 64 left: chanL.subarray(start, end), |
70 right: chanR.subarray(start, end), | 65 right: chanR.subarray(start, end), |
71 length: end - start | 66 length: end - start |
72 }; | 67 }; |
73 } | 68 } |
74 | 69 |
75 // JS implementation of stereo equal power panning. | 70 // JS implementation of stereo equal power panning. |
76 function panStereoEqualPower(pan, inputL, inputR) { | 71 function panStereoEqualPower(pan, inputL, inputR) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 outputR[i] = samples[1]; | 109 outputR[i] = samples[1]; |
115 pan += (endPan - pan) * smoothingConstant; | 110 pan += (endPan - pan) * smoothingConstant; |
116 } | 111 } |
117 | 112 |
118 return { | 113 return { |
119 left: outputL, | 114 left: outputL, |
120 right: outputR | 115 right: outputR |
121 }; | 116 }; |
122 } | 117 } |
123 | 118 |
124 | 119 // Build audio graph and render. Change the pan parameter in the middle of |
120 // rendering. | |
125 function panAndVerify(options, done) { | 121 function panAndVerify(options, done) { |
126 var context = new OfflineAudioContext(2, 44100 * renderDuration, 44100); | 122 var context = new OfflineAudioContext(2, renderDuration * sampleRate, samp leRate); |
127 var source = context.createBufferSource(); | 123 var source = context.createBufferSource(); |
128 var panner = context.createStereoPanner(); | 124 var panner = context.createStereoPanner(); |
129 var stereoBuffer = createConstantBuffer(context, 128, [1.0, 1.0]); | 125 var stereoBuffer = createConstantBuffer(context, renderDuration * sampleRa te, [1.0, 1.0]); |
130 | 126 |
131 source.buffer = stereoBuffer; | 127 source.buffer = stereoBuffer; |
132 source.loop = true; | |
133 | 128 |
134 panner.pan.value = options.startPanValue; | 129 panner.pan.value = options.startPanValue; |
135 | 130 |
136 source.connect(panner); | 131 source.connect(panner); |
137 panner.connect(context.destination); | 132 panner.connect(context.destination); |
138 source.start(); | 133 source.start(); |
139 | 134 |
140 context.onstatechange = function () { | 135 // Schedule the parameter transition by the setter at 1/10 of the render |
141 if (context.state === 'running') | 136 // duration. |
142 panner.pan.value = options.endPanValue; | 137 context.suspend(0.1 * renderDuration).then(function () { |
143 }; | 138 panner.pan.value = options.endPanValue; |
139 context.resume(); | |
140 }); | |
144 | 141 |
145 context.startRendering().then(function (buffer) { | 142 context.startRendering().then(function (buffer) { |
146 var actual = extractPanningTransition(buffer); | 143 var actual = extractPanningTransition(buffer); |
147 var expected = generateStereoEqualPanningResult(stereoBuffer, | 144 var expected = generateStereoEqualPanningResult(stereoBuffer, |
148 options.startPanValue, options.endPanValue, actual.length); | 145 options.startPanValue, options.endPanValue, actual.length); |
149 | 146 |
150 // |notGlitch| tests are redundant if the actual and expected results | 147 // |notGlitch| tests are redundant if the actual and expected results |
151 // match and if the expected results themselves don't glitch. | 148 // match and if the expected results themselves don't glitch. |
152 Should('Channel #0', actual.left).notGlitch(GLITCH_THRESHOLD); | 149 Should('Channel #0', actual.left).notGlitch(GLITCH_THRESHOLD); |
153 Should('Channel #1', actual.right).notGlitch(GLITCH_THRESHOLD); | 150 Should('Channel #1', actual.right).notGlitch(GLITCH_THRESHOLD); |
(...skipping 27 matching lines...) Expand all Loading... | |
181 'negative-to-positive', | 178 'negative-to-positive', |
182 'positive-to-negative', | 179 'positive-to-negative', |
183 'finish-test' | 180 'finish-test' |
184 ); | 181 ); |
185 | 182 |
186 successfullyParsed = true; | 183 successfullyParsed = true; |
187 </script> | 184 </script> |
188 </body> | 185 </body> |
189 | 186 |
190 </html> | 187 </html> |
OLD | NEW |