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

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

Issue 23596014: Keep AudioScheduledSourceNode alive until onended is called. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Implement ActiveDOMObject::stop() Created 7 years, 3 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) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, 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 24 matching lines...) Expand all
35 #include "wtf/MathExtras.h" 35 #include "wtf/MathExtras.h"
36 36
37 using namespace std; 37 using namespace std;
38 38
39 namespace WebCore { 39 namespace WebCore {
40 40
41 const double AudioScheduledSourceNode::UnknownTime = -1; 41 const double AudioScheduledSourceNode::UnknownTime = -1;
42 42
43 AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float sampleRate) 43 AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float sampleRate)
44 : AudioSourceNode(context, sampleRate) 44 : AudioSourceNode(context, sampleRate)
45 , ActiveDOMObject(context->scriptExecutionContext())
45 , m_playbackState(UNSCHEDULED_STATE) 46 , m_playbackState(UNSCHEDULED_STATE)
46 , m_startTime(0) 47 , m_startTime(0)
47 , m_endTime(UnknownTime) 48 , m_endTime(UnknownTime)
48 , m_hasEndedListener(false) 49 , m_hasEndedListener(false)
50 , m_notifyingEndedListener(false)
49 { 51 {
50 } 52 }
51 53
52 void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize, 54 void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize,
53 AudioBus* outputBus, 55 AudioBus* outputBus,
54 size_t& quantumFrameOffset, 56 size_t& quantumFrameOffset,
55 size_t& nonSilentFramesToPro cess) 57 size_t& nonSilentFramesToPro cess)
56 { 58 {
57 ASSERT(outputBus); 59 ASSERT(outputBus);
58 if (!outputBus) 60 if (!outputBus)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 void AudioScheduledSourceNode::start(double when) 139 void AudioScheduledSourceNode::start(double when)
138 { 140 {
139 ASSERT(isMainThread()); 141 ASSERT(isMainThread());
140 if (m_playbackState != UNSCHEDULED_STATE) 142 if (m_playbackState != UNSCHEDULED_STATE)
141 return; 143 return;
142 144
143 m_startTime = when; 145 m_startTime = when;
144 m_playbackState = SCHEDULED_STATE; 146 m_playbackState = SCHEDULED_STATE;
145 } 147 }
146 148
147 void AudioScheduledSourceNode::stop(double when) 149 void AudioScheduledSourceNode::stopNote(double when)
148 { 150 {
149 ASSERT(isMainThread()); 151 ASSERT(isMainThread());
150 if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE )) 152 if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE ))
151 return; 153 return;
152 154
153 when = max(0.0, when); 155 when = max(0.0, when);
154 m_endTime = when; 156 m_endTime = when;
155 } 157 }
156 158
157 void AudioScheduledSourceNode::noteOn(double when) 159 void AudioScheduledSourceNode::noteOn(double when)
158 { 160 {
159 start(when); 161 start(when);
160 } 162 }
161 163
162 void AudioScheduledSourceNode::noteOff(double when) 164 void AudioScheduledSourceNode::noteOff(double when)
163 { 165 {
164 stop(when); 166 stopNote(when);
165 } 167 }
166 168
167 void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener, DO MWrapperWorld* isolatedWorld) 169 void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener, DO MWrapperWorld* isolatedWorld)
168 { 170 {
169 m_hasEndedListener = listener; 171 m_hasEndedListener = listener;
170 setAttributeEventListener(eventNames().endedEvent, listener, isolatedWorld); 172 setAttributeEventListener(eventNames().endedEvent, listener, isolatedWorld);
171 } 173 }
172 174
173 void AudioScheduledSourceNode::finish() 175 void AudioScheduledSourceNode::finish()
174 { 176 {
175 if (m_playbackState != FINISHED_STATE) { 177 if (m_playbackState != FINISHED_STATE) {
176 // Let the context dereference this AudioNode. 178 // Let the context dereference this AudioNode.
177 context()->notifyNodeFinishedProcessing(this); 179 context()->notifyNodeFinishedProcessing(this);
178 m_playbackState = FINISHED_STATE; 180 m_playbackState = FINISHED_STATE;
179 context()->decrementActiveSourceCount(); 181 context()->decrementActiveSourceCount();
180 } 182 }
181 183
182 if (m_hasEndedListener) { 184 if (m_hasEndedListener) {
183 // Reference ourself so we don't accidentally get deleted before notifyE nded gets called. 185 m_notifyingEndedListener = true;
184 ref(); 186 setPendingActivity(this);
185 callOnMainThread(&AudioScheduledSourceNode::notifyEndedDispatch, this); 187 callOnMainThread(&AudioScheduledSourceNode::notifyEndedDispatch, this);
186 } 188 }
187 } 189 }
188 190
189 void AudioScheduledSourceNode::notifyEndedDispatch(void* userData) 191 void AudioScheduledSourceNode::notifyEndedDispatch(void* userData)
190 { 192 {
191 static_cast<AudioScheduledSourceNode*>(userData)->notifyEnded(); 193 static_cast<AudioScheduledSourceNode*>(userData)->notifyEnded();
192 } 194 }
193 195
194 void AudioScheduledSourceNode::notifyEnded() 196 void AudioScheduledSourceNode::notifyEnded()
195 { 197 {
196 // Avoid firing the event if the document has already gone away. 198 // Avoid firing the event if the document has already gone away.
197 if (context()->scriptExecutionContext()) { 199 if (context()->scriptExecutionContext()) {
198 RefPtr<Event> event = Event::create(eventNames().endedEvent); 200 RefPtr<Event> event = Event::create(eventNames().endedEvent);
199 event->setTarget(this); 201 event->setTarget(this);
200 dispatchEvent(event.get()); 202 dispatchEvent(event.get());
201 } 203 }
204 m_notifyingEndedListener = false;
205 unsetPendingActivity(this);
206 }
202 207
203 // Deref to match the ref() call in finish(); 208 ScriptExecutionContext* AudioScheduledSourceNode::scriptExecutionContext() const
204 deref(); 209 {
210 return context()->scriptExecutionContext();
211 }
212
213 void AudioScheduledSourceNode::stop()
214 {
215 if (m_notifyingEndedListener)
haraken 2013/09/09 17:58:51 How about just using hasPendingActivity() instead
Raymond Toy (Google) 2013/09/09 18:23:45 Done. m_notifyingEndedListener removed.
216 unsetPendingActivity(this);
205 } 217 }
206 218
207 } // namespace WebCore 219 } // namespace WebCore
208 220
209 #endif // ENABLE(WEB_AUDIO) 221 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/AudioScheduledSourceNode.h ('k') | Source/modules/webaudio/OscillatorNode.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698