Title: [139262] trunk/Source
Revision
139262
Author
crog...@google.com
Date
2013-01-09 17:40:44 -0800 (Wed, 09 Jan 2013)

Log Message

Allow live/local audio input to be enabled only when needed
https://bugs.webkit.org/show_bug.cgi?id=106490

Source/Platform:

Reviewed by Kenneth Russell.

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

Source/WebCore:

Reviewed by Kenneth Russell.

WebAudio can process live/local audio input using a MediaStreamAudioSourceNode.
But currently the audio back-end is not able to know when/if audio input will be
needed, so it needs to assume the worst and initialize the system to support potential
audio input in all cases.  For some audio back-ends this can end up being less efficient
than initializing for audio output only.  This patch adds the ability for the audio back-end
to be able to initialize itself for audio input later on, only when/if it's needed.

* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::createMediaStreamSource):
* Modules/webaudio/AudioDestinationNode.h:
(AudioDestinationNode):
* Modules/webaudio/DefaultAudioDestinationNode.cpp:
(WebCore::DefaultAudioDestinationNode::DefaultAudioDestinationNode):
(WebCore::DefaultAudioDestinationNode::initialize):
(WebCore::DefaultAudioDestinationNode::uninitialize):
(WebCore::DefaultAudioDestinationNode::createDestination):
(WebCore):
(WebCore::DefaultAudioDestinationNode::enableInput):
* Modules/webaudio/DefaultAudioDestinationNode.h:
(DefaultAudioDestinationNode):
* Modules/webaudio/OfflineAudioDestinationNode.h:
(OfflineAudioDestinationNode):
(WebCore::OfflineAudioDestinationNode::sampleRate):
* platform/audio/AudioDestination.h:
(AudioDestination):
* platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
(WebCore::AudioDestination::create):
* platform/audio/mac/AudioDestinationMac.cpp:
(WebCore::AudioDestination::create):

Source/WebKit/chromium:

Reviewed by Kenneth Russell.

* src/AudioDestinationChromium.cpp:
(WebCore):
(WebCore::AudioDestination::create):
(WebCore::AudioDestinationChromium::AudioDestinationChromium):
(WebCore::AudioDestinationChromium::render):
* src/AudioDestinationChromium.h:
(AudioDestinationChromium):

Modified Paths

Diff

Modified: trunk/Source/Platform/ChangeLog (139261 => 139262)


--- trunk/Source/Platform/ChangeLog	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/Platform/ChangeLog	2013-01-10 01:40:44 UTC (rev 139262)
@@ -1,3 +1,14 @@
+2013-01-09  Chris Rogers  <crog...@google.com>
+
+        Allow live/local audio input to be enabled only when needed
+        https://bugs.webkit.org/show_bug.cgi?id=106490
+
+        Reviewed by Kenneth Russell.
+
+        * chromium/public/Platform.h:
+        (Platform):
+        (WebKit::Platform::createAudioDevice):
+
 2013-01-08  Chris Rogers  <crog...@google.com>
 
         Remove unused/deprecated render() method in chromium WebKit API

Modified: trunk/Source/Platform/chromium/public/Platform.h (139261 => 139262)


--- trunk/Source/Platform/chromium/public/Platform.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/Platform/chromium/public/Platform.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -112,6 +112,12 @@
 
     virtual double audioHardwareSampleRate() { return 0; }
     virtual size_t audioHardwareBufferSize() { return 0; }
+
+    // Creates a device for audio I/O.
+    // Pass in (numberOfInputChannels > 0) if live/local audio input is desired.
+    virtual WebAudioDevice* createAudioDevice(size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfChannels, double sampleRate, WebAudioDevice::RenderCallback*) { return 0; }
+
+    // FIXME: remove deprecated API once chromium switches over to new method.
     virtual WebAudioDevice* createAudioDevice(size_t bufferSize, unsigned numberOfChannels, double sampleRate, WebAudioDevice::RenderCallback*) { return 0; }
 
 

Modified: trunk/Source/WebCore/ChangeLog (139261 => 139262)


--- trunk/Source/WebCore/ChangeLog	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/ChangeLog	2013-01-10 01:40:44 UTC (rev 139262)
@@ -1,3 +1,40 @@
+2013-01-09  Chris Rogers  <crog...@google.com>
+
+        Allow live/local audio input to be enabled only when needed
+        https://bugs.webkit.org/show_bug.cgi?id=106490
+
+        Reviewed by Kenneth Russell.
+        
+        WebAudio can process live/local audio input using a MediaStreamAudioSourceNode.
+        But currently the audio back-end is not able to know when/if audio input will be
+        needed, so it needs to assume the worst and initialize the system to support potential
+        audio input in all cases.  For some audio back-ends this can end up being less efficient
+        than initializing for audio output only.  This patch adds the ability for the audio back-end
+        to be able to initialize itself for audio input later on, only when/if it's needed.
+
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::createMediaStreamSource):
+        * Modules/webaudio/AudioDestinationNode.h:
+        (AudioDestinationNode):
+        * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+        (WebCore::DefaultAudioDestinationNode::DefaultAudioDestinationNode):
+        (WebCore::DefaultAudioDestinationNode::initialize):
+        (WebCore::DefaultAudioDestinationNode::uninitialize):
+        (WebCore::DefaultAudioDestinationNode::createDestination):
+        (WebCore):
+        (WebCore::DefaultAudioDestinationNode::enableInput):
+        * Modules/webaudio/DefaultAudioDestinationNode.h:
+        (DefaultAudioDestinationNode):
+        * Modules/webaudio/OfflineAudioDestinationNode.h:
+        (OfflineAudioDestinationNode):
+        (WebCore::OfflineAudioDestinationNode::sampleRate):
+        * platform/audio/AudioDestination.h:
+        (AudioDestination):
+        * platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
+        (WebCore::AudioDestination::create):
+        * platform/audio/mac/AudioDestinationMac.cpp:
+        (WebCore::AudioDestination::create):
+
 2013-01-09  Tim Horton  <timothy_hor...@apple.com>
 
         Don't drop to huge tile mode if we're only slow-scrolling because of a page overlay

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (139261 => 139262)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2013-01-10 01:40:44 UTC (rev 139262)
@@ -395,9 +395,10 @@
 
     AudioSourceProvider* provider = 0;
 
-    if (mediaStream->isLocal() && mediaStream->audioTracks()->length())
+    if (mediaStream->isLocal() && mediaStream->audioTracks()->length()) {
         provider = destination()->localAudioInputProvider();
-    else {
+        destination()->enableInput();
+    } else {
         // FIXME: get a provider for non-local MediaStreams (like from a remote peer).
         provider = 0;
     }

Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h (139261 => 139262)


--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -54,6 +54,7 @@
 
     virtual unsigned numberOfChannels() const { return 2; } // FIXME: update when multi-channel (more than stereo) is supported
 
+    virtual void enableInput() = 0;
     virtual void startRendering() = 0;
 
     AudioSourceProvider* localAudioInputProvider() { return &m_localAudioInputProvider; }

Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp (139261 => 139262)


--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2013-01-10 01:40:44 UTC (rev 139262)
@@ -30,10 +30,13 @@
 
 #include "Logging.h"
 
+const unsigned EnabledInputChannels = 2;
+
 namespace WebCore {
     
 DefaultAudioDestinationNode::DefaultAudioDestinationNode(AudioContext* context)
     : AudioDestinationNode(context, AudioDestination::hardwareSampleRate())
+    , m_numberOfInputChannels(0)
 {
 }
 
@@ -44,27 +47,48 @@
 
 void DefaultAudioDestinationNode::initialize()
 {
+    ASSERT(isMainThread()); 
     if (isInitialized())
         return;
 
-    float hardwareSampleRate = AudioDestination::hardwareSampleRate();
-    LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
-    
-    m_destination = AudioDestination::create(*this, hardwareSampleRate);
-    
+    createDestination();
     AudioNode::initialize();
 }
 
 void DefaultAudioDestinationNode::uninitialize()
 {
+    ASSERT(isMainThread()); 
     if (!isInitialized())
         return;
 
     m_destination->stop();
+    m_numberOfInputChannels = 0;
 
     AudioNode::uninitialize();
 }
 
+void DefaultAudioDestinationNode::createDestination()
+{
+    float hardwareSampleRate = AudioDestination::hardwareSampleRate();
+    LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
+    
+    m_destination = AudioDestination::create(*this, m_numberOfInputChannels, numberOfChannels(), hardwareSampleRate);
+}
+
+void DefaultAudioDestinationNode::enableInput()
+{
+    ASSERT(isMainThread()); 
+    if (m_numberOfInputChannels != EnabledInputChannels) {
+        m_numberOfInputChannels = EnabledInputChannels;
+
+        if (isInitialized()) {
+            m_destination->stop();
+            createDestination();
+            m_destination->start();
+        }
+    }
+}
+
 void DefaultAudioDestinationNode::startRendering()
 {
     ASSERT(isInitialized());

Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h (139261 => 139262)


--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -43,14 +43,19 @@
     virtual ~DefaultAudioDestinationNode();
     
     // AudioNode   
-    virtual void initialize();
-    virtual void uninitialize();
-    virtual void startRendering();
+    virtual void initialize() OVERRIDE;
+    virtual void uninitialize() OVERRIDE;
+
+    // AudioDestinationNode
+    virtual void enableInput() OVERRIDE;
+    virtual void startRendering() OVERRIDE;
     
 private:
     explicit DefaultAudioDestinationNode(AudioContext*);
+    void createDestination();
 
     OwnPtr<AudioDestination> m_destination;
+    unsigned m_numberOfInputChannels;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h (139261 => 139262)


--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -46,12 +46,15 @@
     virtual ~OfflineAudioDestinationNode();
     
     // AudioNode   
-    virtual void initialize();
-    virtual void uninitialize();
-    virtual float sampleRate() const { return m_renderTarget->sampleRate(); }
+    virtual void initialize() OVERRIDE;
+    virtual void uninitialize() OVERRIDE;
 
-    void startRendering();
-    
+    // AudioDestinationNode
+    virtual void enableInput() OVERRIDE { };
+    virtual void startRendering() OVERRIDE;
+
+    virtual float sampleRate()  const { return m_renderTarget->sampleRate(); }
+
 private:
     OfflineAudioDestinationNode(AudioContext*, AudioBuffer* renderTarget);
 

Modified: trunk/Source/WebCore/platform/audio/AudioDestination.h (139261 => 139262)


--- trunk/Source/WebCore/platform/audio/AudioDestination.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/platform/audio/AudioDestination.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -42,7 +42,8 @@
 
 class AudioDestination {
 public:
-    static PassOwnPtr<AudioDestination> create(AudioIOCallback&, float sampleRate);
+    // Pass in (numberOfInputChannels > 0) if live/local audio input is desired.
+    static PassOwnPtr<AudioDestination> create(AudioIOCallback&, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate);
 
     virtual ~AudioDestination() { }
 

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


--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp	2013-01-10 01:40:44 UTC (rev 139262)
@@ -41,8 +41,16 @@
     return destination->handleMessage(message);
 }
 
-PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, float sampleRate)
+PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
 {
+    // FIXME: Add support for local/live audio input.
+    if (numberOfInputChannels)
+        LOG(Media, "AudioDestination::create(%u, %u, %f) - unhandled input channels", numberOfInputChannels, numberOfOutputChannels, sampleRate);
+
+    // FIXME: Add support for multi-channel (> stereo) output.
+    if (numberOfOutputChannels != 2)
+        LOG(Media, "AudioDestination::create(%u, %u, %f) - unhandled output channels", numberOfInputChannels, numberOfOutputChannels, sampleRate);
+
     return adoptPtr(new AudioDestinationGStreamer(callback, sampleRate));
 }
 

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


--- trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp	2013-01-10 01:40:44 UTC (rev 139262)
@@ -34,6 +34,7 @@
 
 #include "AudioIOCallback.h"
 #include "FloatConversion.h"
+#include "Logging.h"
 #include "VectorMath.h"
 #include <CoreAudio/AudioHardware.h>
 
@@ -44,8 +45,16 @@
 const float kHighThreshold = 1;
 
 // Factory method: Mac-implementation
-PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, float sampleRate)
+PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
 {
+    // FIXME: Add support for local/live audio input.
+    if (numberOfInputChannels)
+        LOG(Media, "AudioDestination::create(%u, %u, %f) - unhandled input channels", numberOfInputChannels, numberOfOutputChannels, sampleRate);
+
+    // FIXME: Add support for multi-channel (> stereo) output.
+    if (numberOfOutputChannels != 2)
+        LOG(Media, "AudioDestination::create(%u, %u, %f) - unhandled output channels", numberOfInputChannels, numberOfOutputChannels, sampleRate);
+
     return adoptPtr(new AudioDestinationMac(callback, sampleRate));
 }
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (139261 => 139262)


--- trunk/Source/WebKit/chromium/ChangeLog	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebKit/chromium/ChangeLog	2013-01-10 01:40:44 UTC (rev 139262)
@@ -1,3 +1,18 @@
+2013-01-09  Chris Rogers  <crog...@google.com>
+
+        Allow live/local audio input to be enabled only when needed
+        https://bugs.webkit.org/show_bug.cgi?id=106490
+
+        Reviewed by Kenneth Russell.
+
+        * src/AudioDestinationChromium.cpp:
+        (WebCore):
+        (WebCore::AudioDestination::create):
+        (WebCore::AudioDestinationChromium::AudioDestinationChromium):
+        (WebCore::AudioDestinationChromium::render):
+        * src/AudioDestinationChromium.h:
+        (AudioDestinationChromium):
+
 2013-01-09  Yue Zhang  <zys...@google.com>
 
         [Chromium] Always enable autocomplete for password fields

Modified: trunk/Source/WebKit/chromium/src/AudioDestinationChromium.cpp (139261 => 139262)


--- trunk/Source/WebKit/chromium/src/AudioDestinationChromium.cpp	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebKit/chromium/src/AudioDestinationChromium.cpp	2013-01-10 01:40:44 UTC (rev 139262)
@@ -44,19 +44,17 @@
 // Size of the FIFO
 const size_t fifoSize = 8192;
 
-// FIXME: add support for multi-channel.
-const unsigned numberOfChannels = 2;
-
 // Factory method: Chromium-implementation
-PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, float sampleRate)
+PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
 {
-    return adoptPtr(new AudioDestinationChromium(callback, sampleRate));
+    return adoptPtr(new AudioDestinationChromium(callback, numberOfInputChannels, numberOfOutputChannels, sampleRate));
 }
 
-AudioDestinationChromium::AudioDestinationChromium(AudioIOCallback& callback, float sampleRate)
+AudioDestinationChromium::AudioDestinationChromium(AudioIOCallback& callback, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
     : m_callback(callback)
-    , m_inputBus(numberOfChannels, renderBufferSize)
-    , m_renderBus(numberOfChannels, renderBufferSize, false)
+    , m_numberOfOutputChannels(numberOfOutputChannels)
+    , m_inputBus(numberOfInputChannels, renderBufferSize)
+    , m_renderBus(numberOfOutputChannels, renderBufferSize, false)
     , m_sampleRate(sampleRate)
     , m_isPlaying(false)
 {
@@ -68,7 +66,8 @@
     if (m_callbackBufferSize + renderBufferSize > fifoSize)
         return;
 
-    m_audioDevice = adoptPtr(WebKit::Platform::current()->createAudioDevice(m_callbackBufferSize, numberOfChannels, sampleRate, this));
+    // FIXME: switch to new API (with input channels) once chromium supports it.
+    m_audioDevice = adoptPtr(WebKit::Platform::current()->createAudioDevice(m_callbackBufferSize, numberOfOutputChannels, sampleRate, this));
     ASSERT(m_audioDevice);
 
     // Create a FIFO to handle the possibility of the callback size
@@ -76,10 +75,10 @@
     // contains enough data, the data will be provided directly.
     // Otherwise, the FIFO will call the provider enough times to
     // satisfy the request for data.
-    m_fifo = adoptPtr(new AudioPullFIFO(*this, numberOfChannels, fifoSize, renderBufferSize));
+    m_fifo = adoptPtr(new AudioPullFIFO(*this, numberOfOutputChannels, fifoSize, renderBufferSize));
 
     // Input buffering.
-    m_inputFifo = adoptPtr(new AudioFIFO(numberOfChannels, fifoSize));
+    m_inputFifo = adoptPtr(new AudioFIFO(numberOfInputChannels, fifoSize));
 
     // If the callback size does not match the render size, then we need to buffer some
     // extra silence for the input. Otherwise, we can over-consume the input FIFO.
@@ -118,7 +117,7 @@
 
 void AudioDestinationChromium::render(const WebVector<float*>& sourceData, const WebVector<float*>& audioData, size_t numberOfFrames)
 {
-    bool isNumberOfChannelsGood = audioData.size() == numberOfChannels;
+    bool isNumberOfChannelsGood = audioData.size() == m_numberOfOutputChannels;
     if (!isNumberOfChannelsGood) {
         ASSERT_NOT_REACHED();
         return;

Modified: trunk/Source/WebKit/chromium/src/AudioDestinationChromium.h (139261 => 139262)


--- trunk/Source/WebKit/chromium/src/AudioDestinationChromium.h	2013-01-10 01:33:46 UTC (rev 139261)
+++ trunk/Source/WebKit/chromium/src/AudioDestinationChromium.h	2013-01-10 01:40:44 UTC (rev 139262)
@@ -47,7 +47,7 @@
 
 class AudioDestinationChromium : public AudioDestination, public WebKit::WebAudioDevice::RenderCallback, public AudioSourceProvider {
 public:
-    AudioDestinationChromium(AudioIOCallback&, float sampleRate);
+    AudioDestinationChromium(AudioIOCallback&, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate);
     virtual ~AudioDestinationChromium();
 
     virtual void start();
@@ -64,6 +64,7 @@
 
 private:
     AudioIOCallback& m_callback;
+    unsigned m_numberOfOutputChannels;
     AudioBus m_inputBus;
     AudioBus m_renderBus;
     float m_sampleRate;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to