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

Side by Side Diff: third_party/WebKit/Source/platform/audio/AudioBus.cpp

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
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 } 212 }
213 213
214 void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channel Interpretation) 214 void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channel Interpretation)
215 { 215 {
216 if (&sourceBus == this) 216 if (&sourceBus == this)
217 return; 217 return;
218 218
219 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 219 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
220 unsigned numberOfDestinationChannels = numberOfChannels(); 220 unsigned numberOfDestinationChannels = numberOfChannels();
221 221
222 if (numberOfDestinationChannels == numberOfSourceChannels) { 222 // If the channel numbers are equal, perform channels-wise copy.
223 if (numberOfSourceChannels == numberOfDestinationChannels) {
223 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 224 for (unsigned i = 0; i < numberOfSourceChannels; ++i)
224 channel(i)->copyFrom(sourceBus.channel(i)); 225 channel(i)->copyFrom(sourceBus.channel(i));
225 } else { 226
226 switch (channelInterpretation) { 227 return;
227 case Speakers: 228 }
228 speakersCopyFrom(sourceBus); 229
229 break; 230 // Otherwise perform up/down-mix or the discrete transfer based on the
230 case Discrete: 231 // number of channels and the channel interpretation.
231 discreteCopyFrom(sourceBus); 232 switch (channelInterpretation) {
232 break; 233 case Speakers:
233 default: 234 // Needs to zero out the bus first because up/down-mixing performs
234 ASSERT_NOT_REACHED(); 235 // in-place summing.
235 } 236 zero();
237
238 if (numberOfSourceChannels < numberOfDestinationChannels)
239 processUpMix(sourceBus);
240 else
241 processDownMix(sourceBus);
242 break;
243 case Discrete:
244 discreteCopyFrom(sourceBus);
245 break;
236 } 246 }
237 } 247 }
238 248
239 void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelI nterpretation) 249 void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelI nterpretation)
240 { 250 {
241 if (&sourceBus == this) 251 if (&sourceBus == this)
242 return; 252 return;
243 253
244 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 254 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
245 unsigned numberOfDestinationChannels = numberOfChannels(); 255 unsigned numberOfDestinationChannels = numberOfChannels();
246 256
247 if (numberOfDestinationChannels == numberOfSourceChannels) { 257 // If the channel numbers are equal, perform channels-wise summing.
258 if (numberOfSourceChannels == numberOfDestinationChannels) {
248 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 259 for (unsigned i = 0; i < numberOfSourceChannels; ++i)
249 channel(i)->sumFrom(sourceBus.channel(i)); 260 channel(i)->sumFrom(sourceBus.channel(i));
250 } else { 261
251 switch (channelInterpretation) { 262 return;
252 case Speakers: 263 }
253 speakersSumFrom(sourceBus); 264
254 break; 265 // Otherwise perform up/down-mix or the discrete transfer based on the
255 case Discrete: 266 // number of channels and the channel interpretation.
256 discreteSumFrom(sourceBus); 267 switch (channelInterpretation) {
257 break; 268 case Speakers:
258 default: 269 if (numberOfSourceChannels < numberOfDestinationChannels)
259 ASSERT_NOT_REACHED(); 270 processUpMix(sourceBus);
260 } 271 else
272 processDownMix(sourceBus);
273 break;
274 case Discrete:
275 discreteSumFrom(sourceBus);
276 break;
261 } 277 }
262 } 278 }
263 279
264 void AudioBus::speakersCopyFrom(const AudioBus& sourceBus) 280 void AudioBus::processUpMix(const AudioBus& sourceBus)
265 { 281 {
266 // FIXME: Implement down mixing 5.1 to stereo.
267 // https://bugs.webkit.org/show_bug.cgi?id=79192
268
269 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 282 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
270 unsigned numberOfDestinationChannels = numberOfChannels(); 283 unsigned numberOfDestinationChannels = numberOfChannels();
271 284
272 if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) { 285 // Up-mixing: 1 -> 2, 1 -> 4
273 // Handle mono -> stereo case (for now simply copy mono channel into bot h left and right) 286 // output.L = input
274 // FIXME: Really we should apply an equal-power scaling factor here, sin ce we're effectively panning center... 287 // output.R = input
275 const AudioChannel* sourceChannel = sourceBus.channel(0); 288 // output.SL = 0 (in the case of 1 -> 4)
276 channel(0)->copyFrom(sourceChannel); 289 // output.SR = 0 (in the case of 1 -> 4)
277 channel(1)->copyFrom(sourceChannel); 290 if ((numberOfSourceChannels == 1 && numberOfDestinationChannels == 2) || (nu mberOfSourceChannels == 1 && numberOfDestinationChannels == 4)) {
278 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) {
279 // Handle stereo -> mono case. output = 0.5 * (input.L + input.R).
280 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
281
282 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
283 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data() ;
284
285 float* destination = channelByType(ChannelLeft)->mutableData();
286 vadd(sourceL, 1, sourceR, 1, destination, 1, length());
287 float scale = 0.5;
288 vsmul(destination, 1, &scale, destination, 1, length());
289 } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) {
290 // Handle mono -> 5.1 case, copy mono channel to center.
291 channel(2)->copyFrom(sourceBus.channel(0));
292 channel(0)->zero();
293 channel(1)->zero();
294 channel(3)->zero();
295 channel(4)->zero();
296 channel(5)->zero();
297 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) {
298 // Handle 5.1 -> mono case.
299 zero();
300 speakersSumFrom5_1_ToMono(sourceBus);
301 } else {
302 // Fallback for unknown combinations.
303 discreteCopyFrom(sourceBus);
304 }
305 }
306
307 void AudioBus::speakersSumFrom(const AudioBus& sourceBus)
308 {
309 // FIXME: Implement down mixing 5.1 to stereo.
310 // https://bugs.webkit.org/show_bug.cgi?id=79192
311
312 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
313 unsigned numberOfDestinationChannels = numberOfChannels();
314
315 if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
316 // Handle mono -> stereo case (summing mono channel into both left and r ight).
317 const AudioChannel* sourceChannel = sourceBus.channel(0); 291 const AudioChannel* sourceChannel = sourceBus.channel(0);
318 channel(0)->sumFrom(sourceChannel); 292 channel(0)->sumFrom(sourceChannel);
319 channel(1)->sumFrom(sourceChannel); 293 channel(1)->sumFrom(sourceChannel);
320 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) { 294
321 // Handle stereo -> mono case. output += 0.5 * (input.L + input.R). 295 return;
322 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus); 296 }
323 297
324 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data(); 298 // Up-mixing: 1 -> 5.1
325 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data() ; 299 // output.L = 0
300 // output.R = 0
301 // output.C = input (put in center channel)
302 // output.LFE = 0
303 // output.SL = 0
304 // output.SR = 0
305 if (numberOfSourceChannels == 1 && numberOfDestinationChannels == 6) {
306 channel(2)->sumFrom(sourceBus.channel(0));
307
308 return;
309 }
310
311 // Up-mixing: 2 -> 4, 2 -> 5.1
312 // output.L = input.L
313 // output.R = input.R
314 // output.C = 0 (in the case of 2 -> 5.1)
315 // output.LFE = 0 (in the case of 2 -> 5.1)
316 // output.SL = 0
317 // output.SR = 0
318 if ((numberOfSourceChannels == 2 && numberOfDestinationChannels == 4) || (nu mberOfSourceChannels == 2 && numberOfDestinationChannels == 6)) {
319 channel(0)->sumFrom(sourceBus.channel(0));
320 channel(1)->sumFrom(sourceBus.channel(1));
321
322 return;
323 }
324
325 // Up-mixing: 4 -> 5.1
326 // output.L = input.L
327 // output.R = input.R
328 // output.C = 0
329 // output.LFE = 0
330 // output.SL = input.SL
331 // output.SR = input.SR
332 if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 6) {
333 channel(0)->sumFrom(sourceBus.channel(0));
334 channel(1)->sumFrom(sourceBus.channel(1));
335 channel(4)->sumFrom(sourceBus.channel(2));
336 channel(5)->sumFrom(sourceBus.channel(3));
337
338 return;
339 }
340
341 // All other cases, fall back to the discrete sum. This will silence the
342 // excessive channels.
343 discreteSumFrom(sourceBus);
344 }
345
346 void AudioBus::processDownMix(const AudioBus& sourceBus)
347 {
348 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
349 unsigned numberOfDestinationChannels = numberOfChannels();
350
351 // Down-mixing: 2 -> 1
352 // output = 0.5 * (input.L + input.R)
353 if (numberOfSourceChannels == 2 && numberOfDestinationChannels == 1) {
354 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
355 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
356 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
326 357
327 float* destination = channelByType(ChannelLeft)->mutableData(); 358 float* destination = channelByType(ChannelLeft)->mutableData();
328 float scale = 0.5; 359 float scale = 0.5;
360
329 vsma(sourceL, 1, &scale, destination, 1, length()); 361 vsma(sourceL, 1, &scale, destination, 1, length());
330 vsma(sourceR, 1, &scale, destination, 1, length()); 362 vsma(sourceR, 1, &scale, destination, 1, length());
331 } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) { 363 return;
332 // Handle mono -> 5.1 case, sum mono channel into center. 364 }
333 channel(2)->sumFrom(sourceBus.channel(0)); 365
334 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) { 366 // Down-mixing: 4 -> 1
335 // Handle 5.1 -> mono case. 367 // output = 0.25 * (input.L + input.R + input.SL + input.SR)
336 speakersSumFrom5_1_ToMono(sourceBus); 368 if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 1) {
337 } else { 369 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
338 // Fallback for unknown combinations. 370 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
339 discreteSumFrom(sourceBus); 371 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
340 } 372 const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft )->data();
373 const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRigh t)->data();
374
375 float* destination = channelByType(ChannelLeft)->mutableData();
376 float scale = 0.25;
377
378 vsma(sourceL, 1, &scale, destination, 1, length());
379 vsma(sourceR, 1, &scale, destination, 1, length());
380 vsma(sourceSL, 1, &scale, destination, 1, length());
381 vsma(sourceSR, 1, &scale, destination, 1, length());
382 return;
383 }
384
385 // Down-mixing: 5.1 -> 1
386 // output = sqrt(1/2) * (input.L + input.R) + input.C
387 // + 0.5 * (input.SL + input.SR)
388 if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 1) {
389 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
390 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
391 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
392 const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data ();
393 const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft )->data();
394 const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRigh t)->data();
395
396 float* destination = channelByType(ChannelLeft)->mutableData();
397 float scaleSqrtHalf = sqrtf(0.5);
398 float scaleHalf = 0.5;
399
400 vsma(sourceL, 1, &scaleSqrtHalf, destination, 1, length());
401 vsma(sourceR, 1, &scaleSqrtHalf, destination, 1, length());
402 vadd(sourceC, 1, destination, 1, destination, 1, length());
403 vsma(sourceSL, 1, &scaleHalf, destination, 1, length());
404 vsma(sourceSR, 1, &scaleHalf, destination, 1, length());
405 return;
406 }
407
408 // Down-mixing: 4 -> 2
409 // output.L = 0.5 * (input.L + input.SL)
410 // output.R = 0.5 * (input.R + input.SR)
411 if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 2) {
412 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
413 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
414 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
415 const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft )->data();
416 const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRigh t)->data();
417
418 float* destinationL = channelByType(ChannelLeft)->mutableData();
419 float* destinationR = channelByType(ChannelRight)->mutableData();
420 float scaleHalf = 0.5;
421
422 vsma(sourceL, 1, &scaleHalf, destinationL, 1, length());
423 vsma(sourceSL, 1, &scaleHalf, destinationL, 1, length());
424 vsma(sourceR, 1, &scaleHalf, destinationR, 1, length());
425 vsma(sourceSR, 1, &scaleHalf, destinationR, 1, length());
426 return;
427 }
428
429 // Down-mixing: 5.1 -> 2
430 // output.L = input.L + sqrt(1/2) * (input.C + input.SL)
431 // output.R = input.R + sqrt(1/2) * (input.C + input.SR)
432 if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 2) {
433 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
434 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
435 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
436 const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data ();
437 const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft )->data();
438 const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRigh t)->data();
439
440 float* destinationL = channelByType(ChannelLeft)->mutableData();
441 float* destinationR = channelByType(ChannelRight)->mutableData();
442 float scaleSqrtHalf = sqrtf(0.5);
443
444 vadd(sourceL, 1, destinationL, 1, destinationL, 1, length());
445 vsma(sourceC, 1, &scaleSqrtHalf, destinationL, 1, length());
446 vsma(sourceSL, 1, &scaleSqrtHalf, destinationL, 1, length());
447 vadd(sourceR, 1, destinationR, 1, destinationR, 1, length());
448 vsma(sourceC, 1, &scaleSqrtHalf, destinationR, 1, length());
449 vsma(sourceSR, 1, &scaleSqrtHalf, destinationR, 1, length());
450 return;
451 }
452
453 // Down-mixing: 5.1 -> 4
454 // output.L = input.L + sqrt(1/2) * input.C
455 // output.R = input.R + sqrt(1/2) * input.C
456 // output.SL = input.SL
457 // output.SR = input.SR
458 if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 4) {
459 AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
460 const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data() ;
461 const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data( );
462 const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data ();
463
464 float* destinationL = channelByType(ChannelLeft)->mutableData();
465 float* destinationR = channelByType(ChannelRight)->mutableData();
466 float scaleSqrtHalf = sqrtf(0.5);
467
468 vadd(sourceL, 1, destinationL, 1, destinationL, 1, length());
469 vsma(sourceC, 1, &scaleSqrtHalf, destinationL, 1, length());
470 vadd(sourceR, 1, destinationR, 1, destinationR, 1, length());
471 vsma(sourceC, 1, &scaleSqrtHalf, destinationR, 1, length());
472 channel(2)->sumFrom(sourceBus.channel(4));
473 channel(3)->sumFrom(sourceBus.channel(5));
474 return;
475 }
476
477 // All other cases, fall back to the discrete sum. This will perform
478 // channel-wise sum until the destination channels run out.
479 discreteSumFrom(sourceBus);
341 } 480 }
342 481
343 void AudioBus::speakersSumFrom5_1_ToMono(const AudioBus& sourceBus)
344 {
345 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
346
347 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
348 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data();
349 const float* sourceC = sourceBusSafe.channelByType(ChannelCenter)->data();
350 const float* sourceSL = sourceBusSafe.channelByType(ChannelSurroundLeft)->da ta();
351 const float* sourceSR = sourceBusSafe.channelByType(ChannelSurroundRight)->d ata();
352
353 float* destination = channelByType(ChannelLeft)->mutableData();
354
355 AudioFloatArray temp(length());
356 float* tempData = temp.data();
357
358 // Sum in L and R.
359 vadd(sourceL, 1, sourceR, 1, tempData, 1, length());
360 float scale = 0.7071;
361 vsmul(tempData, 1, &scale, tempData, 1, length());
362 vadd(tempData, 1, destination, 1, destination, 1, length());
363
364 // Sum in SL and SR.
365 vadd(sourceSL, 1, sourceSR, 1, tempData, 1, length());
366 scale = 0.5;
367 vsmul(tempData, 1, &scale, tempData, 1, length());
368 vadd(tempData, 1, destination, 1, destination, 1, length());
369
370 // Sum in center.
371 vadd(sourceC, 1, destination, 1, destination, 1, length());
372 }
373
374 void AudioBus::discreteCopyFrom(const AudioBus& sourceBus) 482 void AudioBus::discreteCopyFrom(const AudioBus& sourceBus)
375 { 483 {
376 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 484 unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
377 unsigned numberOfDestinationChannels = numberOfChannels(); 485 unsigned numberOfDestinationChannels = numberOfChannels();
378 486
379 if (numberOfDestinationChannels < numberOfSourceChannels) { 487 if (numberOfDestinationChannels < numberOfSourceChannels) {
380 // Down-mix by copying channels and dropping the remaining. 488 // Down-mix by copying channels and dropping the remaining.
381 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) 489 for (unsigned i = 0; i < numberOfDestinationChannels; ++i)
382 channel(i)->copyFrom(sourceBus.channel(i)); 490 channel(i)->copyFrom(sourceBus.channel(i));
383 } else if (numberOfDestinationChannels > numberOfSourceChannels) { 491 } else if (numberOfDestinationChannels > numberOfSourceChannels) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 784
677 // If the bus needs no conversion then return as is. 785 // If the bus needs no conversion then return as is.
678 if ((!mixToMono || audioBus->numberOfChannels() == 1) && audioBus->sampleRat e() == sampleRate) 786 if ((!mixToMono || audioBus->numberOfChannels() == 1) && audioBus->sampleRat e() == sampleRate)
679 return audioBus; 787 return audioBus;
680 788
681 return AudioBus::createBySampleRateConverting(audioBus.get(), mixToMono, sam pleRate); 789 return AudioBus::createBySampleRateConverting(audioBus.get(), mixToMono, sam pleRate);
682 } 790 }
683 791
684 } // namespace blink 792 } // namespace blink
685 793
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698