Exemple #1
0
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();
}
Exemple #4
0
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;
}