Add stub implementation for MediaStreamAudioSourceNode
authorcrogers@google.com <crogers@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Jul 2012 22:07:20 +0000 (22:07 +0000)
committercrogers@google.com <crogers@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Jul 2012 22:07:20 +0000 (22:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=90110

Reviewed by Kenneth Russell.

Source/WebCore:

Test: webaudio/mediastreamaudiosourcenode.html

* CMakeLists.txt:
* DerivedSources.make:
* GNUmakefile.list.am:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
Add MediaStreamAudioSourceNode files to make files.

* Modules/webaudio/AudioContext.cpp:
* Modules/webaudio/AudioContext.h:
* Modules/webaudio/AudioContext.idl:
(WebCore::AudioContext::createMediaStreamSource):
Add new createMediaStreamSource() method.

* Modules/webaudio/AudioNode.h:
Add NodeTypeMediaStreamAudioSource.

* Modules/webaudio/MediaStreamAudioSourceNode.cpp: Added.
* Modules/webaudio/MediaStreamAudioSourceNode.h: Added.
(WebCore::MediaStreamAudioSourceNode::create):
(WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode):
(WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode):
(WebCore::MediaStreamAudioSourceNode::setFormat):
(WebCore::MediaStreamAudioSourceNode::process):
(WebCore::MediaStreamAudioSourceNode::reset):
(WebCore::MediaStreamAudioSourceNode::mediaStream):
(WebCore::MediaStreamAudioSourceNode::audioSourceProvider):
Basic MediaStreamAudioSourceNode implementation.

* Modules/webaudio/MediaStreamAudioSourceNode.idl: Added.

LayoutTests:

* webaudio/mediastreamaudiosourcenode-expected.txt: Added.
* webaudio/mediastreamaudiosourcenode.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@124255 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
LayoutTests/ChangeLog
LayoutTests/webaudio/mediastreamaudiosourcenode-expected.txt [new file with mode: 0644]
LayoutTests/webaudio/mediastreamaudiosourcenode.html [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.make
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Modules/webaudio/AudioContext.cpp
Source/WebCore/Modules/webaudio/AudioContext.h
Source/WebCore/Modules/webaudio/AudioContext.idl
Source/WebCore/Modules/webaudio/AudioNode.h
Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp [new file with mode: 0644]
Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h [new file with mode: 0644]
Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.idl [new file with mode: 0644]
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.xcodeproj/project.pbxproj

index 8cbaa7e..25951d7 100644 (file)
@@ -1,3 +1,13 @@
+2012-07-31  Chris Rogers  <crogers@google.com>
+
+        Add stub implementation for MediaStreamAudioSourceNode
+        https://bugs.webkit.org/show_bug.cgi?id=90110
+
+        Reviewed by Kenneth Russell.
+
+        * webaudio/mediastreamaudiosourcenode-expected.txt: Added.
+        * webaudio/mediastreamaudiosourcenode.html: Added.
+
 2012-07-31  Peter Kasting  <pkasting@google.com>
 
         [Chromium] Rebaselines.
diff --git a/LayoutTests/webaudio/mediastreamaudiosourcenode-expected.txt b/LayoutTests/webaudio/mediastreamaudiosourcenode-expected.txt
new file mode 100644 (file)
index 0000000..5927724
--- /dev/null
@@ -0,0 +1,17 @@
+Basic tests for MediaStreamAudioSourceNode API.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS {audio:true} generated stream
+PASS s.audioTracks.length is 1
+PASS s.videoTracks.length is 0
+PASS Source AudioNode has no inputs.
+PASS Source AudioNode has one output.
+PASS connect() exception thrown for illegal destination AudioNode.
+PASS connect() exception thrown for illegal output index.
+PASS connect() exception thrown for illegal input index.
+PASS mediaStreamSource.connect(context.destination) succeeded.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/webaudio/mediastreamaudiosourcenode.html b/LayoutTests/webaudio/mediastreamaudiosourcenode.html
new file mode 100644 (file)
index 0000000..0a7a552
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/audio-testing.js"></script>
+</head>
+
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Basic tests for MediaStreamAudioSourceNode API.");
+
+var context = 0;
+
+function error() {
+    testFailed('Stream generation failed.');
+    finishJSTest();
+}
+
+function getUserMedia(dictionary, callback) {
+    try {
+        navigator.webkitGetUserMedia(dictionary, callback, error);
+    } catch (e) {
+        testFailed('webkitGetUserMedia threw exception :' + e);
+        finishJSTest();
+    }
+}
+
+function gotStream(stream) {
+    s = stream;
+    testPassed('{audio:true} generated stream');
+    shouldBe('s.audioTracks.length', '1');
+    shouldBe('s.videoTracks.length', '0');
+
+    context = new webkitAudioContext();
+
+    // Create an AudioNode from the stream.
+    var mediaStreamSource = context.createMediaStreamSource(stream);
+
+    // Check number of inputs and outputs.
+    if (mediaStreamSource.numberOfInputs == 0)
+        testPassed("Source AudioNode has no inputs.");
+    else
+        testFailed("Source AudioNode should not have inputs.");
+
+    if (mediaStreamSource.numberOfOutputs == 1)
+        testPassed("Source AudioNode has one output.");
+    else
+        testFailed("Source AudioNode should have one output.");
+
+    // Try calling connect() method with illegal values.
+
+    try {
+        mediaStreamSource.connect(0, 0, 0);
+        testFailed("connect() exception should be thrown for illegal destination AudioNode.");
+    } catch(e) {
+        testPassed("connect() exception thrown for illegal destination AudioNode.");
+    }
+
+    try {
+        mediaStreamSource.connect(context.destination, 5, 0);
+        testFailed("connect() exception should be thrown for illegal output index.");
+    } catch(e) {
+        testPassed("connect() exception thrown for illegal output index.");
+    }
+
+    try {
+        mediaStreamSource.connect(context.destination, 0, 5);
+        testFailed("connect() exception should be thrown for illegal input index.");
+    } catch(e) {
+        testPassed("connect() exception thrown for illegal input index.");
+    }
+
+    // Try calling connect() with proper values.
+    try {
+        mediaStreamSource.connect(context.destination, 0, 0);
+        testPassed("mediaStreamSource.connect(context.destination) succeeded.");
+    } catch(e) {
+        testFailed("mediaStreamSource.connect(context.destination) failed.");
+    }
+
+    finishJSTest();
+}
+
+getUserMedia({audio:true}, gotStream);
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 23d2521..76e70fb 100644 (file)
@@ -250,6 +250,7 @@ SET(WebCore_IDL_FILES
     Modules/webaudio/DynamicsCompressorNode.idl
     Modules/webaudio/JavaScriptAudioNode.idl
     Modules/webaudio/MediaElementAudioSourceNode.idl
+    Modules/webaudio/MediaStreamAudioSourceNode.idl
     Modules/webaudio/OfflineAudioCompletionEvent.idl
     Modules/webaudio/Oscillator.idl
     Modules/webaudio/RealtimeAnalyserNode.idl
@@ -881,6 +882,7 @@ SET(WebCore_SOURCES
     Modules/webaudio/DynamicsCompressorNode.cpp
     Modules/webaudio/JavaScriptAudioNode.cpp
     Modules/webaudio/MediaElementAudioSourceNode.cpp
+    Modules/webaudio/MediaStreamAudioSourceNode.cpp
     Modules/webaudio/OfflineAudioCompletionEvent.cpp
     Modules/webaudio/OfflineAudioDestinationNode.cpp
     Modules/webaudio/Oscillator.cpp
index c494805..cc5a322 100644 (file)
@@ -1,3 +1,42 @@
+2012-07-31  Chris Rogers  <crogers@google.com>
+
+        Add stub implementation for MediaStreamAudioSourceNode
+        https://bugs.webkit.org/show_bug.cgi?id=90110
+
+        Reviewed by Kenneth Russell.
+
+        Test: webaudio/mediastreamaudiosourcenode.html
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add MediaStreamAudioSourceNode files to make files.
+
+        * Modules/webaudio/AudioContext.cpp:
+        * Modules/webaudio/AudioContext.h:
+        * Modules/webaudio/AudioContext.idl:
+        (WebCore::AudioContext::createMediaStreamSource):
+        Add new createMediaStreamSource() method.
+
+        * Modules/webaudio/AudioNode.h:
+        Add NodeTypeMediaStreamAudioSource.
+
+        * Modules/webaudio/MediaStreamAudioSourceNode.cpp: Added.
+        * Modules/webaudio/MediaStreamAudioSourceNode.h: Added.
+        (WebCore::MediaStreamAudioSourceNode::create):
+        (WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode):
+        (WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode):
+        (WebCore::MediaStreamAudioSourceNode::setFormat):
+        (WebCore::MediaStreamAudioSourceNode::process):
+        (WebCore::MediaStreamAudioSourceNode::reset):
+        (WebCore::MediaStreamAudioSourceNode::mediaStream):
+        (WebCore::MediaStreamAudioSourceNode::audioSourceProvider):
+        Basic MediaStreamAudioSourceNode implementation.
+
+        * Modules/webaudio/MediaStreamAudioSourceNode.idl: Added.
+
 2012-07-31  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
 
         FractionalLayoutUnit minor math bugs
index 32e6926..3e2ea90 100644 (file)
@@ -140,6 +140,7 @@ BINDING_IDLS = \
     $(WebCore)/Modules/webaudio/DynamicsCompressorNode.idl \
     $(WebCore)/Modules/webaudio/JavaScriptAudioNode.idl \
     $(WebCore)/Modules/webaudio/MediaElementAudioSourceNode.idl \
+    $(WebCore)/Modules/webaudio/MediaStreamAudioSourceNode.idl \
     $(WebCore)/Modules/webaudio/Oscillator.idl \
     $(WebCore)/Modules/webaudio/OfflineAudioCompletionEvent.idl \
     $(WebCore)/Modules/webaudio/RealtimeAnalyserNode.idl \
index 55679a3..f3563d7 100644 (file)
@@ -5741,6 +5741,8 @@ webcore_sources += \
        Source/WebCore/Modules/webaudio/JavaScriptAudioNode.h \
        Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp \
        Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h \
+       Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp \
+       Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h \
        Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h \
        Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp \
        Source/WebCore/Modules/webaudio/OfflineAudioCompletionEvent.h \
@@ -5880,6 +5882,8 @@ webcore_built_sources += \
        DerivedSources/WebCore/JSOfflineAudioCompletionEvent.h \
        DerivedSources/WebCore/JSMediaElementAudioSourceNode.cpp \
        DerivedSources/WebCore/JSMediaElementAudioSourceNode.h \
+       DerivedSources/WebCore/JSMediaStreamAudioSourceNode.cpp \
+       DerivedSources/WebCore/JSMediaStreamAudioSourceNode.h \
        DerivedSources/WebCore/JSRealtimeAnalyserNode.cpp \
        DerivedSources/WebCore/JSRealtimeAnalyserNode.h
 
@@ -5902,6 +5906,7 @@ dom_binding_idls += \
        $(WebCore)/Modules/webaudio/DelayNode.idl \
        $(WebCore)/Modules/webaudio/JavaScriptAudioNode.idl \
        $(WebCore)/Modules/webaudio/MediaElementAudioSourceNode.idl \
+       $(WebCore)/Modules/webaudio/MediaStreamAudioSourceNode.idl \
        $(WebCore)/Modules/webaudio/OfflineAudioCompletionEvent.idl \
     $(WebCore)/Modules/webaudio/Oscillator.idl \
        $(WebCore)/Modules/webaudio/RealtimeAnalyserNode.idl \
index 9ace951..ab8e172 100644 (file)
 #include "WaveShaperNode.h"
 #include "WaveTable.h"
 
+#if ENABLE(MEDIA_STREAM)
+#include "MediaStream.h"
+#include "MediaStreamAudioSourceNode.h"
+#endif
+
 #if ENABLE(VIDEO)
 #include "HTMLMediaElement.h"
 #include "MediaElementAudioSourceNode.h"
@@ -384,6 +389,26 @@ PassRefPtr<MediaElementAudioSourceNode> AudioContext::createMediaElementSource(H
 }
 #endif
 
+#if ENABLE(MEDIA_STREAM)
+PassRefPtr<MediaStreamAudioSourceNode> AudioContext::createMediaStreamSource(MediaStream* mediaStream, ExceptionCode& ec)
+{
+    ASSERT(mediaStream);
+    if (!mediaStream) {
+        ec = INVALID_STATE_ERR;
+        return 0;
+    }
+
+    ASSERT(isMainThread());
+    lazyInitialize();
+
+    // FIXME: For now we don't give it an AudioSourceProvider, so it will output silence.
+    RefPtr<MediaStreamAudioSourceNode> node = MediaStreamAudioSourceNode::create(this, mediaStream, 0);
+
+    refNode(node.get()); // context keeps reference until node is disconnected
+    return node;
+}
+#endif
+
 PassRefPtr<JavaScriptAudioNode> AudioContext::createJavaScriptNode(size_t bufferSize, ExceptionCode& ec)
 {
     // Set number of input/output channels to stereo by default.
index e6fa12d..fd40b84 100644 (file)
@@ -49,6 +49,7 @@ class AudioBuffer;
 class AudioBufferCallback;
 class AudioBufferSourceNode;
 class MediaElementAudioSourceNode;
+class MediaStreamAudioSourceNode;
 class HTMLMediaElement;
 class AudioChannelMerger;
 class AudioChannelSplitter;
@@ -115,6 +116,9 @@ public:
 #if ENABLE(VIDEO)
     PassRefPtr<MediaElementAudioSourceNode> createMediaElementSource(HTMLMediaElement*, ExceptionCode&);
 #endif
+#if ENABLE(MEDIA_STREAM)
+    PassRefPtr<MediaStreamAudioSourceNode> createMediaStreamSource(MediaStream*, ExceptionCode&);
+#endif
     PassRefPtr<AudioGainNode> createGainNode();
     PassRefPtr<BiquadFilterNode> createBiquadFilter();
     PassRefPtr<WaveShaperNode> createWaveShaper();
index 204b0c7..4856d59 100644 (file)
@@ -58,10 +58,17 @@ module webaudio {
 
         // Sources
         AudioBufferSourceNode createBufferSource();
+
 #if defined(ENABLE_VIDEO) && ENABLE_VIDEO
         MediaElementAudioSourceNode createMediaElementSource(in HTMLMediaElement mediaElement)
             raises(DOMException);
 #endif
+
+#if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM
+        MediaStreamAudioSourceNode createMediaStreamSource(in MediaStream mediaStream)
+            raises(DOMException);
+#endif
+
         // Processing nodes
         AudioGainNode createGainNode();
         DelayNode createDelayNode(in [Optional] double maxDelayTime);
index bee78f7..4ef3e65 100644 (file)
@@ -63,6 +63,7 @@ public:
         NodeTypeOscillator,
         NodeTypeAudioBufferSource,
         NodeTypeMediaElementAudioSource,
+        NodeTypeMediaStreamAudioSource,
         NodeTypeJavaScript,
         NodeTypeBiquadFilter,
         NodeTypePanner,
diff --git a/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp b/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp
new file mode 100644 (file)
index 0000000..6a80f04
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO) && ENABLE(MEDIA_STREAM)
+
+#include "MediaStreamAudioSourceNode.h"
+
+#include "AudioContext.h"
+#include "AudioNodeOutput.h"
+#include "Logging.h"
+#include <wtf/Locker.h>
+
+namespace WebCore {
+
+PassRefPtr<MediaStreamAudioSourceNode> MediaStreamAudioSourceNode::create(AudioContext* context, MediaStream* mediaStream, AudioSourceProvider* audioSourceProvider)
+{
+    return adoptRef(new MediaStreamAudioSourceNode(context, mediaStream, audioSourceProvider));
+}
+
+MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* context, MediaStream* mediaStream, AudioSourceProvider* audioSourceProvider)
+    : AudioSourceNode(context, context->sampleRate())
+    , m_mediaStream(mediaStream)
+    , m_audioSourceProvider(audioSourceProvider)
+    , m_sourceNumberOfChannels(0)
+{
+    // Default to stereo. This could change depending on the format of the MediaStream's audio track.
+    addOutput(adoptPtr(new AudioNodeOutput(this, 2)));
+
+    setNodeType(NodeTypeMediaStreamAudioSource);
+
+    initialize();
+}
+
+MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode()
+{
+    uninitialize();
+}
+
+void MediaStreamAudioSourceNode::setFormat(size_t numberOfChannels, float sourceSampleRate)
+{
+    if (numberOfChannels != m_sourceNumberOfChannels || sourceSampleRate != sampleRate()) {
+        // The sample-rate must be equal to the context's sample-rate.
+        if (!numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels() || sourceSampleRate != sampleRate()) {
+            // process() will generate silence for these uninitialized values.
+            LOG(Media, "MediaStreamAudioSourceNode::setFormat(%u, %f) - unhandled format change", static_cast<unsigned>(numberOfChannels), sourceSampleRate);
+            m_sourceNumberOfChannels = 0;
+            return;
+        }
+
+        // Synchronize with process().
+        MutexLocker locker(m_processLock);
+
+        m_sourceNumberOfChannels = numberOfChannels;
+
+        {
+            // The context must be locked when changing the number of output channels.
+            AudioContext::AutoLocker contextLocker(context());
+
+            // Do any necesssary re-configuration to the output's number of channels.
+            output(0)->setNumberOfChannels(numberOfChannels);
+        }
+    }
+}
+
+void MediaStreamAudioSourceNode::process(size_t numberOfFrames)
+{
+    AudioBus* outputBus = output(0)->bus();
+
+    if (!audioSourceProvider()) {
+        outputBus->zero();
+        return;
+    }
+
+    if (!mediaStream() || m_sourceNumberOfChannels != outputBus->numberOfChannels()) {
+        outputBus->zero();
+        return;
+    }
+
+    // Use a tryLock() to avoid contention in the real-time audio thread.
+    // If we fail to acquire the lock then the MediaStream must be in the middle of
+    // a format change, so we output silence in this case.
+    MutexTryLocker tryLocker(m_processLock);
+    if (tryLocker.locked())
+        audioSourceProvider()->provideInput(outputBus, numberOfFrames);
+    else {
+        // We failed to acquire the lock.
+        outputBus->zero();
+    }
+}
+
+void MediaStreamAudioSourceNode::reset()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO) && ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h b/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h
new file mode 100644 (file)
index 0000000..8bdf287
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaStreamAudioSourceNode_h
+#define MediaStreamAudioSourceNode_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioSourceNode.h"
+#include "AudioSourceProvider.h"
+#include "AudioSourceProviderClient.h"
+#include "MediaStream.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class AudioContext;
+
+class MediaStreamAudioSourceNode : public AudioSourceNode, public AudioSourceProviderClient {
+public:
+    static PassRefPtr<MediaStreamAudioSourceNode> create(AudioContext*, MediaStream*, AudioSourceProvider*);
+
+    virtual ~MediaStreamAudioSourceNode();
+
+    MediaStream* mediaStream() { return m_mediaStream.get(); }
+
+    // AudioNode
+    virtual void process(size_t framesToProcess);
+    virtual void reset();
+
+    // AudioSourceProviderClient
+    virtual void setFormat(size_t numberOfChannels, float sampleRate);
+
+    AudioSourceProvider* audioSourceProvider() const { return m_audioSourceProvider; }
+
+private:
+    MediaStreamAudioSourceNode(AudioContext*, MediaStream*, AudioSourceProvider*);
+
+    // As an audio source, we will never propagate silence.
+    virtual bool propagatesSilence() const OVERRIDE { return false; }
+
+    RefPtr<MediaStream> m_mediaStream;
+    AudioSourceProvider* m_audioSourceProvider;
+
+    Mutex m_processLock;
+
+    unsigned m_sourceNumberOfChannels;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // MediaStreamAudioSourceNode_h
diff --git a/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.idl b/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.idl
new file mode 100644 (file)
index 0000000..14b91a2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module audio {
+    interface [
+        Conditional=MEDIA_STREAM,
+        JSGenerateToJSObject
+    ] MediaStreamAudioSourceNode : AudioSourceNode {
+        readonly attribute MediaStream mediaStream;
+    };
+}
index b86ef21..4d7d597 100644 (file)
             'Modules/webaudio/DynamicsCompressorNode.idl',
             'Modules/webaudio/JavaScriptAudioNode.idl',
             'Modules/webaudio/MediaElementAudioSourceNode.idl',
+            'Modules/webaudio/MediaStreamAudioSourceNode.idl',
             'Modules/webaudio/OfflineAudioCompletionEvent.idl',
             'Modules/webaudio/Oscillator.idl',
             'Modules/webaudio/RealtimeAnalyserNode.idl',
             'Modules/webaudio/JavaScriptAudioNode.h',
             'Modules/webaudio/MediaElementAudioSourceNode.cpp',
             'Modules/webaudio/MediaElementAudioSourceNode.h',
+            'Modules/webaudio/MediaStreamAudioSourceNode.cpp',
+            'Modules/webaudio/MediaStreamAudioSourceNode.h',
             'Modules/webaudio/OfflineAudioCompletionEvent.cpp',
             'Modules/webaudio/OfflineAudioCompletionEvent.h',
             'Modules/webaudio/OfflineAudioDestinationNode.cpp',
index 49ed6ca..dfd1082 100644 (file)
                FD629EA3154B47160006D026 /* AudioBasicInspectorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FD629EA1154B47160006D026 /* AudioBasicInspectorNode.h */; };
                FD629EA4154B47160006D026 /* AudioBasicInspectorNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD629EA2154B47160006D026 /* AudioBasicInspectorNode.cpp */; };
                FD62F52E145898D80094B0ED /* AudioSourceProviderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = FD62F52D145898D80094B0ED /* AudioSourceProviderClient.h */; };
+               FD671A77159BB07000197559 /* MediaStreamAudioSourceNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD671A74159BB07000197559 /* MediaStreamAudioSourceNode.cpp */; };
+               FD671A78159BB07000197559 /* MediaStreamAudioSourceNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FD671A75159BB07000197559 /* MediaStreamAudioSourceNode.h */; };
                FD6ED2C3136B8E42003CF072 /* DynamicsCompressorNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD6ED2C1136B8E42003CF072 /* DynamicsCompressorNode.cpp */; };
                FD6ED2C4136B8E42003CF072 /* DynamicsCompressorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FD6ED2C2136B8E42003CF072 /* DynamicsCompressorNode.h */; };
                FD6ED2C7136B8E66003CF072 /* DynamicsCompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD6ED2C5136B8E66003CF072 /* DynamicsCompressor.cpp */; };
                FDB052E01561A42C00B500D6 /* AudioSummingJunction.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB052DE1561A42C00B500D6 /* AudioSummingJunction.h */; };
                FDB1700514A2BAB200A2B5D9 /* MultiChannelResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */; };
                FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */; };
+               FDBD480C159BC6870093EB4F /* JSMediaStreamAudioSourceNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDBD480A159BC6870093EB4F /* JSMediaStreamAudioSourceNode.cpp */; };
+               FDBD480D159BC6870093EB4F /* JSMediaStreamAudioSourceNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDBD480B159BC6870093EB4F /* JSMediaStreamAudioSourceNode.h */; };
                FDC54F041399B0DA008D9117 /* BiquadFilterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */; };
                FDC54F051399B0DA008D9117 /* BiquadFilterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */; };
                FDE6860215B0A93B00BB480C /* WrapShapeFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD7E95A215ACD6090039E3D0 /* WrapShapeFunctions.cpp */; };
                FD629EA1154B47160006D026 /* AudioBasicInspectorNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioBasicInspectorNode.h; sourceTree = "<group>"; };
                FD629EA2154B47160006D026 /* AudioBasicInspectorNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioBasicInspectorNode.cpp; sourceTree = "<group>"; };
                FD62F52D145898D80094B0ED /* AudioSourceProviderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSourceProviderClient.h; sourceTree = "<group>"; };
+               FD671A74159BB07000197559 /* MediaStreamAudioSourceNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamAudioSourceNode.cpp; sourceTree = "<group>"; };
+               FD671A75159BB07000197559 /* MediaStreamAudioSourceNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamAudioSourceNode.h; sourceTree = "<group>"; };
+               FD671A76159BB07000197559 /* MediaStreamAudioSourceNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaStreamAudioSourceNode.idl; sourceTree = "<group>"; };
                FD6ED2C1136B8E42003CF072 /* DynamicsCompressorNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicsCompressorNode.cpp; sourceTree = "<group>"; };
                FD6ED2C2136B8E42003CF072 /* DynamicsCompressorNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicsCompressorNode.h; sourceTree = "<group>"; };
                FD6ED2C5136B8E66003CF072 /* DynamicsCompressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicsCompressor.cpp; sourceTree = "<group>"; };
                FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiChannelResampler.cpp; sourceTree = "<group>"; };
                FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiChannelResampler.h; sourceTree = "<group>"; };
                FDB51CF4159CD70300E227C5 /* WrapShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WrapShapes.h; path = style/WrapShapes.h; sourceTree = "<group>"; };
+       FDBD480A159BC6870093EB4F /* JSMediaStreamAudioSourceNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaStreamAudioSourceNode.cpp; sourceTree = "<group>"; };
+           FDBD480B159BC6870093EB4F /* JSMediaStreamAudioSourceNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaStreamAudioSourceNode.h; sourceTree = "<group>"; };
                FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BiquadFilterNode.cpp; sourceTree = "<group>"; };
                FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BiquadFilterNode.h; sourceTree = "<group>"; };
                FDC54F031399B0DA008D9117 /* BiquadFilterNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BiquadFilterNode.idl; sourceTree = "<group>"; };
                                FD6F252913F5EF0E0065165F /* MediaElementAudioSourceNode.cpp */,
                                FD6F252A13F5EF0E0065165F /* MediaElementAudioSourceNode.h */,
                                FD6F252B13F5EF0E0065165F /* MediaElementAudioSourceNode.idl */,
+                               FD671A74159BB07000197559 /* MediaStreamAudioSourceNode.cpp */,
+                               FD671A75159BB07000197559 /* MediaStreamAudioSourceNode.h */,
+                               FD671A76159BB07000197559 /* MediaStreamAudioSourceNode.idl */,
                                FDA3E955134A49EF008D4B5A /* OfflineAudioCompletionEvent.cpp */,
                                FDA3E956134A49EF008D4B5A /* OfflineAudioCompletionEvent.h */,
                                FDA3E95D134A49FF008D4B5A /* OfflineAudioCompletionEvent.idl */,
                                FDA15ECC12B03F61003A583A /* JSJavaScriptAudioNode.h */,
                                FD23A12313F5FA5900F67001 /* JSMediaElementAudioSourceNode.cpp */,
                                FD23A12413F5FA5900F67001 /* JSMediaElementAudioSourceNode.h */,
+                               FDBD480A159BC6870093EB4F /* JSMediaStreamAudioSourceNode.cpp */,
+                               FDBD480B159BC6870093EB4F /* JSMediaStreamAudioSourceNode.h */,
                                FDF6BAF6134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp */,
                                FDF6BAF7134A4C9800822920 /* JSOfflineAudioCompletionEvent.h */,
                                FDEA6240152102E200479DF0 /* JSOscillator.cpp */,
                                1059459915B42AA0004D37FD /* PropertyNodeList.h in Headers */,
                                1059459F15B42B1A004D37FD /* JSPropertyNodeList.h in Headers */,
                                49B3760D15C6C6840059131D /* ArrayValue.h in Headers */,
+                               FD671A78159BB07000197559 /* MediaStreamAudioSourceNode.h in Headers */,
+                               FDBD480D159BC6870093EB4F /* JSMediaStreamAudioSourceNode.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1059459D15B42B0C004D37FD /* JSPropertyNodeList.cpp in Sources */,
                                CD37B39815C1B971006DC898 /* DiagnosticLoggingKeys.cpp in Sources */,
                                49B3760C15C6C6840059131D /* ArrayValue.cpp in Sources */,
+                               FD671A77159BB07000197559 /* MediaStreamAudioSourceNode.cpp in Sources */,
+                               FDBD480C159BC6870093EB4F /* JSMediaStreamAudioSourceNode.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };