diff --git a/dom/media/webaudio/AudioBufferSourceNode.cpp b/dom/media/webaudio/AudioBufferSourceNode.cpp index 9993b42dcb76..81a68bf6d918 100644 --- a/dom/media/webaudio/AudioBufferSourceNode.cpp +++ b/dom/media/webaudio/AudioBufferSourceNode.cpp @@ -597,8 +597,8 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext) , 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) { diff --git a/dom/media/webaudio/AudioParam.cpp b/dom/media/webaudio/AudioParam.cpp index 6f557499318a..355c173393b7 100644 --- a/dom/media/webaudio/AudioParam.cpp +++ b/dom/media/webaudio/AudioParam.cpp @@ -35,13 +35,17 @@ 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) { } diff --git a/dom/media/webaudio/AudioParam.h b/dom/media/webaudio/AudioParam.h index 56cee0068708..6d027d60b51d 100644 --- a/dom/media/webaudio/AudioParam.h +++ b/dom/media/webaudio/AudioParam.h @@ -27,8 +27,10 @@ class AudioParam final : public nsWrapperCache, public: AudioParam(AudioNode* aNode, uint32_t aIndex, + const char* aName, float aDefaultValue, - const char* aName); + float aMinValue = -std::numeric_limits::infinity(), + float aMaxValue = std::numeric_limits::infinity()); NS_IMETHOD_(MozExternalRefCountType) AddRef(void); NS_IMETHOD_(MozExternalRefCountType) Release(void); @@ -165,6 +167,16 @@ public: return mDefaultValue; } + float MinValue() const + { + return mMinValue; + } + + float MaxValue() const + { + return mMaxValue; + } + const nsTArray& InputNodes() const { return mInputNodes; @@ -244,6 +256,8 @@ private: RefPtr mNodeStreamPort; const uint32_t mIndex; const float mDefaultValue; + const float mMinValue; + const float mMaxValue; }; } // namespace dom diff --git a/dom/media/webaudio/BiquadFilterNode.cpp b/dom/media/webaudio/BiquadFilterNode.cpp index a853d8d4739b..409a7ff6d8a1 100644 --- a/dom/media/webaudio/BiquadFilterNode.cpp +++ b/dom/media/webaudio/BiquadFilterNode.cpp @@ -251,10 +251,12 @@ BiquadFilterNode::BiquadFilterNode(AudioContext* aContext) 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); diff --git a/dom/media/webaudio/ConstantSourceNode.cpp b/dom/media/webaudio/ConstantSourceNode.cpp index bfcb7e743962..b105706c4264 100644 --- a/dom/media/webaudio/ConstantSourceNode.cpp +++ b/dom/media/webaudio/ConstantSourceNode.cpp @@ -147,7 +147,7 @@ ConstantSourceNode::ConstantSourceNode(AudioContext* aContext) 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()); diff --git a/dom/media/webaudio/DelayNode.cpp b/dom/media/webaudio/DelayNode.cpp index a67a91364ec4..011edee560d4 100644 --- a/dom/media/webaudio/DelayNode.cpp +++ b/dom/media/webaudio/DelayNode.cpp @@ -196,7 +196,8 @@ DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay) 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(), diff --git a/dom/media/webaudio/DynamicsCompressorNode.cpp b/dom/media/webaudio/DynamicsCompressorNode.cpp index 1f02121ee899..d3186d9eaac5 100644 --- a/dom/media/webaudio/DynamicsCompressorNode.cpp +++ b/dom/media/webaudio/DynamicsCompressorNode.cpp @@ -188,16 +188,16 @@ DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext) 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, diff --git a/dom/media/webaudio/GainNode.cpp b/dom/media/webaudio/GainNode.cpp index 775169f286f9..feada0fa489e 100644 --- a/dom/media/webaudio/GainNode.cpp +++ b/dom/media/webaudio/GainNode.cpp @@ -120,7 +120,7 @@ GainNode::GainNode(AudioContext* 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, diff --git a/dom/media/webaudio/OscillatorNode.cpp b/dom/media/webaudio/OscillatorNode.cpp index 54c6c48ab5db..fe70f005ae5a 100644 --- a/dom/media/webaudio/OscillatorNode.cpp +++ b/dom/media/webaudio/OscillatorNode.cpp @@ -413,11 +413,13 @@ OscillatorNode::OscillatorNode(AudioContext* aContext) 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, diff --git a/dom/media/webaudio/PannerNode.cpp b/dom/media/webaudio/PannerNode.cpp index a7c2a609911f..1fb79f532e2f 100644 --- a/dom/media/webaudio/PannerNode.cpp +++ b/dom/media/webaudio/PannerNode.cpp @@ -301,12 +301,12 @@ PannerNode::PannerNode(AudioContext* aContext) // 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.) diff --git a/dom/media/webaudio/StereoPannerNode.cpp b/dom/media/webaudio/StereoPannerNode.cpp index 04f7b7591a08..e39044e580b2 100644 --- a/dom/media/webaudio/StereoPannerNode.cpp +++ b/dom/media/webaudio/StereoPannerNode.cpp @@ -175,7 +175,7 @@ StereoPannerNode::StereoPannerNode(AudioContext* 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, diff --git a/dom/webidl/AudioParam.webidl b/dom/webidl/AudioParam.webidl index ee5514f34f24..7e151b41572a 100644 --- a/dom/webidl/AudioParam.webidl +++ b/dom/webidl/AudioParam.webidl @@ -13,8 +13,10 @@ [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] diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 9a7f94afcef8..4a20822cdc96 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -32193,6 +32193,10 @@ "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" diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html new file mode 100644 index 000000000000..6118748ccf3b --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/idl-test.html @@ -0,0 +1,50 @@ + + + +AudioParam IDL Test + + + + +
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);
+
+};
+ +
+ + + + diff --git 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 index bea39b0a2112..8787414a2fe8 100644 --- 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 @@ -96,8 +96,10 @@ interface AudioNode : EventTarget {
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);
diff --git 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
index 0ae2a9db5ccc..e8500b85393e 100644
--- 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
@@ -95,8 +95,10 @@ interface AudioNode : EventTarget {
 
    
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);