Bug 1308427 - Allow a setTargetAtTime TimeConstant to be 0; r=padenot
authorDan Minor <dminor@mozilla.com>
Thu, 20 Oct 2016 11:10:19 -0400
changeset 319307 5eaae2fa6a52510608aa15afaa614840d8f94cac
parent 319306 7cd638c8fb121147149a22c04ba3871cdc41e057
child 319308 38ac5c0d5d5579c2322b538ba510b411aaa159dd
push id30869
push userphilringnalda@gmail.com
push dateWed, 26 Oct 2016 04:57:48 +0000
treeherdermozilla-central@9471b3c49b2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1308427
milestone52.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 1308427 - Allow a setTargetAtTime TimeConstant to be 0; r=padenot MozReview-Commit-ID: 86YSuJDdks8
dom/media/webaudio/AudioEventTimeline.cpp
dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
dom/media/webaudio/test/mochitest.ini
dom/media/webaudio/test/test_audioParamSetTargetAtTimeZeroTimeConstant.html
--- a/dom/media/webaudio/AudioEventTimeline.cpp
+++ b/dom/media/webaudio/AudioEventTimeline.cpp
@@ -15,17 +15,21 @@ static float LinearInterpolate(double t0
 
 static float ExponentialInterpolate(double t0, float v0, double t1, float v1, double t)
 {
   return v0 * powf(v1 / v0, (t - t0) / (t1 - t0));
 }
 
 static float ExponentialApproach(double t0, double v0, float v1, double timeConstant, double t)
 {
-  return v1 + (v0 - v1) * expf(-(t - t0) / timeConstant);
+  if (!mozilla::dom::WebAudioUtils::FuzzyEqual(timeConstant, 0.0)) {
+    return v1 + (v0 - v1) * expf(-(t - t0) / timeConstant);
+  } else {
+    return v1;
+  }
 }
 
 static float ExtractValueFromCurve(double startTime, float* aCurve, uint32_t aCurveLength, double duration, double t)
 {
   if (t >= startTime + duration) {
     // After the duration, return the last curve value
     return aCurve[aCurveLength - 1];
   }
@@ -64,22 +68,16 @@ AudioEventTimeline::ValidateEvent(AudioT
     for (uint32_t i = 0; i < aEvent.mCurveLength; ++i) {
       if (!IsValid(aEvent.mCurve[i])) {
         aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
         return false;
       }
     }
   }
 
-  if (aEvent.mType == AudioTimelineEvent::SetTarget &&
-      WebAudioUtils::FuzzyEqual(aEvent.mTimeConstant, 0.0)) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return false;
-  }
-
   bool timeAndValueValid = IsValid(aEvent.mValue) &&
                            IsValid(aEvent.mDuration);
   if (!timeAndValueValid) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return false;
   }
 
   // Make sure that non-curve events don't fall within the duration of a
--- a/dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
+++ b/dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
@@ -398,17 +398,17 @@ void TestExponentialRampAtSameTime()
 
 void TestSetTargetZeroTimeConstant()
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetTargetAtTime(20.0f, 1.0, 0.0, rv);
-  is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
+  is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
 }
 
 void TestExponentialInvalidPreviousZeroValue()
 {
   Timeline timeline(0.f);
 
   ErrorResultMock rv;
 
--- a/dom/media/webaudio/test/mochitest.ini
+++ b/dom/media/webaudio/test/mochitest.ini
@@ -61,16 +61,17 @@ tags=capturestream
 [test_AudioParamDevtoolsAPI.html]
 [test_audioParamExponentialRamp.html]
 [test_audioParamGain.html]
 [test_audioParamLinearRamp.html]
 [test_audioParamSetCurveAtTime.html]
 [test_audioParamSetCurveAtTimeTwice.html]
 [test_audioParamSetCurveAtTimeZeroDuration.html]
 [test_audioParamSetTargetAtTime.html]
+[test_audioParamSetTargetAtTimeZeroTimeConstant.html]
 [test_audioParamSetValueAtTime.html]
 [test_audioParamTimelineDestinationOffset.html]
 [test_badConnect.html]
 [test_biquadFilterNode.html]
 [test_biquadFilterNodePassThrough.html]
 [test_biquadFilterNodeWithGain.html]
 [test_bug808374.html]
 [test_bug827541.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/test/test_audioParamSetTargetAtTimeZeroTimeConstant.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test AudioParam.setTargetAtTime with zero time constant</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var V0 = 0.9;
+var V1 = 0.1;
+var T0 = 0;
+var TimeConstant = 0;
+
+var gTest = {
+  length: 2048,
+  numberOfChannels: 1,
+  createGraph: function(context) {
+    var sourceBuffer = context.createBuffer(1, 2048, context.sampleRate);
+    for (var i = 0; i < 2048; ++i) {
+      sourceBuffer.getChannelData(0)[i] = 1;
+    }
+
+    var source = context.createBufferSource();
+    source.buffer = sourceBuffer;
+
+    var gain = context.createGain();
+    gain.gain.value = V0;
+    gain.gain.setTargetAtTime(V1, T0, TimeConstant);
+
+    source.connect(gain);
+
+    source.start(0);
+    return gain;
+  },
+  createExpectedBuffers: function(context) {
+    var T1 = 2048 / context.sampleRate;
+    var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate);
+    for (var i = 0; i < 2048; ++i) {
+      var t = i / context.sampleRate;
+      expectedBuffer.getChannelData(0)[i] = V1;
+    }
+    return expectedBuffer;
+  },
+};
+
+runTest();
+
+</script>
+</pre>
+</body>
+</html>