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

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: Cleaning up and removing casting (after l-g-t-m) 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 that displays the content of AudioBuffer.
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 * http://webaudio.github.io/web-audio-api/#dfn-computednumberofchannels
52 * @param {String} connections A string specifies the connection. For
53 * example, the string "128" means 3
54 * connections, having 1, 2, and 8 channels
55 * respectively.
56 * @param {Number} channelCount Channel count.
57 * @param {String} channelCountMode Channel count mode.
58 * @return {Number} Computed number of channels.
59 */
60 function computeNumberOfChannels(connections, channelCount, channelCountMode) {
61 if (channelCountMode == "explicit")
62 return channelCount;
63
64 // Must have at least one channel.
65 var computedNumberOfChannels = 1;
66
67 // Compute "computedNumberOfChannels" based on all the connections.
68 for (var i = 0; i < connections.length; ++i) {
69 var connectionNumberOfChannels = parseInt(connections[i]);
70 computedNumberOfChannels = Math.max(computedNumberOfChannels, connectionNumb erOfChannels);
71 }
72
73 if (channelCountMode == "clamped-max")
74 computedNumberOfChannels = Math.min(computedNumberOfChannels, channelCount);
75
76 return computedNumberOfChannels;
77 }
78
79 /**
80 * Apply up/down-mixing (in-place summing) based on 'speaker' interpretation.
81 * @param {AudioBuffer} input Input audio buffer.
82 * @param {AudioBuffer} output Output audio buffer.
83 */
84 function speakersSum(input, output) {
85 if (input.length != output.length) {
86 throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
87 + input.length + ', output: ' + output.length + ')';
88 }
89
90 if (input.numberOfChannels === output.numberOfChannels) {
91 for (var channel = 0; channel < output.numberOfChannels; ++channel) {
92 var inputChannel = input.getChannelData(channel);
93 var outputChannel = output.getChannelData(channel);
94 for (var i = 0; i < outputChannel.length; i++)
95 outputChannel[i] += inputChannel[i];
96 }
97 } else if (input.numberOfChannels < output.numberOfChannels) {
98 processUpMix(input, output);
99 } else {
100 processDownMix(input, output);
101 }
102 }
103
104 /**
105 * In-place summing to |output| based on 'discrete' channel interpretation.
106 * @param {AudioBuffer} input Input audio buffer.
107 * @param {AudioBuffer} output Output audio buffer.
108 */
109 function discreteSum(input, output) {
110 if (input.length != output.length) {
111 throw '[mixing-rules.js] speakerSum(): buffer lengths mismatch (input: '
112 + input.length + ', output: ' + output.length + ')';
113 }
114
115 var numberOfChannels = Math.min(input.numberOfChannels, output.numberOfChannel s)
116
117 for (var channel = 0; channel < numberOfChannels; ++channel) {
118 var inputChannel = input.getChannelData(channel);
119 var outputChannel = output.getChannelData(channel);
120 for (var i = 0; i < outputChannel.length; i++)
121 outputChannel[i] += inputChannel[i];
122 }
123 }
124
125 /**
126 * Perform up-mix by in-place summing to |output| buffer.
127 * @param {AudioBuffer} input Input audio buffer.
128 * @param {AudioBuffer} output Output audio buffer.
129 */
130 function processUpMix(input, output) {
131 var numberOfInputChannels = input.numberOfChannels;
132 var numberOfOutputChannels = output.numberOfChannels;
133 var i, length = output.length;
134
135 // Up-mixing: 1 -> 2, 1 -> 4
136 // output.L += input
137 // output.R += input
138 // output.SL += 0 (in the case of 1 -> 4)
139 // output.SR += 0 (in the case of 1 -> 4)
140 if ((numberOfInputChannels === 1 && numberOfOutputChannels === 2) ||
141 (numberOfInputChannels === 1 && numberOfOutputChannels === 4)) {
142 var inputChannel = input.getChannelData(0);
143 var outputChannel0 = output.getChannelData(0);
144 var outputChannel1 = output.getChannelData(1);
145 for (i = 0; i < length; i++) {
146 outputChannel0[i] += inputChannel[i];
147 outputChannel1[i] += inputChannel[i];
148 }
149
150 return;
151 }
152
153 // Up-mixing: 1 -> 5.1
154 // output.L += 0
155 // output.R += 0
156 // output.C += input
157 // output.LFE += 0
158 // output.SL += 0
159 // output.SR += 0
160 if (numberOfInputChannels == 1 && numberOfOutputChannels == 6) {
161 var inputChannel = input.getChannelData(0);
162 var outputChannel2 = output.getChannelData(2);
163 for (i = 0; i < length; i++)
164 outputChannel2[i] += inputChannel[i];
165
166 return;
167 }
168
169 // Up-mixing: 2 -> 4, 2 -> 5.1
170 // output.L += input.L
171 // output.R += input.R
172 // output.C += 0 (in the case of 2 -> 5.1)
173 // output.LFE += 0 (in the case of 2 -> 5.1)
174 // output.SL += 0
175 // output.SR += 0
176 if ((numberOfInputChannels === 2 && numberOfOutputChannels === 4) ||
177 (numberOfInputChannels === 2 && numberOfOutputChannels === 6)) {
178 var inputChannel0 = input.getChannelData(0);
179 var inputChannel1 = input.getChannelData(1);
180 var outputChannel0 = output.getChannelData(0);
181 var outputChannel1 = output.getChannelData(1);
182 for (i = 0; i < length; i++) {
183 outputChannel0[i] += inputChannel0[i];
184 outputChannel1[i] += inputChannel1[i];
185 }
186
187 return;
188 }
189
190 // Up-mixing: 4 -> 5.1
191 // output.L += input.L
192 // output.R += input.R
193 // output.C += 0
194 // output.LFE += 0
195 // output.SL += input.SL
196 // output.SR += input.SR
197 if (numberOfInputChannels === 4 && numberOfOutputChannels === 6) {
198 var inputChannel0 = input.getChannelData(0); // input.L
199 var inputChannel1 = input.getChannelData(1); // input.R
200 var inputChannel2 = input.getChannelData(2); // input.SL
201 var inputChannel3 = input.getChannelData(3); // input.SR
202 var outputChannel0 = output.getChannelData(0); // output.L
203 var outputChannel1 = output.getChannelData(1); // output.R
204 var outputChannel4 = output.getChannelData(4); // output.SL
205 var outputChannel5 = output.getChannelData(5); // output.SR
206 for (i = 0; i < length; i++) {
207 outputChannel0[i] += inputChannel0[i];
208 outputChannel1[i] += inputChannel1[i];
209 outputChannel4[i] += inputChannel2[i];
210 outputChannel5[i] += inputChannel3[i];
211 }
212
213 return;
214 }
215
216 // All other cases, fall back to the discrete sum.
217 discreteSum(input, output);
218 }
219
220 /**
221 * Perform down-mix by in-place summing to |output| buffer.
222 * @param {AudioBuffer} input Input audio buffer.
223 * @param {AudioBuffer} output Output audio buffer.
224 */
225 function processDownMix(input, output) {
226 var numberOfInputChannels = input.numberOfChannels;
227 var numberOfOutputChannels = output.numberOfChannels;
228 var i, length = output.length;
229
230 // Down-mixing: 2 -> 1
231 // output += 0.5 * (input.L + input.R)
232 if (numberOfInputChannels === 2 && numberOfOutputChannels === 1) {
233 var inputChannel0 = input.getChannelData(0); // input.L
234 var inputChannel1 = input.getChannelData(1); // input.R
235 var outputChannel0 = output.getChannelData(0);
236 for (i = 0; i < length; i++)
237 outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel1[i]);
238
239 return;
240 }
241
242 // Down-mixing: 4 -> 1
243 // output += 0.25 * (input.L + input.R + input.SL + input.SR)
244 if (numberOfInputChannels === 4 && numberOfOutputChannels === 1) {
245 var inputChannel0 = input.getChannelData(0); // input.L
246 var inputChannel1 = input.getChannelData(1); // input.R
247 var inputChannel2 = input.getChannelData(2); // input.SL
248 var inputChannel3 = input.getChannelData(3); // input.SR
249 var outputChannel0 = output.getChannelData(0);
250 for (i = 0; i < length; i++) {
251 outputChannel0[i] += 0.25 * (inputChannel0[i] + inputChannel1[i]
252 + inputChannel2[i] + inputChannel3[i]);
253 }
254
255 return;
256 }
257
258 // Down-mixing: 5.1 -> 1
259 // output += sqrt(1/2) * (input.L + input.R) + input.C
260 // + 0.5 * (input.SL + input.SR)
261 if (numberOfInputChannels === 6 && numberOfOutputChannels === 1) {
262 var inputChannel0 = input.getChannelData(0); // input.L
263 var inputChannel1 = input.getChannelData(1); // input.R
264 var inputChannel2 = input.getChannelData(2); // input.C
265 var inputChannel4 = input.getChannelData(4); // input.SL
266 var inputChannel5 = input.getChannelData(5); // input.SR
267 var outputChannel0 = output.getChannelData(0);
268 var scaleSqrtHalf = Math.sqrt(0.5);
269 for (i = 0; i < length; i++) {
270 outputChannel0[i] +=
271 scaleSqrtHalf * (inputChannel0[i] + inputChannel1[i])
272 + inputChannel2[i] + 0.5 * (inputChannel4[i] + inputChannel5[i]);
273 }
274
275 return;
276 }
277
278 // Down-mixing: 4 -> 2
279 // output.L += 0.5 * (input.L + input.SL)
280 // output.R += 0.5 * (input.R + input.SR)
281 if (numberOfInputChannels == 4 && numberOfOutputChannels == 2) {
282 var inputChannel0 = input.getChannelData(0); // input.L
283 var inputChannel1 = input.getChannelData(1); // input.R
284 var inputChannel2 = input.getChannelData(2); // input.SL
285 var inputChannel3 = input.getChannelData(3); // input.SR
286 var outputChannel0 = output.getChannelData(0); // output.L
287 var outputChannel1 = output.getChannelData(1); // output.R
288 for (i = 0; i < length; i++) {
289 outputChannel0[i] += 0.5 * (inputChannel0[i] + inputChannel2[i]);
290 outputChannel1[i] += 0.5 * (inputChannel1[i] + inputChannel3[i]);
291 }
292
293 return;
294 }
295
296 // Down-mixing: 5.1 -> 2
297 // output.L += input.L + sqrt(1/2) * (input.C + input.SL)
298 // output.R += input.R + sqrt(1/2) * (input.C + input.SR)
299 if (numberOfInputChannels == 6 && numberOfOutputChannels == 2) {
300 var inputChannel0 = input.getChannelData(0); // input.L
301 var inputChannel1 = input.getChannelData(1); // input.R
302 var inputChannel2 = input.getChannelData(2); // input.C
303 var inputChannel4 = input.getChannelData(4); // input.SL
304 var inputChannel5 = input.getChannelData(5); // input.SR
305 var outputChannel0 = output.getChannelData(0); // output.L
306 var outputChannel1 = output.getChannelData(1); // output.R
307 var scaleSqrtHalf = Math.sqrt(0.5);
308 for (i = 0; i < length; i++) {
309 outputChannel0[i] += inputChannel0[i]
310 + scaleSqrtHalf * (inputChannel2[i] + inputChannel4[i]);
311 outputChannel1[i] += inputChannel1[i]
312 + scaleSqrtHalf * (inputChannel2[i] + inputChannel5[i]);
313 }
314
315 return;
316 }
317
318 // Down-mixing: 5.1 -> 4
319 // output.L += input.L + sqrt(1/2) * input.C
320 // output.R += input.R + sqrt(1/2) * input.C
321 // output.SL += input.SL
322 // output.SR += input.SR
323 if (numberOfInputChannels === 6 && numberOfOutputChannels === 4) {
324 var inputChannel0 = input.getChannelData(0); // input.L
325 var inputChannel1 = input.getChannelData(1); // input.R
326 var inputChannel2 = input.getChannelData(2); // input.C
327 var inputChannel4 = input.getChannelData(4); // input.SL
328 var inputChannel5 = input.getChannelData(5); // input.SR
329 var outputChannel0 = output.getChannelData(0); // output.L
330 var outputChannel1 = output.getChannelData(1); // output.R
331 var outputChannel2 = output.getChannelData(2); // output.SL
332 var outputChannel3 = output.getChannelData(3); // output.SR
333 var scaleSqrtHalf = Math.sqrt(0.5);
334 for (i = 0; i < length; i++) {
335 outputChannel0[i] += inputChannel0[i] + scaleSqrtHalf * inputChannel2[i];
336 outputChannel1[i] += inputChannel1[i] + scaleSqrtHalf * inputChannel2[i];
337 outputChannel2[i] += inputChannel4[i];
338 outputChannel3[i] += inputChannel5[i];
339 }
340
341 return;
342 }
343
344 // All other cases, fall back to the discrete sum.
345 discreteSum(input, output);
346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698