OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y | 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y |
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N | 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 */ | 23 */ |
24 | 24 |
25 #ifndef AudioContext_h | 25 #ifndef AudioContext_h |
26 #define AudioContext_h | 26 #define AudioContext_h |
27 | 27 |
28 #include "bindings/core/v8/ScriptPromise.h" | |
29 #include "bindings/core/v8/ScriptPromiseResolver.h" | |
30 #include "core/dom/ActiveDOMObject.h" | 28 #include "core/dom/ActiveDOMObject.h" |
31 #include "core/events/EventListener.h" | 29 #include "core/events/EventListener.h" |
32 #include "modules/EventTargetModules.h" | 30 #include "modules/EventTargetModules.h" |
33 #include "modules/webaudio/AsyncAudioDecoder.h" | 31 #include "modules/webaudio/AsyncAudioDecoder.h" |
34 #include "modules/webaudio/AudioDestinationNode.h" | 32 #include "modules/webaudio/AudioDestinationNode.h" |
35 #include "platform/audio/AudioBus.h" | 33 #include "platform/audio/AudioBus.h" |
36 #include "platform/heap/Handle.h" | 34 #include "platform/heap/Handle.h" |
37 #include "wtf/HashSet.h" | 35 #include "wtf/HashSet.h" |
38 #include "wtf/MainThread.h" | 36 #include "wtf/MainThread.h" |
39 #include "wtf/OwnPtr.h" | 37 #include "wtf/OwnPtr.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 class WaveShaperNode; | 70 class WaveShaperNode; |
73 | 71 |
74 // AudioContext is the cornerstone of the web audio API and all AudioNodes are c
reated from it. | 72 // AudioContext is the cornerstone of the web audio API and all AudioNodes are c
reated from it. |
75 // For thread safety between the audio thread and the main thread, it has a rend
ering graph locking mechanism. | 73 // For thread safety between the audio thread and the main thread, it has a rend
ering graph locking mechanism. |
76 | 74 |
77 class AudioContext : public RefCountedGarbageCollectedWillBeGarbageCollectedFina
lized<AudioContext>, public ActiveDOMObject, public EventTargetWithInlineData { | 75 class AudioContext : public RefCountedGarbageCollectedWillBeGarbageCollectedFina
lized<AudioContext>, public ActiveDOMObject, public EventTargetWithInlineData { |
78 DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(RefCountedGarbageCollected<A
udioContext>); | 76 DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(RefCountedGarbageCollected<A
udioContext>); |
79 DEFINE_WRAPPERTYPEINFO(); | 77 DEFINE_WRAPPERTYPEINFO(); |
80 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AudioContext); | 78 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AudioContext); |
81 public: | 79 public: |
82 // The state of an audio context. On creation, the state is Paused. The sta
te is Running if | |
83 // audio is being processed (audio graph is being pulled for data). The stat
e is Released if the | |
84 // audio context has been released. The valid transitions are from Paused t
o either Running or | |
85 // Released; Running to Paused or Released. Once Released, there are no vali
d transitions. | |
86 enum AudioContextState { | |
87 Paused, | |
88 Running, | |
89 Released | |
90 }; | |
91 | |
92 // Create an AudioContext for rendering to the audio hardware. | 80 // Create an AudioContext for rendering to the audio hardware. |
93 static AudioContext* create(Document&, ExceptionState&); | 81 static AudioContext* create(Document&, ExceptionState&); |
94 | 82 |
95 virtual ~AudioContext(); | 83 virtual ~AudioContext(); |
96 | 84 |
97 virtual void trace(Visitor*) override; | 85 virtual void trace(Visitor*) override; |
98 | 86 |
99 bool isInitialized() const { return m_isInitialized; } | 87 bool isInitialized() const { return m_isInitialized; } |
100 bool isOfflineContext() { return m_isOfflineContext; } | 88 bool isOfflineContext() { return m_isOfflineContext; } |
101 | 89 |
102 // Document notification | 90 // Document notification |
103 virtual void stop() override final; | 91 virtual void stop() override final; |
104 virtual bool hasPendingActivity() const override; | 92 virtual bool hasPendingActivity() const override; |
105 | 93 |
106 AudioDestinationNode* destination() { return m_destinationNode.get(); } | 94 AudioDestinationNode* destination() { return m_destinationNode.get(); } |
107 size_t currentSampleFrame() const { return m_destinationNode->currentSampleF
rame(); } | 95 size_t currentSampleFrame() const { return m_destinationNode->currentSampleF
rame(); } |
108 double currentTime() const { return m_destinationNode->currentTime(); } | 96 double currentTime() const { return m_destinationNode->currentTime(); } |
109 float sampleRate() const { return m_destinationNode->sampleRate(); } | 97 float sampleRate() const { return m_destinationNode->sampleRate(); } |
110 String state() const; | |
111 | 98 |
112 AudioBuffer* createBuffer(unsigned numberOfChannels, size_t numberOfFrames,
float sampleRate, ExceptionState&); | 99 AudioBuffer* createBuffer(unsigned numberOfChannels, size_t numberOfFrames,
float sampleRate, ExceptionState&); |
113 | 100 |
114 // Asynchronous audio file data decoding. | 101 // Asynchronous audio file data decoding. |
115 void decodeAudioData(ArrayBuffer*, AudioBufferCallback*, AudioBufferCallback
*, ExceptionState&); | 102 void decodeAudioData(ArrayBuffer*, AudioBufferCallback*, AudioBufferCallback
*, ExceptionState&); |
116 | 103 |
117 AudioListener* listener() { return m_listener.get(); } | 104 AudioListener* listener() { return m_listener.get(); } |
118 | 105 |
119 // The AudioNode create methods are called on the main thread (from JavaScri
pt). | 106 // The AudioNode create methods are called on the main thread (from JavaScri
pt). |
120 AudioBufferSourceNode* createBufferSource(); | 107 AudioBufferSourceNode* createBufferSource(); |
(...skipping 13 matching lines...) Expand all Loading... |
134 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, ExceptionState
&); | 121 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, ExceptionState
&); |
135 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, ExceptionState&); | 122 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, ExceptionState&); |
136 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, size_t numberOfOutputChannels, ExceptionState&); | 123 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, size_t numberOfOutputChannels, ExceptionState&); |
137 ChannelSplitterNode* createChannelSplitter(ExceptionState&); | 124 ChannelSplitterNode* createChannelSplitter(ExceptionState&); |
138 ChannelSplitterNode* createChannelSplitter(size_t numberOfOutputs, Exception
State&); | 125 ChannelSplitterNode* createChannelSplitter(size_t numberOfOutputs, Exception
State&); |
139 ChannelMergerNode* createChannelMerger(ExceptionState&); | 126 ChannelMergerNode* createChannelMerger(ExceptionState&); |
140 ChannelMergerNode* createChannelMerger(size_t numberOfInputs, ExceptionState
&); | 127 ChannelMergerNode* createChannelMerger(size_t numberOfInputs, ExceptionState
&); |
141 OscillatorNode* createOscillator(); | 128 OscillatorNode* createOscillator(); |
142 PeriodicWave* createPeriodicWave(Float32Array* real, Float32Array* imag, Exc
eptionState&); | 129 PeriodicWave* createPeriodicWave(Float32Array* real, Float32Array* imag, Exc
eptionState&); |
143 | 130 |
144 // Pause/Resume | |
145 void suspendContext(ExceptionState&); | |
146 ScriptPromise resumeContext(ScriptState*); | |
147 | |
148 // When a source node has no more processing to do (has finished playing), t
hen it tells the context to dereference it. | 131 // When a source node has no more processing to do (has finished playing), t
hen it tells the context to dereference it. |
149 void notifyNodeFinishedProcessing(AudioNode*); | 132 void notifyNodeFinishedProcessing(AudioNode*); |
150 | 133 |
151 // Called at the start of each render quantum. | 134 // Called at the start of each render quantum. |
152 void handlePreRenderTasks(); | 135 void handlePreRenderTasks(); |
153 | 136 |
154 // Called at the end of each render quantum. | 137 // Called at the end of each render quantum. |
155 void handlePostRenderTasks(); | 138 void handlePostRenderTasks(); |
156 | 139 |
157 // Called periodically at the end of each render quantum to dereference fini
shed source nodes. | 140 // Called periodically at the end of each render quantum to dereference fini
shed source nodes. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 GC_PLUGIN_IGNORE("http://crbug.com/404527") | 267 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
285 Vector<AudioNode*> m_finishedNodes; | 268 Vector<AudioNode*> m_finishedNodes; |
286 | 269 |
287 // List of source nodes. This is either accessed when the graph lock is | 270 // List of source nodes. This is either accessed when the graph lock is |
288 // held, or on the main thread when the audio thread has finished. | 271 // held, or on the main thread when the audio thread has finished. |
289 // Oilpan: This Vector holds connection references. We must call | 272 // Oilpan: This Vector holds connection references. We must call |
290 // AudioNode::makeConnection when we add an AudioNode to this, and must call | 273 // AudioNode::makeConnection when we add an AudioNode to this, and must call |
291 // AudioNode::breakConnection() when we remove an AudioNode from this. | 274 // AudioNode::breakConnection() when we remove an AudioNode from this. |
292 HeapVector<Member<AudioNode> > m_referencedNodes; | 275 HeapVector<Member<AudioNode> > m_referencedNodes; |
293 | 276 |
294 // Stop rendering the audio graph. | |
295 void stopRendering(); | |
296 | |
297 // Handle Promises for resume(). | |
298 void resolvePromisesForResume(); | |
299 void resolvePromisesForResumeOnMainThread(); | |
300 | |
301 // Vector of promises created by resume(). It takes time to handle them, so
we collect all of | |
302 // the promises here until they can be resolved or rejected. | |
303 Vector<RefPtr<ScriptPromiseResolver> > m_resumePromises; | |
304 | |
305 // True if we're in the process of resolving promises for resume(). Resolvi
ng can take some | |
306 // time and the audio context process loop is very fast, so we don't want to
call resolve an | |
307 // excessive number of times. | |
308 bool m_isResolvingResumePromises; | |
309 | |
310 class AudioNodeDisposer { | 277 class AudioNodeDisposer { |
311 public: | 278 public: |
312 explicit AudioNodeDisposer(AudioNode& node) : m_node(node) { } | 279 explicit AudioNodeDisposer(AudioNode& node) : m_node(node) { } |
313 ~AudioNodeDisposer(); | 280 ~AudioNodeDisposer(); |
314 | 281 |
315 private: | 282 private: |
316 AudioNode& m_node; | 283 AudioNode& m_node; |
317 }; | 284 }; |
318 HeapHashMap<WeakMember<AudioNode>, OwnPtr<AudioNodeDisposer> > m_liveNodes; | 285 HeapHashMap<WeakMember<AudioNode>, OwnPtr<AudioNodeDisposer> > m_liveNodes; |
319 | 286 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 // Only accessed in the audio thread. | 331 // Only accessed in the audio thread. |
365 // Oilpan: Since items are added to these vectors by the audio thread (not r
egistered to Oilpan), | 332 // Oilpan: Since items are added to these vectors by the audio thread (not r
egistered to Oilpan), |
366 // we cannot use HeapVectors. | 333 // we cannot use HeapVectors. |
367 GC_PLUGIN_IGNORE("http://crbug.com/404527") | 334 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
368 Vector<AudioNode*> m_deferredBreakConnectionList; | 335 Vector<AudioNode*> m_deferredBreakConnectionList; |
369 | 336 |
370 Member<AudioBuffer> m_renderTarget; | 337 Member<AudioBuffer> m_renderTarget; |
371 | 338 |
372 bool m_isOfflineContext; | 339 bool m_isOfflineContext; |
373 | 340 |
374 AudioContextState m_contextState; | |
375 void setContextState(AudioContextState); | |
376 | |
377 AsyncAudioDecoder m_audioDecoder; | 341 AsyncAudioDecoder m_audioDecoder; |
378 | 342 |
379 // Collection of nodes where the channel count mode has changed. We want the
channel count mode | 343 // Collection of nodes where the channel count mode has changed. We want the
channel count mode |
380 // to change in the pre- or post-rendering phase so as not to disturb the ru
nning audio thread. | 344 // to change in the pre- or post-rendering phase so as not to disturb the ru
nning audio thread. |
381 GC_PLUGIN_IGNORE("http://crbug.com/404527") | 345 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
382 HashSet<AudioNode*> m_deferredCountModeChange; | 346 HashSet<AudioNode*> m_deferredCountModeChange; |
383 | 347 |
384 // This is considering 32 is large enough for multiple channels audio. | 348 // This is considering 32 is large enough for multiple channels audio. |
385 // It is somewhat arbitrary and could be increased if necessary. | 349 // It is somewhat arbitrary and could be increased if necessary. |
386 enum { MaxNumberOfChannels = 32 }; | 350 enum { MaxNumberOfChannels = 32 }; |
387 }; | 351 }; |
388 | 352 |
389 } // namespace blink | 353 } // namespace blink |
390 | 354 |
391 #endif // AudioContext_h | 355 #endif // AudioContext_h |
OLD | NEW |