| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 ASSERT(!m_isInitialized); | 153 ASSERT(!m_isInitialized); |
| 154 ASSERT(!m_referencedNodes.size()); | 154 ASSERT(!m_referencedNodes.size()); |
| 155 ASSERT(!m_finishedNodes.size()); | 155 ASSERT(!m_finishedNodes.size()); |
| 156 ASSERT(!m_automaticPullNodes.size()); | 156 ASSERT(!m_automaticPullNodes.size()); |
| 157 if (m_automaticPullNodesNeedUpdating) | 157 if (m_automaticPullNodesNeedUpdating) |
| 158 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 158 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
| 159 ASSERT(!m_renderingAutomaticPullNodes.size()); | 159 ASSERT(!m_renderingAutomaticPullNodes.size()); |
| 160 ASSERT(!m_suspendResolvers.size()); | 160 ASSERT(!m_suspendResolvers.size()); |
| 161 ASSERT(!m_isResolvingResumePromises); | 161 ASSERT(!m_isResolvingResumePromises); |
| 162 ASSERT(!m_resumeResolvers.size()); | 162 ASSERT(!m_resumeResolvers.size()); |
| 163 ASSERT(!m_audioDecoderResolvers.size()); |
| 163 } | 164 } |
| 164 | 165 |
| 165 void AudioContext::initialize() | 166 void AudioContext::initialize() |
| 166 { | 167 { |
| 167 if (isInitialized()) | 168 if (isInitialized()) |
| 168 return; | 169 return; |
| 169 | 170 |
| 170 FFTFrame::initialize(); | 171 FFTFrame::initialize(); |
| 171 m_listener = AudioListener::create(); | 172 m_listener = AudioListener::create(); |
| 172 | 173 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 266 } |
| 266 | 267 |
| 267 AudioBuffer* AudioContext::createBuffer(unsigned numberOfChannels, size_t number
OfFrames, float sampleRate, ExceptionState& exceptionState) | 268 AudioBuffer* AudioContext::createBuffer(unsigned numberOfChannels, size_t number
OfFrames, float sampleRate, ExceptionState& exceptionState) |
| 268 { | 269 { |
| 269 // It's ok to call createBuffer, even if the context is closed because the A
udioBuffer doesn't | 270 // It's ok to call createBuffer, even if the context is closed because the A
udioBuffer doesn't |
| 270 // really "belong" to any particular context. | 271 // really "belong" to any particular context. |
| 271 | 272 |
| 272 return AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate, exc
eptionState); | 273 return AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate, exc
eptionState); |
| 273 } | 274 } |
| 274 | 275 |
| 275 void AudioContext::decodeAudioData(DOMArrayBuffer* audioData, AudioBufferCallbac
k* successCallback, AudioBufferCallback* errorCallback, ExceptionState& exceptio
nState) | 276 ScriptPromise AudioContext::decodeAudioData(ScriptState* scriptState, DOMArrayBu
ffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* erro
rCallback, ExceptionState& exceptionState) |
| 276 { | 277 { |
| 277 if (isContextClosed()) { | 278 if (isContextClosed()) { |
| 278 throwExceptionForClosedState(exceptionState); | 279 return ScriptPromise::rejectWithDOMException( |
| 279 return; | 280 scriptState, |
| 281 DOMException::create( |
| 282 InvalidStateError, |
| 283 "AudioContext has been closed.")); |
| 280 } | 284 } |
| 281 | 285 |
| 282 if (!audioData) { | 286 if (!audioData) { |
| 283 exceptionState.throwDOMException( | 287 if (errorCallback) |
| 284 SyntaxError, | 288 errorCallback->handleEvent(nullptr); |
| 285 "invalid ArrayBuffer for audioData."); | 289 return ScriptPromise::rejectWithDOMException( |
| 286 return; | 290 scriptState, |
| 291 DOMException::create( |
| 292 NotSupportedError, |
| 293 "invalid ArrayBuffer for audioData.")); |
| 287 } | 294 } |
| 288 m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCa
llback); | 295 |
| 296 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
| 297 ScriptPromise promise = resolver->promise(); |
| 298 |
| 299 m_audioDecoderResolvers.append(resolver); |
| 300 |
| 301 m_audioDecoder.decodeAsync(audioData, sampleRate(), successCallback, errorCa
llback, resolver.get(), this); |
| 302 |
| 303 return promise; |
| 289 } | 304 } |
| 290 | 305 |
| 291 AudioBufferSourceNode* AudioContext::createBufferSource(ExceptionState& exceptio
nState) | 306 AudioBufferSourceNode* AudioContext::createBufferSource(ExceptionState& exceptio
nState) |
| 292 { | 307 { |
| 293 ASSERT(isMainThread()); | 308 ASSERT(isMainThread()); |
| 294 | 309 |
| 295 if (isContextClosed()) { | 310 if (isContextClosed()) { |
| 296 throwExceptionForClosedState(exceptionState); | 311 throwExceptionForClosedState(exceptionState); |
| 297 return nullptr; | 312 return nullptr; |
| 298 } | 313 } |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 // Find AudioBufferSourceNodes to see if we can stop playing them. | 956 // Find AudioBufferSourceNodes to see if we can stop playing them. |
| 942 for (unsigned i = 0; i < m_referencedNodes.size(); ++i) { | 957 for (unsigned i = 0; i < m_referencedNodes.size(); ++i) { |
| 943 AudioNode* node = m_referencedNodes.at(i).get(); | 958 AudioNode* node = m_referencedNodes.at(i).get(); |
| 944 | 959 |
| 945 if (node->nodeType() == AudioNode::NodeTypeAudioBufferSource) { | 960 if (node->nodeType() == AudioNode::NodeTypeAudioBufferSource) { |
| 946 AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNod
e*>(node); | 961 AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNod
e*>(node); |
| 947 sourceNode->handleStoppableSourceNode(); | 962 sourceNode->handleStoppableSourceNode(); |
| 948 } | 963 } |
| 949 } | 964 } |
| 950 } | 965 } |
| 966 |
| 967 void AudioContext::removeAudioDecoderResolver(ScriptPromiseResolver* resolver) |
| 968 { |
| 969 ASSERT(isMainThread()); |
| 970 |
| 971 for (size_t k = 0; k < m_audioDecoderResolvers.size(); ++k) { |
| 972 if (resolver == m_audioDecoderResolvers.at(k)) { |
| 973 m_audioDecoderResolvers.remove(k); |
| 974 break; |
| 975 } |
| 976 } |
| 977 } |
| 978 |
| 951 void AudioContext::handlePreRenderTasks() | 979 void AudioContext::handlePreRenderTasks() |
| 952 { | 980 { |
| 953 ASSERT(isAudioThread()); | 981 ASSERT(isAudioThread()); |
| 954 | 982 |
| 955 // At the beginning of every render quantum, try to update the internal rend
ering graph state (from main thread changes). | 983 // At the beginning of every render quantum, try to update the internal rend
ering graph state (from main thread changes). |
| 956 // It's OK if the tryLock() fails, we'll just take slightly longer to pick u
p the changes. | 984 // It's OK if the tryLock() fails, we'll just take slightly longer to pick u
p the changes. |
| 957 if (tryLock()) { | 985 if (tryLock()) { |
| 958 // Update the channel count mode. | 986 // Update the channel count mode. |
| 959 updateChangedChannelCountMode(); | 987 updateChangedChannelCountMode(); |
| 960 | 988 |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 | 1219 |
| 1192 // Resolve any pending promises created by suspend() | 1220 // Resolve any pending promises created by suspend() |
| 1193 if (m_suspendResolvers.size() > 0) | 1221 if (m_suspendResolvers.size() > 0) |
| 1194 Platform::current()->mainThread()->postTask(FROM_HERE, bind(&AudioContex
t::resolvePromisesForSuspendOnMainThread, this)); | 1222 Platform::current()->mainThread()->postTask(FROM_HERE, bind(&AudioContex
t::resolvePromisesForSuspendOnMainThread, this)); |
| 1195 } | 1223 } |
| 1196 | 1224 |
| 1197 void AudioContext::rejectPendingResolvers() | 1225 void AudioContext::rejectPendingResolvers() |
| 1198 { | 1226 { |
| 1199 ASSERT(isMainThread()); | 1227 ASSERT(isMainThread()); |
| 1200 | 1228 |
| 1201 // Audio context is closing down so reject any suspend or resume promises th
at are still | 1229 // Audio context is closing down so reject any promises that are still pendi
ng. |
| 1202 // pending. | |
| 1203 | 1230 |
| 1204 for (auto& resolver : m_suspendResolvers) { | 1231 for (auto& resolver : m_suspendResolvers) { |
| 1205 resolver->reject(DOMException::create(InvalidStateError, "Audio context
is going away")); | 1232 resolver->reject(DOMException::create(InvalidStateError, "Audio context
is going away")); |
| 1206 } | 1233 } |
| 1207 m_suspendResolvers.clear(); | 1234 m_suspendResolvers.clear(); |
| 1208 | 1235 |
| 1209 for (auto& resolver : m_resumeResolvers) { | 1236 for (auto& resolver : m_resumeResolvers) { |
| 1210 resolver->reject(DOMException::create(InvalidStateError, "Audio context
is going away")); | 1237 resolver->reject(DOMException::create(InvalidStateError, "Audio context
is going away")); |
| 1211 } | 1238 } |
| 1212 m_resumeResolvers.clear(); | 1239 m_resumeResolvers.clear(); |
| 1213 m_isResolvingResumePromises = false; | 1240 m_isResolvingResumePromises = false; |
| 1241 |
| 1242 for (auto& resolver : m_audioDecoderResolvers) { |
| 1243 resolver->reject(DOMException::create(InvalidStateError, "Audio context
is going away")); |
| 1244 } |
| 1245 m_audioDecoderResolvers.clear(); |
| 1214 } | 1246 } |
| 1215 | 1247 |
| 1216 const AtomicString& AudioContext::interfaceName() const | 1248 const AtomicString& AudioContext::interfaceName() const |
| 1217 { | 1249 { |
| 1218 return EventTargetNames::AudioContext; | 1250 return EventTargetNames::AudioContext; |
| 1219 } | 1251 } |
| 1220 | 1252 |
| 1221 ExecutionContext* AudioContext::executionContext() const | 1253 ExecutionContext* AudioContext::executionContext() const |
| 1222 { | 1254 { |
| 1223 return m_isStopScheduled ? 0 : ActiveDOMObject::executionContext(); | 1255 return m_isStopScheduled ? 0 : ActiveDOMObject::executionContext(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 // Avoid firing the event if the document has already gone away. | 1298 // Avoid firing the event if the document has already gone away. |
| 1267 if (executionContext()) { | 1299 if (executionContext()) { |
| 1268 // Call the offline rendering completion event listener and resolve the
promise too. | 1300 // Call the offline rendering completion event listener and resolve the
promise too. |
| 1269 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); | 1301 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); |
| 1270 m_offlineResolver->resolve(renderedBuffer); | 1302 m_offlineResolver->resolve(renderedBuffer); |
| 1271 } | 1303 } |
| 1272 } | 1304 } |
| 1273 | 1305 |
| 1274 DEFINE_TRACE(AudioContext) | 1306 DEFINE_TRACE(AudioContext) |
| 1275 { | 1307 { |
| 1308 visitor->trace(m_audioDecoderResolvers); |
| 1276 visitor->trace(m_closeResolver); | 1309 visitor->trace(m_closeResolver); |
| 1277 visitor->trace(m_offlineResolver); | 1310 visitor->trace(m_offlineResolver); |
| 1278 visitor->trace(m_renderTarget); | 1311 visitor->trace(m_renderTarget); |
| 1279 visitor->trace(m_destinationNode); | 1312 visitor->trace(m_destinationNode); |
| 1280 visitor->trace(m_listener); | 1313 visitor->trace(m_listener); |
| 1281 // trace() can be called in AudioContext constructor, and | 1314 // trace() can be called in AudioContext constructor, and |
| 1282 // m_contextGraphMutex might be unavailable. | 1315 // m_contextGraphMutex might be unavailable. |
| 1283 if (m_didInitializeContextGraphMutex) { | 1316 if (m_didInitializeContextGraphMutex) { |
| 1284 AutoLocker lock(this); | 1317 AutoLocker lock(this); |
| 1285 visitor->trace(m_referencedNodes); | 1318 visitor->trace(m_referencedNodes); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise | 1393 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise |
| 1361 // created here. | 1394 // created here. |
| 1362 stop(); | 1395 stop(); |
| 1363 | 1396 |
| 1364 return promise; | 1397 return promise; |
| 1365 } | 1398 } |
| 1366 | 1399 |
| 1367 } // namespace blink | 1400 } // namespace blink |
| 1368 | 1401 |
| 1369 #endif // ENABLE(WEB_AUDIO) | 1402 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |