<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[190115] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/190115">190115</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2015-09-22 07:31:24 -0700 (Tue, 22 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MediaStream Mac] implement WebAudioSourceProvider
https://bugs.webkit.org/show_bug.cgi?id=149419

Reviewed by Darin Adler.

* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::audioSourceProvider): New.
* Modules/mediastream/MediaStreamTrack.h:

* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::createMediaStreamSource): Rewrite.

* Modules/webaudio/MediaStreamAudioDestinationNode.cpp:
(WebCore::MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode): We know the Vector
  size, so reserve capacity.

* Modules/webaudio/MediaStreamAudioSource.cpp:
(WebCore::MediaStreamAudioSource::audioSourceProvider): Add.
* Modules/webaudio/MediaStreamAudioSource.h:
(WebCore::MediaStreamAudioSource::~MediaStreamAudioSource):
(WebCore::MediaStreamAudioSource::deviceId):
(WebCore::MediaStreamAudioSource::setDeviceId):
(WebCore::MediaStreamAudioSource::useIDForTrackID): Deleted.

* Modules/webaudio/MediaStreamAudioSourceNode.cpp:
(WebCore::MediaStreamAudioSourceNode::create): Context and track can't be null so take references.
(WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode): Ditto.
(WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode): Clear provider client.
(WebCore::MediaStreamAudioSourceNode::setFormat): Create a resampler when necessary.
(WebCore::MediaStreamAudioSourceNode::process): Process.
(WebCore::MediaStreamAudioSourceNode::reset): Deleted.
* Modules/webaudio/MediaStreamAudioSourceNode.h:
(WebCore::MediaStreamAudioSourceNode::mediaStream):
(WebCore::MediaStreamAudioSourceNode::audioSourceProvider): Deleted.

* WebCore.xcodeproj/project.pbxproj: Add WebAudioSourceProviderAVFObjC.cpp/h.

* platform/mediastream/MediaStreamTrackPrivate.cpp:
(WebCore::MediaStreamTrackPrivate::audioSourceProvider): New, passthrough to source.
* platform/mediastream/MediaStreamTrackPrivate.h:
* platform/mediastream/RealtimeMediaSource.h:
(WebCore::RealtimeMediaSource::audioSourceProvider):

* platform/mediastream/mac/AVAudioCaptureSource.h:
* platform/mediastream/mac/AVAudioCaptureSource.mm:
(WebCore::AVAudioCaptureSource::audioSourceProvider): New.
* platform/mediastream/mac/AVCaptureDeviceManager.mm:
* platform/mediastream/mac/AVMediaCaptureSource.h:
* platform/mediastream/mac/AVMediaCaptureSource.mm:
(WebCore::AVMediaCaptureSource::audioSourceProvider): Assert, this shouldn't be reachable.

* platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h: Added.
* platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm: Added.
(WebCore::WebAudioSourceProviderAVFObjC::create):
(WebCore::WebAudioSourceProviderAVFObjC::WebAudioSourceProviderAVFObjC):
(WebCore::WebAudioSourceProviderAVFObjC::~WebAudioSourceProviderAVFObjC):
(WebCore::WebAudioSourceProviderAVFObjC::startProducingData):
(WebCore::WebAudioSourceProviderAVFObjC::stopProducingData):
(WebCore::WebAudioSourceProviderAVFObjC::provideInput):
(WebCore::WebAudioSourceProviderAVFObjC::setClient):
(WebCore::operator==):
(WebCore::operator!=):
(WebCore::WebAudioSourceProviderAVFObjC::prepare):
(WebCore::WebAudioSourceProviderAVFObjC::unprepare):
(WebCore::WebAudioSourceProviderAVFObjC::process):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackh">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAudioContextcpp">trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAudioDestinationNodecpp">trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAudioDestinationNodeh">trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioMediaStreamAudioDestinationNodecpp">trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourcecpp">trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceh">trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceNodecpp">trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceNodeh">trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformmediastreammacWebAudioSourceProviderAVFObjCh">trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacWebAudioSourceProviderAVFObjCmm">trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/ChangeLog        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2015-09-22  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [MediaStream Mac] implement WebAudioSourceProvider
+        https://bugs.webkit.org/show_bug.cgi?id=149419
+
+        Reviewed by Darin Adler.
+
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::audioSourceProvider): New.
+        * Modules/mediastream/MediaStreamTrack.h:
+
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::createMediaStreamSource): Rewrite.
+
+        * Modules/webaudio/MediaStreamAudioDestinationNode.cpp:
+        (WebCore::MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode): We know the Vector
+          size, so reserve capacity.
+
+        * Modules/webaudio/MediaStreamAudioSource.cpp:
+        (WebCore::MediaStreamAudioSource::audioSourceProvider): Add.
+        * Modules/webaudio/MediaStreamAudioSource.h:
+        (WebCore::MediaStreamAudioSource::~MediaStreamAudioSource):
+        (WebCore::MediaStreamAudioSource::deviceId):
+        (WebCore::MediaStreamAudioSource::setDeviceId):
+        (WebCore::MediaStreamAudioSource::useIDForTrackID): Deleted.
+
+        * Modules/webaudio/MediaStreamAudioSourceNode.cpp:
+        (WebCore::MediaStreamAudioSourceNode::create): Context and track can't be null so take references.
+        (WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode): Ditto.
+        (WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode): Clear provider client.
+        (WebCore::MediaStreamAudioSourceNode::setFormat): Create a resampler when necessary.
+        (WebCore::MediaStreamAudioSourceNode::process): Process.
+        (WebCore::MediaStreamAudioSourceNode::reset): Deleted.
+        * Modules/webaudio/MediaStreamAudioSourceNode.h:
+        (WebCore::MediaStreamAudioSourceNode::mediaStream):
+        (WebCore::MediaStreamAudioSourceNode::audioSourceProvider): Deleted.
+
+        * WebCore.xcodeproj/project.pbxproj: Add WebAudioSourceProviderAVFObjC.cpp/h.
+
+        * platform/mediastream/MediaStreamTrackPrivate.cpp:
+        (WebCore::MediaStreamTrackPrivate::audioSourceProvider): New, passthrough to source.
+        * platform/mediastream/MediaStreamTrackPrivate.h:
+        * platform/mediastream/RealtimeMediaSource.h:
+        (WebCore::RealtimeMediaSource::audioSourceProvider):
+
+        * platform/mediastream/mac/AVAudioCaptureSource.h:
+        * platform/mediastream/mac/AVAudioCaptureSource.mm:
+        (WebCore::AVAudioCaptureSource::audioSourceProvider): New.
+        * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+        * platform/mediastream/mac/AVMediaCaptureSource.h:
+        * platform/mediastream/mac/AVMediaCaptureSource.mm:
+        (WebCore::AVMediaCaptureSource::audioSourceProvider): Assert, this shouldn't be reachable.
+
+        * platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h: Added.
+        * platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm: Added.
+        (WebCore::WebAudioSourceProviderAVFObjC::create):
+        (WebCore::WebAudioSourceProviderAVFObjC::WebAudioSourceProviderAVFObjC):
+        (WebCore::WebAudioSourceProviderAVFObjC::~WebAudioSourceProviderAVFObjC):
+        (WebCore::WebAudioSourceProviderAVFObjC::startProducingData):
+        (WebCore::WebAudioSourceProviderAVFObjC::stopProducingData):
+        (WebCore::WebAudioSourceProviderAVFObjC::provideInput):
+        (WebCore::WebAudioSourceProviderAVFObjC::setClient):
+        (WebCore::operator==):
+        (WebCore::operator!=):
+        (WebCore::WebAudioSourceProviderAVFObjC::prepare):
+        (WebCore::WebAudioSourceProviderAVFObjC::unprepare):
+        (WebCore::WebAudioSourceProviderAVFObjC::process):
+
</ins><span class="cx"> 2015-09-22  sangdeug.kim  &lt;sangdeug.kim@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CurrentTime on mediaController is set as 0 when playback is completed.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -235,6 +235,11 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AudioSourceProvider* MediaStreamTrack::audioSourceProvider()
+{
+    return m_private-&gt;audioSourceProvider();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -87,6 +87,8 @@
</span><span class="cx">     RealtimeMediaSource* source() const { return m_private-&gt;source(); }
</span><span class="cx">     MediaStreamTrackPrivate&amp; privateTrack() { return m_private.get(); }
</span><span class="cx"> 
</span><ins>+    AudioSourceProvider* audioSourceProvider();
+
</ins><span class="cx">     void addObserver(Observer*);
</span><span class="cx">     void removeObserver(Observer*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAudioContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -455,38 +455,40 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> PassRefPtr&lt;MediaStreamAudioSourceNode&gt; AudioContext::createMediaStreamSource(MediaStream* mediaStream, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><ins>+    ASSERT(isMainThread());
+
</ins><span class="cx">     ASSERT(mediaStream);
</span><span class="cx">     if (!mediaStream) {
</span><span class="cx">         ec = INVALID_STATE_ERR;
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(isMainThread());
-    lazyInitialize();
</del><ins>+    auto audioTracks = mediaStream-&gt;getAudioTracks();
+    if (audioTracks.isEmpty()) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
</ins><span class="cx"> 
</span><del>-    AudioSourceProvider* provider = nullptr;
-
-    RefPtr&lt;MediaStreamTrack&gt; audioTrack;
-
-    // FIXME: get a provider for non-local MediaStreams (like from a remote peer).
-    for (auto&amp; track : mediaStream-&gt;getAudioTracks()) {
-        audioTrack = track;
-        if (audioTrack-&gt;source()-&gt;isAudioStreamSource()) {
-            auto source = static_cast&lt;MediaStreamAudioSource*&gt;(audioTrack-&gt;source());
-            ASSERT(!source-&gt;deviceId().isEmpty());
-            destination()-&gt;enableInput(source-&gt;deviceId());
-            provider = destination()-&gt;localAudioInputProvider();
</del><ins>+    MediaStreamTrack* providerTrack = nullptr;
+    for (auto&amp; track : audioTracks) {
+        if (track-&gt;audioSourceProvider()) {
+            providerTrack = track.get();
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RefPtr&lt;MediaStreamAudioSourceNode&gt; node = MediaStreamAudioSourceNode::create(this, mediaStream, audioTrack.get(), provider);
</del><ins>+    if (!providerTrack) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
</ins><span class="cx"> 
</span><del>-    // FIXME: Only stereo streams are supported right now. We should be able to accept multi-channel streams.
</del><ins>+    lazyInitialize();
+
+    auto node = MediaStreamAudioSourceNode::create(*this, *mediaStream, *providerTrack);
</ins><span class="cx">     node-&gt;setFormat(2, sampleRate());
</span><span class="cx"> 
</span><del>-    refNode(node.get()); // context keeps reference until node is disconnected
-    return node;
</del><ins>+    refNode(&amp;node.get()); // context keeps reference until node is disconnected
+    return &amp;node.get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;MediaStreamAudioDestinationNode&gt; AudioContext::createMediaStreamDestination()
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAudioDestinationNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     uninitialize();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AudioDestinationNode::render(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames)
</del><ins>+void AudioDestinationNode::render(AudioBus*, AudioBus* destinationBus, size_t numberOfFrames)
</ins><span class="cx"> {
</span><span class="cx">     // We don't want denormals slowing down any of the audio processing
</span><span class="cx">     // since they can very seriously hurt performance.
</span><span class="lines">@@ -71,10 +71,6 @@
</span><span class="cx">     // Let the context take care of any business at the start of each render quantum.
</span><span class="cx">     context()-&gt;handlePreRenderTasks();
</span><span class="cx"> 
</span><del>-    // Prepare the local audio input provider for this render quantum.
-    if (sourceBus)
-        m_localAudioInputProvider.set(sourceBus);
-
</del><span class="cx">     // This will cause the node(s) connected to us to process, which in turn will pull on their input(s),
</span><span class="cx">     // all the way backwards through the rendering graph.
</span><span class="cx">     AudioBus* renderedBus = input(0)-&gt;pull(destinationBus, numberOfFrames);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAudioDestinationNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -62,42 +62,12 @@
</span><span class="cx">     virtual void suspend(std::function&lt;void()&gt;) { }
</span><span class="cx">     virtual void close(std::function&lt;void()&gt;) { }
</span><span class="cx"> 
</span><del>-    AudioSourceProvider* localAudioInputProvider() { return &amp;m_localAudioInputProvider; }
-
</del><span class="cx">     virtual bool isPlaying() { return false; }
</span><span class="cx">     virtual void isPlayingDidChange() override;
</span><span class="cx">     bool isPlayingAudio() const { return m_isEffectivelyPlayingAudio; }
</span><span class="cx">     void setMuted(bool muted) { m_muted = muted; }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    // LocalAudioInputProvider allows us to expose an AudioSourceProvider for local/live audio input.
-    // If there is local/live audio input, we call set() with the audio input data every render quantum.
-    class LocalAudioInputProvider : public AudioSourceProvider {
-    public:
-        LocalAudioInputProvider()
-            : m_sourceBus(AudioBus::create(2, AudioNode::ProcessingSizeInFrames)) // FIXME: handle non-stereo local input.
-        {
-        }
-
-        void set(AudioBus* bus)
-        {
-            if (bus)
-                m_sourceBus-&gt;copyFrom(*bus);
-        }
-
-        // AudioSourceProvider.
-        virtual void provideInput(AudioBus* destinationBus, size_t numberOfFrames) override
-        {
-            bool isGood = destinationBus &amp;&amp; destinationBus-&gt;length() == numberOfFrames &amp;&amp; m_sourceBus-&gt;length() == numberOfFrames;
-            ASSERT(isGood);
-            if (isGood)
-                destinationBus-&gt;copyFrom(*m_sourceBus);
-        }
-
-    private:
-        RefPtr&lt;AudioBus&gt; m_sourceBus;
-    };
-
</del><span class="cx">     virtual double tailTime() const override { return 0; }
</span><span class="cx">     virtual double latencyTime() const override { return 0; }
</span><span class="cx"> 
</span><span class="lines">@@ -107,7 +77,6 @@
</span><span class="cx">     // Counts the number of sample-frames processed by the destination.
</span><span class="cx">     size_t m_currentSampleFrame;
</span><span class="cx"> 
</span><del>-    LocalAudioInputProvider m_localAudioInputProvider;
</del><span class="cx">     bool m_isSilent;
</span><span class="cx">     bool m_isEffectivelyPlayingAudio;
</span><span class="cx">     bool m_muted;
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioMediaStreamAudioDestinationNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -49,9 +49,8 @@
</span><span class="cx">     setNodeType(NodeTypeMediaStreamAudioDestination);
</span><span class="cx"> 
</span><span class="cx">     m_source = MediaStreamAudioSource::create();
</span><del>-    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources;
-    audioSources.append(m_source);
-    m_stream = MediaStream::create(*context-&gt;scriptExecutionContext(), MediaStreamPrivate::create(audioSources, Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;()));
</del><ins>+    Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt; audioSources(1, m_source);
+    m_stream = MediaStream::create(*context-&gt;scriptExecutionContext(), MediaStreamPrivate::create(WTF::move(audioSources), Vector&lt;RefPtr&lt;RealtimeMediaSource&gt;&gt;()));
</ins><span class="cx"> 
</span><span class="cx">     m_source-&gt;setAudioFormat(numberOfChannels, context-&gt;sampleRate());
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -24,11 +24,11 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><ins>+#include &quot;MediaStreamAudioSource.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><del>-#include &quot;MediaStreamAudioSource.h&quot;
-
</del><ins>+#include &quot;AudioSourceProvider.h&quot;
</ins><span class="cx"> #include &quot;NotImplemented.h&quot;
</span><span class="cx"> #include &quot;UUID.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -58,9 +58,15 @@
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=122430
</span><span class="cx">     notImplemented();
</span><span class="cx">     return m_currentStates;
</span><del>-    
</del><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AudioSourceProvider* MediaStreamAudioSource::audioSourceProvider()
+{
+    // FIXME: implement this.
+    notImplemented();
+    return nullptr;
+}
+
</ins><span class="cx"> void MediaStreamAudioSource::addAudioConsumer(PassRefPtr&lt;AudioDestinationConsumer&gt; consumer)
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_audioConsumersLock);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -47,10 +47,8 @@
</span><span class="cx"> 
</span><span class="cx">     ~MediaStreamAudioSource() { }
</span><span class="cx"> 
</span><del>-    virtual bool useIDForTrackID() const { return true; }
-
-    virtual RefPtr&lt;RealtimeMediaSourceCapabilities&gt; capabilities() const;
-    virtual const RealtimeMediaSourceStates&amp; states();
</del><ins>+    RefPtr&lt;RealtimeMediaSourceCapabilities&gt; capabilities() const override;
+    const RealtimeMediaSourceStates&amp; states() override;
</ins><span class="cx">     
</span><span class="cx">     const String&amp; deviceId() const { return m_deviceId; }
</span><span class="cx">     void setDeviceId(const String&amp; deviceId) { m_deviceId = deviceId; }
</span><span class="lines">@@ -65,6 +63,8 @@
</span><span class="cx"> private:
</span><span class="cx">     MediaStreamAudioSource();
</span><span class="cx"> 
</span><ins>+    AudioSourceProvider* audioSourceProvider() override;
+
</ins><span class="cx">     String m_deviceId;
</span><span class="cx">     Lock m_audioConsumersLock;
</span><span class="cx">     Vector&lt;RefPtr&lt;AudioDestinationConsumer&gt;&gt; m_audioConsumers;
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -35,18 +35,21 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-Ref&lt;MediaStreamAudioSourceNode&gt; MediaStreamAudioSourceNode::create(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, AudioSourceProvider* audioSourceProvider)
</del><ins>+Ref&lt;MediaStreamAudioSourceNode&gt; MediaStreamAudioSourceNode::create(AudioContext&amp; context, MediaStream&amp; mediaStream, MediaStreamTrack&amp; audioTrack)
</ins><span class="cx"> {
</span><del>-    return adoptRef(*new MediaStreamAudioSourceNode(context, mediaStream, audioTrack, audioSourceProvider));
</del><ins>+    return adoptRef(*new MediaStreamAudioSourceNode(context, mediaStream, audioTrack));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, AudioSourceProvider* audioSourceProvider)
-    : AudioNode(context, context-&gt;sampleRate())
</del><ins>+MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext&amp; context, MediaStream&amp; mediaStream, MediaStreamTrack&amp; audioTrack)
+    : AudioNode(&amp;context, context.sampleRate())
</ins><span class="cx">     , m_mediaStream(mediaStream)
</span><span class="cx">     , m_audioTrack(audioTrack)
</span><del>-    , m_audioSourceProvider(audioSourceProvider)
-    , m_sourceNumberOfChannels(0)
</del><span class="cx"> {
</span><ins>+    AudioSourceProvider* audioSourceProvider = m_audioTrack-&gt;audioSourceProvider();
+    ASSERT(audioSourceProvider);
+
+    audioSourceProvider-&gt;setClient(this);
+    
</ins><span class="cx">     // Default to stereo. This could change depending on the format of the MediaStream's audio track.
</span><span class="cx">     addOutput(std::make_unique&lt;AudioNodeOutput&gt;(this, 2));
</span><span class="cx"> 
</span><span class="lines">@@ -57,14 +60,18 @@
</span><span class="cx"> 
</span><span class="cx"> MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode()
</span><span class="cx"> {
</span><ins>+    AudioSourceProvider* audioSourceProvider = m_audioTrack-&gt;audioSourceProvider();
+    ASSERT(audioSourceProvider);
+    audioSourceProvider-&gt;setClient(nullptr);
</ins><span class="cx">     uninitialize();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaStreamAudioSourceNode::setFormat(size_t numberOfChannels, float sourceSampleRate)
</span><span class="cx"> {
</span><del>-    if (numberOfChannels != m_sourceNumberOfChannels || sourceSampleRate != sampleRate()) {
</del><ins>+    float sampleRate = this-&gt;sampleRate();
+    if (numberOfChannels != m_sourceNumberOfChannels || sourceSampleRate != sampleRate) {
</ins><span class="cx">         // The sample-rate must be equal to the context's sample-rate.
</span><del>-        if (!numberOfChannels || numberOfChannels &gt; AudioContext::maxNumberOfChannels() || sourceSampleRate != sampleRate()) {
</del><ins>+        if (!numberOfChannels || numberOfChannels &gt; AudioContext::maxNumberOfChannels() || sourceSampleRate != sampleRate) {
</ins><span class="cx">             // process() will generate silence for these uninitialized values.
</span><span class="cx">             LOG(Media, &quot;MediaStreamAudioSourceNode::setFormat(%u, %f) - unhandled format change&quot;, static_cast&lt;unsigned&gt;(numberOfChannels), sourceSampleRate);
</span><span class="cx">             m_sourceNumberOfChannels = 0;
</span><span class="lines">@@ -75,7 +82,17 @@
</span><span class="cx">         std::lock_guard&lt;Lock&gt; lock(m_processMutex);
</span><span class="cx"> 
</span><span class="cx">         m_sourceNumberOfChannels = numberOfChannels;
</span><ins>+        m_sourceSampleRate = sourceSampleRate;
</ins><span class="cx"> 
</span><ins>+        if (sourceSampleRate == sampleRate)
+            m_multiChannelResampler = nullptr;
+        else {
+            double scaleFactor = sourceSampleRate / sampleRate;
+            m_multiChannelResampler = std::make_unique&lt;MultiChannelResampler&gt;(scaleFactor, numberOfChannels);
+        }
+
+        m_sourceNumberOfChannels = numberOfChannels;
+
</ins><span class="cx">         {
</span><span class="cx">             // The context must be locked when changing the number of output channels.
</span><span class="cx">             AudioContext::AutoLocker contextLocker(*context());
</span><span class="lines">@@ -89,17 +106,13 @@
</span><span class="cx"> void MediaStreamAudioSourceNode::process(size_t numberOfFrames)
</span><span class="cx"> {
</span><span class="cx">     AudioBus* outputBus = output(0)-&gt;bus();
</span><ins>+    AudioSourceProvider* provider = m_audioTrack-&gt;audioSourceProvider();
</ins><span class="cx"> 
</span><del>-    if (!audioSourceProvider()) {
</del><ins>+    if (!mediaStream() || !m_sourceNumberOfChannels || !m_sourceSampleRate || !provider) {
</ins><span class="cx">         outputBus-&gt;zero();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!mediaStream() || m_sourceNumberOfChannels != outputBus-&gt;numberOfChannels()) {
-        outputBus-&gt;zero();
-        return;
-    }
-
</del><span class="cx">     // Use std::try_to_lock to avoid contention in the real-time audio thread.
</span><span class="cx">     // If we fail to acquire the lock then the MediaStream must be in the middle of
</span><span class="cx">     // a format change, so we output silence in this case.
</span><span class="lines">@@ -110,13 +123,16 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    audioSourceProvider()-&gt;provideInput(outputBus, numberOfFrames);
</del><ins>+    if (m_multiChannelResampler.get()) {
+        ASSERT(m_sourceSampleRate != sampleRate());
+        m_multiChannelResampler-&gt;process(provider, outputBus, numberOfFrames);
+    } else {
+        // Bypass the resampler completely if the source is at the context's sample-rate.
+        ASSERT(m_sourceSampleRate == sampleRate());
+        provider-&gt;provideInput(outputBus, numberOfFrames);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaStreamAudioSourceNode::reset()
-{
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEB_AUDIO) &amp;&amp; ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioMediaStreamAudioSourceNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -31,46 +31,47 @@
</span><span class="cx"> #include &quot;AudioSourceProvider.h&quot;
</span><span class="cx"> #include &quot;AudioSourceProviderClient.h&quot;
</span><span class="cx"> #include &quot;MediaStream.h&quot;
</span><ins>+#include &quot;MultiChannelResampler.h&quot;
</ins><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><del>-#include &lt;wtf/PassRefPtr.h&gt;
</del><ins>+#include &lt;wtf/RefPtr.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class AudioContext;
</span><ins>+class MultiChannelResampler;
</ins><span class="cx"> 
</span><span class="cx"> class MediaStreamAudioSourceNode : public AudioNode, public AudioSourceProviderClient {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;MediaStreamAudioSourceNode&gt; create(AudioContext*, MediaStream*, MediaStreamTrack*, AudioSourceProvider*);
</del><ins>+    static Ref&lt;MediaStreamAudioSourceNode&gt; create(AudioContext&amp;, MediaStream&amp;, MediaStreamTrack&amp;);
</ins><span class="cx"> 
</span><span class="cx">     virtual ~MediaStreamAudioSourceNode();
</span><span class="cx"> 
</span><del>-    MediaStream* mediaStream() { return m_mediaStream.get(); }
</del><ins>+    MediaStream* mediaStream() { return &amp;m_mediaStream.get(); }
</ins><span class="cx"> 
</span><span class="cx">     // AudioNode
</span><del>-    virtual void process(size_t framesToProcess) override;
-    virtual void reset() override;
</del><ins>+    void process(size_t framesToProcess) override;
+    void reset() override { }
</ins><span class="cx"> 
</span><span class="cx">     // AudioSourceProviderClient
</span><del>-    virtual void setFormat(size_t numberOfChannels, float sampleRate) override;
</del><ins>+    void setFormat(size_t numberOfChannels, float sampleRate) override;
</ins><span class="cx"> 
</span><del>-    AudioSourceProvider* audioSourceProvider() const { return m_audioSourceProvider; }
-
</del><span class="cx"> private:
</span><del>-    MediaStreamAudioSourceNode(AudioContext*, MediaStream*, MediaStreamTrack*, AudioSourceProvider*);
</del><ins>+    MediaStreamAudioSourceNode(AudioContext&amp;, MediaStream&amp;, MediaStreamTrack&amp;);
</ins><span class="cx"> 
</span><del>-    virtual double tailTime() const override { return 0; }
-    virtual double latencyTime() const override { return 0; }
</del><ins>+    double tailTime() const override { return 0; }
+    double latencyTime() const override { return 0; }
</ins><span class="cx"> 
</span><span class="cx">     // As an audio source, we will never propagate silence.
</span><del>-    virtual bool propagatesSilence() const override { return false; }
</del><ins>+    bool propagatesSilence() const override { return false; }
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;MediaStream&gt; m_mediaStream;
-    RefPtr&lt;MediaStreamTrack&gt; m_audioTrack;
-    AudioSourceProvider* m_audioSourceProvider;
</del><ins>+    Ref&lt;MediaStream&gt; m_mediaStream;
+    Ref&lt;MediaStreamTrack&gt; m_audioTrack;
+    std::unique_ptr&lt;MultiChannelResampler&gt; m_multiChannelResampler;
</ins><span class="cx"> 
</span><span class="cx">     Lock m_processMutex;
</span><span class="cx"> 
</span><del>-    unsigned m_sourceNumberOfChannels;
</del><ins>+    unsigned m_sourceNumberOfChannels { 0 };
+    double m_sourceSampleRate { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -340,6 +340,8 @@
</span><span class="cx">                 07CA120E182D67D800D12197 /* JSRTCPeerConnectionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07CA120D182D67D800D12197 /* JSRTCPeerConnectionCustom.cpp */; };
</span><span class="cx">                 07CE77D516712A6A00C55A47 /* InbandTextTrackPrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 07D07B141834158800ABDD3C /* JSRTCSessionDescriptionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07D07B131834158800ABDD3C /* JSRTCSessionDescriptionCustom.cpp */; };
</span><ins>+                07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */; };
+                07D637411BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */; };
</ins><span class="cx">                 07DC5FD417D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07DC5FD317D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp */; };
</span><span class="cx">                 07E116B11489C9A100EC5ACE /* JSTextTrackCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E116B01489C9A100EC5ACE /* JSTextTrackCustom.cpp */; };
</span><span class="cx">                 07E117071489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E117061489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp */; };
</span><span class="lines">@@ -6694,7 +6696,7 @@
</span><span class="cx">                 FD31608612B026F700C1A359 /* AudioResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = FD31605012B026F700C1A359 /* AudioResampler.h */; };
</span><span class="cx">                 FD31608712B026F700C1A359 /* AudioResamplerKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD31605112B026F700C1A359 /* AudioResamplerKernel.cpp */; };
</span><span class="cx">                 FD31608812B026F700C1A359 /* AudioResamplerKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = FD31605212B026F700C1A359 /* AudioResamplerKernel.h */; };
</span><del>-                FD31608912B026F700C1A359 /* AudioSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = FD31605312B026F700C1A359 /* AudioSourceProvider.h */; };
</del><ins>+                FD31608912B026F700C1A359 /* AudioSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = FD31605312B026F700C1A359 /* AudioSourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 FD31608A12B026F700C1A359 /* AudioUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD31605412B026F700C1A359 /* AudioUtilities.cpp */; };
</span><span class="cx">                 FD31608B12B026F700C1A359 /* AudioUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = FD31605512B026F700C1A359 /* AudioUtilities.h */; };
</span><span class="cx">                 FD31608C12B026F700C1A359 /* Biquad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD31605612B026F700C1A359 /* Biquad.cpp */; };
</span><span class="lines">@@ -7492,6 +7494,8 @@
</span><span class="cx">                 07CA120D182D67D800D12197 /* JSRTCPeerConnectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRTCPeerConnectionCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivateClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07D07B131834158800ABDD3C /* JSRTCSessionDescriptionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRTCSessionDescriptionCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAudioSourceProviderAVFObjC.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebAudioSourceProviderAVFObjC.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 07DC5FD317D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRTCStatsResponseCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07E116B01489C9A100EC5ACE /* JSTextTrackCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07E117061489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCueCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -15002,6 +15006,8 @@
</span><span class="cx">                                 070363DF181A1CDC00C074A5 /* AVVideoCaptureSource.mm */,
</span><span class="cx">                                 4A0FFAA31AAF5EF60062803B /* RealtimeMediaSourceCenterMac.cpp */,
</span><span class="cx">                                 4A0FFAA41AAF5EF60062803B /* RealtimeMediaSourceCenterMac.h */,
</span><ins>+                                07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */,
+                                07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = mac;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -26591,6 +26597,7 @@
</span><span class="cx">                                 BC85F23D151915E000BC17BE /* RenderNamedFlowThread.h in Headers */,
</span><span class="cx">                                 BCEA4880097D93020094C9E4 /* RenderObject.h in Headers */,
</span><span class="cx">                                 BCFA930810333193007B25D1 /* RenderOverflow.h in Headers */,
</span><ins>+                                07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */,
</ins><span class="cx">                                 A43BF59D1149292800C643CA /* RenderProgress.h in Headers */,
</span><span class="cx">                                 B5B65874186FDE4C009C26E8 /* RenderPtr.h in Headers */,
</span><span class="cx">                                 31B313DF1B6988C500F2AABC /* NSButtonCellSPI.h in Headers */,
</span><span class="lines">@@ -30393,6 +30400,7 @@
</span><span class="cx">                                 AA2A5ACD16A485FA00975A25 /* SpeechSynthesisVoice.cpp in Sources */,
</span><span class="cx">                                 A78FE13B12366B1000ACE8D0 /* SpellChecker.cpp in Sources */,
</span><span class="cx">                                 B8DBDB4D130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp in Sources */,
</span><ins>+                                07D637411BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm in Sources */,
</ins><span class="cx">                                 5103C2B11BA22D1A00E26337 /* LegacyAny.cpp in Sources */,
</span><span class="cx">                                 4512502215DCE37D002F84E2 /* SpinButtonElement.cpp in Sources */,
</span><span class="cx">                                 93309E11099E64920056E581 /* SplitElementCommand.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -150,6 +150,11 @@
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=122428
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
+{
+    return m_source-&gt;audioSourceProvider();
+}
+
</ins><span class="cx"> void MediaStreamTrackPrivate::sourceStopped()
</span><span class="cx"> {
</span><span class="cx">     if (m_isEnded)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -88,6 +88,8 @@
</span><span class="cx">     RefPtr&lt;MediaConstraints&gt; constraints() const;
</span><span class="cx">     void applyConstraints(const MediaConstraints&amp;);
</span><span class="cx"> 
</span><ins>+    AudioSourceProvider* audioSourceProvider();
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&amp;);
</span><span class="cx">     MediaStreamTrackPrivate(RefPtr&lt;RealtimeMediaSource&gt;&amp;&amp;, const String&amp; id);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><ins>+#include &quot;AudioSourceProvider.h&quot;
</ins><span class="cx"> #include &quot;MediaConstraints.h&quot;
</span><span class="cx"> #include &quot;RealtimeMediaSourceCapabilities.h&quot;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="lines">@@ -107,6 +108,8 @@
</span><span class="cx"> 
</span><span class="cx">     void reset();
</span><span class="cx"> 
</span><ins>+    virtual AudioSourceProvider* audioSourceProvider() { return nullptr; }
+    
</ins><span class="cx"> protected:
</span><span class="cx">     RealtimeMediaSource(const String&amp; id, Type, const String&amp; name);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -36,6 +36,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class WebAudioSourceProviderAVFObjC;
+
</ins><span class="cx"> class AVAudioCaptureSource : public AVMediaCaptureSource {
</span><span class="cx"> public:
</span><span class="cx"> 
</span><span class="lines">@@ -61,9 +63,11 @@
</span><span class="cx">     
</span><span class="cx">     void setupCaptureSession() override;
</span><span class="cx">     void updateStates() override;
</span><ins>+    AudioSourceProvider* audioSourceProvider() override;
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;AVCaptureConnection&gt; m_audioConnection;
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;WebAudioSourceProviderAVFObjC&gt; m_audioSourceProvider;
</ins><span class="cx">     std::unique_ptr&lt;AudioStreamBasicDescription&gt; m_inputDescription;
</span><span class="cx">     Vector&lt;Observer*&gt; m_observers;
</span><span class="cx">     Lock m_lock;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #import &quot;NotImplemented.h&quot;
</span><span class="cx"> #import &quot;RealtimeMediaSourceStates.h&quot;
</span><span class="cx"> #import &quot;SoftLinking.h&quot;
</span><ins>+#import &quot;WebAudioSourceProviderAVFObjC.h&quot;
</ins><span class="cx"> #import &lt;AVFoundation/AVFoundation.h&gt;
</span><span class="cx"> #import &lt;CoreAudio/CoreAudioTypes.h&gt;
</span><span class="cx"> #import &lt;wtf/HashSet.h&gt;
</span><span class="lines">@@ -164,6 +165,14 @@
</span><span class="cx">         observer-&gt;process(formatDescription, sampleBuffer);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AudioSourceProvider* AVAudioCaptureSource::audioSourceProvider()
+{
+    if (!m_audioSourceProvider)
+        m_audioSourceProvider = WebAudioSourceProviderAVFObjC::create(*this);
+
+    return m_audioSourceProvider.get();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx">     AVMediaCaptureSource(AVCaptureDevice*, const AtomicString&amp;, RealtimeMediaSource::Type, PassRefPtr&lt;MediaConstraints&gt;);
</span><span class="cx"> 
</span><span class="cx">     const RealtimeMediaSourceStates&amp; states() override;
</span><ins>+    AudioSourceProvider* audioSourceProvider() override;
</ins><span class="cx"> 
</span><span class="cx">     virtual void setupCaptureSession() = 0;
</span><span class="cx">     virtual void updateStates() = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (190114 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2015-09-22 13:59:38 UTC (rev 190114)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -209,6 +209,12 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AudioSourceProvider* AVMediaCaptureSource::audioSourceProvider()
+{
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> @implementation WebCoreAVMediaCaptureSourceObserver
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacWebAudioSourceProviderAVFObjCh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h (0 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h                                (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 WebAudioSourceProviderAVFObjC_h
+#define WebAudioSourceProviderAVFObjC_h
+
+#if ENABLE(WEB_AUDIO) &amp;&amp; ENABLE(MEDIA_STREAM)
+
+#include &quot;AVAudioCaptureSource.h&quot;
+#include &quot;AudioSourceProvider.h&quot;
+#include &lt;wtf/Lock.h&gt;
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
+#include &lt;wtf/RetainPtr.h&gt;
+
+typedef struct AudioBufferList AudioBufferList;
+typedef struct OpaqueAudioConverter* AudioConverterRef;
+typedef struct AudioStreamBasicDescription AudioStreamBasicDescription;
+typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
+typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
+
+namespace WebCore {
+
+class AVAudioCaptureSource;
+class CARingBuffer;
+
+class WebAudioSourceProviderAVFObjC : public RefCounted&lt;WebAudioSourceProviderAVFObjC&gt;, public AudioSourceProvider, public AVAudioCaptureSource::Observer {
+public:
+    static Ref&lt;WebAudioSourceProviderAVFObjC&gt; create(AVAudioCaptureSource&amp;);
+    virtual ~WebAudioSourceProviderAVFObjC();
+
+private:
+    WebAudioSourceProviderAVFObjC(AVAudioCaptureSource&amp;);
+
+    void startProducingData();
+    void stopProducingData();
+
+    // AudioSourceProvider
+    void provideInput(AudioBus*, size_t) override;
+    void setClient(AudioSourceProviderClient*) override;
+
+    // AVAudioCaptureSource::Observer
+    void prepare(const AudioStreamBasicDescription *) override;
+    void unprepare() override;
+    void process(CMFormatDescriptionRef, CMSampleBufferRef) override;
+
+    size_t m_listBufferSize { 0 };
+    std::unique_ptr&lt;AudioBufferList&gt; m_list;
+    RetainPtr&lt;AudioConverterRef&gt; m_converter;
+    std::unique_ptr&lt;AudioStreamBasicDescription&gt; m_inputDescription;
+    std::unique_ptr&lt;AudioStreamBasicDescription&gt; m_outputDescription;
+    std::unique_ptr&lt;CARingBuffer&gt; m_ringBuffer;
+
+    uint64_t m_writeAheadCount { 0 };
+    uint64_t m_writeCount { 0 };
+    uint64_t m_readCount { 0 };
+    AudioSourceProviderClient* m_client { nullptr };
+    AVAudioCaptureSource* m_captureSource { nullptr };
+    bool m_connected { false };
+};
+    
+}
+
+#endif
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacWebAudioSourceProviderAVFObjCmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm (0 => 190115)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm        2015-09-22 14:31:24 UTC (rev 190115)
</span><span class="lines">@@ -0,0 +1,247 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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. 
+ */
+
+#import &quot;config.h&quot;
+#import &quot;WebAudioSourceProviderAVFObjC.h&quot;
+
+#if ENABLE(WEB_AUDIO) &amp;&amp; ENABLE(MEDIA_STREAM)
+
+#import &quot;AudioBus.h&quot;
+#import &quot;AudioChannel.h&quot;
+#import &quot;AudioSourceProviderClient.h&quot;
+#import &quot;CARingBuffer.h&quot;
+#import &quot;Logging.h&quot;
+#import &quot;MediaTimeAVFoundation.h&quot;
+#import &lt;AVFoundation/AVAssetTrack.h&gt;
+#import &lt;AVFoundation/AVAudioMix.h&gt;
+#import &lt;AVFoundation/AVMediaFormat.h&gt;
+#import &lt;AVFoundation/AVPlayerItem.h&gt;
+#import &lt;objc/runtime.h&gt;
+#import &lt;wtf/MainThread.h&gt;
+
+#if !LOG_DISABLED
+#import &lt;wtf/StringPrintStream.h&gt;
+#endif
+
+#import &quot;CoreMediaSoftLink.h&quot;
+
+SOFT_LINK_FRAMEWORK(AVFoundation)
+SOFT_LINK_FRAMEWORK(AudioToolbox)
+
+SOFT_LINK_CLASS(AVFoundation, AVPlayerItem)
+SOFT_LINK_CLASS(AVFoundation, AVMutableAudioMix)
+SOFT_LINK_CLASS(AVFoundation, AVMutableAudioMixInputParameters)
+
+SOFT_LINK(AudioToolbox, AudioConverterConvertComplexBuffer, OSStatus, (AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList* inInputData, AudioBufferList* outOutputData), (inAudioConverter, inNumberPCMFrames, inInputData, outOutputData))
+SOFT_LINK(AudioToolbox, AudioConverterNew, OSStatus, (const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat, AudioConverterRef* outAudioConverter), (inSourceFormat, inDestinationFormat, outAudioConverter))
+
+namespace WebCore {
+
+static const double kRingBufferDuration = 1;
+
+Ref&lt;WebAudioSourceProviderAVFObjC&gt; WebAudioSourceProviderAVFObjC::create(AVAudioCaptureSource&amp; source)
+{
+    return adoptRef(*new WebAudioSourceProviderAVFObjC(source));
+}
+
+WebAudioSourceProviderAVFObjC::WebAudioSourceProviderAVFObjC(AVAudioCaptureSource&amp; source)
+    : m_captureSource(&amp;source)
+{
+}
+
+WebAudioSourceProviderAVFObjC::~WebAudioSourceProviderAVFObjC()
+{
+    if (m_connected)
+        m_captureSource-&gt;removeObserver(this);
+}
+
+void WebAudioSourceProviderAVFObjC::startProducingData()
+{
+    m_captureSource-&gt;startProducingData();
+}
+
+void WebAudioSourceProviderAVFObjC::stopProducingData()
+{
+    m_captureSource-&gt;stopProducingData();
+}
+
+void WebAudioSourceProviderAVFObjC::provideInput(AudioBus* bus, size_t framesToProcess)
+{
+    if (!m_ringBuffer) {
+        bus-&gt;zero();
+        return;
+    }
+
+    uint64_t startFrame = 0;
+    uint64_t endFrame = 0;
+    m_ringBuffer-&gt;getCurrentFrameBounds(startFrame, endFrame);
+
+    if (m_writeCount &lt;= m_readCount + m_writeAheadCount) {
+        bus-&gt;zero();
+        return;
+    }
+
+    uint64_t framesAvailable = endFrame - (m_readCount + m_writeAheadCount);
+    if (framesAvailable &lt; framesToProcess) {
+        framesToProcess = framesAvailable;
+        bus-&gt;zero();
+    }
+
+    ASSERT(bus-&gt;numberOfChannels() == m_ringBuffer-&gt;channelCount());
+
+    for (unsigned i = 0; i &lt; m_list-&gt;mNumberBuffers; ++i) {
+        AudioChannel&amp; channel = *bus-&gt;channel(i);
+        auto&amp; buffer = m_list-&gt;mBuffers[i];
+        buffer.mNumberChannels = 1;
+        buffer.mData = channel.mutableData();
+        buffer.mDataByteSize = channel.length() * sizeof(float);
+    }
+
+    m_ringBuffer-&gt;fetch(m_list.get(), framesToProcess, m_readCount);
+    m_readCount += framesToProcess;
+
+    if (m_converter)
+        AudioConverterConvertComplexBuffer(m_converter.get(), framesToProcess, m_list.get(), m_list.get());
+}
+
+void WebAudioSourceProviderAVFObjC::setClient(AudioSourceProviderClient* client)
+{
+    if (m_client == client)
+        return;
+
+    m_client = client;
+
+    if (m_client &amp;&amp; !m_connected) {
+        m_connected = true;
+        m_captureSource-&gt;addObserver(this);
+        m_captureSource-&gt;startProducingData();
+    } else if (!m_client &amp;&amp; m_connected) {
+        m_captureSource-&gt;removeObserver(this);
+        m_connected = false;
+    }
+}
+
+static bool operator==(const AudioStreamBasicDescription&amp; a, const AudioStreamBasicDescription&amp; b)
+{
+    return a.mSampleRate == b.mSampleRate
+        &amp;&amp; a.mFormatID == b.mFormatID
+        &amp;&amp; a.mFormatFlags == b.mFormatFlags
+        &amp;&amp; a.mBytesPerPacket == b.mBytesPerPacket
+        &amp;&amp; a.mFramesPerPacket == b.mFramesPerPacket
+        &amp;&amp; a.mBytesPerFrame == b.mBytesPerFrame
+        &amp;&amp; a.mChannelsPerFrame == b.mChannelsPerFrame
+        &amp;&amp; a.mBitsPerChannel == b.mBitsPerChannel;
+}
+
+static bool operator!=(const AudioStreamBasicDescription&amp; a, const AudioStreamBasicDescription&amp; b)
+{
+    return !(a == b);
+}
+
+void WebAudioSourceProviderAVFObjC::prepare(const AudioStreamBasicDescription* format)
+{
+    LOG(Media, &quot;WebAudioSourceProviderAVFObjC::prepare(%p)&quot;, this);
+
+    m_inputDescription = std::make_unique&lt;AudioStreamBasicDescription&gt;(*format);
+    int numberOfChannels = format-&gt;mChannelsPerFrame;
+    double sampleRate = format-&gt;mSampleRate;
+    ASSERT(sampleRate &gt;= 0);
+
+    m_outputDescription = std::make_unique&lt;AudioStreamBasicDescription&gt;();
+    m_outputDescription-&gt;mSampleRate = sampleRate;
+    m_outputDescription-&gt;mFormatID = kAudioFormatLinearPCM;
+    m_outputDescription-&gt;mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
+    m_outputDescription-&gt;mBitsPerChannel = 8 * sizeof(Float32);
+    m_outputDescription-&gt;mChannelsPerFrame = numberOfChannels;
+    m_outputDescription-&gt;mFramesPerPacket = 1;
+    m_outputDescription-&gt;mBytesPerPacket = sizeof(Float32);
+    m_outputDescription-&gt;mBytesPerFrame = sizeof(Float32);
+    m_outputDescription-&gt;mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+
+    if (*m_inputDescription != *m_outputDescription) {
+        AudioConverterRef outConverter = nullptr;
+        AudioConverterNew(m_inputDescription.get(), m_outputDescription.get(), &amp;outConverter);
+        m_converter = outConverter;
+    }
+
+    // Make the ringbuffer large enough to store 1 second.
+    uint64_t capacity = kRingBufferDuration * sampleRate;
+    ASSERT(capacity &lt;= SIZE_MAX);
+    if (capacity &gt; SIZE_MAX)
+        return;
+
+    // AudioBufferList is a variable-length struct, so create on the heap with a generic new() operator
+    // with a custom size, and initialize the struct manually.
+    uint64_t bufferListSize = offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * std::max(1, numberOfChannels));
+    ASSERT(bufferListSize &lt;= SIZE_MAX);
+    if (bufferListSize &gt; SIZE_MAX)
+        return;
+
+    m_ringBuffer = std::make_unique&lt;CARingBuffer&gt;();
+    m_ringBuffer-&gt;allocate(numberOfChannels, format-&gt;mBytesPerFrame, static_cast&lt;size_t&gt;(capacity));
+
+    m_listBufferSize = static_cast&lt;size_t&gt;(bufferListSize);
+    m_list = std::unique_ptr&lt;AudioBufferList&gt;(static_cast&lt;AudioBufferList*&gt;(::operator new (m_listBufferSize)));
+    memset(m_list.get(), 0, m_listBufferSize);
+    m_list-&gt;mNumberBuffers = numberOfChannels;
+
+    RefPtr&lt;WebAudioSourceProviderAVFObjC&gt; strongThis = this;
+    callOnMainThread([strongThis, numberOfChannels, sampleRate] {
+        if (strongThis-&gt;m_client)
+            strongThis-&gt;m_client-&gt;setFormat(numberOfChannels, sampleRate);
+    });
+}
+
+void WebAudioSourceProviderAVFObjC::unprepare()
+{
+    m_inputDescription = nullptr;
+    m_outputDescription = nullptr;
+    m_ringBuffer = nullptr;
+    m_list = nullptr;
+    m_listBufferSize = 0;
+}
+
+void WebAudioSourceProviderAVFObjC::process(CMFormatDescriptionRef, CMSampleBufferRef sampleBuffer)
+{
+    if (!m_ringBuffer)
+        return;
+
+    CMItemCount frameCount = CMSampleBufferGetNumSamples(sampleBuffer);
+    CMBlockBufferRef buffer = nil;
+
+    OSStatus err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nullptr, m_list.get(), m_listBufferSize, kCFAllocatorSystemDefault, kCFAllocatorSystemDefault, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &amp;buffer);
+
+    if (err) {
+        LOG(Media, &quot;WebAudioSourceProviderAVFObjC::proess(%p) - CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer returned error %i&quot;, this, err);
+        return;
+    }
+
+    m_ringBuffer-&gt;store(m_list.get(), frameCount, m_writeCount);
+    m_writeCount += frameCount;
+}
+
+}
+
+#endif // ENABLE(WEB_AUDIO) &amp;&amp; ENABLE(MEDIA_STREAM)
</ins></span></pre>
</div>
</div>

</body>
</html>