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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 } | 92 } |
93 | 93 |
94 AudioContext* audioContext = new AudioContext(&document); | 94 AudioContext* audioContext = new AudioContext(&document); |
95 audioContext->suspendIfNeeded(); | 95 audioContext->suspendIfNeeded(); |
96 return audioContext; | 96 return audioContext; |
97 } | 97 } |
98 | 98 |
99 // Constructor for rendering to the audio hardware. | 99 // Constructor for rendering to the audio hardware. |
100 AudioContext::AudioContext(Document* document) | 100 AudioContext::AudioContext(Document* document) |
101 : ActiveDOMObject(document) | 101 : ActiveDOMObject(document) |
102 , m_didInitializeContextGraphMutex(false) | |
103 , m_isOfflineContext(false) | |
104 , m_destinationNode(nullptr) | |
102 , m_isStopScheduled(false) | 105 , m_isStopScheduled(false) |
103 , m_isCleared(false) | 106 , m_isCleared(false) |
104 , m_isInitialized(false) | 107 , m_isInitialized(false) |
105 , m_destinationNode(nullptr) | |
106 , m_isResolvingResumePromises(false) | 108 , m_isResolvingResumePromises(false) |
107 , m_connectionCount(0) | 109 , m_connectionCount(0) |
108 , m_didInitializeContextGraphMutex(false) | |
109 , m_deferredTaskHandler(DeferredTaskHandler::create()) | 110 , m_deferredTaskHandler(DeferredTaskHandler::create()) |
110 , m_isOfflineContext(false) | |
111 , m_contextState(Suspended) | 111 , m_contextState(Suspended) |
112 { | 112 { |
113 m_didInitializeContextGraphMutex = true; | 113 m_didInitializeContextGraphMutex = true; |
114 m_destinationNode = DefaultAudioDestinationNode::create(this); | 114 m_destinationNode = DefaultAudioDestinationNode::create(this); |
115 | 115 |
116 initialize(); | 116 initialize(); |
117 } | 117 } |
118 | 118 |
119 // Constructor for offline (non-realtime) rendering. | 119 // Constructor for offline (non-realtime) rendering. |
120 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) | 120 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) |
121 : ActiveDOMObject(document) | 121 : ActiveDOMObject(document) |
122 , m_didInitializeContextGraphMutex(false) | |
123 , m_isOfflineContext(true) | |
124 , m_destinationNode(nullptr) | |
122 , m_isStopScheduled(false) | 125 , m_isStopScheduled(false) |
123 , m_isCleared(false) | 126 , m_isCleared(false) |
124 , m_isInitialized(false) | 127 , m_isInitialized(false) |
125 , m_destinationNode(nullptr) | |
126 , m_isResolvingResumePromises(false) | 128 , m_isResolvingResumePromises(false) |
127 , m_connectionCount(0) | 129 , m_connectionCount(0) |
128 , m_didInitializeContextGraphMutex(false) | |
129 , m_deferredTaskHandler(DeferredTaskHandler::create()) | 130 , m_deferredTaskHandler(DeferredTaskHandler::create()) |
130 , m_isOfflineContext(true) | |
131 , m_contextState(Suspended) | 131 , m_contextState(Suspended) |
132 { | 132 { |
133 m_didInitializeContextGraphMutex = true; | 133 m_didInitializeContextGraphMutex = true; |
134 | |
134 // Create a new destination for offline rendering. | 135 // Create a new destination for offline rendering. |
135 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); | 136 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); |
136 if (m_renderTarget.get()) | 137 if (m_renderTarget.get()) |
137 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); | 138 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); |
138 | 139 |
139 initialize(); | 140 initialize(); |
140 } | 141 } |
141 | 142 |
142 AudioContext::~AudioContext() | 143 AudioContext::~AudioContext() |
143 { | 144 { |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 } | 712 } |
712 | 713 |
713 if (newState == m_contextState) { | 714 if (newState == m_contextState) { |
714 // ASSERTs above failed; just return. | 715 // ASSERTs above failed; just return. |
715 return; | 716 return; |
716 } | 717 } |
717 | 718 |
718 m_contextState = newState; | 719 m_contextState = newState; |
719 | 720 |
720 // Notify context that state changed | 721 // Notify context that state changed |
721 if (executionContext()) | 722 if (executionContext()) { |
722 executionContext()->postTask(FROM_HERE, createSameThreadTask(&AudioConte xt::notifyStateChange, this)); | 723 executionContext()->postTask(FROM_HERE, |
724 createSameThreadTask(&AudioContext::notifyStateChange, this)); | |
725 } | |
Raymond Toy
2015/05/28 16:37:35
This change isn't really necessary, is it?
hongchan
2015/06/09 20:49:59
No, I am reverting this in PS6.
| |
723 } | 726 } |
724 | 727 |
725 void AudioContext::notifyStateChange() | 728 void AudioContext::notifyStateChange() |
726 { | 729 { |
727 dispatchEvent(Event::create(EventTypeNames::statechange)); | 730 dispatchEvent(Event::create(EventTypeNames::statechange)); |
728 } | 731 } |
729 | 732 |
730 ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) | 733 ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) |
731 { | 734 { |
732 ASSERT(isMainThread()); | 735 ASSERT(isMainThread()); |
736 ASSERT(!isOfflineContext()); | |
737 | |
733 AutoLocker locker(this); | 738 AutoLocker locker(this); |
734 | 739 |
735 if (isOfflineContext()) { | |
736 return ScriptPromise::rejectWithDOMException( | |
737 scriptState, | |
738 DOMException::create( | |
739 InvalidAccessError, | |
740 "cannot suspend an OfflineAudioContext")); | |
741 } | |
742 | |
743 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 740 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
744 ScriptPromise promise = resolver->promise(); | 741 ScriptPromise promise = resolver->promise(); |
745 | 742 |
746 if (m_contextState == Closed) { | 743 if (m_contextState == Closed) { |
747 resolver->reject( | 744 resolver->reject( |
748 DOMException::create(InvalidStateError, "Cannot suspend a context th at has been closed")); | 745 DOMException::create(InvalidStateError, "Cannot suspend a context th at has been closed")); |
749 } else { | 746 } else { |
750 // Stop rendering now. | 747 // Stop rendering now. |
751 if (m_destinationNode) | 748 if (m_destinationNode) |
752 stopRendering(); | 749 stopRendering(); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
938 return EventTargetNames::AudioContext; | 935 return EventTargetNames::AudioContext; |
939 } | 936 } |
940 | 937 |
941 ExecutionContext* AudioContext::executionContext() const | 938 ExecutionContext* AudioContext::executionContext() const |
942 { | 939 { |
943 return m_isStopScheduled ? 0 : ActiveDOMObject::executionContext(); | 940 return m_isStopScheduled ? 0 : ActiveDOMObject::executionContext(); |
944 } | 941 } |
945 | 942 |
946 void AudioContext::startRendering() | 943 void AudioContext::startRendering() |
947 { | 944 { |
948 // This is called for both online and offline contexts. | 945 // This is only for the real-time context. |
Raymond Toy
2015/05/28 16:37:35
Add assert for !isOfflineContext()?
hongchan
2015/06/09 20:49:59
Done.
| |
949 ASSERT(isMainThread()); | 946 ASSERT(isMainThread()); |
950 ASSERT(m_destinationNode); | 947 ASSERT(m_destinationNode); |
951 | 948 |
952 if (m_contextState == Suspended) { | 949 if (m_contextState == Suspended) { |
953 destination()->audioDestinationHandler().startRendering(); | 950 destination()->audioDestinationHandler().startRendering(); |
954 setContextState(Running); | 951 setContextState(Running); |
955 } | 952 } |
956 } | 953 } |
957 | 954 |
958 void AudioContext::stopRendering() | 955 void AudioContext::stopRendering() |
959 { | 956 { |
960 ASSERT(isMainThread()); | 957 ASSERT(isMainThread()); |
961 ASSERT(m_destinationNode); | 958 ASSERT(m_destinationNode); |
962 ASSERT(!isOfflineContext()); | 959 ASSERT(!isOfflineContext()); |
963 | 960 |
964 if (m_contextState == Running) { | 961 if (m_contextState == Running) { |
965 destination()->audioDestinationHandler().stopRendering(); | 962 destination()->audioDestinationHandler().stopRendering(); |
966 setContextState(Suspended); | 963 setContextState(Suspended); |
967 deferredTaskHandler().clearHandlersToBeDeleted(); | 964 deferredTaskHandler().clearHandlersToBeDeleted(); |
968 } | 965 } |
969 } | 966 } |
970 | 967 |
968 bool AudioContext::shouldSuspendNow() | |
Raymond Toy
2015/05/28 16:37:35
Can't this be a method just on an OfflineAudioCont
hongchan
2015/06/09 20:49:58
The problem is OAC is a very thin wrapper for AC.
Raymond Toy
2015/06/09 22:34:59
Why not make context() be virtual? I don't know wh
| |
969 { | |
970 ASSERT_WITH_MESSAGE(1, "shouldSuspendNow() only valid for offline audio cont ext"); | |
971 return false; | |
972 } | |
973 | |
971 void AudioContext::fireCompletionEvent() | 974 void AudioContext::fireCompletionEvent() |
Raymond Toy
2015/05/28 16:37:35
Could this be moved to the OfflineAudioContext cla
hongchan
2015/06/09 20:49:59
The same reason above.
| |
972 { | 975 { |
973 ASSERT(isMainThread()); | 976 ASSERT_WITH_MESSAGE(1, "fireCompletionEvent() only valid for offline audio c ontext"); |
974 if (!isMainThread()) | |
975 return; | |
976 | |
977 AudioBuffer* renderedBuffer = m_renderTarget.get(); | |
978 | |
979 // For an offline context, we set the state to closed here so that the oncom plete handler sees | |
980 // that the context has been closed. | |
981 setContextState(Closed); | |
982 | |
983 ASSERT(renderedBuffer); | |
984 if (!renderedBuffer) | |
985 return; | |
986 | |
987 // Avoid firing the event if the document has already gone away. | |
988 if (executionContext()) { | |
989 // Call the offline rendering completion event listener and resolve the promise too. | |
990 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); | |
991 m_offlineResolver->resolve(renderedBuffer); | |
992 } | |
993 } | 977 } |
994 | 978 |
995 DEFINE_TRACE(AudioContext) | 979 DEFINE_TRACE(AudioContext) |
996 { | 980 { |
997 visitor->trace(m_closeResolver); | 981 visitor->trace(m_closeResolver); |
998 visitor->trace(m_offlineResolver); | |
999 visitor->trace(m_renderTarget); | 982 visitor->trace(m_renderTarget); |
1000 visitor->trace(m_destinationNode); | 983 visitor->trace(m_destinationNode); |
1001 visitor->trace(m_listener); | 984 visitor->trace(m_listener); |
1002 // trace() can be called in AudioContext constructor, and | 985 // trace() can be called in AudioContext constructor, and |
1003 // m_contextGraphMutex might be unavailable. | 986 // m_contextGraphMutex might be unavailable. |
1004 if (m_didInitializeContextGraphMutex) { | 987 if (m_didInitializeContextGraphMutex) { |
1005 AutoLocker lock(this); | 988 AutoLocker lock(this); |
1006 visitor->trace(m_activeSourceNodes); | 989 visitor->trace(m_activeSourceNodes); |
1007 } else { | 990 } else { |
1008 visitor->trace(m_activeSourceNodes); | 991 visitor->trace(m_activeSourceNodes); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 // the destination node can GCed if JS has no references. stop() will also r esolve the Promise | 1028 // the destination node can GCed if JS has no references. stop() will also r esolve the Promise |
1046 // created here. | 1029 // created here. |
1047 stop(); | 1030 stop(); |
1048 | 1031 |
1049 return promise; | 1032 return promise; |
1050 } | 1033 } |
1051 | 1034 |
1052 } // namespace blink | 1035 } // namespace blink |
1053 | 1036 |
1054 #endif // ENABLE(WEB_AUDIO) | 1037 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |