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

Unified 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: Clean up and addressing feedback 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/audio/AudioBus.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/platform/audio/AudioBus.cpp
diff --git a/third_party/WebKit/Source/platform/audio/AudioBus.cpp b/third_party/WebKit/Source/platform/audio/AudioBus.cpp
index 2b29e70916b8184cddcae076ec3fde3595e0316c..250d9e030b0955b68140596c1dc1f5faea0977f0 100644
--- a/third_party/WebKit/Source/platform/audio/AudioBus.cpp
+++ b/third_party/WebKit/Source/platform/audio/AudioBus.cpp
@@ -216,24 +216,9 @@ void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channel
if (&sourceBus == this)
return;
- unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
- unsigned numberOfDestinationChannels = numberOfChannels();
-
- if (numberOfDestinationChannels == numberOfSourceChannels) {
- for (unsigned i = 0; i < numberOfSourceChannels; ++i)
- channel(i)->copyFrom(sourceBus.channel(i));
- } else {
- switch (channelInterpretation) {
- case Speakers:
- speakersCopyFrom(sourceBus);
- break;
- case Discrete:
- discreteCopyFrom(sourceBus);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
+ // Copying bus is equivalent to zeroing and then summing.
+ zero();
+ sumFrom(sourceBus, channelInterpretation);
}
void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation)
@@ -244,164 +229,214 @@ void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelI
unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
unsigned numberOfDestinationChannels = numberOfChannels();
- if (numberOfDestinationChannels == numberOfSourceChannels) {
+ // If the channel numbers are equal, perform channels-wise summing.
+ if (numberOfSourceChannels == numberOfDestinationChannels) {
for (unsigned i = 0; i < numberOfSourceChannels; ++i)
channel(i)->sumFrom(sourceBus.channel(i));
- } else {
- switch (channelInterpretation) {
- case Speakers:
- speakersSumFrom(sourceBus);
- break;
- case Discrete:
- discreteSumFrom(sourceBus);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
+
+ return;
+ }
+
+ // Otherwise perform up/down-mix or the discrete transfer based on the
+ // number of channels and the channel interpretation.
+ switch (channelInterpretation) {
+ case Speakers:
+ if (numberOfSourceChannels < numberOfDestinationChannels)
+ sumFromByUpMixing(sourceBus);
+ else
+ sumFromByDownMixing(sourceBus);
+ break;
+ case Discrete:
+ discreteSumFrom(sourceBus);
+ break;
}
}
-void AudioBus::speakersCopyFrom(const AudioBus& sourceBus)
+void AudioBus::discreteSumFrom(const AudioBus& sourceBus)
{
- // FIXME: Implement down mixing 5.1 to stereo.
- // https://bugs.webkit.org/show_bug.cgi?id=79192
-
unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
unsigned numberOfDestinationChannels = numberOfChannels();
- if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
- // Handle mono -> stereo case (for now simply copy mono channel into both left and right)
- // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
- const AudioChannel* sourceChannel = sourceBus.channel(0);
- channel(0)->copyFrom(sourceChannel);
- channel(1)->copyFrom(sourceChannel);
- } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) {
- // Handle stereo -> mono case. output = 0.5 * (input.L + input.R).
- AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
-
- const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
- const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data();
-
- float* destination = channelByType(ChannelLeft)->mutableData();
- vadd(sourceL, 1, sourceR, 1, destination, 1, length());
- float scale = 0.5;
- vsmul(destination, 1, &scale, destination, 1, length());
- } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) {
- // Handle mono -> 5.1 case, copy mono channel to center.
- channel(2)->copyFrom(sourceBus.channel(0));
- channel(0)->zero();
- channel(1)->zero();
- channel(3)->zero();
- channel(4)->zero();
- channel(5)->zero();
- } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) {
- // Handle 5.1 -> mono case.
- zero();
- speakersSumFrom5_1_ToMono(sourceBus);
- } else {
- // Fallback for unknown combinations.
- discreteCopyFrom(sourceBus);
+ if (numberOfDestinationChannels < numberOfSourceChannels) {
+ // Down-mix by summing channels and dropping the remaining.
+ for (unsigned i = 0; i < numberOfDestinationChannels; ++i)
+ channel(i)->sumFrom(sourceBus.channel(i));
+ } else if (numberOfDestinationChannels > numberOfSourceChannels) {
+ // Up-mix by summing as many channels as we have.
+ for (unsigned i = 0; i < numberOfSourceChannels; ++i)
+ channel(i)->sumFrom(sourceBus.channel(i));
}
}
-void AudioBus::speakersSumFrom(const AudioBus& sourceBus)
+void AudioBus::sumFromByUpMixing(const AudioBus& sourceBus)
{
- // FIXME: Implement down mixing 5.1 to stereo.
- // https://bugs.webkit.org/show_bug.cgi?id=79192
-
unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
unsigned numberOfDestinationChannels = numberOfChannels();
- if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
- // Handle mono -> stereo case (summing mono channel into both left and right).
+ if ((numberOfSourceChannels == 1 && numberOfDestinationChannels == 2) || (numberOfSourceChannels == 1 && numberOfDestinationChannels == 4)) {
Raymond Toy 2016/03/10 18:56:47 Not something to fix here, but we should probably
hongchan 2016/03/11 19:48:06 Acknowledged, but "git cl format" always reverts m
Raymond Toy 2016/03/11 19:53:17 Oh well. We'll just have to wait for the Great Ref
+ // Up-mixing: 1 -> 2, 1 -> 4
+ // output.L = input
+ // output.R = input
+ // output.SL = 0 (in the case of 1 -> 4)
+ // output.SR = 0 (in the case of 1 -> 4)
const AudioChannel* sourceChannel = sourceBus.channel(0);
Raymond Toy 2016/03/10 18:56:47 Style nit: In sumFromByDownMixing, you access cha
hongchan 2016/03/11 19:48:06 Done, but what about the sources? Should we change
channel(0)->sumFrom(sourceChannel);
channel(1)->sumFrom(sourceChannel);
- } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) {
- // Handle stereo -> mono case. output += 0.5 * (input.L + input.R).
- AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
-
- const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
- const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data();
-
- float* destination = channelByType(ChannelLeft)->mutableData();
- float scale = 0.5;
- vsma(sourceL, 1, &scale, destination, 1, length());
- vsma(sourceR, 1, &scale, destination, 1, length());
- } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) {
- // Handle mono -> 5.1 case, sum mono channel into center.
+ } else if (numberOfSourceChannels == 1 && numberOfDestinationChannels == 6) {
+ // Up-mixing: 1 -> 5.1
+ // output.L = 0
+ // output.R = 0
+ // output.C = input (put in center channel)
+ // output.LFE = 0
+ // output.SL = 0
+ // output.SR = 0
channel(2)->sumFrom(sourceBus.channel(0));
- } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) {
- // Handle 5.1 -> mono case.
- speakersSumFrom5_1_ToMono(sourceBus);
+ } else if ((numberOfSourceChannels == 2 && numberOfDestinationChannels == 4) || (numberOfSourceChannels == 2 && numberOfDestinationChannels == 6)) {
+ // Up-mixing: 2 -> 4, 2 -> 5.1
+ // output.L = input.L
+ // output.R = input.R
+ // output.C = 0 (in the case of 2 -> 5.1)
+ // output.LFE = 0 (in the case of 2 -> 5.1)
+ // output.SL = 0
+ // output.SR = 0
+ channel(0)->sumFrom(sourceBus.channel(0));
+ channel(1)->sumFrom(sourceBus.channel(1));
+ } else if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 6) {
+ // Up-mixing: 4 -> 5.1
+ // output.L = input.L
+ // output.R = input.R
+ // output.C = 0
+ // output.LFE = 0
+ // output.SL = input.SL
+ // output.SR = input.SR
+ channel(0)->sumFrom(sourceBus.channel(0));
+ channel(1)->sumFrom(sourceBus.channel(1));
+ channel(4)->sumFrom(sourceBus.channel(2));
+ channel(5)->sumFrom(sourceBus.channel(3));
} else {
- // Fallback for unknown combinations.
+ // All other cases, fall back to the discrete sum. This will silence the
+ // excessive channels.
discreteSumFrom(sourceBus);
}
}
-void AudioBus::speakersSumFrom5_1_ToMono(const AudioBus& sourceBus)
+void AudioBus::sumFromByDownMixing(const AudioBus& sourceBus)
{
- AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
-
- const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
- const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data();
- const float* sourceC = sourceBusSafe.channelByType(ChannelCenter)->data();
- const float* sourceSL = sourceBusSafe.channelByType(ChannelSurroundLeft)->data();
- const float* sourceSR = sourceBusSafe.channelByType(ChannelSurroundRight)->data();
-
- float* destination = channelByType(ChannelLeft)->mutableData();
-
- AudioFloatArray temp(length());
- float* tempData = temp.data();
-
- // Sum in L and R.
- vadd(sourceL, 1, sourceR, 1, tempData, 1, length());
- float scale = 0.7071;
- vsmul(tempData, 1, &scale, tempData, 1, length());
- vadd(tempData, 1, destination, 1, destination, 1, length());
+ unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
+ unsigned numberOfDestinationChannels = numberOfChannels();
- // Sum in SL and SR.
- vadd(sourceSL, 1, sourceSR, 1, tempData, 1, length());
- scale = 0.5;
- vsmul(tempData, 1, &scale, tempData, 1, length());
- vadd(tempData, 1, destination, 1, destination, 1, length());
+ if (numberOfSourceChannels == 2 && numberOfDestinationChannels == 1) {
+ // Down-mixing: 2 -> 1
+ // output = 0.5 * (input.L + input.R)
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
- // Sum in center.
- vadd(sourceC, 1, destination, 1, destination, 1, length());
-}
+ float* destination = channelByType(ChannelLeft)->mutableData();
+ float scale = 0.5;
-void AudioBus::discreteCopyFrom(const AudioBus& sourceBus)
-{
- unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
- unsigned numberOfDestinationChannels = numberOfChannels();
+ vsma(sourceL, 1, &scale, destination, 1, length());
+ vsma(sourceR, 1, &scale, destination, 1, length());
+ } else if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 1) {
+ // Down-mixing: 4 -> 1
+ // output = 0.25 * (input.L + input.R + input.SL + input.SR)
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
+ const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft)->data();
+ const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRight)->data();
- if (numberOfDestinationChannels < numberOfSourceChannels) {
- // Down-mix by copying channels and dropping the remaining.
- for (unsigned i = 0; i < numberOfDestinationChannels; ++i)
- channel(i)->copyFrom(sourceBus.channel(i));
- } else if (numberOfDestinationChannels > numberOfSourceChannels) {
- // Up-mix by copying as many channels as we have, then zeroing remaining channels.
- for (unsigned i = 0; i < numberOfSourceChannels; ++i)
- channel(i)->copyFrom(sourceBus.channel(i));
- for (unsigned i = numberOfSourceChannels; i < numberOfDestinationChannels; ++i)
- channel(i)->zero();
- }
-}
+ float* destination = channelByType(ChannelLeft)->mutableData();
+ float scale = 0.25;
-void AudioBus::discreteSumFrom(const AudioBus& sourceBus)
-{
- unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
- unsigned numberOfDestinationChannels = numberOfChannels();
+ vsma(sourceL, 1, &scale, destination, 1, length());
+ vsma(sourceR, 1, &scale, destination, 1, length());
+ vsma(sourceSL, 1, &scale, destination, 1, length());
+ vsma(sourceSR, 1, &scale, destination, 1, length());
+ } else if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 1) {
+ // Down-mixing: 5.1 -> 1
+ // output = sqrt(1/2) * (input.L + input.R) + input.C
+ // + 0.5 * (input.SL + input.SR)
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
Raymond Toy 2016/03/10 18:56:47 Seems weird that you have to do a const cast. I'm
hongchan 2016/03/11 19:48:06 After the discussion we had, I removed the all con
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
+ const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data();
+ const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft)->data();
+ const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRight)->data();
- if (numberOfDestinationChannels < numberOfSourceChannels) {
- // Down-mix by summing channels and dropping the remaining.
- for (unsigned i = 0; i < numberOfDestinationChannels; ++i)
- channel(i)->sumFrom(sourceBus.channel(i));
- } else if (numberOfDestinationChannels > numberOfSourceChannels) {
- // Up-mix by summing as many channels as we have.
- for (unsigned i = 0; i < numberOfSourceChannels; ++i)
- channel(i)->sumFrom(sourceBus.channel(i));
+ float* destination = channelByType(ChannelLeft)->mutableData();
+ float scaleSqrtHalf = sqrtf(0.5);
+ float scaleHalf = 0.5;
+
+ vsma(sourceL, 1, &scaleSqrtHalf, destination, 1, length());
+ vsma(sourceR, 1, &scaleSqrtHalf, destination, 1, length());
+ vadd(sourceC, 1, destination, 1, destination, 1, length());
+ vsma(sourceSL, 1, &scaleHalf, destination, 1, length());
+ vsma(sourceSR, 1, &scaleHalf, destination, 1, length());
+ } else if (numberOfSourceChannels == 4 && numberOfDestinationChannels == 2) {
+ // Down-mixing: 4 -> 2
+ // output.L = 0.5 * (input.L + input.SL)
+ // output.R = 0.5 * (input.R + input.SR)
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
+ const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft)->data();
+ const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRight)->data();
+
+ float* destinationL = channelByType(ChannelLeft)->mutableData();
+ float* destinationR = channelByType(ChannelRight)->mutableData();
+ float scaleHalf = 0.5;
+
+ vsma(sourceL, 1, &scaleHalf, destinationL, 1, length());
+ vsma(sourceSL, 1, &scaleHalf, destinationL, 1, length());
+ vsma(sourceR, 1, &scaleHalf, destinationR, 1, length());
+ vsma(sourceSR, 1, &scaleHalf, destinationR, 1, length());
+ } else if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 2) {
+ // Down-mixing: 5.1 -> 2
+ // output.L = input.L + sqrt(1/2) * (input.C + input.SL)
+ // output.R = input.R + sqrt(1/2) * (input.C + input.SR)
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
+ const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data();
+ const float* sourceSL = sourceBusConst.channelByType(ChannelSurroundLeft)->data();
+ const float* sourceSR = sourceBusConst.channelByType(ChannelSurroundRight)->data();
+
+ float* destinationL = channelByType(ChannelLeft)->mutableData();
+ float* destinationR = channelByType(ChannelRight)->mutableData();
+ float scaleSqrtHalf = sqrtf(0.5);
+
+ vadd(sourceL, 1, destinationL, 1, destinationL, 1, length());
+ vsma(sourceC, 1, &scaleSqrtHalf, destinationL, 1, length());
+ vsma(sourceSL, 1, &scaleSqrtHalf, destinationL, 1, length());
+ vadd(sourceR, 1, destinationR, 1, destinationR, 1, length());
+ vsma(sourceC, 1, &scaleSqrtHalf, destinationR, 1, length());
+ vsma(sourceSR, 1, &scaleSqrtHalf, destinationR, 1, length());
+ } else if (numberOfSourceChannels == 6 && numberOfDestinationChannels == 4) {
+ // Down-mixing: 5.1 -> 4
+ // output.L = input.L + sqrt(1/2) * input.C
+ // output.R = input.R + sqrt(1/2) * input.C
+ // output.SL = input.SL
+ // output.SR = input.SR
+ AudioBus& sourceBusConst = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusConst.channelByType(ChannelLeft)->data();
+ const float* sourceR = sourceBusConst.channelByType(ChannelRight)->data();
+ const float* sourceC = sourceBusConst.channelByType(ChannelCenter)->data();
+
+ float* destinationL = channelByType(ChannelLeft)->mutableData();
+ float* destinationR = channelByType(ChannelRight)->mutableData();
+ float scaleSqrtHalf = sqrtf(0.5);
+
+ vadd(sourceL, 1, destinationL, 1, destinationL, 1, length());
+ vsma(sourceC, 1, &scaleSqrtHalf, destinationL, 1, length());
+ vadd(sourceR, 1, destinationR, 1, destinationR, 1, length());
+ vsma(sourceC, 1, &scaleSqrtHalf, destinationR, 1, length());
+ channel(2)->sumFrom(sourceBus.channel(4));
+ channel(3)->sumFrom(sourceBus.channel(5));
+ } else {
+ // All other cases, fall back to the discrete sum. This will perform
+ // channel-wise sum until the destination channels run out.
+ discreteSumFrom(sourceBus);
}
}
« no previous file with comments | « third_party/WebKit/Source/platform/audio/AudioBus.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698