Bug 1324659 - AudioParam.minValue/maxValue, r=padenot
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 21 Dec 2016 10:53:38 +0100
changeset 326784 bf42716f602061dfc2777c60c5fb8a612a3f40fe
parent 326783 a454e4dae7b9fdc4dd3fd5ddfd03bbcbbaac3189
child 326785 be8e8021b000d7bb397c2a6a1e048a2764a4eded
push id31111
push usercbook@mozilla.com
push dateWed, 21 Dec 2016 15:57:24 +0000
treeherdermozilla-central@10a5e2fc24e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1324659
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 1324659 - AudioParam.minValue/maxValue, r=padenot
dom/media/webaudio/AudioBufferSourceNode.cpp
dom/media/webaudio/AudioParam.cpp
dom/media/webaudio/AudioParam.h
dom/media/webaudio/BiquadFilterNode.cpp
dom/media/webaudio/ConstantSourceNode.cpp
dom/media/webaudio/DelayNode.cpp
dom/media/webaudio/DynamicsCompressorNode.cpp
dom/media/webaudio/GainNode.cpp
dom/media/webaudio/OscillatorNode.cpp
dom/media/webaudio/PannerNode.cpp
dom/media/webaudio/StereoPannerNode.cpp
dom/webidl/AudioParam.webidl
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html
testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -592,18 +592,18 @@ public:
 AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
   : 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"))
+  , mPlaybackRate(new AudioParam(this, PLAYBACKRATE, "playbackRate", 1.0f))
+  , mDetune(new AudioParam(this, DETUNE, "detune", 0.0f))
   , mLoop(false)
   , mStartCalled(false)
 {
   AudioBufferSourceNodeEngine* engine = new AudioBufferSourceNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
                                     aContext->Graph());
   engine->SetSourceStream(mStream);
--- a/dom/media/webaudio/AudioParam.cpp
+++ b/dom/media/webaudio/AudioParam.cpp
@@ -30,23 +30,27 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCA
 NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(AudioParam)
 NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(AudioParam)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioParam, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioParam, Release)
 
 AudioParam::AudioParam(AudioNode* aNode,
                        uint32_t aIndex,
+                       const char* aName,
                        float aDefaultValue,
-                       const char* aName)
+                       float aMinValue,
+                       float aMaxValue)
   : AudioParamTimeline(aDefaultValue)
   , mNode(aNode)
   , mName(aName)
   , mIndex(aIndex)
   , mDefaultValue(aDefaultValue)
+  , mMinValue(aMinValue)
+  , mMaxValue(aMaxValue)
 {
 }
 
 AudioParam::~AudioParam()
 {
   DisconnectFromGraphAndDestroyStream();
 }
 
--- a/dom/media/webaudio/AudioParam.h
+++ b/dom/media/webaudio/AudioParam.h
@@ -22,18 +22,20 @@ namespace dom {
 class AudioParam final : public nsWrapperCache,
                          public AudioParamTimeline
 {
   virtual ~AudioParam();
 
 public:
   AudioParam(AudioNode* aNode,
              uint32_t aIndex,
+             const char* aName,
              float aDefaultValue,
-             const char* aName);
+             float aMinValue = -std::numeric_limits<float>::infinity(),
+             float aMaxValue = std::numeric_limits<float>::infinity());
 
   NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
   NS_IMETHOD_(MozExternalRefCountType) Release(void);
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioParam)
 
   AudioContext* GetParentObject() const
   {
     return mNode->Context();
@@ -160,16 +162,26 @@ public:
     aName.AssignASCII(mName);
   }
 
   float DefaultValue() const
   {
     return mDefaultValue;
   }
 
+  float MinValue() const
+  {
+    return mMinValue;
+  }
+
+  float MaxValue() const
+  {
+    return mMaxValue;
+  }
+
   const nsTArray<AudioNode::InputNode>& InputNodes() const
   {
     return mInputNodes;
   }
 
   void RemoveInputNode(uint32_t aIndex)
   {
     mInputNodes.RemoveElementAt(aIndex);
@@ -239,15 +251,17 @@ private:
   // For every InputNode, there is a corresponding entry in mOutputParams of the
   // InputNode's mInputNode.
   nsTArray<AudioNode::InputNode> mInputNodes;
   const char* mName;
   // The input port used to connect the AudioParam's stream to its node's stream
   RefPtr<MediaInputPort> mNodeStreamPort;
   const uint32_t mIndex;
   const float mDefaultValue;
+  const float mMinValue;
+  const float mMaxValue;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
 
--- a/dom/media/webaudio/BiquadFilterNode.cpp
+++ b/dom/media/webaudio/BiquadFilterNode.cpp
@@ -246,20 +246,22 @@ private:
 
 BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Max,
               ChannelInterpretation::Speakers)
   , mType(BiquadFilterType::Lowpass)
   , mFrequency(new AudioParam(this, BiquadFilterNodeEngine::FREQUENCY,
-                              350.f, "frequency"))
-  , mDetune(new AudioParam(this, BiquadFilterNodeEngine::DETUNE, 0.f, "detune"))
-  , mQ(new AudioParam(this, BiquadFilterNodeEngine::Q, 1.f, "Q"))
-  , mGain(new AudioParam(this, BiquadFilterNodeEngine::GAIN, 0.f, "gain"))
+                              "frequency", 350.f,
+                              -(aContext->SampleRate() / 2),
+                              aContext->SampleRate() / 2))
+  , mDetune(new AudioParam(this, BiquadFilterNodeEngine::DETUNE, "detune", 0.f))
+  , mQ(new AudioParam(this, BiquadFilterNodeEngine::Q, "Q", 1.f))
+  , mGain(new AudioParam(this, BiquadFilterNodeEngine::GAIN, "gain", 0.f))
 {
   uint64_t windowID = aContext->GetParentObject()->WindowID();
   BiquadFilterNodeEngine* engine = new BiquadFilterNodeEngine(this, aContext->Destination(), windowID);
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NO_STREAM_FLAGS,
                                     aContext->Graph());
 }
 
--- a/dom/media/webaudio/ConstantSourceNode.cpp
+++ b/dom/media/webaudio/ConstantSourceNode.cpp
@@ -142,17 +142,17 @@ public:
 };
 
 ConstantSourceNode::ConstantSourceNode(AudioContext* aContext)
   : AudioScheduledSourceNode(aContext,
                              1,
                              ChannelCountMode::Max,
                              ChannelInterpretation::Speakers)
   , mOffset(new AudioParam(this, ConstantSourceNodeEngine::OFFSET,
-                           1.0, "offset"))
+                           "offset", 1.0f))
   , mStartCalled(false)
 {
   ConstantSourceNodeEngine* engine = new ConstantSourceNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
                                     aContext->Graph());
   engine->SetSourceStream(mStream);
   mStream->AddMainThreadListener(this);
--- a/dom/media/webaudio/DelayNode.cpp
+++ b/dom/media/webaudio/DelayNode.cpp
@@ -191,17 +191,18 @@ public:
   int32_t mLeftOverData;
 };
 
 DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Max,
               ChannelInterpretation::Speakers)
-  , mDelay(new AudioParam(this, DelayNodeEngine::DELAY, 0.0f, "delayTime"))
+  , mDelay(new AudioParam(this, DelayNodeEngine::DELAY, "delayTime", 0.0f,
+                          0.f, aMaxDelay))
 {
   DelayNodeEngine* engine =
     new DelayNodeEngine(this, aContext->Destination(),
                         aContext->SampleRate() * aMaxDelay);
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NO_STREAM_FLAGS,
                                     aContext->Graph());
 }
--- a/dom/media/webaudio/DynamicsCompressorNode.cpp
+++ b/dom/media/webaudio/DynamicsCompressorNode.cpp
@@ -183,26 +183,26 @@ private:
 };
 
 DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Explicit,
               ChannelInterpretation::Speakers)
   , mThreshold(new AudioParam(this, DynamicsCompressorNodeEngine::THRESHOLD,
-                              -24.f, "threshold"))
+                              "threshold", -24.f, -100.f, 0.f))
   , mKnee(new AudioParam(this, DynamicsCompressorNodeEngine::KNEE,
-                         30.f, "knee"))
+                         "knee", 30.f, 0.f, 40.f))
   , mRatio(new AudioParam(this, DynamicsCompressorNodeEngine::RATIO,
-                          12.f, "ratio"))
+                          "ratio", 12.f, 1.f, 20.f))
   , mReduction(0)
   , mAttack(new AudioParam(this, DynamicsCompressorNodeEngine::ATTACK,
-                           0.003f, "attack"))
+                           "attack", 0.003f, 0.f, 1.f))
   , mRelease(new AudioParam(this, DynamicsCompressorNodeEngine::RELEASE,
-                            0.25f, "release"))
+                            "release", 0.25f, 0.f, 1.f))
 {
   DynamicsCompressorNodeEngine* engine = new DynamicsCompressorNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NO_STREAM_FLAGS,
                                     aContext->Graph());
 }
 
 /* static */ already_AddRefed<DynamicsCompressorNode>
--- a/dom/media/webaudio/GainNode.cpp
+++ b/dom/media/webaudio/GainNode.cpp
@@ -115,17 +115,17 @@ public:
   AudioParamTimeline mGain;
 };
 
 GainNode::GainNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Max,
               ChannelInterpretation::Speakers)
-  , mGain(new AudioParam(this, GainNodeEngine::GAIN, 1.0f, "gain"))
+  , mGain(new AudioParam(this, GainNodeEngine::GAIN, "gain", 1.0f))
 {
   GainNodeEngine* engine = new GainNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NO_STREAM_FLAGS,
                                     aContext->Graph());
 }
 
 /* static */ already_AddRefed<GainNode>
--- a/dom/media/webaudio/OscillatorNode.cpp
+++ b/dom/media/webaudio/OscillatorNode.cpp
@@ -408,21 +408,23 @@ public:
 };
 
 OscillatorNode::OscillatorNode(AudioContext* aContext)
   : 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"))
+  , mFrequency(
+    new AudioParam(this, OscillatorNodeEngine::FREQUENCY, "frequency", 440.0f,
+                   -(aContext->SampleRate() / 2), aContext->SampleRate() / 2))
+  , mDetune(new AudioParam(this, OscillatorNodeEngine::DETUNE, "detune", 0.0f))
   , mStartCalled(false)
 {
+
   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);
 }
 
--- a/dom/media/webaudio/PannerNode.cpp
+++ b/dom/media/webaudio/PannerNode.cpp
@@ -296,22 +296,22 @@ public:
 PannerNode::PannerNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Clamped_max,
               ChannelInterpretation::Speakers)
   // Please keep these default values consistent with PannerNodeEngine::PannerNodeEngine above.
   , mPanningModel(PanningModelType::Equalpower)
   , mDistanceModel(DistanceModelType::Inverse)
-  , mPositionX(new AudioParam(this, PannerNode::POSITIONX, 0., this->NodeType()))
-  , mPositionY(new AudioParam(this, PannerNode::POSITIONY, 0., this->NodeType()))
-  , mPositionZ(new AudioParam(this, PannerNode::POSITIONZ, 0., this->NodeType()))
-  , mOrientationX(new AudioParam(this, PannerNode::ORIENTATIONX, 1., this->NodeType()))
-  , mOrientationY(new AudioParam(this, PannerNode::ORIENTATIONY, 0., this->NodeType()))
-  , mOrientationZ(new AudioParam(this, PannerNode::ORIENTATIONZ, 0., this->NodeType()))
+  , mPositionX(new AudioParam(this, PannerNode::POSITIONX, this->NodeType(), 0.f))
+  , mPositionY(new AudioParam(this, PannerNode::POSITIONY, this->NodeType(), 0.f))
+  , mPositionZ(new AudioParam(this, PannerNode::POSITIONZ, this->NodeType(), 0.f))
+  , mOrientationX(new AudioParam(this, PannerNode::ORIENTATIONX, this->NodeType(), 1.0f))
+  , mOrientationY(new AudioParam(this, PannerNode::ORIENTATIONY, this->NodeType(), 0.f))
+  , mOrientationZ(new AudioParam(this, PannerNode::ORIENTATIONZ, this->NodeType(), 0.f))
   , mVelocity()
   , mRefDistance(1.)
   , mMaxDistance(10000.)
   , mRolloffFactor(1.)
   , mConeInnerAngle(360.)
   , mConeOuterAngle(360.)
   , mConeOuterGain(0.)
 {
--- a/dom/media/webaudio/StereoPannerNode.cpp
+++ b/dom/media/webaudio/StereoPannerNode.cpp
@@ -170,17 +170,17 @@ public:
   AudioParamTimeline mPan;
 };
 
 StereoPannerNode::StereoPannerNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Clamped_max,
               ChannelInterpretation::Speakers)
-  , mPan(new AudioParam(this, StereoPannerNodeEngine::PAN, 0.f, "pan"))
+  , mPan(new AudioParam(this, StereoPannerNodeEngine::PAN, "pan", 0.f, -1.f, 1.f))
 {
   StereoPannerNodeEngine* engine = new StereoPannerNodeEngine(this, aContext->Destination());
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::NO_STREAM_FLAGS,
                                     aContext->Graph());
 }
 
 /* static */ already_AddRefed<StereoPannerNode>
--- a/dom/webidl/AudioParam.webidl
+++ b/dom/webidl/AudioParam.webidl
@@ -8,18 +8,20 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Pref="dom.webaudio.enabled"]
 interface AudioParam {
 
-    attribute float value;
-    readonly attribute float defaultValue;
+                    attribute float value;
+    readonly        attribute float defaultValue;
+    readonly        attribute float minValue;
+    readonly        attribute float maxValue;
 
     // Parameter automation. 
     [Throws]
     AudioParam setValueAtTime(float value, double startTime);
     [Throws]
     AudioParam linearRampToValueAtTime(float value, double endTime);
     [Throws]
     AudioParam exponentialRampToValueAtTime(float value, double endTime);
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -32189,16 +32189,20 @@
         "path": "webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html",
         "url": "/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html"
       },
       {
         "path": "webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html",
         "url": "/webaudio/the-audio-api/the-audionode-interface/audionode-connect-return-value.html"
       },
       {
+        "path": "webaudio/the-audio-api/the-audioparam-interface/idl-test.html",
+        "url": "/webaudio/the-audio-api/the-audioparam-interface/idl-test.html"
+      },
+      {
         "path": "webaudio/the-audio-api/the-audioparam-interface/retrospective-setValueAtTime.html",
         "url": "/webaudio/the-audio-api/the-audioparam-interface/retrospective-setValueAtTime.html"
       },
       {
         "path": "webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html",
         "url": "/webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html"
       },
       {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class="a">
+<head>
+<title>AudioParam IDL Test</title>
+<script src="/resources/testharness.js"></script><script src="/resources/testharnessreport.js"></script><script src="/resources/idlharness.js"></script><script src="/resources/WebIDLParser.js"></script><script src="/webaudio/js/lodash.js"></script><script src="/webaudio/js/vendor-prefixes.js"></script><script src="/webaudio/js/helpers.js"></script><style type="text/css">
+    #audio-param-idl
+    { visibility:hidden; height: 0px;}
+  </style>
+</head>
+<body class="a">
+
+   <pre id="audio-param-idl">interface AudioParam {
+
+                    attribute float value;
+    readonly        attribute float defaultValue;
+    readonly        attribute float minValue;
+    readonly        attribute float maxValue;
+
+    // Parameter automation.
+    void setValueAtTime(float value, double startTime);
+    void linearRampToValueAtTime(float value, double endTime);
+    void exponentialRampToValueAtTime(float value, double endTime);
+
+    // Exponentially approach the target value with a rate having the given time constant.
+    void setTargetAtTime(float target, double startTime, double timeConstant);
+
+    // Sets an array of arbitrary parameter values starting at time for the given duration.
+    // The number of values will be scaled to fit into the desired duration.
+    void setValueCurveAtTime(Float32Array values, double startTime, double duration);
+
+    // Cancels all scheduled parameter changes with times greater than or equal to startTime.
+    void cancelScheduledValues(double startTime);
+
+};</pre>
+
+  <div id="log"></div>
+
+  <script>
+(function() {
+  var idl_array = new IdlArray();
+  idl_array.add_untested_idls(document.getElementById("audio-param-idl").textContent);
+
+  delay_time = (new AudioContext).createDelay().delayTime;
+
+  idl_array.add_objects({AudioParam: ["delay_time"]});
+  idl_array.test();
+})();
+  </script>
+</body>
+</html>
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
@@ -91,18 +91,20 @@ interface AudioNode : EventTarget {
     attribute unsigned long channelCount;
     attribute ChannelCountMode channelCountMode;
     attribute ChannelInterpretation channelInterpretation;
 
 };</pre>
 
    <pre id="audio-param-idl">interface AudioParam {
 
-    attribute float value;
-    readonly attribute float defaultValue;
+                    attribute float value;
+    readonly        attribute float defaultValue;
+    readonly        attribute float minValue;
+    readonly        attribute float maxValue;
 
     // Parameter automation.
     void setValueAtTime(float value, double startTime);
     void linearRampToValueAtTime(float value, double endTime);
     void exponentialRampToValueAtTime(float value, double endTime);
 
     // Exponentially approach the target value with a rate having the given time constant.
     void setTargetAtTime(float target, double startTime, double timeConstant);
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
@@ -90,18 +90,20 @@ interface AudioNode : EventTarget {
     attribute unsigned long channelCount;
     attribute ChannelCountMode channelCountMode;
     attribute ChannelInterpretation channelInterpretation;
 
 };</pre>
 
    <pre id="audio-param-idl">interface AudioParam {
 
-    attribute float value;
-    readonly attribute float defaultValue;
+                    attribute float value;
+    readonly        attribute float defaultValue;
+    readonly        attribute float minValue;
+    readonly        attribute float maxValue;
 
     // Parameter automation.
     void setValueAtTime(float value, double startTime);
     void linearRampToValueAtTime(float value, double endTime);
     void exponentialRampToValueAtTime(float value, double endTime);
 
     // Exponentially approach the target value with a rate having the given time constant.
     void setTargetAtTime(float target, double startTime, double timeConstant);