<!DOCTYPE html>
<html>
  <head>
    <title>
      Test setTargetAtTime with timeConstant=0
    </title>
    <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script src="../resources/audit.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      // Fairly arbitrary sample rate and number of frames, so choose a low
      // sample rate, and short rendering length.
      let sampleRate = 8000;
      let renderFrames = 128;

      // Array specifying parameters for setTargetAtTime.  |frame| is the frame
      // (not necessarily an integer) at which setTargetAtTime starts, and
      // |value| is the target value.  Non-integral values for |frame| tests
      // that we started the setTargetAtTime at the right time.
      let targetValueInfo = [
        {frame: 10.1, value: 0}, {frame: 20.3, value: 0.5},
        {frame: 100.5, value: 1}
      ];

      let audit = Audit.createTaskRunner();

      audit.define('timeconstant-0', (task, should) => {
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);

        // Simple constant source for testing.

        let src = new ConstantSourceNode(context);

        // We're going to automate the gain node to test setTargetAtTime.
        let gain = new GainNode(context, {gain: 1});

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

        for (let k = 0; k < targetValueInfo.length; ++k) {
          gain.gain.setTargetAtTime(
              targetValueInfo[k].value,
              targetValueInfo[k].frame / context.sampleRate, 0);
        }

        src.start();

        context.startRendering()
            .then(function(resultBuffer) {
              let result = resultBuffer.getChannelData(0);
              let success = true;

              // Because the time constant is 0, the automation should instantly
              // jump to the target value at the start time.  Verify that the
              // output has the expected value.
              for (let k = 0; k < targetValueInfo.length; ++k) {
                let startFrame = Math.ceil(targetValueInfo[k].frame);
                let endFrame = k < targetValueInfo.length - 1 ?
                    Math.ceil(targetValueInfo[k + 1].frame) :
                    renderFrames;
                let value = targetValueInfo[k].value;

                should(
                    result.slice(startFrame, endFrame),
                    'Output for frame [' + startFrame + ', ' + endFrame + ')')
                    .beConstantValueOf(value);
              }

            })
            .then(() => task.done());
      });

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