void AudioContext::stopRendering() { ASSERT(isMainThread()); ASSERT(destination()); if (contextState() == Running) { destination()->audioDestinationHandler().stopRendering(); setContextState(Suspended); deferredTaskHandler().clearHandlersToBeDeleted(); } }
ScriptPromise OfflineAudioContext::resumeContext(ScriptState* scriptState) { ASSERT(isMainThread()); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // If the rendering has not started, reject the promise. if (!m_isRenderingStarted) { resolver->reject(DOMException::create(InvalidStateError, "cannot resume an offline context that has not started")); return promise; } // If the context is in a closed state, reject the promise. if (contextState() == AudioContextState::Closed) { resolver->reject(DOMException::create(InvalidStateError, "cannot resume a closed offline context")); return promise; } // If the context is already running, resolve the promise without altering // the current state or starting the rendering loop. if (contextState() == AudioContextState::Running) { resolver->resolve(); return promise; } ASSERT(contextState() == AudioContextState::Suspended); // If the context is suspended, resume rendering by setting the state to // "Running". and calling startRendering(). Note that resuming is possible // only after the rendering started. setContextState(Running); destinationHandler().startRendering(); // Resolve the promise immediately. resolver->resolve(); return promise; }
ScriptPromise OfflineAudioContext::startOfflineRendering(ScriptState* scriptState) { ASSERT(isMainThread()); // Calling close() on an OfflineAudioContext is not supported/allowed, // but it might well have been stopped by its execution context. // // See: crbug.com/435867 if (isContextClosed()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create( InvalidStateError, "cannot call startRendering on an OfflineAudioContext in a stopped state.")); } // If the context is not in the suspended state (i.e. running), reject the promise. if (contextState() != AudioContextState::Suspended) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create( InvalidStateError, "cannot startRendering when an OfflineAudioContext is " + state())); } // Can't call startRendering more than once. Return a rejected promise now. if (m_isRenderingStarted) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create( InvalidStateError, "cannot call startRendering more than once")); } ASSERT(!m_isRenderingStarted); m_completeResolver = ScriptPromiseResolver::create(scriptState); // Start rendering and return the promise. m_isRenderingStarted = true; setContextState(Running); destinationHandler().startRendering(); return m_completeResolver->promise(); }
ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) { ASSERT(isMainThread()); AutoLocker locker(this); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); if (contextState() == Closed) { resolver->reject( DOMException::create(InvalidStateError, "Cannot suspend a context that has been closed")); } else { // Stop rendering now. if (destination()) stopRendering(); // Since we don't have any way of knowing when the hardware actually stops, we'll just // resolve the promise now. resolver->resolve(); } return promise; }