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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/panner-automation-basic.html

Issue 1820403002: Implement Automations for PannerNode and AutioListener (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update test because CL for min/maxValue AudioParam landed Created 4 years, 7 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 <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 PannerNode with Automation Position Properties</title>
9 </head>
10
11 <body>
12 <script>
13 description("Test Basic PannerNode with Automation Position 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 // Array of tests for setting the panner positions. These tests basically verify that the
26 // position setters for the panner and listener are working correctly.
27 var testConfig = [{
28 setter: "positionX",
29 }, {
30 setter: "positionY",
31 }, {
32 setter: "positionZ",
33 }];
34
35 // Create tests for the panner position setters. Both mono and steroe sou rces are tested.
36 for (var k = 0; k < testConfig.length; ++k) {
37 var config = testConfig[k];
38 // Function to create the test to define the test.
39 var tester = function (config, channelCount) {
40 return function (done) {
41 var nodes = createGraph(channelCount);
42 var {context, source, panner} = nodes;
43
44 var message = channelCount == 1 ? "Mono" : "Stereo";
45 message += " panner." + config.setter;
46
47 testPositionSetter({
48 nodes: nodes,
49 pannerSetter: panner[config.setter],
50 message: message
51 }).then(done);
52 }
53 }
54
55 audit.defineTask("Stereo panner." + config.setter, tester(config, 2));
56 audit.defineTask("Mono panner." + config.setter, tester(config, 1));
57 }
58
59 // Create tests for the listener position setters. Both mono and steroe s ources are tested.
60 for (var k = 0; k < testConfig.length; ++k) {
61 var config = testConfig[k];
62 // Function to create the test to define the test.
63 var tester = function (config, channelCount) {
64 return function (done) {
65 var nodes = createGraph(channelCount);
66 var {context, source, panner} = nodes;
67
68 var message = channelCount == 1 ? "Mono" : "Stereo";
69 message += " listener." + config.setter;
70
71 // Some relatively arbitrary (non-default) position for the source l ocation.
72 panner.setPosition(1,0,1);
73
74 testPositionSetter({
75 nodes: nodes,
76 pannerSetter: context.listener[config.setter],
77 message: message
78 }).then(done);
79 }
80 }
81
82 audit.defineTask("Stereo listener." + config.setter, tester(config, 2));
83 audit.defineTask("Mono listener." + config.setter, tester(config, 1));
84 }
85
86 // Test setPosition method.
87 audit.defineTask("setPosition", function (done) {
88 var {context, panner, source} = createGraph(2);
89
90 // Initialize source position (values don't really matter).
91 panner.setPosition(1,1,1);
92
93 // After some (unimportant) time, move the panner to a (any) new locatio n.
94 var suspendFrame = 128;
95 context.suspend(suspendFrame / sampleRate).then(function () {
96 panner.setPosition(-100, 2000, 8000);
97 }).then(context.resume.bind(context));
98
99 context.startRendering().then(function (resultBuffer) {
100 verifyPannerOutputChanged(resultBuffer, {message: "setPosition", suspe ndFrame: suspendFrame});
101 }).then(done);
102 });
103
104 audit.defineTask("orientation setter", function (done) {
105 var {context, panner, source} = createGraph(2);
106
107 // For orientation to matter, we need to make the source directional, an d also move away
108 // from the listener (because the default location is 0,0,0).
109 panner.setPosition(0,0,1);
110 panner.coneInnerAngle = 0;
111 panner.coneOuterAngle = 360;
112 panner.coneOuterGain = .001;
113
114 // After some (unimportant) time, change the panner orientation to a new orientation. The
115 // only constraint is that the orientation changes from before.
116 var suspendFrame = 128;
117 context.suspend(suspendFrame / sampleRate).then(function () {
118 panner.orientationX.value = -100;
119 panner.orientationY.value = 2000;
120 panner.orientationZ.value = 8000;
121 }).then(context.resume.bind(context));
122
123 context.startRendering().then(function (resultBuffer) {
124 verifyPannerOutputChanged(resultBuffer, {message: "panner.orientation{ XYZ}", suspendFrame: suspendFrame});
125 }).then(done);
126 });
127
128 audit.defineTask("forward setter", function (done) {
129 var {context, panner, source} = createGraph(2);
130
131 // For orientation to matter, we need to make the source directional, an d also move away
132 // from the listener (because the default location is 0,0,0).
133 panner.setPosition(0,0,1);
134 panner.coneInnerAngle = 0;
135 panner.coneOuterAngle = 360;
136 panner.coneOuterGain = .001;
137
138 // After some (unimportant) time, change the panner orientation to a new orientation. The
139 // only constraint is that the orientation changes from before.
140 var suspendFrame = 128;
141 context.suspend(suspendFrame / sampleRate).then(function () {
142 context.listener.forwardX.value = -100;
143 context.listener.forwardY.value = 2000;
144 context.listener.forwardZ.value = 8000;
145 }).then(context.resume.bind(context));
146
147 context.startRendering().then(function (resultBuffer) {
148 verifyPannerOutputChanged(resultBuffer, {message: "listener.forward{XY Z}", suspendFrame: suspendFrame});
149 }).then(done);
150 });
151
152 audit.defineTask("up setter", function (done) {
153 var {context, panner, source} = createGraph(2);
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 panner.setPosition(1,0,1);
162
163 // After some (unimportant) time, change the panner orientation to a new orientation. The
164 // only constraint is that the orientation changes from before.
165 var suspendFrame = 128;
166 context.suspend(suspendFrame / sampleRate).then(function () {
167 context.listener.upX.value = 100;
168 context.listener.upY.value = 100;
169 context.listener.upZ.value = 100;;
170 }).then(context.resume.bind(context));
171
172 context.startRendering().then(function (resultBuffer) {
173 verifyPannerOutputChanged(resultBuffer, {message: "listener.up{XYZ}", suspendFrame: suspendFrame});
174 }).then(done);
175 });
176
177 audit.defineTask("finish", function (done) {
178 finishJSTest();
179 done();
180 });
181
182 audit.runTasks();
183
184 function createGraph(channelCount) {
185 var context = new OfflineAudioContext(2, renderFrames, sampleRate);
186 var panner = context.createPanner();
187 var source = context.createBufferSource();
188 source.buffer = createConstantBuffer(context, 1, channelCount == 1 ? 1 : [1, 2]);
189 source.loop = true;
190
191 source.connect(panner);
192 panner.connect(context.destination);
193
194 source.start();
195 return {
196 context: context,
197 source: source,
198 panner: panner
199 };
200 }
201
202 function testPositionSetter(options) {
203 var {nodes, pannerSetter, message} = options;
204
205 var {context, source, panner} = nodes;
206
207 // Set panner x position. (Value doesn't matter);
208 pannerSetter.value = 1;
209
210 // Wait a bit and set a new position. (Actual time and position doesn't matter).
211 var suspendFrame = 128;
212 context.suspend(suspendFrame / sampleRate).then(function () {
213 pannerSetter.value = 10000;
214 }).then(context.resume.bind(context));
215
216 return context.startRendering().then(function (resultBuffer) {
217 verifyPannerOutputChanged(resultBuffer, {message: message, suspendFram e: suspendFrame});
218 });
219 }
220
221 function verifyPannerOutputChanged(resultBuffer, options) {
222 var {message, suspendFrame} = options;
223 // Verify that the first part of output is constant. (Doesn't matter w hat.)
224 var success = true;
225 var data0 = resultBuffer.getChannelData(0);
226 var data1 = resultBuffer.getChannelData(1);
227
228 var middle = "[0, " + suspendFrame + ") ";
229 success = Should(message + ".value frame " + middle + "channel 0", dat a0.slice(0, suspendFrame))
230 .beConstantValueOf(data0[0]) && success;
231 success = Should(message + ".value frame " + middle + "channel 1", dat a1.slice(0, suspendFrame))
232 .beConstantValueOf(data1[0]) && success;
233
234 // The rest after suspendTime should be constant and different from th e first part.
235 middle = "[" + suspendFrame + ", " + renderFrames + ") ";
236 success = Should(message + ".value frame " + middle + "channel 0",
237 data0.slice(suspendFrame))
238 .beConstantValueOf(data0[suspendFrame]) && success;
239 success = Should(message + ".value frame " + middle + "channel 0",
240 data1.slice(suspendFrame))
241 .beConstantValueOf(data1[suspendFrame]) && success;
242 success = Should("Output at frame " + suspendFrame + " channel 0", dat a0[suspendFrame])
243 .notBeEqualTo(data0[0]) && success;
244 success = Should("Output at frame " + suspendFrame + " channel 1", dat a1[suspendFrame])
245 .notBeEqualTo(data1[0]) && success;
246
247 var prefix = "Directly setting " + message + ".value";
248 if (success)
249 testPassed(prefix + " worked.\n");
250 else
251 testFailed(prefix + " failed.\n");
252 }
253 </script>
254 </body>
255 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698