Title: [143094] trunk/Source/WebCore
Revision
143094
Author
crog...@google.com
Date
2013-02-15 19:47:19 -0800 (Fri, 15 Feb 2013)

Log Message

Enhance AudioBus copyFrom() and sumFrom() to be able to handle discrete and speakers up and down-mixing
https://bugs.webkit.org/show_bug.cgi?id=109983

Reviewed by Kenneth Russell.

The Web Audio spec has a more detailed explanation for how channels are to be up and down-mixed:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#UpMix

This patch adds the initial support for handling ChannelInterpretation, although no
new JS API is yet implemented.

No new tests since no new APIs have yet been exposed.

* platform/audio/AudioBus.cpp:
(WebCore::AudioBus::copyFrom):
(WebCore):
(WebCore::AudioBus::sumFrom):
(WebCore::AudioBus::speakersCopyFrom):
(WebCore::AudioBus::speakersSumFrom):
(WebCore::AudioBus::discreteCopyFrom):
(WebCore::AudioBus::discreteSumFrom):
* platform/audio/AudioBus.h:
(AudioBus):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (143093 => 143094)


--- trunk/Source/WebCore/ChangeLog	2013-02-16 03:26:06 UTC (rev 143093)
+++ trunk/Source/WebCore/ChangeLog	2013-02-16 03:47:19 UTC (rev 143094)
@@ -1,3 +1,29 @@
+2013-02-15  Chris Rogers  <crog...@google.com>
+
+        Enhance AudioBus copyFrom() and sumFrom() to be able to handle discrete and speakers up and down-mixing
+        https://bugs.webkit.org/show_bug.cgi?id=109983
+
+        Reviewed by Kenneth Russell.
+
+        The Web Audio spec has a more detailed explanation for how channels are to be up and down-mixed:
+        https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#UpMix
+
+        This patch adds the initial support for handling ChannelInterpretation, although no
+        new JS API is yet implemented.
+
+        No new tests since no new APIs have yet been exposed.
+
+        * platform/audio/AudioBus.cpp:
+        (WebCore::AudioBus::copyFrom):
+        (WebCore):
+        (WebCore::AudioBus::sumFrom):
+        (WebCore::AudioBus::speakersCopyFrom):
+        (WebCore::AudioBus::speakersSumFrom):
+        (WebCore::AudioBus::discreteCopyFrom):
+        (WebCore::AudioBus::discreteSumFrom):
+        * platform/audio/AudioBus.h:
+        (AudioBus):
+
 2013-02-15  Tony Chang  <t...@chromium.org>
 
         Padding and border changes doesn't trigger relayout of children

Modified: trunk/Source/WebCore/platform/audio/AudioBus.cpp (143093 => 143094)


--- trunk/Source/WebCore/platform/audio/AudioBus.cpp	2013-02-16 03:26:06 UTC (rev 143093)
+++ trunk/Source/WebCore/platform/audio/AudioBus.cpp	2013-02-16 03:47:19 UTC (rev 143094)
@@ -210,10 +210,7 @@
         channel(i)->scale(scale);
 }
 
-// Just copies the samples from the source bus to this one.
-// This is just a simple copy if the number of channels match, otherwise a mixup or mixdown is done.
-// For now, we just support mixup from mono -> stereo and mixdown from stereo -> mono.
-void AudioBus::copyFrom(const AudioBus& sourceBus)
+void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation)
 {
     if (&sourceBus == this)
         return;
@@ -224,7 +221,54 @@
     if (numberOfDestinationChannels == numberOfSourceChannels) {
         for (unsigned i = 0; i < numberOfSourceChannels; ++i)
             channel(i)->copyFrom(sourceBus.channel(i));
-    } else if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
+    } else {
+        switch (channelInterpretation) {
+        case Speakers:
+            speakersCopyFrom(sourceBus);
+            break;
+        case Discrete:
+            discreteCopyFrom(sourceBus);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+}
+
+void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation)
+{
+    if (&sourceBus == this)
+        return;
+
+    unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
+    unsigned numberOfDestinationChannels = numberOfChannels();
+
+    if (numberOfDestinationChannels == numberOfSourceChannels) {
+        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();
+        }
+    }
+}
+
+void AudioBus::speakersCopyFrom(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);
@@ -253,37 +297,22 @@
         // Handle 5.1 -> mono case, copy center channel into mono.
         // FIXME: We should have a better algorithm for this down mixing.
         channel(0)->copyFrom(sourceBus.channel(2));
-    } else if (numberOfDestinationChannels < numberOfSourceChannels) {
-        // Default down mixing handling, just match the source channels with the first available destination channels. 
-        // 5.1 -> stereo case covered here. 
-        // FIXME: We should have a better algorithm for down mixing 5.1 to stereo.
-        // https://bugs.webkit.org/show_bug.cgi?id=79192
-        for (unsigned i = 0; i < numberOfDestinationChannels; ++i)
-            channel(i)->copyFrom(sourceBus.channel(i));
-    } else if (numberOfDestinationChannels > numberOfSourceChannels) {
-        // Default up mixing handling, just match the destination channels with the first available source channels. 
-        // Stereo -> 5.1 case covered here. 
-        for (unsigned i = 0; i < numberOfSourceChannels; ++i) 
-            channel(i)->copyFrom(sourceBus.channel(i));
-        for (unsigned i = numberOfSourceChannels; i < numberOfDestinationChannels; ++i)
-            channel(i)->zero();
     } else {
-        // Case not handled
-        ASSERT_NOT_REACHED();
+        // Fallback for unknown combinations.
+        discreteCopyFrom(sourceBus);
     }
 }
 
-void AudioBus::sumFrom(const AudioBus &sourceBus)
+void AudioBus::speakersSumFrom(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 == numberOfSourceChannels) {
-        for (unsigned i = 0; i < numberOfChannels(); ++i)
-            channel(i)->sumFrom(sourceBus.channel(i));
-    } else if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
-        // Handle mono -> stereo case (for now simply sum mono channel into both left and right)
-        // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
+    if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) {
+        // Handle mono -> stereo case (summing mono channel into both left and right).
         const AudioChannel* sourceChannel = sourceBus.channel(0);
         channel(0)->sumFrom(sourceChannel);
         channel(1)->sumFrom(sourceChannel);
@@ -305,21 +334,43 @@
         // Handle 5.1 -> mono case, sum center channel into mono.
         // FIXME: We should have a better algorithm for this down mixing.
         channel(0)->sumFrom(sourceBus.channel(2));
-    } else if (numberOfDestinationChannels < numberOfSourceChannels) {
-        // Default down mixing, just summing the first available destination channels. 
-        // 5.1 -> stereo case covered here.
-        // FIXME: We should have a better algorithm for down mixing 5.1 to stereo.
-        // https://bugs.webkit.org/show_bug.cgi?id=79192
+    } else {
+        // Fallback for unknown combinations.
+        discreteSumFrom(sourceBus);
+    }
+}
+
+void AudioBus::discreteCopyFrom(const AudioBus& sourceBus)
+{
+    unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
+    unsigned numberOfDestinationChannels = numberOfChannels();
+    
+    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();
+    }
+}
+
+void AudioBus::discreteSumFrom(const AudioBus& sourceBus)
+{
+    unsigned numberOfSourceChannels = sourceBus.numberOfChannels();
+    unsigned numberOfDestinationChannels = numberOfChannels();
+
+    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) {
-        // Default up mixing, just summing the first available source channels. 
-        // stereo -> 5.1 case covered here.
+        // Up-mix by summing as many channels as we have.
         for (unsigned i = 0; i < numberOfSourceChannels; ++i) 
             channel(i)->sumFrom(sourceBus.channel(i));
-    } else {
-        // Case not handled
-        ASSERT_NOT_REACHED();
     }
 }
 

Modified: trunk/Source/WebCore/platform/audio/AudioBus.h (143093 => 143094)


--- trunk/Source/WebCore/platform/audio/AudioBus.h	2013-02-16 03:26:06 UTC (rev 143093)
+++ trunk/Source/WebCore/platform/audio/AudioBus.h	2013-02-16 03:47:19 UTC (rev 143094)
@@ -57,6 +57,11 @@
         // Can define non-standard layouts here
     };
 
+    enum ChannelInterpretation {
+        Speakers,
+        Discrete,
+    };
+
     // allocate indicates whether or not to initially have the AudioChannels created with managed storage.
     // Normal usage is to pass true here, in which case the AudioChannels will memory-manage their own storage.
     // If allocate is false then setChannelMemory() has to be called later on for each channel before the AudioBus is useable...
@@ -115,12 +120,13 @@
 
     void reset() { m_isFirstTime = true; } // for de-zippering
 
-    // Assuming sourceBus has the same topology, copies sample data from each channel of sourceBus to our corresponding channel.
-    void copyFrom(const AudioBus &sourceBus);
+    // Copies the samples from the source bus to this one.
+    // This is just a simple per-channel copy if the number of channels match, otherwise an up-mix or down-mix is done.
+    void copyFrom(const AudioBus& sourceBus, ChannelInterpretation = Speakers);
 
-    // Sums the sourceBus into our bus with unity gain.
-    // Our own internal gain m_busGain is ignored.
-    void sumFrom(const AudioBus &sourceBus);
+    // Sums the samples from the source bus to this one.
+    // This is just a simple per-channel summing if the number of channels match, otherwise an up-mix or down-mix is done.
+    void sumFrom(const AudioBus& sourceBus, ChannelInterpretation = Speakers);
 
     // Copy each channel from sourceBus into our corresponding channel.
     // We scale by targetGain (and our own internal gain m_busGain), performing "de-zippering" to smoothly change from *lastMixGain to (targetGain*m_busGain).
@@ -142,6 +148,11 @@
 protected:
     AudioBus() { };
 
+    void speakersCopyFrom(const AudioBus&);
+    void discreteCopyFrom(const AudioBus&);
+    void speakersSumFrom(const AudioBus&);
+    void discreteSumFrom(const AudioBus&);
+
     size_t m_length;
     Vector<OwnPtr<AudioChannel> > m_channels;
     int m_layout;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to