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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 , m_isInitialized(false) | 112 , m_isInitialized(false) |
113 , m_isAudioThreadFinished(false) | 113 , m_isAudioThreadFinished(false) |
114 , m_destinationNode(nullptr) | 114 , m_destinationNode(nullptr) |
115 , m_isDeletionScheduled(false) | 115 , m_isDeletionScheduled(false) |
116 , m_automaticPullNodesNeedUpdating(false) | 116 , m_automaticPullNodesNeedUpdating(false) |
117 , m_connectionCount(0) | 117 , m_connectionCount(0) |
118 , m_audioThread(0) | 118 , m_audioThread(0) |
119 , m_graphOwnerThread(UndefinedThreadIdentifier) | 119 , m_graphOwnerThread(UndefinedThreadIdentifier) |
120 , m_isOfflineContext(false) | 120 , m_isOfflineContext(false) |
121 { | 121 { |
122 m_destinationNode = DefaultAudioDestinationNode::create(this); | |
123 | |
122 constructCommon(); | 124 constructCommon(); |
123 | |
124 m_destinationNode = DefaultAudioDestinationNode::create(this); | |
Raymond Toy
2014/05/27 17:49:45
Why are these two lines swapped?
KhNo
2014/05/28 14:39:51
It must be initialized after creating m_destinatio
| |
125 } | 125 } |
126 | 126 |
127 // Constructor for offline (non-realtime) rendering. | 127 // Constructor for offline (non-realtime) rendering. |
128 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) | 128 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) |
129 : ActiveDOMObject(document) | 129 : ActiveDOMObject(document) |
130 , m_isStopScheduled(false) | 130 , m_isStopScheduled(false) |
131 , m_isCleared(false) | 131 , m_isCleared(false) |
132 , m_isInitialized(false) | 132 , m_isInitialized(false) |
133 , m_isAudioThreadFinished(false) | 133 , m_isAudioThreadFinished(false) |
134 , m_destinationNode(nullptr) | 134 , m_destinationNode(nullptr) |
135 , m_automaticPullNodesNeedUpdating(false) | 135 , m_automaticPullNodesNeedUpdating(false) |
136 , m_connectionCount(0) | 136 , m_connectionCount(0) |
137 , m_audioThread(0) | 137 , m_audioThread(0) |
138 , m_graphOwnerThread(UndefinedThreadIdentifier) | 138 , m_graphOwnerThread(UndefinedThreadIdentifier) |
139 , m_isOfflineContext(true) | 139 , m_isOfflineContext(true) |
140 { | 140 { |
141 constructCommon(); | |
142 | |
143 // Create a new destination for offline rendering. | 141 // Create a new destination for offline rendering. |
144 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); | 142 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); |
145 if (m_renderTarget.get()) | 143 if (m_renderTarget.get()) |
146 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); | 144 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); |
145 | |
146 constructCommon(); | |
Raymond Toy
2014/05/27 17:49:45
Why is this moved from the beginning to the end?
KhNo
2014/05/28 14:39:51
It must be initialized after creating m_destinatio
| |
147 } | 147 } |
148 | 148 |
149 void AudioContext::constructCommon() | 149 void AudioContext::constructCommon() |
150 { | 150 { |
151 ScriptWrappable::init(this); | 151 ScriptWrappable::init(this); |
152 | 152 |
153 FFTFrame::initialize(); | 153 FFTFrame::initialize(); |
154 | 154 |
155 m_listener = AudioListener::create(); | 155 m_listener = AudioListener::create(); |
156 | |
157 initialize(); | |
156 } | 158 } |
157 | 159 |
158 AudioContext::~AudioContext() | 160 AudioContext::~AudioContext() |
159 { | 161 { |
160 #if DEBUG_AUDIONODE_REFERENCES | 162 #if DEBUG_AUDIONODE_REFERENCES |
161 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); | 163 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); |
162 #endif | 164 #endif |
163 // 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. | 165 // 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. |
164 ASSERT(!m_isInitialized); | 166 ASSERT(!m_isInitialized); |
165 ASSERT(!m_nodesToDelete.size()); | 167 ASSERT(!m_nodesToDelete.size()); |
166 ASSERT(!m_referencedNodes.size()); | 168 ASSERT(!m_referencedNodes.size()); |
167 ASSERT(!m_finishedNodes.size()); | 169 ASSERT(!m_finishedNodes.size()); |
168 ASSERT(!m_automaticPullNodes.size()); | 170 ASSERT(!m_automaticPullNodes.size()); |
169 if (m_automaticPullNodesNeedUpdating) | 171 if (m_automaticPullNodesNeedUpdating) |
170 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 172 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
171 ASSERT(!m_renderingAutomaticPullNodes.size()); | 173 ASSERT(!m_renderingAutomaticPullNodes.size()); |
172 } | 174 } |
173 | 175 |
174 void AudioContext::lazyInitialize() | 176 void AudioContext::initialize() |
175 { | 177 { |
176 if (!m_isInitialized) { | 178 // Don't allow the context to initialize a second time after it's already be en explicitly uninitialized. |
177 // Don't allow the context to initialize a second time after it's alread y been explicitly uninitialized. | 179 if (isInitialized()) |
178 ASSERT(!m_isAudioThreadFinished); | 180 return; |
179 if (!m_isAudioThreadFinished) { | |
180 // Creation of a destination node should not start the audio HW. The | |
181 // creation of any other AudioNode will initialize the audio HW and start processing | |
182 if (m_destinationNode.get()) { | |
183 m_destinationNode->initialize(); | |
184 | 181 |
185 if (!isOfflineContext()) { | 182 if (m_destinationNode) { |
186 // This starts the audio thread. The destination node's prov ideInput() method will now be called repeatedly to render audio. | 183 if (!isOfflineContext()) |
187 // Each time provideInput() is called, a portion of the audi o stream is rendered. Let's call this time period a "render quantum". | 184 ++s_hardwareContextCount; |
188 // NOTE: for now default AudioContext does not need an expli cit startRendering() call from JavaScript. | |
189 // We may want to consider requiring it for symmetry with Of flineAudioContext. | |
190 m_destinationNode->startRendering(); | |
Raymond Toy
2014/05/27 17:49:45
Don't we still need to call startRendering()?
KhNo
2014/05/28 14:39:51
This is my big mistake. Sorry about it. It must be
| |
191 ++s_hardwareContextCount; | |
192 } | |
193 | 185 |
194 m_isInitialized = true; | 186 m_destinationNode->initialize(); |
195 } | 187 m_isInitialized = true; |
196 } | |
197 } | 188 } |
198 } | 189 } |
199 | 190 |
200 void AudioContext::clear() | 191 void AudioContext::clear() |
201 { | 192 { |
202 // We have to release our reference to the destination node before the conte xt will ever be deleted since the destination node holds a reference to the cont ext. | 193 // We have to release our reference to the destination node before the conte xt will ever be deleted since the destination node holds a reference to the cont ext. |
203 if (m_destinationNode) | 194 if (m_destinationNode) |
204 m_destinationNode.clear(); | 195 m_destinationNode.clear(); |
205 | 196 |
206 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. | 197 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
971 { | 962 { |
972 visitor->trace(m_renderTarget); | 963 visitor->trace(m_renderTarget); |
973 visitor->trace(m_destinationNode); | 964 visitor->trace(m_destinationNode); |
974 visitor->trace(m_listener); | 965 visitor->trace(m_listener); |
975 visitor->trace(m_dirtySummingJunctions); | 966 visitor->trace(m_dirtySummingJunctions); |
976 } | 967 } |
977 | 968 |
978 } // namespace WebCore | 969 } // namespace WebCore |
979 | 970 |
980 #endif // ENABLE(WEB_AUDIO) | 971 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |