<!DOCTYPE html>
<html>
  <head>
    <title>
      Test setTargetAtTime Approach to Limit
    </title>
    <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script src="../resources/audit-util.js"></script>
    <script src="../resources/audit.js"></script>
    <script src="../resources/audioparam-testing.js"></script>
    <script src="../resources/audio-param.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      let audit = Audit.createTaskRunner();

      audit.define('approach 1', (task, should) => {
        let sampleRate = 48000;

        // A really short time constant so that setTargetAtTime approaches the
        // limiting value well before the end of the test.
        let timeConstant = 0.001;

        // Find the time where setTargetAtTime is close enough to the limit.
        // Since we're approaching 1, use a value of eps smaller than
        // kSetTargetThreshold (1.5e-6) in AudioParamTimeline.cpp.  This is to
        // account for round-off in the actual implementation (which uses a
        // filter and not the formula.)
        let limitThreshold = 1e-6;

        runTest(should, {
          sampleRate: sampleRate,
          v0: 0,
          v1: 1,
          timeConstant: timeConstant,
          eps: limitThreshold,
          // Experimentally determined
          threshold: 2.4e-5,
          tailThreshold: {relativeThreshold: 9.8234e-7}
        }).then(() => task.done());
      })

      audit.define('approach 0', (task, should) => {
        // Use the equation for setTargetAtTime to figure out when we are close
        // to 0:
        //
        //   v(t) = exp(-t/tau)
        //
        // So find t such that exp(-t/tau) <= eps.  Thus t >= - tau * log(eps).
        //
        // For eps, use exp(-10).

        let sampleRate = 48000;

        // A really short time constant so that setTargetAtTime approaches the
        // limiting value well before the end of the test.
        let timeConstant = 0.001;

        // Find the time where setTargetAtTime is close enough to the limit.
        // Since we're approaching 0, use a value of eps smaller than
        // kSetTargetZeroThreshold (1e-20) in AudioParamTimeline.cpp.  This is
        // to account for round-off in the actual implementation (which uses a
        // filter and not the formula.)
        let limitThreshold = Math.exp(-10);

        runTest(should, {
          sampleRate: sampleRate,
          v0: 1,
          v1: 0,
          timeConstant: timeConstant,
          eps: limitThreshold,
          // Experimentally determined
          threshold: 4.7470e-8,
          tailThreshold: {absoluteThreshold: 2.3310e-5}
        }).then(() => task.done());
      });

      audit.define('crbug.com/835294', (task, should) => {
        let sampleRate = 8000;
        let duration = 8;
        let context = new OfflineAudioContext({
          length: duration * sampleRate,
          sampleRate: sampleRate});

        let src = new ConstantSourceNode(context);
        let gain = new GainNode(context);

        src.connect(gain).connect(context.destination);

        let targetValue = 0.8;
        let targetStartTime = 0;
        let timeConstant = 2;
        gain.gain.setValueAtTime(0, 0);
        gain.gain.setTargetAtTime(targetValue, targetStartTime, timeConstant);
        src.start();

        context.startRendering()
          .then(renderedBuffer => {
             // The output should be a simple exponential approach to 0.8
             // starting at 0 at time 0.1.
             let actual = renderedBuffer.getChannelData(0);
             let expected = createExponentialApproachArray(targetStartTime,
               duration, 0, targetValue, context.sampleRate, timeConstant);

             should(actual, 'Output')
              .beCloseToArray(expected, {absoluteThreshold: 9.8172e-7});
          })
          .then(() => task.done());
      });

      function findLimitTime(v0, v1, timeConstant, eps) {
        // Find the time at which the setTargetAtTime is close enough to the
        // target value |v1| where we can consider the curve to have reached its
        // limiting value.
        //
        // If v1 = 0, |eps| is the absolute error between the actual value and
        // |v1|.  Otherwise, |eps| is the relative error between the actual
        // value and |v1|.
        //
        // The curve is
        //
        //   v(t) = v1 - (v1 - v0) * exp(-t/timeConstant)
        //
        // If v1 = 0,
        //
        //   v(t) = v0 * exp(-t/timeConstant)
        //
        // Solve this for when |v(t)| <= eps:
        //
        //   t >= timeConstant * log(v0/eps)
        //
        // For v1 not zero, we want |v(t) - v1|/|v1| <= eps:
        //
        //   t >= timeConstant * log(abs(v1-v0)/eps/v1)

        if (v1)
          return timeConstant * Math.log(Math.abs(v1 - v0) / eps / v1);
        else
          return timeConstant * Math.log(v0 / eps);
      }

      function runTest(should, options) {
        let renderLength = 1;

        let context = new OfflineAudioContext(
            1, renderLength * sampleRate, options.sampleRate);

        // A constant source
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;

        let gain = context.createGain();
        gain.gain.setValueAtTime(options.v0, 0);
        gain.gain.setTargetAtTime(options.v1, 0, options.timeConstant);

        source.connect(gain);
        gain.connect(context.destination);

        source.start();

        return context.startRendering().then(function(resultBuffer) {
          let actual = resultBuffer.getChannelData(0);
          let expected = createExponentialApproachArray(
              0, renderLength, options.v0, options.v1, options.sampleRate,
              options.timeConstant);

          let message = 'setTargetAtTime(' + options.v1 + ', 0, ' +
              options.timeConstant + ')';

          // Determine where the tail of the curve begins.  (Where the curve has
          // basically reached the limit value.)
          let tailTime = findLimitTime(
              options.v0, options.v1, options.timeConstant, options.eps);
          let tailFrame = Math.ceil(tailTime * options.sampleRate);

          should(
              actual.slice(0, tailFrame),
              'Initial output of ' + tailFrame + ' samples for ' + message)
              .beCloseToArray(
                  expected.slice(0, tailFrame),
                  {absoluteThreshold: options.threshold});

          should(actual.slice(tailFrame), 'Tail output for ' + message)
              .beCloseToArray(expected.slice(tailFrame), options.tailThreshold);
        });
      }

      audit.run();
    </script>
  </body>
</html>
