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();