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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-1-chan.html

Issue 2732523003: Make ConvolverNode conform to spec (Closed)
Patch Set: Remove unneeded numberOfChannels parameter and simplify code Created 3 years, 8 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 <title>Test Convolver Channel Outputs for Response with 1 channel</title>
5 <script src="../../resources/testharness.js"></script>
6 <script src="../../resources/testharnessreport.js"></script>
7 <script src="../resources/audit-util.js"></script>
8 <script src="../resources/audit.js"></script>
9 </head>
10
11 <body>
12 <script>
13 // Test various convolver configurations when the convolver response has
14 // one channel (mono).
15 //
16 // Fairly arbitrary sample rate, except that we want the rate to be a
17 // power of two so that 1/sampleRate is exactly respresentable as a
18 // single-precision float.
19 let sampleRate = 8192;
20
21 // A fairly arbitrary number of frames, except the number of frames should
22 // be more than a few render quanta.
23 let renderFrames = 10 * 128;
24
25 let audit = Audit.createTaskRunner();
26
27 // Convolver response
28 let response;
29
30 audit.define(
31 {
32 label: 'initialize',
33 description: 'Convolver response with one channel'
34 },
35 (task, should) => {
36 // Convolver response
37 should(
38 () => {
39 response = new AudioBuffer(
40 {numberOfChannels: 1, length: 2, sampleRate: sampleRate});
41 response.getChannelData(0)[1] = 1;
42 },
43 'new AudioBuffer({numberOfChannels: 1, length: 2, sampleRate: ' +
44 sampleRate + '})')
45 .notThrow();
46
47 task.done();
48 });
49
50 audit.define(
51 {label: '1-channel input', description: 'produces 1-channel output'},
52 (task, should) => {
53 // Create a 3-channel context: channel 0 = convolver under test,
54 // channel 1: test that convolver output is not stereo, channel 2:
55 // expected output. The context MUST be discrete so that the
56 // channels don't get mixed in some unexpected way.
57 let context = new OfflineAudioContext(3, renderFrames, sampleRate);
58 context.destination.channelInterpretation = 'discrete';
59
60 let src = new OscillatorNode(context);
61 let conv = new ConvolverNode(
62 context, {disableNormalization: true, buffer: response});
63
64 // Splitter node to verify that the output of the convolver is mono.
65 // channelInterpretation must be 'discrete' so we don't do any
66 // mixing of the input to the node.
67 let splitter = new ChannelSplitterNode(
68 context,
69 {numberOfOutputs: 2, channelInterpretation: 'discrete'});
70
71 // Final merger to feed all of the individual channels into the
72 // destination.
73 let merger = new ChannelMergerNode(context, {numberOfInputs: 3});
74
75 src.connect(conv).connect(splitter);
76 splitter.connect(merger, 0, 0);
77 splitter.connect(merger, 1, 1);
78
79 // The convolver response is a 1-sample delay. Use a delay node to
80 // implement this.
81 let delay =
82 new DelayNode(context, {delayTime: 1 / context.sampleRate});
83 src.connect(delay);
84 delay.connect(merger, 0, 2);
85
86 merger.connect(context.destination);
87
88 src.start();
89
90 context.startRendering()
91 .then(audioBuffer => {
92 // Extract out the three channels
93 let actual = audioBuffer.getChannelData(0);
94 let c1 = audioBuffer.getChannelData(1);
95 let expected = audioBuffer.getChannelData(2);
96
97 // c1 is expected to be zero.
98 should(c1, '1: Channel 1').beConstantValueOf(0);
99
100 // The expected and actual results should be identical
101 should(actual, 'Convolver output').beEqualToArray(expected);
102 })
103 .then(() => task.done());
104 });
105
106 audit.define(
107 {label: '2-channel input', description: 'produces 2-channel output'},
108 (task, should) => {
109 downMixTest({numberOfInputs: 2, prefix: '2'}, should)
110 .then(() => task.done());
111 });
112
113 audit.define(
114 {
115 label: '3-channel input',
116 description: '3->2 downmix producing 2-channel output'
117 },
118 (task, should) => {
119 downMixTest({numberOfInputs: 3, prefix: '3'}, should)
120 .then(() => task.done());
121 });
122
123 audit.define(
124 {
125 label: '4-channel input',
126 description: '4->2 downmix producing 2-channel output'
127 },
128 (task, should) => {
129 downMixTest({numberOfInputs: 4, prefix: '4'}, should)
130 .then(() => task.done());
131 });
132
133 audit.define(
134 {
135 label: '5.1-channel input',
136 description: '5.1->2 downmix producing 2-channel output'
137 },
138 (task, should) => {
139 downMixTest({numberOfInputs: 6, prefix: '5.1'}, should)
140 .then(() => task.done());
141 });
142
143 function downMixTest(options, should) {
144 // Create an 4-channel offline context. The first two channels are for
145 // the stereo output of the convolver and the next two channels are for
146 // the reference stereo signal.
147 let context = new OfflineAudioContext(4, renderFrames, sampleRate);
148 context.destination.channelInterpretation = 'discrete';
149
150 // Create oscillators for use as the input. The type and frequency is
151 // arbitrary except that oscillators must be different.
152 let src = new Array(options.numberOfInputs);
153 for (let k = 0; k < src.length; ++k) {
154 src[k] = new OscillatorNode(
155 context, {type: 'square', frequency: 440 + 220 * k});
156 }
157
158 // Merger to combine the oscillators into one output stream.
159 let srcMerger =
160 new ChannelMergerNode(context, {numberOfInputs: src.length});
161
162 for (let k = 0; k < src.length; ++k) {
163 src[k].connect(srcMerger, 0, k);
164 }
165
166 // Convolver under test.
167 let conv = new ConvolverNode(
168 context, {disableNormalization: true, buffer: response});
169 srcMerger.connect(conv);
170
171 // Splitter to get individual channels of the convolver output so we can
172 // feed them (eventually) to the context in the right set of channels.
173 let splitter = new ChannelSplitterNode(context, {numberOfOutputs: 2});
174 conv.connect(splitter);
175
176 // Reference graph consists of a delay node to simulate the response of
177 // the convolver. (The convolver response is designed this way.)
178 let delay = new DelayNode(context, {delayTime: 1 / context.sampleRate});
179
180 // Gain node to mix the sources to stereo in the desired way. (Could be
181 // done in the delay node, but let's keep the mixing separated from the
182 // functionality.)
183 let gainMixer = new GainNode(
184 context, {channelCount: 2, channelCountMode: 'explicit'});
185 srcMerger.connect(gainMixer);
186
187 // Splitter to extract the channels of the reference signal.
188 let refSplitter =
189 new ChannelSplitterNode(context, {numberOfOutputs: 2});
190 gainMixer.connect(delay).connect(refSplitter);
191
192 // Final merger to bring back the individual channels from the convolver
193 // and the reference in the right order for the destination.
194 let finalMerger = new ChannelMergerNode(
195 context, {numberOfInputs: context.destination.channelCount});
196
197 // First two channels are for the convolver output, and the next two are
198 // for the reference.
199 splitter.connect(finalMerger, 0, 0);
200 splitter.connect(finalMerger, 1, 1);
201 refSplitter.connect(finalMerger, 0, 2);
202 refSplitter.connect(finalMerger, 1, 3);
203
204 finalMerger.connect(context.destination);
205
206 // Start the sources at last.
207 for (let k = 0; k < src.length; ++k) {
208 src[k].start();
209 }
210
211 return context.startRendering().then(audioBuffer => {
212 // Extract the various channels out
213 let actual0 = audioBuffer.getChannelData(0);
214 let actual1 = audioBuffer.getChannelData(1);
215 let expected0 = audioBuffer.getChannelData(2);
216 let expected1 = audioBuffer.getChannelData(3);
217
218 // Verify that each output channel of the convolver matches
219 // the delayed signal from the reference
220 should(actual0, options.prefix + ': Channel 0')
221 .beEqualToArray(expected0);
222 should(actual1, options.prefix + ': Channel 1')
223 .beEqualToArray(expected1);
224 });
225 }
226
227 audit.run();
228 </script>
229 </body>
230 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698