Index: Source/modules/webaudio/AudioContext.h |
diff --git a/Source/modules/webaudio/AudioContext.h b/Source/modules/webaudio/AudioContext.h |
index fde6ef7ed7740ff95a48abdf0ce71b0919cf28bc..021168019b2129b36a502dc25768272d78bd85e7 100644 |
--- a/Source/modules/webaudio/AudioContext.h |
+++ b/Source/modules/webaudio/AudioContext.h |
@@ -25,6 +25,8 @@ |
#ifndef AudioContext_h |
#define AudioContext_h |
+#include "bindings/core/v8/ScriptPromise.h" |
+#include "bindings/core/v8/ScriptPromiseResolver.h" |
#include "core/dom/ActiveDOMObject.h" |
#include "core/events/EventListener.h" |
#include "modules/EventTargetModules.h" |
@@ -77,6 +79,16 @@ class AudioContext : public RefCountedGarbageCollectedWillBeGarbageCollectedFina |
DEFINE_WRAPPERTYPEINFO(); |
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AudioContext); |
public: |
+ // The state of an audio context. On creation, the state is Paused. The state is Running if |
+ // audio is being processed (audio graph is being pulled for data). The state is Released if the |
+ // audio context has been released. The valid transitions are from Paused to either Running or |
+ // Released; Running to Paused or Released. Once Released, there are no valid transitions. |
+ enum AudioContextState { |
+ Paused, |
+ Running, |
+ Released |
+ }; |
+ |
// Create an AudioContext for rendering to the audio hardware. |
static AudioContext* create(Document&, ExceptionState&); |
@@ -95,6 +107,7 @@ public: |
size_t currentSampleFrame() const { return m_destinationNode->currentSampleFrame(); } |
double currentTime() const { return m_destinationNode->currentTime(); } |
float sampleRate() const { return m_destinationNode->sampleRate(); } |
+ String state() const; |
AudioBuffer* createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&); |
@@ -128,6 +141,10 @@ public: |
OscillatorNode* createOscillator(); |
PeriodicWave* createPeriodicWave(Float32Array* real, Float32Array* imag, ExceptionState&); |
+ // Pause/Resume |
+ void suspendContext(ExceptionState&); |
+ ScriptPromise resumeContext(ScriptState*); |
+ |
// When a source node has no more processing to do (has finished playing), then it tells the context to dereference it. |
void notifyNodeFinishedProcessing(AudioNode*); |
@@ -274,6 +291,22 @@ private: |
// AudioNode::breakConnection() when we remove an AudioNode from this. |
HeapVector<Member<AudioNode> > m_referencedNodes; |
+ // Stop rendering the audio graph. |
+ void stopRendering(); |
+ |
+ // Handle Promises for resume(). |
+ void resolvePromisesForResume(); |
+ void resolvePromisesForResumeOnMainThread(); |
+ |
+ // Vector of promises created by resume(). It takes time to handle them, so we collect all of |
+ // the promises here until they can be resolved or rejected. |
+ Vector<RefPtr<ScriptPromiseResolver> > m_resumePromises; |
+ |
+ // True if we're in the process of resolving promises for resume(). Resolving can take some |
+ // time and the audio context process loop is very fast, so we don't want to call resolve an |
+ // excessive number of times. |
+ bool m_isResolvingResumePromises; |
+ |
class AudioNodeDisposer { |
public: |
explicit AudioNodeDisposer(AudioNode& node) : m_node(node) { } |
@@ -338,6 +371,9 @@ private: |
bool m_isOfflineContext; |
+ AudioContextState m_contextState; |
+ void setContextState(AudioContextState); |
+ |
AsyncAudioDecoder m_audioDecoder; |
// Collection of nodes where the channel count mode has changed. We want the channel count mode |