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); | 173 ASSERT(m_isCleared); |
kouhei (in TOK)
2014/03/26 01:21:34
m_isStopScheduled is not set when OfflineAudioCont
| |
175 ASSERT(!m_nodesToDelete.size()); | 174 ASSERT(!m_nodesToDelete.size()); |
176 ASSERT(!m_referencedNodes.size()); | 175 ASSERT(!m_referencedNodes.size()); |
177 ASSERT(!m_finishedNodes.size()); | 176 ASSERT(!m_finishedNodes.size()); |
178 ASSERT(!m_automaticPullNodes.size()); | 177 ASSERT(!m_automaticPullNodes.size()); |
179 if (m_automaticPullNodesNeedUpdating) | 178 if (m_automaticPullNodesNeedUpdating) |
180 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 179 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
181 ASSERT(!m_renderingAutomaticPullNodes.size()); | 180 ASSERT(!m_renderingAutomaticPullNodes.size()); |
182 } | 181 } |
183 | 182 |
184 void AudioContext::lazyInitialize() | 183 void AudioContext::lazyInitialize() |
(...skipping 26 matching lines...) Expand all Loading... | |
211 if (m_destinationNode) | 210 if (m_destinationNode) |
212 m_destinationNode.clear(); | 211 m_destinationNode.clear(); |
213 | 212 |
214 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. | 213 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. |
215 do { | 214 do { |
216 deleteMarkedNodes(); | 215 deleteMarkedNodes(); |
217 m_nodesToDelete.appendVector(m_nodesMarkedForDeletion); | 216 m_nodesToDelete.appendVector(m_nodesMarkedForDeletion); |
218 m_nodesMarkedForDeletion.clear(); | 217 m_nodesMarkedForDeletion.clear(); |
219 } while (m_nodesToDelete.size()); | 218 } while (m_nodesToDelete.size()); |
220 | 219 |
221 // It was set in constructCommon. | 220 m_isCleared = true; |
222 unsetPendingActivity(this); | |
223 } | 221 } |
224 | 222 |
225 void AudioContext::uninitialize() | 223 void AudioContext::uninitialize() |
226 { | 224 { |
227 ASSERT(isMainThread()); | 225 ASSERT(isMainThread()); |
228 | 226 |
229 if (!m_isInitialized) | 227 if (!m_isInitialized) |
230 return; | 228 return; |
231 | 229 |
232 // This stops the audio thread and all audio rendering. | 230 // This stops the audio thread and all audio rendering. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 return; | 267 return; |
270 m_isStopScheduled = true; | 268 m_isStopScheduled = true; |
271 | 269 |
272 // Don't call uninitialize() immediately here because the ExecutionContext i s in the middle | 270 // 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 | 271 // 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. | 272 // ActiveDOMObjects so let's schedule uninitialize() to be called later. |
275 // FIXME: see if there's a more direct way to handle this issue. | 273 // FIXME: see if there's a more direct way to handle this issue. |
276 callOnMainThread(stopDispatch, this); | 274 callOnMainThread(stopDispatch, this); |
277 } | 275 } |
278 | 276 |
277 bool AudioContext::hasPendingActivity() const | |
278 { | |
279 // According to spec AudioContext must die only after page navigates. | |
280 return m_isCleared; | |
281 } | |
282 | |
279 PassRefPtr<AudioBuffer> AudioContext::createBuffer(unsigned numberOfChannels, si ze_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) | 283 PassRefPtr<AudioBuffer> AudioContext::createBuffer(unsigned numberOfChannels, si ze_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) |
280 { | 284 { |
281 RefPtr<AudioBuffer> audioBuffer = AudioBuffer::create(numberOfChannels, numb erOfFrames, sampleRate); | 285 RefPtr<AudioBuffer> audioBuffer = AudioBuffer::create(numberOfChannels, numb erOfFrames, sampleRate); |
282 if (!audioBuffer.get()) { | 286 if (!audioBuffer.get()) { |
283 if (numberOfChannels > AudioContext::maxNumberOfChannels()) { | 287 if (numberOfChannels > AudioContext::maxNumberOfChannels()) { |
284 exceptionState.throwDOMException( | 288 exceptionState.throwDOMException( |
285 NotSupportedError, | 289 NotSupportedError, |
286 "requested number of channels (" + String::number(numberOfChanne ls) + ") exceeds maximum (" + String::number(AudioContext::maxNumberOfChannels() ) + ")"); | 290 "requested number of channels (" + String::number(numberOfChanne ls) + ") exceeds maximum (" + String::number(AudioContext::maxNumberOfChannels() ) + ")"); |
287 } else if (sampleRate < AudioBuffer::minAllowedSampleRate() || sampleRat e > AudioBuffer::maxAllowedSampleRate()) { | 291 } else if (sampleRate < AudioBuffer::minAllowedSampleRate() || sampleRat e > AudioBuffer::maxAllowedSampleRate()) { |
288 exceptionState.throwDOMException( | 292 exceptionState.throwDOMException( |
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1039 } | 1043 } |
1040 | 1044 |
1041 void AudioContext::decrementActiveSourceCount() | 1045 void AudioContext::decrementActiveSourceCount() |
1042 { | 1046 { |
1043 atomicDecrement(&m_activeSourceCount); | 1047 atomicDecrement(&m_activeSourceCount); |
1044 } | 1048 } |
1045 | 1049 |
1046 } // namespace WebCore | 1050 } // namespace WebCore |
1047 | 1051 |
1048 #endif // ENABLE(WEB_AUDIO) | 1052 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |