Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(770)

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch.html

Issue 2581463002: Refactor WebAudio test directory (Closed)
Patch Set: Use correct path for wav result files Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!DOCTYPE html>
2 <html>
3
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 </head>
10
11 <body>
12 <script>
13 description('Test if StereoPannerNode producing glitches by crossing zero.') ;
14 window.jsTestIsAsync = true;
15
16 var sampleRate = 44100;
17 var renderDuration = 0.5;
18
19 // The threshold for glitch detection. This was experimentally determined.
20 var GLITCH_THRESHOLD = 0.0005;
21
22 // The maximum threshold for the error between the actual and the expected
23 // sample values. Experimentally determined.
24 var MAX_ERROR_ALLOWED = 0.0000001;
25
26 // Option for |Should| test util. The number of array elements to be printed
27 // out is arbitrary.
28 var SHOULD_OPTS = {
29 numberOfArrayLog: 2
30 };
31
32 var audit = Audit.createTaskRunner();
33
34 // Extract a transitional region from the AudioBuffer. If no transition
35 // found, fail this test.
36 function extractPanningTransition(input) {
37 var chanL = input.getChannelData(0);
38 var chanR = input.getChannelData(1);
39 var start, end;
40 var index = 1;
41
42 // Find transition by comparing two consecutive samples. If two consecutiv e
43 // samples are identical, the transition has not started.
44 while (chanL[index-1] === chanL[index] || chanR[index-1] === chanR[index]) {
45 if (++index >= input.length) {
46 testFailed('No transition found in the channel data.');
47 return null;
48 }
49 }
50 start = index - 1;
51
52 // Find the end of transition. If two consecutive samples are not equal,
53 // the transition is still ongoing.
54 while (chanL[index-1] !== chanL[index] || chanR[index-1] !== chanR[index]) {
55 if (++index >= input.length) {
56 testFailed('A transition found but the buffer ended prematurely.');
57 return null;
58 }
59 }
60 end = index;
61
62 testPassed('Transition found between sample #' + start + ' and #' + end + '.');
63
64 return {
65 left: chanL.subarray(start, end),
66 right: chanR.subarray(start, end),
67 length: end - start
68 };
69 }
70
71 // JS implementation of stereo equal power panning.
72 function panStereoEqualPower(pan, inputL, inputR) {
73 pan = Math.min(1.0, Math.max(-1.0, pan));
74 var output = [];
75 var panRadian;
76 if (!inputR) { // mono case.
77 panRadian = (pan * 0.5 + 0.5) * Math.PI / 2;
78 output[0] = inputL * Math.cos(panRadian);
79 output[1] = inputR * Math.sin(panRadian);
80 } else { // stereo case.
81 panRadian = (pan <= 0 ? pan + 1 : pan) * Math.PI / 2;
82 var gainL = Math.cos(panRadian);
83 var gainR = Math.sin(panRadian);
84 if (pan <= 0) {
85 output[0] = inputL + inputR * gainL;
86 output[1] = inputR * gainR;
87 } else {
88 output[0] = inputL * gainL;
89 output[1] = inputR + inputL * gainR;
90 }
91 }
92 return output;
93 }
94
95 // Generate the expected result of stereo equal panning. |input| is an
96 // AudioBuffer to be panned.
97 function generateStereoEqualPanningResult(input, startPan, endPan, length) {
98
99 // Smoothing constant time is 0.05 second.
100 var smoothingConstant = 1 - Math.exp(-1 / (sampleRate * 0.05));
101
102 var inputL = input.getChannelData(0);
103 var inputR = input.getChannelData(1);
104 var pan = startPan;
105 var outputL = [], outputR = [];
106
107 for (var i = 0; i < length; i++) {
108 var samples = panStereoEqualPower(pan, inputL[i], inputR[i]);
109 outputL[i] = samples[0];
110 outputR[i] = samples[1];
111 pan += (endPan - pan) * smoothingConstant;
112 }
113
114 return {
115 left: outputL,
116 right: outputR
117 };
118 }
119
120 // Build audio graph and render. Change the pan parameter in the middle of
121 // rendering.
122 function panAndVerify(options, done) {
123 var context = new OfflineAudioContext(2, renderDuration * sampleRate, samp leRate);
124 var source = context.createBufferSource();
125 var panner = context.createStereoPanner();
126 var stereoBuffer = createConstantBuffer(context, renderDuration * sampleRa te, [1.0, 1.0]);
127
128 source.buffer = stereoBuffer;
129
130 panner.pan.value = options.startPanValue;
131
132 source.connect(panner);
133 panner.connect(context.destination);
134 source.start();
135
136 // Schedule the parameter transition by the setter at 1/10 of the render
137 // duration.
138 context.suspend(0.1 * renderDuration).then(function () {
139 panner.pan.value = options.endPanValue;
140 context.resume();
141 });
142
143 context.startRendering().then(function (buffer) {
144 var actual = extractPanningTransition(buffer);
145 var expected = generateStereoEqualPanningResult(stereoBuffer,
146 options.startPanValue, options.endPanValue, actual.length);
147
148 // |notGlitch| tests are redundant if the actual and expected results
149 // match and if the expected results themselves don't glitch.
150 Should('Channel #0', actual.left).notGlitch(GLITCH_THRESHOLD);
151 Should('Channel #1', actual.right).notGlitch(GLITCH_THRESHOLD);
152
153 Should('Channel #0', actual.left, SHOULD_OPTS)
154 .beCloseToArray(expected.left, MAX_ERROR_ALLOWED);
155 Should('Channel #1', actual.right, SHOULD_OPTS)
156 .beCloseToArray(expected.right, MAX_ERROR_ALLOWED);
157 }).then(done);
158 }
159
160 // Task: move pan from negative (-0.1) to positive (0.1) value to check if
161 // there is a glitch during the transition. See crbug.com/470559.
162 audit.defineTask('negative-to-positive', function (done) {
163 panAndVerify({ startPanValue: -0.1, endPanValue: 0.1 }, done);
164 });
165
166
167 // Task: move pan from positive (0.1) to negative (-0.1) value to check if
168 // there is a glitch during the transition.
169 audit.defineTask('positive-to-negative', function (done) {
170 panAndVerify({ startPanValue: 0.1, endPanValue: -0.1 }, done);
171 });
172
173 audit.defineTask('finish-test', function (done) {
174 done();
175 finishJSTest();
176 });
177
178 audit.runTasks(
179 'negative-to-positive',
180 'positive-to-negative',
181 'finish-test'
182 );
183
184 successfullyParsed = true;
185 </script>
186 </body>
187
188 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698