<!DOCTYPE html>
<html>
  <head>
    <title>
      SetTarget Followed by Linear or Exponential Ramp Is Continuous
    </title>
    <script src="../../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>
  </head>
  <body>
    <script id="layout-test-code">
      let sampleRate = 48000;
      let renderQuantum = 128;
      // Test doesn't need to run for very long.
      let renderDuration = 0.1;
      // Where the ramp should end
      let rampEndTime = renderDuration - .05;
      let renderFrames = renderDuration * sampleRate;
      let timeConstant = 0.01;

      let audit = Audit.createTaskRunner();

      // All of the tests start a SetTargetAtTime after one rendering quantum.
      // The following tests handle various cases where a linear or exponential
      // ramp is scheduled at or after SetTargetAtTime starts.

      audit.define('linear ramp replace', (task, should) => {
        // Schedule a linear ramp to start at the same time as SetTargetAtTime.
        // This effectively replaces the SetTargetAtTime as if it never existed.
        runTest(should, 'Linear ramp', {
          automationFunction: function(audioparam, endValue, endTime) {
            audioparam.linearRampToValueAtTime(endValue, endTime);
          },
          referenceFunction: linearResult,
          automationTime: renderQuantum / sampleRate,
          thresholdSetTarget: 0,
          thresholdRamp: 1.26765e-6
        }).then(() => task.done());
      });

      audit.define('delayed linear ramp', (task, should) => {
        // Schedule a linear ramp to start after the SetTargetAtTime has already
        // started rendering. This is the main test to verify that the linear
        // ramp is continuous with the SetTargetAtTime curve.
        runTest(should, 'Delayed linear ramp', {
          automationFunction: function(audioparam, endValue, endTime) {
            audioparam.linearRampToValueAtTime(endValue, endTime);
          },
          referenceFunction: linearResult,
          automationTime: 4 * renderQuantum / sampleRate,
          thresholdSetTarget: 3.43632e-7,
          thresholdRamp: 1.07972e-6
        }).then(() => task.done());
      });

      audit.define('expo ramp replace', (task, should) => {
        // Like "linear ramp replace", but with an exponential ramp instead.
        runTest(should, 'Exponential ramp', {
          automationFunction: function(audioparam, endValue, endTime) {
            audioparam.exponentialRampToValueAtTime(endValue, endTime);
          },
          referenceFunction: exponentialResult,
          automationTime: renderQuantum / sampleRate,
          thresholdSetTarget: 0,
          thresholdRamp: 1.14441e-5
        }).then(() => task.done());
      });

      audit.define('delayed expo ramp', (task, should) => {
        // Like "delayed linear ramp", but with an exponential ramp instead.
        runTest(should, 'Delayed exponential ramp', {
          automationFunction: function(audioparam, endValue, endTime) {
            audioparam.exponentialRampToValueAtTime(endValue, endTime);
          },
          referenceFunction: exponentialResult,
          automationTime: 4 * renderQuantum / sampleRate,
          thresholdSetTarget: 3.43632e-7,
          thresholdRamp: 4.29154e-6
        }).then(() => task.done());
      });

      audit.run();

      function computeExpectedResult(
          automationTime, timeConstant, endValue, endTime, rampFunction) {
        // The result is a constant value of 1 for one rendering quantum, then a
        // SetTarget event lasting to |automationTime|, at which point a ramp
        // starts which ends at |endValue| at |endTime|.  Then the rest of curve
        // should be held constant at |endValue|.
        let initialPart = new Array(renderQuantum);
        initialPart.fill(1);

        // Generate 1 extra frame so that we know where to start the linear
        // ramp.  The last sample of the array is where the ramp should start
        // from.
        let setTargetPart = createExponentialApproachArray(
            renderQuantum / sampleRate, automationTime + 1 / sampleRate, 1, 0,
            sampleRate, timeConstant);
        let setTargetLength = setTargetPart.length;

        // Generate the ramp starting at |automationTime| with a value from last
        // value of the SetTarget curve above.
        let rampPart = rampFunction(
            automationTime, endTime, setTargetPart[setTargetLength - 1],
            endValue, sampleRate);

        // Finally finish out the rest with a constant value of |endValue|, if
        // needed.
        let finalPart =
            new Array(Math.floor((renderDuration - endTime) * sampleRate));
        finalPart.fill(endValue);

        // Return the four parts separately for testing.
        return {
          initialPart: initialPart,
          setTargetPart: setTargetPart.slice(0, setTargetLength - 1),
          rampPart: rampPart,
          tailPart: finalPart
        };
      }

      function linearResult(automationTime, timeConstant, endValue, endTime) {
        return computeExpectedResult(
            automationTime, timeConstant, endValue, endTime,
            createLinearRampArray);
      }

      function exponentialResult(
          automationTime, timeConstant, endValue, endTime) {
        return computeExpectedResult(
            automationTime, timeConstant, endValue, endTime,
            createExponentialRampArray);
      }

      // Run test to verify that a SetTarget followed by a ramp produces a
      // continuous curve. |prefix| is a string to use as a prefix for the
      // messages. |options| is a dictionary describing how the test is run:
      //
      //   |options.automationFunction|
      //     The function to use to start the automation, which should be a
      //     linear or exponential ramp automation.  This function has three
      //     arguments:
      //       audioparam - the AudioParam to be automated
      //       endValue   - the end value of the ramp
      //       endTime    - the end time fo the ramp.
      //   |options.referenceFunction|
      //     The function to generated the expected result.  This function has
      //     four arguments:
      //       automationTime - the value of  |options.automationTime|
      //       timeConstant   - time constant used for SetTargetAtTime
      //       rampEndValue   - end value for the ramp (same value used for
      //       automationFunction) rampEndTime    - end time for the ramp (same
      //       value used for automationFunction)
      //   |options.automationTime|
      //     Time at which the |automationFunction| is called to start the
      //     automation.
      //   |options.thresholdSetTarget|
      //     Threshold to use for verifying that the initial (if any)
      //     SetTargetAtTime portion had the correct values.
      //   |options.thresholdRamp|
      //     Threshold to use for verifying that the ramp portion had the
      //     correct values.
      function runTest(should, prefix, options) {
        let automationFunction = options.automationFunction;
        let referenceFunction = options.referenceFunction;
        let automationTime = options.automationTime;
        let thresholdSetTarget = options.thresholdSetTarget || 0;
        let thresholdRamp = options.thresholdRamp || 0;

        // End value for the ramp.  Fairly arbitrary, but should be distinctly
        // different from the target value for SetTargetAtTime and the initial
        // value of gain.gain.
        let rampEndValue = 2;
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);

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

        let gain = context.createGain();

        // The SetTarget starts after one rendering quantum.
        gain.gain.setTargetAtTime(
            0, renderQuantum / context.sampleRate, timeConstant);

        // Schedule the ramp at |automationTime|.  If this time is past the
        // first rendering quantum, the SetTarget event will run for a bit
        // before running the ramp.  Otherwise, the SetTarget should be
        // completely replaced by the ramp.
        context.suspend(automationTime).then(function() {
          automationFunction(gain.gain, rampEndValue, rampEndTime);
          context.resume();
        });

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

        source.start();

        return context.startRendering().then(function(resultBuffer) {
          let success = true;
          let result = resultBuffer.getChannelData(0);
          let expected = referenceFunction(
              automationTime, timeConstant, rampEndValue, rampEndTime);

          // Verify each part of the curve separately.
          let startIndex = 0;
          let length = expected.initialPart.length;

          // Verify that the initial part of the curve is constant.
          should(result.slice(0, length), prefix + ': Initial part')
              .beCloseToArray(expected.initialPart);

          // Verify the SetTarget part of the curve, if the SetTarget did
          // actually run.
          startIndex += length;
          length = expected.setTargetPart.length;
          if (length) {
            should(
                result.slice(startIndex, startIndex + length),
                prefix + ': SetTarget part')
                .beCloseToArray(
                    expected.setTargetPart,
                    {absoluteThreshold: thresholdSetTarget});
          } else {
            should(!length, prefix + ': SetTarget part')
                .message(
                    'was correctly replaced by the ramp',
                    'was incorrectly replaced by the ramp');
          }

          // Verify the ramp part of the curve
          startIndex += length;
          length = expected.rampPart.length;
          should(result.slice(startIndex, startIndex + length), prefix)
              .beCloseToArray(
                  expected.rampPart, {absoluteThreshold: thresholdRamp});

          // Verify that the end of the curve after the ramp (if any) is a
          // constant.
          startIndex += length;
          should(result.slice(startIndex), prefix + ': Tail part')
              .beCloseToArray(expected.tailPart);

        });
      }
    </script>
  </body>
</html>
