Bug 1324568 - Implement AudioScheduledSourceNode, r=padenot
☠☠ backed out by 4ee212f486d7 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 20 Dec 2016 20:20:41 +0100
changeset 326655 d70b97db8d9e50e3b698f4fd76a5bf995b9ddb4a
parent 326654 50a74758ee7d3079f021694c61f20eba60b0eae2
child 326656 f350bbf9e6363a685520b2ad9ba8071f6eebfd07
push id31108
push userphilringnalda@gmail.com
push dateWed, 21 Dec 2016 04:15:33 +0000
treeherdermozilla-central@c36fbe84042d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1324568
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1324568 - Implement AudioScheduledSourceNode, r=padenot
dom/media/webaudio/AudioBufferSourceNode.cpp
dom/media/webaudio/AudioBufferSourceNode.h
dom/media/webaudio/AudioScheduledSourceNode.cpp
dom/media/webaudio/AudioScheduledSourceNode.h
dom/media/webaudio/ConstantSourceNode.cpp
dom/media/webaudio/ConstantSourceNode.h
dom/media/webaudio/OscillatorNode.cpp
dom/media/webaudio/OscillatorNode.h
dom/media/webaudio/moz.build
dom/webidl/AudioBufferSourceNode.webidl
dom/webidl/AudioScheduledSourceNode.webidl
dom/webidl/ConstantSourceNode.webidl
dom/webidl/OscillatorNode.webidl
dom/webidl/moz.build
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -17,23 +17,25 @@
 #include "AudioDestinationNode.h"
 #include "AudioParamTimeline.h"
 #include <limits>
 #include <algorithm>
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioBufferSourceNode, AudioNode, mBuffer, mPlaybackRate, mDetune)
+NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioBufferSourceNode,
+                                   AudioScheduledSourceNode, mBuffer,
+                                   mPlaybackRate, mDetune)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioBufferSourceNode)
-NS_INTERFACE_MAP_END_INHERITING(AudioNode)
+NS_INTERFACE_MAP_END_INHERITING(AudioScheduledSourceNode)
 
-NS_IMPL_ADDREF_INHERITED(AudioBufferSourceNode, AudioNode)
-NS_IMPL_RELEASE_INHERITED(AudioBufferSourceNode, AudioNode)
+NS_IMPL_ADDREF_INHERITED(AudioBufferSourceNode, AudioScheduledSourceNode)
+NS_IMPL_RELEASE_INHERITED(AudioBufferSourceNode, AudioScheduledSourceNode)
 
 /**
  * Media-thread playback engine for AudioBufferSourceNode.
  * Nothing is played until a non-null buffer has been set (via
  * AudioNodeStream::SetBuffer) and a non-zero mBufferEnd has been set (via
  * AudioNodeStream::SetInt32Parameter).
  */
 class AudioBufferSourceNodeEngine final : public AudioNodeEngine
@@ -583,20 +585,20 @@ public:
   AudioNodeStream* mDestination;
   AudioNodeStream* mSource;
   AudioParamTimeline mPlaybackRateTimeline;
   AudioParamTimeline mDetuneTimeline;
   bool mLoop;
 };
 
 AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
-  : AudioNode(aContext,
-              2,
-              ChannelCountMode::Max,
-              ChannelInterpretation::Speakers)
+  : AudioScheduledSourceNode(aContext,
+                             2,
+                             ChannelCountMode::Max,
+                             ChannelInterpretation::Speakers)
   , mLoopStart(0.0)
   , mLoopEnd(0.0)
   // mOffset and mDuration are initialized in Start().
   , mPlaybackRate(new AudioParam(this, PLAYBACKRATE, 1.0f, "playbackRate"))
   , mDetune(new AudioParam(this, DETUNE, 0.0f, "detune"))
   , mLoop(false)
   , mStartCalled(false)
 {
@@ -707,16 +709,22 @@ AudioBufferSourceNode::Start(double aWhe
 
   // Don't set parameter unnecessarily
   if (aWhen > 0.0) {
     ns->SetDoubleParameter(START, aWhen);
   }
 }
 
 void
+AudioBufferSourceNode::Start(double aWhen, ErrorResult& aRv)
+{
+  Start(aWhen, 0 /* offset */, Optional<double>(), aRv);
+}
+
+void
 AudioBufferSourceNode::SendBufferParameterToStream(JSContext* aCx)
 {
   AudioNodeStream* ns = mStream;
   if (!ns) {
     return;
   }
 
   if (mBuffer) {
--- a/dom/media/webaudio/AudioBufferSourceNode.h
+++ b/dom/media/webaudio/AudioBufferSourceNode.h
@@ -2,26 +2,26 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioBufferSourceNode_h_
 #define AudioBufferSourceNode_h_
 
-#include "AudioNode.h"
+#include "AudioScheduledSourceNode.h"
 #include "AudioBuffer.h"
 
 namespace mozilla {
 namespace dom {
 
 struct AudioBufferSourceOptions;
 class AudioParam;
 
-class AudioBufferSourceNode final : public AudioNode
+class AudioBufferSourceNode final : public AudioScheduledSourceNode
                                   , public MainThreadMediaStreamListener
 {
 public:
   static already_AddRefed<AudioBufferSourceNode>
   Create(JSContext* aCx, AudioContext& aAudioContext,
          const AudioBufferSourceOptions& aOptions, ErrorResult& aRv);
 
   void DestroyMediaStream() override;
@@ -30,30 +30,33 @@ public:
   {
     return 0;
   }
   AudioBufferSourceNode* AsAudioBufferSourceNode() override
   {
     return this;
   }
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode, AudioNode)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode,
+                                           AudioScheduledSourceNode)
 
   static already_AddRefed<AudioBufferSourceNode>
   Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
               const AudioBufferSourceOptions& aOptions, ErrorResult& aRv)
   {
     return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
   }
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void Start(double aWhen, double aOffset,
              const Optional<double>& aDuration, ErrorResult& aRv);
-  void Stop(double aWhen, ErrorResult& aRv);
+
+  void Start(double aWhen, ErrorResult& aRv) override;
+  void Stop(double aWhen, ErrorResult& aRv) override;
 
   AudioBuffer* GetBuffer(JSContext* aCx) const
   {
     return mBuffer;
   }
   void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer)
   {
     mBuffer = aBuffer;
@@ -92,18 +95,16 @@ public:
   }
   void SetLoopEnd(double aEnd)
   {
     mLoopEnd = aEnd;
     SendLoopParametersToStream();
   }
   void SendDopplerShiftToStream(double aDopplerShift);
 
-  IMPL_EVENT_HANDLER(ended)
-
   void NotifyMainThreadStreamFinished() override;
 
   const char* NodeType() const override
   {
     return "AudioBufferSourceNode";
   }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/AudioScheduledSourceNode.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AudioScheduledSourceNode.h"
+#include "mozilla/dom/AudioScheduledSourceNodeBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* aContext,
+                                                   uint32_t aChannelCount,
+                                                   ChannelCountMode aChannelCountMode,
+                                                   ChannelInterpretation aChannelInterpretation)
+  : AudioNode(aContext, aChannelCount, aChannelCountMode,
+              aChannelInterpretation)
+{}
+
+JSObject*
+AudioScheduledSourceNode::WrapObject(JSContext* aCx,
+                                     JS::Handle<JSObject*> aGivenProto)
+{
+  return AudioScheduledSourceNodeBinding::Wrap(aCx, this, aGivenProto);
+}
+
+} // dom namespace
+} // mozilla namespace
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/AudioScheduledSourceNode.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef AudioScheduledSourceNode_h_
+#define AudioScheduledSourceNode_h_
+
+#include "AudioNode.h"
+#include "mozilla/dom/AudioScheduledSourceNodeBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+class AudioContext;
+
+class AudioScheduledSourceNode : public AudioNode
+{
+public:
+  JSObject* WrapObject(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto) override;
+
+  virtual void Start(double aWhen, ErrorResult& aRv) = 0;
+  virtual void Stop(double aWhen, ErrorResult& aRv) = 0;
+
+  IMPL_EVENT_HANDLER(ended)
+
+protected:
+  AudioScheduledSourceNode(AudioContext* aContext,
+                           uint32_t aChannelCount,
+                           ChannelCountMode aChannelCountMode,
+                           ChannelInterpretation aChannelInterpretation);
+  virtual ~AudioScheduledSourceNode() = default;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
--- a/dom/media/webaudio/ConstantSourceNode.cpp
+++ b/dom/media/webaudio/ConstantSourceNode.cpp
@@ -7,24 +7,24 @@
 #include "ConstantSourceNode.h"
 
 #include "AudioDestinationNode.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(ConstantSourceNode, AudioNode,
+NS_IMPL_CYCLE_COLLECTION_INHERITED(ConstantSourceNode, AudioScheduledSourceNode,
                                    mOffset)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ConstantSourceNode)
-NS_INTERFACE_MAP_END_INHERITING(AudioNode)
+NS_INTERFACE_MAP_END_INHERITING(AudioScheduledSourceNode)
 
-NS_IMPL_ADDREF_INHERITED(ConstantSourceNode, AudioNode)
-NS_IMPL_RELEASE_INHERITED(ConstantSourceNode, AudioNode)
+NS_IMPL_ADDREF_INHERITED(ConstantSourceNode, AudioScheduledSourceNode)
+NS_IMPL_RELEASE_INHERITED(ConstantSourceNode, AudioScheduledSourceNode)
 
 class ConstantSourceNodeEngine final : public AudioNodeEngine
 {
 public:
   ConstantSourceNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)
     : AudioNodeEngine(aNode)
     , mSource(nullptr)
     , mDestination(aDestination->Stream())
@@ -137,20 +137,20 @@ public:
   AudioNodeStream* mSource;
   AudioNodeStream* mDestination;
   StreamTime mStart;
   StreamTime mStop;
   AudioParamTimeline mOffset;
 };
 
 ConstantSourceNode::ConstantSourceNode(AudioContext* aContext)
-  : AudioNode(aContext,
-              1,
-              ChannelCountMode::Max,
-              ChannelInterpretation::Speakers)
+  : AudioScheduledSourceNode(aContext,
+                             1,
+                             ChannelCountMode::Max,
+                             ChannelInterpretation::Speakers)
   , mOffset(new AudioParam(this, ConstantSourceNodeEngine::OFFSET,
                            1.0, "offset"))
   , mStartCalled(false)
 {
   ConstantSourceNodeEngine* engine = new ConstantSourceNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
                                     aContext->Graph());
--- a/dom/media/webaudio/ConstantSourceNode.h
+++ b/dom/media/webaudio/ConstantSourceNode.h
@@ -2,33 +2,33 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ConstantSourceNode_h_
 #define ConstantSourceNode_h_
 
-#include "AudioNode.h"
+#include "AudioScheduledSourceNode.h"
 #include "AudioParam.h"
 #include "mozilla/dom/ConstantSourceNodeBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 
-class ConstantSourceNode final : public AudioNode,
-                                 public MainThreadMediaStreamListener
+class ConstantSourceNode final : public AudioScheduledSourceNode
+                               , public MainThreadMediaStreamListener
 {
 public:
   explicit ConstantSourceNode(AudioContext* aContext);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConstantSourceNode, AudioNode)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConstantSourceNode, AudioScheduledSourceNode)
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<ConstantSourceNode>
   Constructor(const GlobalObject& aGlobal,
               AudioContext& aContext,
               const ConstantSourceOptions& aOptions,
               ErrorResult& aRv);
@@ -40,20 +40,18 @@ public:
     return 0;
   }
 
   AudioParam* Offset() const
   {
     return mOffset;
   }
 
-  void Start(double aWhen, ErrorResult& rv);
-  void Stop(double aWhen, ErrorResult& rv);
-
-  IMPL_EVENT_HANDLER(ended)
+  void Start(double aWhen, ErrorResult& rv) override;
+  void Stop(double aWhen, ErrorResult& rv) override;
 
   void NotifyMainThreadStreamFinished() override;
 
   const char* NodeType() const override
   {
     return "ConstantSourceNode";
   }
 
--- a/dom/media/webaudio/OscillatorNode.cpp
+++ b/dom/media/webaudio/OscillatorNode.cpp
@@ -10,24 +10,24 @@
 #include "AudioDestinationNode.h"
 #include "nsContentUtils.h"
 #include "WebAudioUtils.h"
 #include "blink/PeriodicWave.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(OscillatorNode, AudioNode,
+NS_IMPL_CYCLE_COLLECTION_INHERITED(OscillatorNode, AudioScheduledSourceNode,
                                    mPeriodicWave, mFrequency, mDetune)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(OscillatorNode)
-NS_INTERFACE_MAP_END_INHERITING(AudioNode)
+NS_INTERFACE_MAP_END_INHERITING(AudioScheduledSourceNode)
 
-NS_IMPL_ADDREF_INHERITED(OscillatorNode, AudioNode)
-NS_IMPL_RELEASE_INHERITED(OscillatorNode, AudioNode)
+NS_IMPL_ADDREF_INHERITED(OscillatorNode, AudioScheduledSourceNode)
+NS_IMPL_RELEASE_INHERITED(OscillatorNode, AudioScheduledSourceNode)
 
 class OscillatorNodeEngine final : public AudioNodeEngine
 {
 public:
   OscillatorNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)
     : AudioNodeEngine(aNode)
     , mSource(nullptr)
     , mDestination(aDestination->Stream())
@@ -403,20 +403,20 @@ public:
   RefPtr<ThreadSharedFloatArrayBufferList> mCustom;
   RefPtr<BasicWaveFormCache> mBasicWaveFormCache;
   uint32_t mCustomLength;
   bool mCustomDisableNormalization;
   RefPtr<WebCore::PeriodicWave> mPeriodicWave;
 };
 
 OscillatorNode::OscillatorNode(AudioContext* aContext)
-  : AudioNode(aContext,
-              2,
-              ChannelCountMode::Max,
-              ChannelInterpretation::Speakers)
+  : AudioScheduledSourceNode(aContext,
+                             2,
+                             ChannelCountMode::Max,
+                             ChannelInterpretation::Speakers)
   , mType(OscillatorType::Sine)
   , mFrequency(new AudioParam(this, OscillatorNodeEngine::FREQUENCY,
                               440.0f, "frequency"))
   , mDetune(new AudioParam(this, OscillatorNodeEngine::DETUNE, 0.0f, "detune"))
   , mStartCalled(false)
 {
   OscillatorNodeEngine* engine = new OscillatorNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
--- a/dom/media/webaudio/OscillatorNode.h
+++ b/dom/media/webaudio/OscillatorNode.h
@@ -2,37 +2,37 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef OscillatorNode_h_
 #define OscillatorNode_h_
 
-#include "AudioNode.h"
+#include "AudioScheduledSourceNode.h"
 #include "AudioParam.h"
 #include "PeriodicWave.h"
 #include "mozilla/dom/OscillatorNodeBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 struct OscillatorOptions;
 
-class OscillatorNode final : public AudioNode,
-                             public MainThreadMediaStreamListener
+class OscillatorNode final : public AudioScheduledSourceNode
+                           , public MainThreadMediaStreamListener
 {
 public:
   static already_AddRefed<OscillatorNode>
   Create(AudioContext& aAudioContext, const OscillatorOptions& aOptions,
          ErrorResult& aRv);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OscillatorNode, AudioNode)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OscillatorNode, AudioScheduledSourceNode)
 
   static already_AddRefed<OscillatorNode>
   Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
               const OscillatorOptions& aOptions, ErrorResult& aRv)
   {
     return Create(aAudioContext, aOptions, aRv);
   }
 
@@ -65,28 +65,27 @@ public:
   {
     return mFrequency;
   }
   AudioParam* Detune() const
   {
     return mDetune;
   }
 
-  void Start(double aWhen, ErrorResult& aRv);
-  void Stop(double aWhen, ErrorResult& aRv);
+  void Start(double aWhen, ErrorResult& aRv) override;
+  void Stop(double aWhen, ErrorResult& aRv) override;
+
   void SetPeriodicWave(PeriodicWave& aPeriodicWave)
   {
     mPeriodicWave = &aPeriodicWave;
     // SendTypeToStream will call SendPeriodicWaveToStream for us.
     mType = OscillatorType::Custom;
     SendTypeToStream();
   }
 
-  IMPL_EVENT_HANDLER(ended)
-
   void NotifyMainThreadStreamFinished() override;
 
   const char* NodeType() const override
   {
     return "OscillatorNode";
   }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
--- a/dom/media/webaudio/moz.build
+++ b/dom/media/webaudio/moz.build
@@ -49,16 +49,17 @@ EXPORTS.mozilla.dom += [
     'AudioBuffer.h',
     'AudioBufferSourceNode.h',
     'AudioContext.h',
     'AudioDestinationNode.h',
     'AudioListener.h',
     'AudioNode.h',
     'AudioParam.h',
     'AudioProcessingEvent.h',
+    'AudioScheduledSourceNode.h',
     'BiquadFilterNode.h',
     'ChannelMergerNode.h',
     'ChannelSplitterNode.h',
     'ConstantSourceNode.h',
     'ConvolverNode.h',
     'DelayNode.h',
     'DynamicsCompressorNode.h',
     'GainNode.h',
@@ -84,16 +85,17 @@ UNIFIED_SOURCES += [
     'AudioEventTimeline.cpp',
     'AudioListener.cpp',
     'AudioNode.cpp',
     'AudioNodeEngine.cpp',
     'AudioNodeExternalInputStream.cpp',
     'AudioNodeStream.cpp',
     'AudioParam.cpp',
     'AudioProcessingEvent.cpp',
+    'AudioScheduledSourceNode.cpp',
     'BiquadFilterNode.cpp',
     'BufferDecoder.cpp',
     'ChannelMergerNode.cpp',
     'ChannelSplitterNode.cpp',
     'ConstantSourceNode.cpp',
     'ConvolverNode.cpp',
     'DelayBuffer.cpp',
     'DelayNode.cpp',
--- a/dom/webidl/AudioBufferSourceNode.webidl
+++ b/dom/webidl/AudioBufferSourceNode.webidl
@@ -16,30 +16,26 @@ dictionary AudioBufferSourceOptions {
              boolean      loop = false;
              double       loopEnd = 0;
              double       loopStart = 0;
              float        playbackRate = 1;
 };
 
 [Pref="dom.webaudio.enabled",
  Constructor(BaseAudioContext context, optional AudioBufferSourceOptions options)]
-interface AudioBufferSourceNode : AudioNode {
+interface AudioBufferSourceNode : AudioScheduledSourceNode {
 
     attribute AudioBuffer? buffer;
 
     readonly attribute AudioParam playbackRate;
     readonly attribute AudioParam detune;
 
     attribute boolean loop;
     attribute double loopStart;
     attribute double loopEnd;
 
     [Throws, UnsafeInPrerendering]
     void start(optional double when = 0, optional double grainOffset = 0,
                optional double grainDuration);
-    [Throws, UnsafeInPrerendering]
-    void stop(optional double when = 0);
-
-    attribute EventHandler onended;
 };
 
 // Mozilla extensions
 AudioBufferSourceNode implements AudioNodePassThrough;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/AudioScheduledSourceNode.webidl
@@ -0,0 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * https://webaudio.github.io/web-audio-api/#idl-def-AudioScheduledSourceNode
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface AudioScheduledSourceNode : AudioNode {
+                    attribute EventHandler onended;
+    [Throws, UnsafeInPrerendering]
+    void start (optional double when = 0);
+
+    [Throws, UnsafeInPrerendering]
+    void stop (optional double when = 0);
+};
--- a/dom/webidl/ConstantSourceNode.webidl
+++ b/dom/webidl/ConstantSourceNode.webidl
@@ -11,16 +11,11 @@
  */
 
 dictionary ConstantSourceOptions {
     float offset = 1;
 };
 
 [Pref="dom.webaudio.enabled",
  Constructor(BaseAudioContext context, optional ConstantSourceOptions options)]
-interface ConstantSourceNode : AudioNode {
+interface ConstantSourceNode :  AudioScheduledSourceNode {
     readonly        attribute AudioParam   offset;
-                    attribute EventHandler onended;
-    [Throws, UnsafeInPrerendering]
-    void start (optional double when = 0);
-    [Throws, UnsafeInPrerendering]
-    void stop (optional double when = 0);
 };
--- a/dom/webidl/OscillatorNode.webidl
+++ b/dom/webidl/OscillatorNode.webidl
@@ -22,28 +22,21 @@ dictionary OscillatorOptions : AudioNode
              OscillatorType type = "sine";
              float          frequency = 440;
              float          detune = 0;
              PeriodicWave   periodicWave;
 };
 
 [Pref="dom.webaudio.enabled",
  Constructor(BaseAudioContext context, optional OscillatorOptions options)]
-interface OscillatorNode : AudioNode {
+interface OscillatorNode : AudioScheduledSourceNode {
 
     [SetterThrows]
     attribute OscillatorType type;
 
     readonly attribute AudioParam frequency; // in Hertz
     readonly attribute AudioParam detune; // in Cents
 
-    [Throws, UnsafeInPrerendering]
-    void start(optional double when = 0);
-    [Throws, UnsafeInPrerendering]
-    void stop(optional double when = 0);
     void setPeriodicWave(PeriodicWave periodicWave);
-
-    attribute EventHandler onended;
-
 };
 
 // Mozilla extensions
 OscillatorNode implements AudioNodePassThrough;
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -36,16 +36,17 @@ WEBIDL_FILES = [
     'AudioBufferSourceNode.webidl',
     'AudioChannel.webidl',
     'AudioContext.webidl',
     'AudioDestinationNode.webidl',
     'AudioListener.webidl',
     'AudioNode.webidl',
     'AudioParam.webidl',
     'AudioProcessingEvent.webidl',
+    'AudioScheduledSourceNode.webidl',
     'AudioStreamTrack.webidl',
     'AudioTrack.webidl',
     'AudioTrackList.webidl',
     'AudioWorkletGlobalScope.webidl',
     'AutocompleteInfo.webidl',
     'BarProp.webidl',
     'BaseAudioContext.webidl',
     'BaseKeyframeTypes.webidl',