Title: [144720] trunk/Source
Revision
144720
Author
[email protected]
Date
2013-03-04 22:04:26 -0800 (Mon, 04 Mar 2013)

Log Message

Source/Platform: Add audio hardware support for multi-channel by implementing AudioDestinationNode.maxChannelCount
https://bugs.webkit.org/show_bug.cgi?id=111385

Reviewed by James Robinson.

* chromium/public/Platform.h:
(WebKit::Platform::audioHardwareOutputChannels):

Source/WebCore: Add audio hardware support for multi-channel output by implementing AudioDestinationNode.maxChannelCount
https://bugs.webkit.org/show_bug.cgi?id=111385

Reviewed by James Robinson.

See specification details for .maxChannelCount:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioDestinationNode

* Modules/webaudio/AudioDestinationNode.h:
(WebCore::AudioDestinationNode::maxChannelCount):
* Modules/webaudio/AudioDestinationNode.idl:
* Modules/webaudio/AudioNode.h:
Implement .maxChannelCount attribute.

(AudioNode):
* Modules/webaudio/DefaultAudioDestinationNode.h:
* Modules/webaudio/DefaultAudioDestinationNode.cpp:
(WebCore::DefaultAudioDestinationNode::initialize):
(WebCore::DefaultAudioDestinationNode::createDestination):
(WebCore::DefaultAudioDestinationNode::enableInput):
Call to createDestination() now takes no argument.
Instead we maintain a member variable for the input device ID.
(WebCore::DefaultAudioDestinationNode::maxChannelCount):
(WebCore::DefaultAudioDestinationNode::setChannelCount):
Check port-specific hardware support for maxChannelCount(),
and allow setting the channel count based on what the hardware
supports.

* platform/audio/AudioDestination.h:
(AudioDestination):
* platform/audio/chromium/AudioDestinationChromium.cpp:
(WebCore::AudioDestination::maxChannelCount):
(WebCore::AudioDestinationChromium::render):
Call into chromium WebKit API: audioHardwareOutputChannels().

* platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
(WebCore::AudioDestination::maxChannelCount):
Add basic implementation for maxChannelCount() only supporting stereo output.

* platform/audio/mac/AudioDestinationMac.cpp:
(WebCore::AudioDestination::maxChannelCount):
Add basic implementation for maxChannelCount() only supporting stereo output.
Later, the mac port can support more than this with some small improvements to AudioDestinationMac.

Modified Paths

Diff

Modified: trunk/Source/Platform/ChangeLog (144719 => 144720)


--- trunk/Source/Platform/ChangeLog	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/Platform/ChangeLog	2013-03-05 06:04:26 UTC (rev 144720)
@@ -1,3 +1,13 @@
+2013-03-04  Chris Rogers  <[email protected]>
+
+        Add audio hardware support for multi-channel by implementing AudioDestinationNode.maxChannelCount
+        https://bugs.webkit.org/show_bug.cgi?id=111385
+
+        Reviewed by James Robinson.
+
+        * chromium/public/Platform.h:
+        (WebKit::Platform::audioHardwareOutputChannels):
+
 2013-02-26  Kentaro Hara  <[email protected]>
 
         [chromium] Implement TRACE_EVENT macros for sampling profiling

Modified: trunk/Source/Platform/chromium/public/Platform.h (144719 => 144720)


--- trunk/Source/Platform/chromium/public/Platform.h	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/Platform/chromium/public/Platform.h	2013-03-05 06:04:26 UTC (rev 144720)
@@ -120,6 +120,7 @@
 
     virtual double audioHardwareSampleRate() { return 0; }
     virtual size_t audioHardwareBufferSize() { return 0; }
+    virtual unsigned audioHardwareOutputChannels() { return 0; }
 
     // Creates a device for audio I/O.
     // Pass in (numberOfInputChannels > 0) if live/local audio input is desired.

Modified: trunk/Source/WebCore/ChangeLog (144719 => 144720)


--- trunk/Source/WebCore/ChangeLog	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/ChangeLog	2013-03-05 06:04:26 UTC (rev 144720)
@@ -1,3 +1,49 @@
+2013-03-04  Chris Rogers  <[email protected]>
+
+        Add audio hardware support for multi-channel output by implementing AudioDestinationNode.maxChannelCount
+        https://bugs.webkit.org/show_bug.cgi?id=111385
+
+        Reviewed by James Robinson.
+        
+        See specification details for .maxChannelCount:
+        https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioDestinationNode
+        
+        * Modules/webaudio/AudioDestinationNode.h:
+        (WebCore::AudioDestinationNode::maxChannelCount):
+        * Modules/webaudio/AudioDestinationNode.idl:
+        * Modules/webaudio/AudioNode.h:
+        Implement .maxChannelCount attribute.
+        
+        (AudioNode):
+        * Modules/webaudio/DefaultAudioDestinationNode.h:
+        * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+        (WebCore::DefaultAudioDestinationNode::initialize):
+        (WebCore::DefaultAudioDestinationNode::createDestination):
+        (WebCore::DefaultAudioDestinationNode::enableInput):
+        Call to createDestination() now takes no argument.
+        Instead we maintain a member variable for the input device ID.
+        (WebCore::DefaultAudioDestinationNode::maxChannelCount):
+        (WebCore::DefaultAudioDestinationNode::setChannelCount):
+        Check port-specific hardware support for maxChannelCount(),
+        and allow setting the channel count based on what the hardware
+        supports.
+        
+        * platform/audio/AudioDestination.h:
+        (AudioDestination):
+        * platform/audio/chromium/AudioDestinationChromium.cpp:
+        (WebCore::AudioDestination::maxChannelCount):
+        (WebCore::AudioDestinationChromium::render):
+        Call into chromium WebKit API: audioHardwareOutputChannels().
+
+        * platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
+        (WebCore::AudioDestination::maxChannelCount):
+        Add basic implementation for maxChannelCount() only supporting stereo output.
+
+        * platform/audio/mac/AudioDestinationMac.cpp:
+        (WebCore::AudioDestination::maxChannelCount):
+        Add basic implementation for maxChannelCount() only supporting stereo output.
+        Later, the mac port can support more than this with some small improvements to AudioDestinationMac.
+
 2013-03-04  Adam Barth  <[email protected]>
 
         Background HTML parser can rewind the tokenizer after end-of-file

Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h (144719 => 144720)


--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h	2013-03-05 06:04:26 UTC (rev 144720)
@@ -52,7 +52,7 @@
     size_t currentSampleFrame() const { return m_currentSampleFrame; }
     double currentTime() const { return currentSampleFrame() / static_cast<double>(sampleRate()); }
 
-    virtual unsigned numberOfChannels() const { return 2; } // FIXME: update when multi-channel (more than stereo) is supported
+    virtual unsigned long maxChannelCount() const { return 0; }
 
     // Enable local/live input for the specified device.
     virtual void enableInput(const String& inputDeviceId) = 0;

Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl (144719 => 144720)


--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl	2013-03-05 06:04:26 UTC (rev 144720)
@@ -27,5 +27,5 @@
     JSGenerateToJSObject,
     V8SkipVTableValidation
 ] interface AudioDestinationNode : AudioNode {
-    readonly attribute long numberOfChannels;
+    readonly attribute unsigned long maxChannelCount;
 };

Modified: trunk/Source/WebCore/Modules/webaudio/AudioNode.h (144719 => 144720)


--- trunk/Source/WebCore/Modules/webaudio/AudioNode.h	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNode.h	2013-03-05 06:04:26 UTC (rev 144720)
@@ -169,7 +169,7 @@
     void reportMemoryUsage(MemoryObjectInfo*) const;
 
     unsigned long channelCount();
-    void setChannelCount(unsigned long, ExceptionCode&);
+    virtual void setChannelCount(unsigned long, ExceptionCode&);
 
     String channelCountMode();
     void setChannelCountMode(const String&, ExceptionCode&);

Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp (144719 => 144720)


--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2013-03-05 06:04:26 UTC (rev 144720)
@@ -28,6 +28,7 @@
 
 #include "DefaultAudioDestinationNode.h"
 
+#include "ExceptionCode.h"
 #include "Logging.h"
 #include <wtf/MainThread.h>
 
@@ -56,7 +57,7 @@
     if (isInitialized())
         return;
 
-    createDestination(String());
+    createDestination();
     AudioNode::initialize();
 }
 
@@ -72,12 +73,12 @@
     AudioNode::uninitialize();
 }
 
-void DefaultAudioDestinationNode::createDestination(const String& inputDeviceId)
+void DefaultAudioDestinationNode::createDestination()
 {
     float hardwareSampleRate = AudioDestination::hardwareSampleRate();
     LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
     
-    m_destination = AudioDestination::create(*this, inputDeviceId, m_numberOfInputChannels, numberOfChannels(), hardwareSampleRate);
+    m_destination = AudioDestination::create(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), hardwareSampleRate);
 }
 
 void DefaultAudioDestinationNode::enableInput(const String& inputDeviceId)
@@ -85,11 +86,12 @@
     ASSERT(isMainThread());
     if (m_numberOfInputChannels != EnabledInputChannels) {
         m_numberOfInputChannels = EnabledInputChannels;
+        m_inputDeviceId = inputDeviceId;
 
         if (isInitialized()) {
             // Re-create destination.
             m_destination->stop();
-            createDestination(inputDeviceId);
+            createDestination();
             m_destination->start();
         }
     }
@@ -102,6 +104,35 @@
         m_destination->start();
 }
 
+unsigned long DefaultAudioDestinationNode::maxChannelCount() const
+{
+    return AudioDestination::maxChannelCount();
+}
+
+void DefaultAudioDestinationNode::setChannelCount(unsigned long channelCount, ExceptionCode& ec)
+{
+    // The channelCount for the input to this node controls the actual number of channels we
+    // send to the audio hardware. It can only be set depending on the maximum number of
+    // channels supported by the hardware.
+
+    ASSERT(isMainThread());
+
+    if (!maxChannelCount() || channelCount > maxChannelCount()) {
+        ec = INVALID_STATE_ERR;
+        return;
+    }
+
+    unsigned long oldChannelCount = this->channelCount();
+    AudioNode::setChannelCount(channelCount, ec);
+
+    if (!ec && this->channelCount() != oldChannelCount && isInitialized()) {
+        // Re-create destination.
+        m_destination->stop();
+        createDestination();
+        m_destination->start();
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUDIO)

Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h (144719 => 144720)


--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h	2013-03-05 06:04:26 UTC (rev 144720)
@@ -45,16 +45,19 @@
     // AudioNode   
     virtual void initialize() OVERRIDE;
     virtual void uninitialize() OVERRIDE;
+    virtual void setChannelCount(unsigned long, ExceptionCode&) OVERRIDE;
 
     // AudioDestinationNode
     virtual void enableInput(const String& inputDeviceId) OVERRIDE;
     virtual void startRendering() OVERRIDE;
+    virtual unsigned long maxChannelCount() const OVERRIDE;
     
 private:
     explicit DefaultAudioDestinationNode(AudioContext*);
-    void createDestination(const String& inputDeviceId);
+    void createDestination();
 
     OwnPtr<AudioDestination> m_destination;
+    String m_inputDeviceId;
     unsigned m_numberOfInputChannels;
 };
 

Modified: trunk/Source/WebCore/platform/audio/AudioDestination.h (144719 => 144720)


--- trunk/Source/WebCore/platform/audio/AudioDestination.h	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/AudioDestination.h	2013-03-05 06:04:26 UTC (rev 144720)
@@ -56,6 +56,14 @@
     // Sample-rate conversion may happen in AudioDestination to the hardware sample-rate
     virtual float sampleRate() const = 0;
     static float hardwareSampleRate();
+
+    // maxChannelCount() returns the total number of output channels of the audio hardware.
+    // A value of 0 indicates that the number of channels cannot be configured and
+    // that only stereo (2-channel) destinations can be created.
+    // The numberOfOutputChannels parameter of AudioDestination::create() is allowed to
+    // be a value: 1 <= numberOfOutputChannels <= maxChannelCount(),
+    // or if maxChannelCount() equals 0, then numberOfOutputChannels must be 2.
+    static unsigned long maxChannelCount();
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp (144719 => 144720)


--- trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp	2013-03-05 06:04:26 UTC (rev 144720)
@@ -114,6 +114,11 @@
     return static_cast<float>(WebKit::Platform::current()->audioHardwareSampleRate());
 }
 
+unsigned long AudioDestination::maxChannelCount()
+{
+    return static_cast<float>(WebKit::Platform::current()->audioHardwareOutputChannels());
+}
+
 void AudioDestinationChromium::render(const WebKit::WebVector<float*>& sourceData, const WebKit::WebVector<float*>& audioData, size_t numberOfFrames)
 {
     bool isNumberOfChannelsGood = audioData.size() == m_numberOfOutputChannels;
@@ -137,8 +142,8 @@
         m_inputFifo->push(&wrapperBus);
     }
 
-    m_renderBus.setChannelMemory(0, audioData[0], numberOfFrames);
-    m_renderBus.setChannelMemory(1, audioData[1], numberOfFrames);
+    for (unsigned i = 0; i < m_numberOfOutputChannels; ++i)
+        m_renderBus.setChannelMemory(i, audioData[i], numberOfFrames);
 
     m_fifo->consume(&m_renderBus, numberOfFrames);
 }

Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp (144719 => 144720)


--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-03-05 06:04:26 UTC (rev 144720)
@@ -63,6 +63,13 @@
     return 44100;
 }
 
+unsigned long AudioDestination::maxChannelCount()
+{
+    // FIXME: query the default audio hardware device to return the actual number
+    // of channels of the device. Also see corresponding FIXME in create().
+    return 0;
+}
+
 #ifndef GST_API_VERSION_1
 static void onGStreamerWavparsePadAddedCallback(GstElement*, GstPad* pad, AudioDestinationGStreamer* destination)
 {

Modified: trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp (144719 => 144720)


--- trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp	2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp	2013-03-05 06:04:26 UTC (rev 144720)
@@ -82,6 +82,15 @@
     return narrowPrecisionToFloat(nominalSampleRate);
 }
 
+unsigned long AudioDestination::maxChannelCount()
+{
+    // FIXME: query the default audio hardware device to return the actual number
+    // of channels of the device. Also see corresponding FIXME in create().
+    // There is a small amount of code which assumes stereo in AudioDestinationMac which
+    // can be upgraded.
+    return 0;
+}
+
 AudioDestinationMac::AudioDestinationMac(AudioIOCallback& callback, float sampleRate)
     : m_outputUnit(0)
     , m_callback(callback)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to