Title: [89478] trunk/Source/WebCore
Revision
89478
Author
[email protected]
Date
2011-06-22 14:14:38 -0700 (Wed, 22 Jun 2011)

Log Message

2011-06-22  Chris Rogers  <[email protected]>

        Reviewed by Kenneth Russell.

        AudioContext needs non-blocking call to create AudioBuffer from audio file data
        https://bugs.webkit.org/show_bug.cgi?id=61947

        No new tests since audio API is not yet implemented.

        * DerivedSources.make:
        * WebCore.gypi:
        * WebCore.xcodeproj/project.pbxproj:
        * webaudio/AsyncAudioDecoder.cpp: Added.
        (WebCore::AsyncAudioDecoder::AsyncAudioDecoder):
        (WebCore::AsyncAudioDecoder::~AsyncAudioDecoder):
        (WebCore::AsyncAudioDecoder::decodeAsync):
        (WebCore::AsyncAudioDecoder::threadEntry):
        (WebCore::AsyncAudioDecoder::runLoop):
        (WebCore::AsyncAudioDecoder::DecodingTask::DecodingTask):
        (WebCore::AsyncAudioDecoder::DecodingTask::decode):
        (WebCore::AsyncAudioDecoder::DecodingTask::notifyCompleteDispatch):
        (WebCore::AsyncAudioDecoder::DecodingTask::notifyComplete):
        * webaudio/AsyncAudioDecoder.h: Added.
        (WebCore::AsyncAudioDecoder::DecodingTask::audioData):
        (WebCore::AsyncAudioDecoder::DecodingTask::sampleRate):
        (WebCore::AsyncAudioDecoder::DecodingTask::successCallback):
        (WebCore::AsyncAudioDecoder::DecodingTask::errorCallback):
        (WebCore::AsyncAudioDecoder::DecodingTask::audioBuffer):
        * webaudio/AudioBufferCallback.h: Added.
        (WebCore::AudioBufferCallback::~AudioBufferCallback):
        * webaudio/AudioBufferCallback.idl: Added.
        * webaudio/AudioContext.cpp:
        (WebCore::AudioContext::decodeAudioData):
        * webaudio/AudioContext.h:
        * webaudio/AudioContext.idl:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (89477 => 89478)


--- trunk/Source/WebCore/ChangeLog	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/ChangeLog	2011-06-22 21:14:38 UTC (rev 89478)
@@ -1,3 +1,39 @@
+2011-06-22  Chris Rogers  <[email protected]>
+
+        Reviewed by Kenneth Russell.
+
+        AudioContext needs non-blocking call to create AudioBuffer from audio file data
+        https://bugs.webkit.org/show_bug.cgi?id=61947
+
+        No new tests since audio API is not yet implemented.
+
+        * DerivedSources.make:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * webaudio/AsyncAudioDecoder.cpp: Added.
+        (WebCore::AsyncAudioDecoder::AsyncAudioDecoder):
+        (WebCore::AsyncAudioDecoder::~AsyncAudioDecoder):
+        (WebCore::AsyncAudioDecoder::decodeAsync):
+        (WebCore::AsyncAudioDecoder::threadEntry):
+        (WebCore::AsyncAudioDecoder::runLoop):
+        (WebCore::AsyncAudioDecoder::DecodingTask::DecodingTask):
+        (WebCore::AsyncAudioDecoder::DecodingTask::decode):
+        (WebCore::AsyncAudioDecoder::DecodingTask::notifyCompleteDispatch):
+        (WebCore::AsyncAudioDecoder::DecodingTask::notifyComplete):
+        * webaudio/AsyncAudioDecoder.h: Added.
+        (WebCore::AsyncAudioDecoder::DecodingTask::audioData):
+        (WebCore::AsyncAudioDecoder::DecodingTask::sampleRate):
+        (WebCore::AsyncAudioDecoder::DecodingTask::successCallback):
+        (WebCore::AsyncAudioDecoder::DecodingTask::errorCallback):
+        (WebCore::AsyncAudioDecoder::DecodingTask::audioBuffer):
+        * webaudio/AudioBufferCallback.h: Added.
+        (WebCore::AudioBufferCallback::~AudioBufferCallback):
+        * webaudio/AudioBufferCallback.idl: Added.
+        * webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::decodeAudioData):
+        * webaudio/AudioContext.h:
+        * webaudio/AudioContext.idl:
+
 2011-06-22  Beth Dakin  <[email protected]>
 
         Reviewed by Simon Fraser.

Modified: trunk/Source/WebCore/DerivedSources.make (89477 => 89478)


--- trunk/Source/WebCore/DerivedSources.make	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/DerivedSources.make	2011-06-22 21:14:38 UTC (rev 89478)
@@ -55,6 +55,7 @@
     AbstractWorker \
     Attr \
     AudioBuffer \
+    AudioBufferCallback \
     AudioBufferSourceNode \
     AudioChannelSplitter \
     AudioChannelMerger \

Modified: trunk/Source/WebCore/WebCore.gypi (89477 => 89478)


--- trunk/Source/WebCore/WebCore.gypi	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/WebCore.gypi	2011-06-22 21:14:38 UTC (rev 89478)
@@ -1415,6 +1415,7 @@
             'storage/StorageInfoQuotaCallback.idl',
             'storage/StorageInfoUsageCallback.idl',
             'webaudio/AudioBuffer.idl',
+            'webaudio/AudioBufferCallback.idl',
             'webaudio/AudioBufferSourceNode.idl',
             'webaudio/AudioChannelMerger.idl',
             'webaudio/AudioChannelSplitter.idl',
@@ -5992,6 +5993,7 @@
             'webaudio/AudioBasicProcessorNode.h',
             'webaudio/AudioBuffer.cpp',
             'webaudio/AudioBuffer.h',
+            'webaudio/AudioBufferCallback.h',
             'webaudio/AudioBufferSourceNode.cpp',
             'webaudio/AudioBufferSourceNode.h',
             'webaudio/AudioChannelMerger.cpp',
@@ -6022,6 +6024,8 @@
             'webaudio/AudioProcessingEvent.cpp',
             'webaudio/AudioProcessingEvent.h',
             'webaudio/AudioSourceNode.h',
+            'webaudio/AsyncAudioDecoder.cpp',
+            'webaudio/AsyncAudioDecoder.h',
             'webaudio/BiquadDSPKernel.cpp',
             'webaudio/BiquadDSPKernel.h',
             'webaudio/BiquadFilterNode.cpp',

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (89477 => 89478)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2011-06-22 21:14:38 UTC (rev 89478)
@@ -5834,6 +5834,9 @@
 		FD537353137B651800008DCE /* ZeroPole.h in Headers */ = {isa = PBXBuildFile; fileRef = FD537351137B651800008DCE /* ZeroPole.h */; };
 		FD537356137B653B00008DCE /* DynamicsCompressorKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD537354137B653B00008DCE /* DynamicsCompressorKernel.cpp */; };
 		FD537357137B653B00008DCE /* DynamicsCompressorKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = FD537355137B653B00008DCE /* DynamicsCompressorKernel.h */; };
+		FD5686C913AC180200B69C68 /* AsyncAudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD5686C713AC180200B69C68 /* AsyncAudioDecoder.cpp */; };
+		FD5686CA13AC180200B69C68 /* AsyncAudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FD5686C813AC180200B69C68 /* AsyncAudioDecoder.h */; };
+		FD5686CC13AC181400B69C68 /* AudioBufferCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FD5686CB13AC181400B69C68 /* AudioBufferCallback.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 */; };
@@ -5895,6 +5898,8 @@
 		FDF09DC91399B62200688E5B /* JSBiquadFilterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDF09DC71399B62200688E5B /* JSBiquadFilterNode.h */; };
 		FDF6BAF8134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDF6BAF6134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp */; };
 		FDF6BAF9134A4C9800822920 /* JSOfflineAudioCompletionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = FDF6BAF7134A4C9800822920 /* JSOfflineAudioCompletionEvent.h */; };
+		FDF7E9C313AC21DB00A51EAC /* JSAudioBufferCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDF7E9C113AC21DB00A51EAC /* JSAudioBufferCallback.cpp */; };
+		FDF7E9C413AC21DB00A51EAC /* JSAudioBufferCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FDF7E9C213AC21DB00A51EAC /* JSAudioBufferCallback.h */; };
 		FE6FD4880F676E5700092873 /* Coordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD4850F676E5700092873 /* Coordinates.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */; };
 		FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD48C0F676E9300092873 /* JSCoordinates.h */; };
@@ -12531,6 +12536,10 @@
 		FD537351137B651800008DCE /* ZeroPole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZeroPole.h; sourceTree = "<group>"; };
 		FD537354137B653B00008DCE /* DynamicsCompressorKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicsCompressorKernel.cpp; sourceTree = "<group>"; };
 		FD537355137B653B00008DCE /* DynamicsCompressorKernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicsCompressorKernel.h; sourceTree = "<group>"; };
+		FD5686C713AC180200B69C68 /* AsyncAudioDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncAudioDecoder.cpp; sourceTree = "<group>"; };
+		FD5686C813AC180200B69C68 /* AsyncAudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncAudioDecoder.h; sourceTree = "<group>"; };
+		FD5686CB13AC181400B69C68 /* AudioBufferCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioBufferCallback.h; sourceTree = "<group>"; };
+		FD5686CD13AC183E00B69C68 /* AudioBufferCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AudioBufferCallback.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>"; };
@@ -12595,6 +12604,8 @@
 		FDF09DC71399B62200688E5B /* JSBiquadFilterNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBiquadFilterNode.h; sourceTree = "<group>"; };
 		FDF6BAF6134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSOfflineAudioCompletionEvent.cpp; sourceTree = "<group>"; };
 		FDF6BAF7134A4C9800822920 /* JSOfflineAudioCompletionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSOfflineAudioCompletionEvent.h; sourceTree = "<group>"; };
+		FDF7E9C113AC21DB00A51EAC /* JSAudioBufferCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAudioBufferCallback.cpp; sourceTree = "<group>"; };
+		FDF7E9C213AC21DB00A51EAC /* JSAudioBufferCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAudioBufferCallback.h; sourceTree = "<group>"; };
 		FE49EF970DC51462004266E1 /* DashboardSupportCSSPropertyNames.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DashboardSupportCSSPropertyNames.in; sourceTree = "<group>"; };
 		FE6FD4850F676E5700092873 /* Coordinates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Coordinates.h; sourceTree = "<group>"; };
 		FE6FD4860F676E5700092873 /* Coordinates.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Coordinates.idl; sourceTree = "<group>"; };
@@ -19810,11 +19821,15 @@
 		FD315FA212B025B100C1A359 /* webaudio */ = {
 			isa = PBXGroup;
 			children = (
+				FD5686C713AC180200B69C68 /* AsyncAudioDecoder.cpp */,
+				FD5686C813AC180200B69C68 /* AsyncAudioDecoder.h */,
 				FD315FAC12B0267500C1A359 /* AudioBasicProcessorNode.cpp */,
 				FD315FAD12B0267500C1A359 /* AudioBasicProcessorNode.h */,
 				FD315FAE12B0267500C1A359 /* AudioBuffer.cpp */,
 				FD315FAF12B0267500C1A359 /* AudioBuffer.h */,
 				FD315FB012B0267500C1A359 /* AudioBuffer.idl */,
+				FD5686CB13AC181400B69C68 /* AudioBufferCallback.h */,
+				FD5686CD13AC183E00B69C68 /* AudioBufferCallback.idl */,
 				FD315FB112B0267500C1A359 /* AudioBufferSourceNode.cpp */,
 				FD315FB212B0267500C1A359 /* AudioBufferSourceNode.h */,
 				FD315FB312B0267500C1A359 /* AudioBufferSourceNode.idl */,
@@ -19990,6 +20005,8 @@
 			children = (
 				FDA15E8112B03EE1003A583A /* JSAudioBuffer.cpp */,
 				FDA15E8212B03EE1003A583A /* JSAudioBuffer.h */,
+				FDF7E9C113AC21DB00A51EAC /* JSAudioBufferCallback.cpp */,
+				FDF7E9C213AC21DB00A51EAC /* JSAudioBufferCallback.h */,
 				FDA15E8312B03EE1003A583A /* JSAudioBufferSourceNode.cpp */,
 				FDA15E8412B03EE1003A583A /* JSAudioBufferSourceNode.h */,
 				FDA15E8512B03EE1003A583A /* JSAudioChannelMerger.cpp */,
@@ -23014,6 +23031,9 @@
 				977E2E0F12F0FC9C00C13379 /* XSSAuditor.h in Headers */,
 				FD537353137B651800008DCE /* ZeroPole.h in Headers */,
 				985BB96E13A94058007A0B69 /* LinkRelAttribute.h in Headers */,
+				FD5686CA13AC180200B69C68 /* AsyncAudioDecoder.h in Headers */,
+				FD5686CC13AC181400B69C68 /* AudioBufferCallback.h in Headers */,
+				FDF7E9C413AC21DB00A51EAC /* JSAudioBufferCallback.h in Headers */,
 				B1AD4E5D13A12A0B00846B27 /* CueIndex.h in Headers */,
 				B1AD4E5F13A12A0B00846B27 /* LoadableTextTrack.h in Headers */,
 				B1AD4E6113A12A0B00846B27 /* LoadableTextTrackImpl.h in Headers */,
@@ -25770,6 +25790,8 @@
 				977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
 				FD537352137B651800008DCE /* ZeroPole.cpp in Sources */,
 				985BB96D13A94058007A0B69 /* LinkRelAttribute.cpp in Sources */,
+				FD5686C913AC180200B69C68 /* AsyncAudioDecoder.cpp in Sources */,
+				FDF7E9C313AC21DB00A51EAC /* JSAudioBufferCallback.cpp in Sources */,
 				B1AD4E5C13A12A0B00846B27 /* CueIndex.cpp in Sources */,
 				B1AD4E5E13A12A0B00846B27 /* LoadableTextTrack.cpp in Sources */,
 				B1AD4E6013A12A0B00846B27 /* LoadableTextTrackImpl.cpp in Sources */,

Added: trunk/Source/WebCore/webaudio/AsyncAudioDecoder.cpp (0 => 89478)


--- trunk/Source/WebCore/webaudio/AsyncAudioDecoder.cpp	                        (rev 0)
+++ trunk/Source/WebCore/webaudio/AsyncAudioDecoder.cpp	2011-06-22 21:14:38 UTC (rev 89478)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2011, 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)
+
+#include "AsyncAudioDecoder.h"
+
+#include "ArrayBuffer.h"
+#include "AudioBuffer.h"
+#include "AudioBufferCallback.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+AsyncAudioDecoder::AsyncAudioDecoder()
+{
+    // Start worker thread.
+    MutexLocker lock(m_threadCreationMutex);
+    m_threadID = createThread(AsyncAudioDecoder::threadEntry, this, "Audio Decoder");
+}
+
+AsyncAudioDecoder::~AsyncAudioDecoder()
+{
+    m_queue.kill();
+    
+    // Stop thread.
+    void* exitCode;
+    waitForThreadCompletion(m_threadID, &exitCode);
+    m_threadID = 0;
+}
+
+void AsyncAudioDecoder::decodeAsync(ArrayBuffer* audioData, double sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback)
+{
+    ASSERT(isMainThread());
+    ASSERT(audioData);
+    if (!audioData)
+        return;
+
+    OwnPtr<DecodingTask> decodingTask = adoptPtr(new DecodingTask(audioData, sampleRate, successCallback, errorCallback));
+    m_queue.append(decodingTask.release()); // note that ownership of the task is effectively taken by the queue.
+}
+
+// Asynchronously decode in this thread.
+void* AsyncAudioDecoder::threadEntry(void* threadData)
+{
+    ASSERT(threadData);
+    AsyncAudioDecoder* decoder = reinterpret_cast<AsyncAudioDecoder*>(threadData);
+    decoder->runLoop();
+    return 0;
+}
+
+void AsyncAudioDecoder::runLoop()
+{
+    ASSERT(!isMainThread());
+
+    {
+        // Wait for until we have m_threadID established before starting the run loop.
+        MutexLocker lock(m_threadCreationMutex);
+    }
+
+    // Keep running decoding tasks until we're killed.
+    while (OwnPtr<DecodingTask> decodingTask = m_queue.waitForMessage()) {
+        // Let the task take care of its own ownership.
+        // See DecodingTask::notifyComplete() for cleanup.
+        decodingTask.leakPtr()->decode();
+    }
+}
+
+AsyncAudioDecoder::DecodingTask::DecodingTask(ArrayBuffer* audioData, double sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback)
+    : m_audioData(audioData)
+    , m_sampleRate(sampleRate)
+    , m_successCallback(successCallback)
+    , m_errorCallback(errorCallback)
+{
+}
+
+void AsyncAudioDecoder::DecodingTask::decode()
+{
+    ASSERT(m_audioData.get());
+    if (!m_audioData.get())
+        return;
+
+    // Do the actual decoding and invoke the callback.
+    m_audioBuffer = AudioBuffer::createFromAudioFileData(m_audioData->data(), m_audioData->byteLength(), false, sampleRate());
+    
+    // Decoding is finished, but we need to do the callbacks on the main thread.
+    callOnMainThread(notifyCompleteDispatch, this);
+}
+
+void AsyncAudioDecoder::DecodingTask::notifyCompleteDispatch(void* userData)
+{
+    AsyncAudioDecoder::DecodingTask* task = reinterpret_cast<AsyncAudioDecoder::DecodingTask*>(userData);
+    ASSERT(task);
+    if (!task)
+        return;
+
+    task->notifyComplete();
+}
+
+void AsyncAudioDecoder::DecodingTask::notifyComplete()
+{
+    if (audioBuffer() && successCallback())
+        successCallback()->handleEvent(audioBuffer());
+    else if (errorCallback())
+        errorCallback()->handleEvent(audioBuffer());
+
+    // Our ownership was given up in AsyncAudioDecoder::runLoop()
+    // Make sure to clean up here.
+    delete this;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)

Added: trunk/Source/WebCore/webaudio/AsyncAudioDecoder.h (0 => 89478)


--- trunk/Source/WebCore/webaudio/AsyncAudioDecoder.h	                        (rev 0)
+++ trunk/Source/WebCore/webaudio/AsyncAudioDecoder.h	2011-06-22 21:14:38 UTC (rev 89478)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011, 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 AsyncAudioDecoder_h
+#define AsyncAudioDecoder_h
+
+#include <wtf/MessageQueue.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class ArrayBuffer;
+class AudioBuffer;
+class AudioBufferCallback;
+
+// AsyncAudioDecoder asynchronously decodes audio file data from an ArrayBuffer in a worker thread.
+// Upon successful decoding, a completion callback will be invoked with the decoded PCM data in an AudioBuffer.
+
+class AsyncAudioDecoder {
+public:
+    AsyncAudioDecoder();
+    ~AsyncAudioDecoder();
+
+    // Must be called on the main thread.
+    void decodeAsync(ArrayBuffer* audioData, double sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback);
+
+private:
+    class DecodingTask {
+        WTF_MAKE_NONCOPYABLE(DecodingTask);
+    public:
+        DecodingTask(ArrayBuffer* audioData, double sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback);
+        
+        void decode();
+        
+    private:
+        ArrayBuffer* audioData() { return m_audioData.get(); }
+        double sampleRate() const { return m_sampleRate; }
+        AudioBufferCallback* successCallback() { return m_successCallback.get(); }
+        AudioBufferCallback* errorCallback() { return m_errorCallback.get(); }
+        AudioBuffer* audioBuffer() { return m_audioBuffer.get(); }
+
+        static void notifyCompleteDispatch(void* userData);
+        void notifyComplete();
+
+        RefPtr<ArrayBuffer> m_audioData;
+        double m_sampleRate;
+        RefPtr<AudioBufferCallback> m_successCallback;
+        RefPtr<AudioBufferCallback> m_errorCallback;
+        RefPtr<AudioBuffer> m_audioBuffer;
+    };
+    
+    static void* threadEntry(void* threadData);
+    void runLoop();
+
+    WTF::ThreadIdentifier m_threadID;
+    Mutex m_threadCreationMutex;
+    MessageQueue<DecodingTask> m_queue;
+};
+
+} // namespace WebCore
+
+#endif // AsyncAudioDecoder_h

Added: trunk/Source/WebCore/webaudio/AudioBufferCallback.h (0 => 89478)


--- trunk/Source/WebCore/webaudio/AudioBufferCallback.h	                        (rev 0)
+++ trunk/Source/WebCore/webaudio/AudioBufferCallback.h	2011-06-22 21:14:38 UTC (rev 89478)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011, 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 AudioBufferCallback_h
+#define AudioBufferCallback_h
+
+#if ENABLE(WEB_AUDIO)
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class AudioBuffer;
+
+class AudioBufferCallback : public RefCounted<AudioBufferCallback> {
+public:
+    virtual ~AudioBufferCallback() { }
+    virtual bool handleEvent(AudioBuffer*) = 0;
+};
+
+} // namespace
+
+#endif // ENABLE(WEB_AUDIO)
+
+#endif // AudioBufferCallback_h

Added: trunk/Source/WebCore/webaudio/AudioBufferCallback.idl (0 => 89478)


--- trunk/Source/WebCore/webaudio/AudioBufferCallback.idl	                        (rev 0)
+++ trunk/Source/WebCore/webaudio/AudioBufferCallback.idl	2011-06-22 21:14:38 UTC (rev 89478)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011, 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=WEB_AUDIO,
+        GenerateToJS,
+        Callback
+    ] AudioBufferCallback {
+        boolean handleEvent(in AudioBuffer audioBuffer);
+    };
+}

Modified: trunk/Source/WebCore/webaudio/AudioContext.cpp (89477 => 89478)


--- trunk/Source/WebCore/webaudio/AudioContext.cpp	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/webaudio/AudioContext.cpp	2011-06-22 21:14:38 UTC (rev 89478)
@@ -29,7 +29,9 @@
 #include "AudioContext.h"
 
 #include "ArrayBuffer.h"
+#include "AsyncAudioDecoder.h"
 #include "AudioBuffer.h"
+#include "AudioBufferCallback.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioChannelMerger.h"
 #include "AudioChannelSplitter.h"
@@ -246,6 +248,15 @@
     return AudioBuffer::createFromAudioFileData(arrayBuffer->data(), arrayBuffer->byteLength(), mixToMono, sampleRate());
 }
 
+void AudioContext::decodeAudioData(ArrayBuffer* audioData, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback, ExceptionCode& ec)
+{
+    if (!audioData) {
+        ec = SYNTAX_ERR;
+        return;
+    }
+    m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCallback);
+}
+
 PassRefPtr<AudioBufferSourceNode> AudioContext::createBufferSource()
 {
     ASSERT(isMainThread());

Modified: trunk/Source/WebCore/webaudio/AudioContext.h (89477 => 89478)


--- trunk/Source/WebCore/webaudio/AudioContext.h	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/webaudio/AudioContext.h	2011-06-22 21:14:38 UTC (rev 89478)
@@ -26,6 +26,7 @@
 #define AudioContext_h
 
 #include "ActiveDOMObject.h"
+#include "AsyncAudioDecoder.h"
 #include "AudioBus.h"
 #include "AudioDestinationNode.h"
 #include "EventListener.h"
@@ -44,6 +45,7 @@
 
 class ArrayBuffer;
 class AudioBuffer;
+class AudioBufferCallback;
 class AudioBufferSourceNode;
 class AudioChannelMerger;
 class AudioChannelSplitter;
@@ -93,6 +95,9 @@
     PassRefPtr<AudioBuffer> createBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate);
     PassRefPtr<AudioBuffer> createBuffer(ArrayBuffer* arrayBuffer, bool mixToMono);
 
+    // Asynchronous audio file data decoding.
+    void decodeAudioData(ArrayBuffer*, PassRefPtr<AudioBufferCallback>, PassRefPtr<AudioBufferCallback>, ExceptionCode& ec);
+
     // Keep track of this buffer so we can release memory after the context is shut down...
     void refBuffer(PassRefPtr<AudioBuffer> buffer);
 
@@ -291,6 +296,8 @@
     RefPtr<AudioBuffer> m_renderTarget;
     
     bool m_isOfflineContext;
+
+    AsyncAudioDecoder m_audioDecoder;
 };
 
 } // WebCore

Modified: trunk/Source/WebCore/webaudio/AudioContext.idl (89477 => 89478)


--- trunk/Source/WebCore/webaudio/AudioContext.idl	2011-06-22 20:55:48 UTC (rev 89477)
+++ trunk/Source/WebCore/webaudio/AudioContext.idl	2011-06-22 21:14:38 UTC (rev 89478)
@@ -52,6 +52,10 @@
         // AudioBuffer createBuffer(in ArrayBuffer buffer, in boolean mixToMono);
         [Custom] AudioBuffer createBuffer()
             raises(DOMException);
+            
+        // Asynchronous audio file data decoding.
+        void decodeAudioData(in ArrayBuffer audioData, in [Callback] AudioBufferCallback successCallback, in [Optional, Callback] AudioBufferCallback errorCallback)
+            raises(DOMException);
 
         // Source
         AudioBufferSourceNode createBufferSource();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to