| Index: Source/modules/webaudio/AudioContext.cpp
|
| diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp
|
| index ebab3b8851a59fb698968cac7c46e373c5966ed7..c3d6fde4e7e2f05b1b7b3da6bf0b50954ca34007 100644
|
| --- a/Source/modules/webaudio/AudioContext.cpp
|
| +++ b/Source/modules/webaudio/AudioContext.cpp
|
| @@ -160,6 +160,7 @@ AudioContext::~AudioContext()
|
| ASSERT(!m_suspendResolvers.size());
|
| ASSERT(!m_isResolvingResumePromises);
|
| ASSERT(!m_resumeResolvers.size());
|
| + ASSERT(!m_audioDecoderResolvers.size());
|
| }
|
|
|
| void AudioContext::initialize()
|
| @@ -272,20 +273,34 @@ 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;
|
| + return ScriptPromise::rejectWithDOMException(
|
| + scriptState,
|
| + DOMException::create(
|
| + InvalidStateError,
|
| + "AudioContext has been closed."));
|
| }
|
|
|
| if (!audioData) {
|
| - exceptionState.throwDOMException(
|
| - SyntaxError,
|
| - "invalid ArrayBuffer for audioData.");
|
| - return;
|
| + if (errorCallback)
|
| + errorCallback->handleEvent(nullptr);
|
| + return ScriptPromise::rejectWithDOMException(
|
| + scriptState,
|
| + DOMException::create(
|
| + NotSupportedError,
|
| + "invalid ArrayBuffer for audioData."));
|
| }
|
| - m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCallback);
|
| +
|
| + RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| +
|
| + m_audioDecoderResolvers.append(resolver);
|
| +
|
| + m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCallback, resolver.get(), this);
|
| +
|
| + return promise;
|
| }
|
|
|
| AudioBufferSourceNode* AudioContext::createBufferSource(ExceptionState& exceptionState)
|
| @@ -948,6 +963,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());
|
| @@ -1198,8 +1226,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"));
|
| @@ -1211,6 +1238,11 @@ void AudioContext::rejectPendingResolvers()
|
| }
|
| m_resumeResolvers.clear();
|
| m_isResolvingResumePromises = false;
|
| +
|
| + for (auto& resolver : m_audioDecoderResolvers) {
|
| + resolver->reject(DOMException::create(InvalidStateError, "Audio context is going away"));
|
| + }
|
| + m_audioDecoderResolvers.clear();
|
| }
|
|
|
| const AtomicString& AudioContext::interfaceName() const
|
| @@ -1273,6 +1305,7 @@ void AudioContext::fireCompletionEvent()
|
|
|
| DEFINE_TRACE(AudioContext)
|
| {
|
| + visitor->trace(m_audioDecoderResolvers);
|
| visitor->trace(m_closeResolver);
|
| visitor->trace(m_offlineResolver);
|
| visitor->trace(m_renderTarget);
|
|
|