Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2028)

Unified Diff: Source/modules/webaudio/AudioContext.cpp

Issue 1006963003: AudioContext.decodeAudioData returns a Promise (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update for review Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/webaudio/AudioContext.h ('k') | Source/modules/webaudio/AudioContext.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/webaudio/AudioContext.cpp
diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp
index 306485e48560889c5626c5c53bb6a3836b9f377e..e4fd7b7dee28250b02e6a236100dc514e36243b3 100644
--- a/Source/modules/webaudio/AudioContext.cpp
+++ b/Source/modules/webaudio/AudioContext.cpp
@@ -115,6 +115,7 @@ AudioContext::AudioContext(Document* document)
, m_isOfflineContext(false)
, m_contextState(Suspended)
, m_cachedSampleFrame(0)
+ , m_closedContextSampleRate(-1)
{
m_didInitializeContextGraphMutex = true;
m_destinationNode = DefaultAudioDestinationNode::create(this);
@@ -136,6 +137,7 @@ AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
, m_isOfflineContext(true)
, m_contextState(Suspended)
, m_cachedSampleFrame(0)
+ , m_closedContextSampleRate(-1)
{
m_didInitializeContextGraphMutex = true;
// Create a new destination for offline rendering.
@@ -152,12 +154,14 @@ AudioContext::~AudioContext()
fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId);
#endif
// AudioNodes keep a reference to their context, so there should be no way to be in the destructor if there are still AudioNodes around.
+
ASSERT(!m_isInitialized);
ASSERT(!m_referencedNodes.size());
ASSERT(!m_finishedNodes.size());
ASSERT(!m_suspendResolvers.size());
ASSERT(!m_isResolvingResumePromises);
ASSERT(!m_resumeResolvers.size());
+ ASSERT(!m_audioDecoderResolvers.size());
}
void AudioContext::initialize()
@@ -233,6 +237,14 @@ void AudioContext::uninitialize()
ASSERT(m_listener);
m_listener->waitForHRTFDatabaseLoaderThreadCompletion();
+ // Reject any decodeAudioData promises that haven't been fulfilled yet.
+ for (auto& resolver : m_audioDecoderResolvers) {
+ resolver->reject(DOMException::create(InvalidStateError, "Audio context is going away"));
+ }
+ m_audioDecoderResolvers.clear();
+
+ // Uninitialization done, so clear flags to indicate that the AudioContext has no pending
+ // activity anymore.
clear();
}
@@ -269,20 +281,30 @@ AudioBuffer* AudioContext::createBuffer(unsigned numberOfChannels, size_t number
return AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate, exceptionState);
}
-void AudioContext::decodeAudioData(DOMArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, ExceptionState& exceptionState)
+ScriptPromise AudioContext::decodeAudioData(ScriptState* scriptState, DOMArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, ExceptionState& exceptionState)
{
- if (isContextClosed()) {
- throwExceptionForClosedState(exceptionState);
- return;
- }
-
if (!audioData) {
- exceptionState.throwDOMException(
- SyntaxError,
+ RefPtrWillBeRawPtr<DOMException> error = DOMException::create(
+ NotSupportedError,
"invalid ArrayBuffer for audioData.");
- return;
+ if (errorCallback) {
+ errorCallback->handleEvent(error.get());
+ }
+ return ScriptPromise::rejectWithDOMException(scriptState, error);
}
- m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCallback);
+
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+
+ m_audioDecoderResolvers.append(resolver);
+
+ float rate = isContextClosed() ? m_closedContextSampleRate : sampleRate();
+
+ ASSERT(rate > 0);
+
+ m_audioDecoder.decodeAsync(audioData, rate, successCallback, errorCallback, resolver.get(), this);
+
+ return promise;
}
AudioBufferSourceNode* AudioContext::createBufferSource(ExceptionState& exceptionState)
@@ -912,6 +934,19 @@ void AudioContext::handleStoppableSourceNodes()
}
}
}
+
+void AudioContext::removeAudioDecoderResolver(ScriptPromiseResolver* resolver)
+{
+ ASSERT(isMainThread());
+
+ for (size_t k = 0; k < m_audioDecoderResolvers.size(); ++k) {
+ if (resolver == m_audioDecoderResolvers.at(k)) {
+ m_audioDecoderResolvers.remove(k);
+ break;
+ }
+ }
+}
+
void AudioContext::handlePreRenderTasks()
{
ASSERT(isAudioThread());
@@ -1129,8 +1164,7 @@ void AudioContext::rejectPendingResolvers()
{
ASSERT(isMainThread());
- // Audio context is closing down so reject any suspend or resume promises that are still
- // pending.
+ // Audio context is closing down so reject any promises that are still pending.
for (auto& resolver : m_suspendResolvers) {
resolver->reject(DOMException::create(InvalidStateError, "Audio context is going away"));
@@ -1204,6 +1238,7 @@ void AudioContext::fireCompletionEvent()
DEFINE_TRACE(AudioContext)
{
+ visitor->trace(m_audioDecoderResolvers);
visitor->trace(m_closeResolver);
visitor->trace(m_offlineResolver);
visitor->trace(m_renderTarget);
@@ -1271,6 +1306,9 @@ ScriptPromise AudioContext::closeContext(ScriptState* scriptState)
"Cannot close a context that is being closed or has already been closed."));
}
+ // Save the current sample rate for any subsequent decodeAudioData calls.
+ m_closedContextSampleRate = sampleRate();
+
m_closeResolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = m_closeResolver->promise();
« no previous file with comments | « Source/modules/webaudio/AudioContext.h ('k') | Source/modules/webaudio/AudioContext.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698