Bug 1322883 - AudioNode constructors - part 13 - OscillatorNode, r=padenot
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 15 Dec 2016 19:24:42 +0100
changeset 326044 ee819615a35ad17dd2c38a95c14c790ce76d8f26
parent 326043 8aa5c90d81922db1b5b8552966c4c1ec34e78980
child 326045 32d6100a73ad8da43364f61742296a2f8fdf8457
push id31084
push userphilringnalda@gmail.com
push dateFri, 16 Dec 2016 01:47:54 +0000
treeherdermozilla-central@63b447888a64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1322883
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 1322883 - AudioNode constructors - part 13 - OscillatorNode, r=padenot
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/OscillatorNode.cpp
dom/media/webaudio/OscillatorNode.h
dom/media/webaudio/test/test_oscillatorNode.html
dom/webidl/OscillatorNode.webidl
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -20,16 +20,17 @@
 #include "mozilla/dom/ChannelSplitterNodeBinding.h"
 #include "mozilla/dom/ConvolverNodeBinding.h"
 #include "mozilla/dom/DelayNodeBinding.h"
 #include "mozilla/dom/DynamicsCompressorNodeBinding.h"
 #include "mozilla/dom/GainNodeBinding.h"
 #include "mozilla/dom/IIRFilterNodeBinding.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/OfflineAudioContextBinding.h"
+#include "mozilla/dom/OscillatorNodeBinding.h"
 #include "mozilla/dom/PannerNodeBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/StereoPannerNodeBinding.h"
 #include "mozilla/dom/WaveShaperNodeBinding.h"
 
 #include "AudioBuffer.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioChannelService.h"
@@ -469,23 +470,17 @@ AudioContext::CreateIIRFilter(const mozi
   options.mFeedforward = aFeedforward;
   options.mFeedback = aFeedback;
   return IIRFilterNode::Create(*this, options, aRv);
 }
 
 already_AddRefed<OscillatorNode>
 AudioContext::CreateOscillator(ErrorResult& aRv)
 {
-  if (CheckClosed(aRv)) {
-    return nullptr;
-  }
-
-  RefPtr<OscillatorNode> oscillatorNode =
-    new OscillatorNode(this);
-  return oscillatorNode.forget();
+  return OscillatorNode::Create(*this, OscillatorOptions(), aRv);
 }
 
 already_AddRefed<PeriodicWave>
 AudioContext::CreatePeriodicWave(const Float32Array& aRealData,
                                  const Float32Array& aImagData,
                                  const PeriodicWaveConstraints& aConstraints,
                                  ErrorResult& aRv)
 {
--- a/dom/media/webaudio/OscillatorNode.cpp
+++ b/dom/media/webaudio/OscillatorNode.cpp
@@ -421,18 +421,45 @@ OscillatorNode::OscillatorNode(AudioCont
   OscillatorNodeEngine* engine = new OscillatorNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
                                     aContext->Graph());
   engine->SetSourceStream(mStream);
   mStream->AddMainThreadListener(this);
 }
 
-OscillatorNode::~OscillatorNode()
+/* static */ already_AddRefed<OscillatorNode>
+OscillatorNode::Create(AudioContext& aAudioContext,
+                       const OscillatorOptions& aOptions,
+                       ErrorResult& aRv)
 {
+  if (aAudioContext.CheckClosed(aRv)) {
+    return nullptr;
+  }
+
+  RefPtr<OscillatorNode> audioNode = new OscillatorNode(&aAudioContext);
+
+  audioNode->Initialize(aOptions, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  audioNode->SetType(aOptions.mType, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  audioNode->Frequency()->SetValue(aOptions.mFrequency);
+  audioNode->Detune()->SetValue(aOptions.mDetune);
+
+  if (aOptions.mPeriodicWave.WasPassed()) {
+    audioNode->SetPeriodicWave(aOptions.mPeriodicWave.Value());
+  }
+
+  return audioNode.forget();
 }
 
 size_t
 OscillatorNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
 
   // For now only report if we know for sure that it's not shared.
--- a/dom/media/webaudio/OscillatorNode.h
+++ b/dom/media/webaudio/OscillatorNode.h
@@ -11,26 +11,36 @@
 #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
 {
 public:
-  explicit OscillatorNode(AudioContext* aContext);
+  static already_AddRefed<OscillatorNode>
+  Create(AudioContext& aAudioContext, const OscillatorOptions& aOptions,
+         ErrorResult& aRv);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OscillatorNode, AudioNode)
 
+  static already_AddRefed<OscillatorNode>
+  Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
+              const OscillatorOptions& aOptions, ErrorResult& aRv)
+  {
+    return Create(aAudioContext, aOptions, aRv);
+  }
+
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void DestroyMediaStream() override;
 
   uint16_t NumberOfInputs() const final override
   {
     return 0;
   }
@@ -77,28 +87,26 @@ public:
   const char* NodeType() const override
   {
     return "OscillatorNode";
   }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
 
-protected:
-  virtual ~OscillatorNode();
+private:
+  explicit OscillatorNode(AudioContext* aContext);
+  ~OscillatorNode() = default;
 
-private:
   void SendTypeToStream();
   void SendPeriodicWaveToStream();
 
-private:
   OscillatorType mType;
   RefPtr<PeriodicWave> mPeriodicWave;
   RefPtr<AudioParam> mFrequency;
   RefPtr<AudioParam> mDetune;
   bool mStartCalled;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
-
--- a/dom/media/webaudio/test/test_oscillatorNode.html
+++ b/dom/media/webaudio/test/test_oscillatorNode.html
@@ -9,17 +9,17 @@
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function() {
 
   var context = new AudioContext();
-  var osc = context.createOscillator();
+  var osc = new OscillatorNode(context);
 
   is(osc.channelCount, 2, "Oscillator node has 2 input channels by default");
   is(osc.channelCountMode, "max", "Correct channelCountMode for the Oscillator node");
   is(osc.channelInterpretation, "speakers", "Correct channelCountInterpretation for the Oscillator node");
   is(osc.type, "sine", "Correct default type");
   expectException(function() {
     osc.type = "custom";
   }, DOMException.INVALID_STATE_ERR);
--- a/dom/webidl/OscillatorNode.webidl
+++ b/dom/webidl/OscillatorNode.webidl
@@ -13,17 +13,25 @@
 enum OscillatorType {
   "sine",
   "square",
   "sawtooth",
   "triangle",
   "custom"
 };
 
-[Pref="dom.webaudio.enabled"]
+dictionary OscillatorOptions : AudioNodeOptions {
+             OscillatorType type = "sine";
+             float          frequency = 440;
+             float          detune = 0;
+             PeriodicWave   periodicWave;
+};
+
+[Pref="dom.webaudio.enabled",
+ Constructor(AudioContext context, optional OscillatorOptions options)]
 interface OscillatorNode : AudioNode {
 
     [SetterThrows]
     attribute OscillatorType type;
 
     readonly attribute AudioParam frequency; // in Hertz
     readonly attribute AudioParam detune; // in Cents
 
@@ -34,9 +42,8 @@ interface OscillatorNode : AudioNode {
     void setPeriodicWave(PeriodicWave periodicWave);
 
     attribute EventHandler onended;
 
 };
 
 // Mozilla extensions
 OscillatorNode implements AudioNodePassThrough;
-