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 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 PassRefPtr<AudioContext> AudioContext::create(Document& document, unsigned numbe
rOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionS
tate) | 107 PassRefPtr<AudioContext> AudioContext::create(Document& document, unsigned numbe
rOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionS
tate) |
108 { | 108 { |
109 document.addConsoleMessage(JSMessageSource, WarningMessageLevel, "Deprecated
AudioContext constructor: use OfflineAudioContext instead"); | 109 document.addConsoleMessage(JSMessageSource, WarningMessageLevel, "Deprecated
AudioContext constructor: use OfflineAudioContext instead"); |
110 return OfflineAudioContext::create(&document, numberOfChannels, numberOfFram
es, sampleRate, exceptionState); | 110 return OfflineAudioContext::create(&document, numberOfChannels, numberOfFram
es, sampleRate, exceptionState); |
111 } | 111 } |
112 | 112 |
113 // Constructor for rendering to the audio hardware. | 113 // Constructor for rendering to the audio hardware. |
114 AudioContext::AudioContext(Document* document) | 114 AudioContext::AudioContext(Document* document) |
115 : ActiveDOMObject(document) | 115 : ActiveDOMObject(document) |
116 , m_isStopScheduled(false) | 116 , m_isStopScheduled(false) |
| 117 , m_isCleared(false) |
117 , m_isInitialized(false) | 118 , m_isInitialized(false) |
118 , m_isAudioThreadFinished(false) | 119 , m_isAudioThreadFinished(false) |
119 , m_destinationNode(nullptr) | 120 , m_destinationNode(nullptr) |
120 , m_isDeletionScheduled(false) | 121 , m_isDeletionScheduled(false) |
121 , m_automaticPullNodesNeedUpdating(false) | 122 , m_automaticPullNodesNeedUpdating(false) |
122 , m_connectionCount(0) | 123 , m_connectionCount(0) |
123 , m_audioThread(0) | 124 , m_audioThread(0) |
124 , m_graphOwnerThread(UndefinedThreadIdentifier) | 125 , m_graphOwnerThread(UndefinedThreadIdentifier) |
125 , m_isOfflineContext(false) | 126 , m_isOfflineContext(false) |
126 , m_activeSourceCount(0) | 127 , m_activeSourceCount(0) |
127 { | 128 { |
128 constructCommon(); | 129 constructCommon(); |
129 | 130 |
130 m_destinationNode = DefaultAudioDestinationNode::create(this); | 131 m_destinationNode = DefaultAudioDestinationNode::create(this); |
131 } | 132 } |
132 | 133 |
133 // Constructor for offline (non-realtime) rendering. | 134 // Constructor for offline (non-realtime) rendering. |
134 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) | 135 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) |
135 : ActiveDOMObject(document) | 136 : ActiveDOMObject(document) |
136 , m_isStopScheduled(false) | 137 , m_isStopScheduled(false) |
| 138 , m_isCleared(false) |
137 , m_isInitialized(false) | 139 , m_isInitialized(false) |
138 , m_isAudioThreadFinished(false) | 140 , m_isAudioThreadFinished(false) |
139 , m_destinationNode(nullptr) | 141 , m_destinationNode(nullptr) |
140 , m_automaticPullNodesNeedUpdating(false) | 142 , m_automaticPullNodesNeedUpdating(false) |
141 , m_connectionCount(0) | 143 , m_connectionCount(0) |
142 , m_audioThread(0) | 144 , m_audioThread(0) |
143 , m_graphOwnerThread(UndefinedThreadIdentifier) | 145 , m_graphOwnerThread(UndefinedThreadIdentifier) |
144 , m_isOfflineContext(true) | 146 , m_isOfflineContext(true) |
145 , m_activeSourceCount(0) | 147 , m_activeSourceCount(0) |
146 { | 148 { |
147 constructCommon(); | 149 constructCommon(); |
148 | 150 |
149 // Create a new destination for offline rendering. | 151 // Create a new destination for offline rendering. |
150 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); | 152 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); |
151 if (m_renderTarget.get()) | 153 if (m_renderTarget.get()) |
152 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); | 154 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); |
153 } | 155 } |
154 | 156 |
155 void AudioContext::constructCommon() | 157 void AudioContext::constructCommon() |
156 { | 158 { |
157 ScriptWrappable::init(this); | 159 ScriptWrappable::init(this); |
158 // According to spec AudioContext must die only after page navigate. | |
159 // Lets mark it as ActiveDOMObject with pending activity and unmark it in cl
ear method. | |
160 setPendingActivity(this); | |
161 | 160 |
162 FFTFrame::initialize(); | 161 FFTFrame::initialize(); |
163 | 162 |
164 m_listener = AudioListener::create(); | 163 m_listener = AudioListener::create(); |
165 } | 164 } |
166 | 165 |
167 AudioContext::~AudioContext() | 166 AudioContext::~AudioContext() |
168 { | 167 { |
169 #if DEBUG_AUDIONODE_REFERENCES | 168 #if DEBUG_AUDIONODE_REFERENCES |
170 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); | 169 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); |
171 #endif | 170 #endif |
172 // AudioNodes keep a reference to their context, so there should be no way t
o be in the destructor if there are still AudioNodes around. | 171 // AudioNodes keep a reference to their context, so there should be no way t
o be in the destructor if there are still AudioNodes around. |
173 ASSERT(!m_isInitialized); | 172 ASSERT(!m_isInitialized); |
174 ASSERT(m_isStopScheduled); | |
175 ASSERT(!m_nodesToDelete.size()); | 173 ASSERT(!m_nodesToDelete.size()); |
176 ASSERT(!m_referencedNodes.size()); | 174 ASSERT(!m_referencedNodes.size()); |
177 ASSERT(!m_finishedNodes.size()); | 175 ASSERT(!m_finishedNodes.size()); |
178 ASSERT(!m_automaticPullNodes.size()); | 176 ASSERT(!m_automaticPullNodes.size()); |
179 if (m_automaticPullNodesNeedUpdating) | 177 if (m_automaticPullNodesNeedUpdating) |
180 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 178 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
181 ASSERT(!m_renderingAutomaticPullNodes.size()); | 179 ASSERT(!m_renderingAutomaticPullNodes.size()); |
182 } | 180 } |
183 | 181 |
184 void AudioContext::lazyInitialize() | 182 void AudioContext::lazyInitialize() |
(...skipping 26 matching lines...) Expand all Loading... |
211 if (m_destinationNode) | 209 if (m_destinationNode) |
212 m_destinationNode.clear(); | 210 m_destinationNode.clear(); |
213 | 211 |
214 // Audio thread is dead. Nobody will schedule node deletion action. Let's do
it ourselves. | 212 // Audio thread is dead. Nobody will schedule node deletion action. Let's do
it ourselves. |
215 do { | 213 do { |
216 deleteMarkedNodes(); | 214 deleteMarkedNodes(); |
217 m_nodesToDelete.appendVector(m_nodesMarkedForDeletion); | 215 m_nodesToDelete.appendVector(m_nodesMarkedForDeletion); |
218 m_nodesMarkedForDeletion.clear(); | 216 m_nodesMarkedForDeletion.clear(); |
219 } while (m_nodesToDelete.size()); | 217 } while (m_nodesToDelete.size()); |
220 | 218 |
221 // It was set in constructCommon. | 219 m_isCleared = true; |
222 unsetPendingActivity(this); | |
223 } | 220 } |
224 | 221 |
225 void AudioContext::uninitialize() | 222 void AudioContext::uninitialize() |
226 { | 223 { |
227 ASSERT(isMainThread()); | 224 ASSERT(isMainThread()); |
228 | 225 |
229 if (!m_isInitialized) | 226 if (!m_isInitialized) |
230 return; | 227 return; |
231 | 228 |
232 // This stops the audio thread and all audio rendering. | 229 // This stops the audio thread and all audio rendering. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return; | 266 return; |
270 m_isStopScheduled = true; | 267 m_isStopScheduled = true; |
271 | 268 |
272 // Don't call uninitialize() immediately here because the ExecutionContext i
s in the middle | 269 // Don't call uninitialize() immediately here because the ExecutionContext i
s in the middle |
273 // of dealing with all of its ActiveDOMObjects at this point. uninitialize()
can de-reference other | 270 // of dealing with all of its ActiveDOMObjects at this point. uninitialize()
can de-reference other |
274 // ActiveDOMObjects so let's schedule uninitialize() to be called later. | 271 // ActiveDOMObjects so let's schedule uninitialize() to be called later. |
275 // FIXME: see if there's a more direct way to handle this issue. | 272 // FIXME: see if there's a more direct way to handle this issue. |
276 callOnMainThread(stopDispatch, this); | 273 callOnMainThread(stopDispatch, this); |
277 } | 274 } |
278 | 275 |
| 276 bool AudioContext::hasPendingActivity() const |
| 277 { |
| 278 // According to spec AudioContext must die only after page navigates. |
| 279 return !m_isCleared; |
| 280 } |
| 281 |
279 PassRefPtr<AudioBuffer> AudioContext::createBuffer(unsigned numberOfChannels, si
ze_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) | 282 PassRefPtr<AudioBuffer> AudioContext::createBuffer(unsigned numberOfChannels, si
ze_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) |
280 { | 283 { |
281 RefPtr<AudioBuffer> audioBuffer = AudioBuffer::create(numberOfChannels, numb
erOfFrames, sampleRate); | 284 RefPtr<AudioBuffer> audioBuffer = AudioBuffer::create(numberOfChannels, numb
erOfFrames, sampleRate); |
282 if (!audioBuffer.get()) { | 285 if (!audioBuffer.get()) { |
283 if (numberOfChannels > AudioContext::maxNumberOfChannels()) { | 286 if (numberOfChannels > AudioContext::maxNumberOfChannels()) { |
284 exceptionState.throwDOMException( | 287 exceptionState.throwDOMException( |
285 NotSupportedError, | 288 NotSupportedError, |
286 "requested number of channels (" + String::number(numberOfChanne
ls) + ") exceeds maximum (" + String::number(AudioContext::maxNumberOfChannels()
) + ")"); | 289 "requested number of channels (" + String::number(numberOfChanne
ls) + ") exceeds maximum (" + String::number(AudioContext::maxNumberOfChannels()
) + ")"); |
287 } else if (sampleRate < AudioBuffer::minAllowedSampleRate() || sampleRat
e > AudioBuffer::maxAllowedSampleRate()) { | 290 } else if (sampleRate < AudioBuffer::minAllowedSampleRate() || sampleRat
e > AudioBuffer::maxAllowedSampleRate()) { |
288 exceptionState.throwDOMException( | 291 exceptionState.throwDOMException( |
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 } | 1042 } |
1040 | 1043 |
1041 void AudioContext::decrementActiveSourceCount() | 1044 void AudioContext::decrementActiveSourceCount() |
1042 { | 1045 { |
1043 atomicDecrement(&m_activeSourceCount); | 1046 atomicDecrement(&m_activeSourceCount); |
1044 } | 1047 } |
1045 | 1048 |
1046 } // namespace WebCore | 1049 } // namespace WebCore |
1047 | 1050 |
1048 #endif // ENABLE(WEB_AUDIO) | 1051 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |