Index: Source/modules/webaudio/AudioScheduledSourceNode.cpp |
diff --git a/Source/modules/webaudio/AudioScheduledSourceNode.cpp b/Source/modules/webaudio/AudioScheduledSourceNode.cpp |
index 876da2a1b6c24a6d556685a9ac5a5e17fda89519..7aa6439f9edddb5db49fdfafa14d7f1e4bd2c49a 100644 |
--- a/Source/modules/webaudio/AudioScheduledSourceNode.cpp |
+++ b/Source/modules/webaudio/AudioScheduledSourceNode.cpp |
@@ -28,6 +28,9 @@ |
#include "modules/webaudio/AudioScheduledSourceNode.h" |
+#include "bindings/v8/ExceptionMessages.h" |
+#include "bindings/v8/ExceptionState.h" |
+#include "core/dom/ExceptionCode.h" |
#include "core/events/Event.h" |
#include "platform/audio/AudioUtilities.h" |
#include "modules/webaudio/AudioContext.h" |
@@ -46,6 +49,7 @@ AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float |
, m_startTime(0) |
, m_endTime(UnknownTime) |
, m_hasEndedListener(false) |
+ , m_stopCalled(false) |
{ |
} |
@@ -134,34 +138,51 @@ void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize, |
return; |
} |
-void AudioScheduledSourceNode::start(double when) |
+ |
+void AudioScheduledSourceNode::start(double when, ExceptionState& es) |
{ |
ASSERT(isMainThread()); |
- if (m_playbackState != UNSCHEDULED_STATE) |
+ |
+ if (m_playbackState != UNSCHEDULED_STATE) { |
+ es.throwDOMException( |
+ InvalidStateError, |
+ ExceptionMessages::failedToExecute( |
+ "start", |
+ "OscillatorNode", |
+ "cannot call start more than once.")); |
return; |
+ } |
m_startTime = when; |
m_playbackState = SCHEDULED_STATE; |
} |
-void AudioScheduledSourceNode::stop(double when) |
+void AudioScheduledSourceNode::stop(double when, ExceptionState& es) |
{ |
ASSERT(isMainThread()); |
- if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE)) |
- return; |
- |
- when = max(0.0, when); |
- m_endTime = when; |
-} |
-void AudioScheduledSourceNode::noteOn(double when) |
-{ |
- start(when); |
-} |
- |
-void AudioScheduledSourceNode::noteOff(double when) |
-{ |
- stop(when); |
+ if (m_stopCalled) { |
+ es.throwDOMException( |
+ InvalidStateError, |
+ ExceptionMessages::failedToExecute( |
+ "stop", |
+ "OscillatorNode", |
+ "cannot call stop more than once.")); |
+ } else if (m_playbackState == UNSCHEDULED_STATE) { |
+ es.throwDOMException( |
+ InvalidStateError, |
+ ExceptionMessages::failedToExecute( |
+ "stop", |
+ "OscillatorNode", |
+ "cannot call stop without calling start first.")); |
+ } else { |
+ // This can only happen from the SCHEDULED_STATE or PLAYING_STATE. The UNSCHEDULED_STATE is |
+ // handled above, and the FINISHED_STATE is only reachable after stop() has been called, and |
+ // hence m_stopCalled is true. But that case is handled above. |
+ when = max(0.0, when); |
+ m_endTime = when; |
+ m_stopCalled = true; |
+ } |
} |
void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) |