Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: Source/modules/webaudio/AudioContext.cpp

Issue 1006963003: AudioContext.decodeAudioData returns a Promise (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix idl; small cleanups Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698