<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Sampling of LinearRampToValueAtTime
    </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>
  </head>
  <body>
    <script id="layout-test-code">
      let sampleRate = 12800;
      let context;

      let audit = Audit.createTaskRunner();

      function runTest(should, config) {
        // Create a short context with a constant signal source connected to a
        // gain node that will be automated.
        context = new OfflineAudioContext(1, 256, sampleRate);

        // Create a constant unit amplitude source.
        let source = context.createBufferSource();
        let b = createConstantBuffer(context, 1, 1);
        source.buffer = b;
        source.loop = true;

        // Gain node that is to be automated.
        let gain = context.createGain();
        gain.gain.value = 0;
        gain.gain.setValueAtTime(config.startValue, config.startTime);
        config.automationFunction(gain);

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

        source.start();

        return context.startRendering().then(function(resultBuffer) {
          // Check that the automation has the correct sampling.
          let resultData = resultBuffer.getChannelData(0);

          // The automation has starts at config.startTime, so the frame just
          // after this should have the automation applied.
          let startFrame = Math.ceil(config.startTime * sampleRate);

          // The automation ends at config.endTime so the frame just before this
          // should have the automation applied.
          let endFrame = Math.floor(config.endTime * sampleRate);

          // Use the true automation to find the expected values.
          let expectedStart = config.expectedFunction(startFrame / sampleRate);
          let expectedEnd = config.expectedFunction(endFrame / sampleRate);

          should(resultData[startFrame], config.desc + ': Sample ' + startFrame)
              .beCloseTo(
                  expectedStart, {threshold: config.startValueThreshold});
          should(resultData[endFrame], config.desc + ': Sample ' + endFrame)
              .beCloseTo(expectedEnd, {threshold: config.endValueThreshold});
        });
      }

      function expectedLinear(t) {
        let slope =
            (this.endValue - this.startValue) / (this.endTime - this.startTime);
        return this.startValue + slope * (t - this.startTime);
      };

      function expectedExponential(t) {
        let ratio = this.endValue / this.startValue;
        let exponent = (t - this.startTime) / (this.endTime - this.startTime);
        return this.startValue * Math.pow(ratio, exponent);
      };

      function linearAutomation(g) {
        g.gain.linearRampToValueAtTime(this.endValue, this.endTime);
      }

      function exponentialAutomation(g) {
        g.gain.exponentialRampToValueAtTime(this.endValue, this.endTime);
      }

      // Basically want to test that if neither the start time nor end time is
      // on a frame boundary that we sample the automation curve correctly.  The
      // start times and end times are mostly arbitrary, except that they cannot
      // be on a frame boundary.
      let testConfigs = [
        {
          desc: 'linearRamp',
          startTime: .1 / sampleRate,
          endTime: 128.1 / sampleRate,
          startValue: 1,
          endValue: 0,
          startValueThreshold: 1.201e-8,
          endValueThreshold: 1.526e-5,
          automationFunction: linearAutomation,
          expectedFunction: expectedLinear
        },
        {
          desc: 'linearRamp:short',
          startTime: .1 / sampleRate,
          endTime: 5.1 / sampleRate,
          startValue: 1,
          endValue: 0,
          startValueThreshold: 8.723e-9,
          endValueThreshold: 9.537e-7,
          automationFunction: linearAutomation,
          expectedFunction: expectedLinear
        },
        {
          desc: 'linearRamp:long',
          startTime: .1 / sampleRate,
          endTime: 200.1 / sampleRate,
          startValue: 1,
          endValue: 0,
          startValueThreshold: 2.827e-8,
          endValueThreshold: 4.674e-5,
          automationFunction: linearAutomation,
          expectedFunction: expectedLinear
        },
        {
          desc: 'exponentialRamp',
          startTime: .1 / sampleRate,
          endTime: 128.1 / sampleRate,
          startValue: 1,
          endValue: 1e-5,
          startValueThreshold: 2.505e-8,
          endValueThreshold: 1.484e-7,
          automationFunction: exponentialAutomation,
          expectedFunction: expectedExponential
        },
        {
          desc: 'exponentialRamp:short',
          startTime: .1 / sampleRate,
          endTime: 5.1 / sampleRate,
          startValue: 1,
          endValue: 1e-5,
          startValueThreshold: 5.027e-8,
          endValueThreshold: 3.821e-7,
          automationFunction: exponentialAutomation,
          expectedFunction: expectedExponential
        },
        {
          desc: 'exponentialRamp:long',
          startTime: .1 / sampleRate,
          endTime: 200.1 / sampleRate,
          startValue: 1,
          endValue: 1e-5,
          startValueThreshold: 8.035e-9,
          endValueThreshold: 1.337e-6,
          automationFunction: exponentialAutomation,
          expectedFunction: expectedExponential
        },
      ];

      function createTaskFunction(config) {
        return (task, should) => {
          runTest(should, config).then(() => task.done());
        };
      }

      // Create all of the tasks from the test configs
      for (let k = 0; k < testConfigs.length; ++k) {
        let config = testConfigs[k];
        let taskName = config.desc + ':task' + k;
        audit.define(taskName, createTaskFunction(config));
      }

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