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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/mixing-rules.js

Issue 1773973002: Complete the implementation of up/down-mixing rules for AudioNode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing Feedback (1) Created 4 years, 9 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 // Utilities for mixing rule testing.
2 // http://webaudio.github.io/web-audio-api/#channel-up-mixing-and-down-mixing
3
4
5 /**
6 * Create an n-channel buffer, with all sample data zero except for a shifted
7 * impulse. The impulse position depends on the channel index. For example, for
8 * a 4-channel buffer:
9 * channel 0: 1 0 0 0 0 0 0 0
10 * channel 1: 0 1 0 0 0 0 0 0
11 * channel 2: 0 0 1 0 0 0 0 0
12 * channel 3: 0 0 0 1 0 0 0 0
13 * @param {AudioContext} context Associated AudioContext.
14 * @param {Number} numberOfChannels Number of channels of test buffer.
15 * @param {Number} frameLength Buffer length in frames.
16 * @return {AudioBuffer}
17 */
18 function createShiftedImpulseBuffer(context, numberOfChannels, frameLength) {
19 var shiftedImpulseBuffer = context.createBuffer(numberOfChannels, frameLengt h, context.sampleRate);
20 for (var channel = 0; channel < numberOfChannels; ++channel) {
21 var data = shiftedImpulseBuffer.getChannelData(channel);
22 data[channel] = 1;
23 }
24
25 return shiftedImpulseBuffer;
26 }
27
28 /**
29 * Create a string displays the content of AudioBuffer.
Raymond Toy 2016/03/09 22:14:19 "string displays" -> "string that displays"
hongchan 2016/03/09 23:26:11 Done.
30 * @param {AudioBuffer} audioBuffer AudioBuffer object to stringify.
31 * @param {Number} frameLength Number of frames to be printed.
32 * @param {Number} frameOffset Starting frame position for printing.
33 * @return {String}
34 */
35 function stringifyBuffer(audioBuffer, frameLength, frameOffset) {
36 frameOffset = (frameOffset || 0);
37
38 var stringifiedBuffer = '';
39 for (var channel = 0; channel < audioBuffer.numberOfChannels; ++channel) {
40 var channelData = audioBuffer.getChannelData(channel);
41 for (var i = 0; i < frameLength; ++i)
42 stringifiedBuffer += channelData[i + frameOffset] + ' ';
43 stringifiedBuffer += '\n';
44 }
45
46 return stringifiedBuffer;
47 }
48
49 /**
50 * Compute number of channels from the connection.
51 * @param {String} connections A string specifies the connection. For
52 * example, the string "128" means 3
53 * connections, having 1, 2, and 8 channels
54 * respectively.
55 * @param {Number} channelCount Channel count.
56 * @param {String} channelCountMode Channel count mode.
57 * @return {Number} Computed number of channels.
58 */
59 function computeNumberOfChannels(connections, channelCount, channelCountMode) {
60 if (channelCountMode == "explicit")
61 return channelCount;
62
63 // Must have at least one channel.
64 var computedNumberOfChannels = 1;
65
66 // Compute "computedNumberOfChannels" based on all the connections.
67 for (var i = 0; i < connections.length; ++i) {
68 var connectionNumberOfChannels = parseInt(connections[i]);
69 computedNumberOfChannels = Math.max(computedNumberOfChannels, connectionNumb erOfChannels);
70 }
71
72 if (channelCountMode == "clamped-max")
73 computedNumberOfChannels = Math.min(computedNumberOfChannels, channelCount);
74
75 return computedNumberOfChannels;
76 }
77
78 /**
79 * Apply up/down-mixing (in-place summing) based on 'speaker' interpretation.
80 * @param {AudioBuffer} input Input audio buffer.
81 * @param {AudioBuffer} output Output audio buffer.
82 */
83 function speakersSum(input, output) {
84 if (input.length != output.length) {
85 throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
86 + input.length + ', output: ' + output.length + ')';
87 }
88
89 if (input.numberOfChannels === output.numberOfChannels) {
90 for (var channel = 0; channel < output.numberOfChannels; ++channel) {
91 var inputChannel = input.getChannelData(channel);
92 var outputChannel = output.getChannelData(channel);
93 for (var i = 0; i < outputChannel.length; i++)
94 outputChannel[i] += inputChannel[i];
95 }
96 } else if (input.numberOfChannels < output.numberOfChannels) {
97 processUpMix(input, output);
98 } else {
99 processDownMix(input, output);
100 }
101 }
102
103 /**
104 * In-place summing to |output| based on 'discrete' channel interpretation.
105 * @param {AudioBuffer} input Input audio buffer.
106 * @param {AudioBuffer} output Output audio buffer.
107 */
108 function discreteSum(input, output) {
109 if (input.length != output.length) {
110 throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
111 + input.length + ', output: ' + output.length + ')';
112 }
113
114 var numberOfChannels = Math.min(input.numberOfChannels, output.numberOfChannel s)
115
116 for (var channel = 0; channel < numberOfChannels; ++channel) {
117 var inputChannel = input.getChannelData(channel);
118 var outputChannel = output.getChannelData(channel);
119 for (var i = 0; i < outputChannel.length; i++)
120 outputChannel[i] += inputChannel[i];
121 }
122 }
123
124 /**
125 * Perform up-mix by in-place summing to |output| buffer.
Raymond Toy 2016/03/09 22:14:19 For consistency, you probably want to add this com
hongchan 2016/03/09 23:26:11 Done.
126 * @param {AudioBuffer} input Input audio buffer.
127 * @param {AudioBuffer} output Output audio buffer.
128 */
129 function processUpMix(input, output) {
130 var numberOfInputChannels = input.numberOfChannels;
131 var numberOfOutputChannels = output.numberOfChannels;
132 var i, length = output.length;
133
134 // Up-mixing: 1 -> 2, 1 -> 4
135 // output.L += input
136 // output.R += input
137 // output.SL += 0 (in the case of 1 -> 4)
138 // output.SR += 0 (in the case of 1 -> 4)
139 if ((numberOfInputChannels === 1 && numberOfOutputChannels === 2) ||
140 (numberOfInputChannels === 1 && numberOfOutputChannels === 4)) {
141 var inputChannel = input.getChannelData(0);
142 var outputChannel0 = output.getChannelData(0);
143 var outputChannel1 = output.getChannelData(1);
144 for (i = 0; i < length; i++) {
145 outputChannel0[i] += inputChannel[i];
146 outputChannel1[i] += inputChannel[i];
147 }
148
149 return;
150 }
151
152 // Up-mixing: 1 -> 5.1
153 // output.L += 0
154 // output.R += 0
155 // output.C += input
156 // output.LFE += 0
157 // output.SL += 0
158 // output.SR += 0
159 if (numberOfInputChannels == 1 && numberOfOutputChannels == 6) {
160 var inputChannel = input.getChannelData(0);
161 var outputChannel2 = output.getChannelData(2);
162 for (i = 0; i < length; i++)
163 outputChannel2[i] += inputChannel[i];
164
165 return;
166 }
167
168 // Up-mixing: 2 -> 4, 2 -> 5.1
169 // output.L += input.L
170 // output.R += input.R
171 // output.C += 0 (in the case of 2 -> 5.1)
172 // output.LFE += 0 (in the case of 2 -> 5.1)
173 // output.SL += 0
174 // output.SR += 0
175 if ((numberOfInputChannels === 2 && numberOfOutputChannels === 4) ||
176 (numberOfInputChannels === 2 && numberOfOutputChannels === 6)) {
177 var inputChannel0 = input.getChannelData(0);
178 var inputChannel1 = input.getChannelData(1);
179 var outputChannel0 = output.getChannelData(0);
180 var outputChannel1 = output.getChannelData(1);
181 for (i = 0; i < length; i++) {
182 outputChannel0[i] += inputChannel0[i];
183 outputChannel1[i] += inputChannel1[i];
184 }
185
186 return;
187 }
188
189 // Up-mixing: 4 -> 5.1
190 // output.L += input.L
191 // output.R += input.R
192 // output.C += 0
193 // output.LFE += 0
194 // output.SL += input.SL
195 // output.SR += input.SR
196 if (numberOfInputChannels === 4 && numberOfOutputChannels === 6) {
197 var inputChannel0 = input.getChannelData(0); // input.L
198 var inputChannel1 = input.getChannelData(1); // input.R
199 var inputChannel2 = input.getChannelData(2); // input.SL
200 var inputChannel3 = input.getChannelData(3); // input.SR
201 var outputChannel0 = output.getChannelData(0); // output.L
202 var outputChannel1 = output.getChannelData(1); // output.R
203 var outputChannel4 = output.getChannelData(4); // output.SL
204 var outputChannel5 = output.getChannelData(5); // output.SR
205 for (i = 0; i < length; i++) {
206 outputChannel0[i] += inputChannel0[i];
207 outputChannel1[i] += inputChannel1[i];
208 outputChannel4[i] += inputChannel2[i];
209 outputChannel5[i] += inputChannel3[i];
210 }
211
212 return;
213 }
214
215 // All other cases, fall back to the discrete sum.
216 discreteSum(input, output);
217 }
218
219 /**
220 * Process down-mix from source to destination by summing into the existing data .
221 * @param {AudioBuffer} input Input audio buffer.
222 * @param {AudioBuffer} output Output audio buffer.
223 */
224 function processDownMix(input, output) {
225 var numberOfInputChannels = input.numberOfChannels;
226 var numberOfOutputChannels = output.numberOfChannels;
227 var i, length = output.length;
228
229 // Down-mixing: 2 -> 1
230 // output += 0.5 * (input.L + input.R)
231 if (numberOfInputChannels === 2 && numberOfOutputChannels === 1) {
232 var inputChannel0 = input.getChannelData(0); // input.L
233 var inputChannel1 = input.getChannelData(1); // input.R
234 var outputChannel0 = output.getChannelData(0);
235 for (i = 0; i < length; i++)
236 outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel1[i]);
237
238 return;
239 }
240
241 // Down-mixing: 4 -> 1
242 // output += 0.25 * (input.L + input.R + input.SL + input.SR)
243 if (numberOfInputChannels === 4 && numberOfOutputChannels === 1) {
244 var inputChannel0 = input.getChannelData(0); // input.L
245 var inputChannel1 = input.getChannelData(1); // input.R
246 var inputChannel2 = input.getChannelData(2); // input.SL
247 var inputChannel3 = input.getChannelData(3); // input.SR
248 var outputChannel0 = output.getChannelData(0);
249 for (i = 0; i < length; i++) {
250 outputChannel0[i] += 0.25 * (inputChannel0[i] + inputChannel1[i]
251 + inputChannel2[i] + inputChannel3[i]);
252 }
253
254 return;
255 }
256
257 // Down-mixing: 5.1 -> 1
258 // output += sqrt(1/2) * (input.L + input.R) + input.C
259 // + 0.5 * (input.SL + input.SR)
260 if (numberOfInputChannels === 6 && numberOfOutputChannels === 1) {
261 var inputChannel0 = input.getChannelData(0); // input.L
262 var inputChannel1 = input.getChannelData(1); // input.R
263 var inputChannel2 = input.getChannelData(2); // input.C
264 var inputChannel4 = input.getChannelData(4); // input.SL
265 var inputChannel5 = input.getChannelData(5); // input.SR
266 var outputChannel0 = output.getChannelData(0);
267 var scaleSqrtHalf = Math.sqrt(0.5);
268 for (i = 0; i < length; i++) {
269 outputChannel0[i] +=
270 scaleSqrtHalf * (inputChannel0[i] + inputChannel1[i])
271 + inputChannel2[i] + 0.5 * (inputChannel4[i] + inputChannel5[i]);
272 }
273
274 return;
275 }
276
277 // Down-mixing: 4 -> 2
278 // output.L += 0.5 * (input.L + input.SL)
279 // output.R += 0.5 * (input.R + input.SR)
280 if (numberOfInputChannels == 4 && numberOfOutputChannels == 2) {
281 var inputChannel0 = input.getChannelData(0); // input.L
282 var inputChannel1 = input.getChannelData(1); // input.R
283 var inputChannel2 = input.getChannelData(2); // input.SL
284 var inputChannel3 = input.getChannelData(3); // input.SR
285 var outputChannel0 = output.getChannelData(0); // output.L
286 var outputChannel1 = output.getChannelData(1); // output.R
287 for (i = 0; i < length; i++) {
288 outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel2[i]);
289 outputChannel1[i] += 0.5 * (inputChannel1[i] + inputChannel3[i]);
290 }
291
292 return;
293 }
294
295 // Down-mixing: 5.1 -> 2
296 // output.L += input.L + sqrt(1/2) * (input.C + input.SL)
297 // output.R += input.R + sqrt(1/2) * (input.C + input.SR)
298 if (numberOfInputChannels == 6 && numberOfOutputChannels == 2) {
299 var inputChannel0 = input.getChannelData(0); // input.L
300 var inputChannel1 = input.getChannelData(1); // input.R
301 var inputChannel2 = input.getChannelData(2); // input.C
302 var inputChannel4 = input.getChannelData(4); // input.SL
303 var inputChannel5 = input.getChannelData(5); // input.SR
304 var outputChannel0 = output.getChannelData(0); // output.L
305 var outputChannel1 = output.getChannelData(1); // output.R
306 var scaleSqrtHalf = Math.sqrt(0.5);
307 for (i = 0; i < length; i++) {
308 outputChannel0[i] += inputChannel0[i]
309 + scaleSqrtHalf * (inputChannel2[i] + inputChannel4[i]);
310 outputChannel1[i] += inputChannel1[i]
311 + scaleSqrtHalf * (inputChannel2[i] + inputChannel5[i]);
312 }
313
314 return;
315 }
316
317 // Down-mixing: 5.1 -> 4
318 // output.L += input.L + sqrt(1/2) * input.C
319 // output.R += input.R + sqrt(1/2) * input.C
320 // output.SL += input.SL
321 // output.SR += input.SR
322 if (numberOfInputChannels === 6 && numberOfOutputChannels === 4) {
323 var inputChannel0 = input.getChannelData(0); // input.L
324 var inputChannel1 = input.getChannelData(1); // input.R
325 var inputChannel2 = input.getChannelData(2); // input.C
326 var inputChannel4 = input.getChannelData(4); // input.SL
327 var inputChannel5 = input.getChannelData(5); // input.SR
328 var outputChannel0 = output.getChannelData(0); // output.L
329 var outputChannel1 = output.getChannelData(1); // output.R
330 var outputChannel2 = output.getChannelData(2); // output.SL
331 var outputChannel3 = output.getChannelData(3); // output.SR
332 var scaleSqrtHalf = Math.sqrt(0.5);
333 for (i = 0; i < length; i++) {
334 outputChannel0[i] += inputChannel0[i] + scaleSqrtHalf * inputChannel2[i];
335 outputChannel1[i] += inputChannel1[i] + scaleSqrtHalf * inputChannel2[i];
336 outputChannel2[i] += inputChannel4[i];
337 outputChannel3[i] += inputChannel5[i];
338 }
339
340 return;
341 }
342
343 // All other cases, fall back to the discrete sum.
344 discreteSum(input, output);
345 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698