<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Clamping of AudioParam Time
    </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>
  </head>
  <body>
    <script id="layout-test-code">
      // Fairly arbitrary sample rate and render frames.
      let sampleRate = 24000;
      let renderFrames = 1024;

      let audit = Audit.createTaskRunner();

      audit.define('setValue', (task, should) => {
        let suspendFrame = 128;
        createGraph({
          suspendFrame: suspendFrame,
          method: 'setValueAtTime',
          initialGain: 0,
          arg0: 1,
        })
            .then(function(resultBuffer) {
              // Just verify that the cosine wave actually started at
              // suspendFrame.
              let result = resultBuffer.getChannelData(0);

              should(
                  result.slice(0, suspendFrame),
                  'setValue: Output[0-' + (suspendFrame - 1) + ']')
                  .beConstantValueOf(0);
              should(
                  result.slice(suspendFrame),
                  'setValue: Output[' + suspendFrame + '-' +
                      (renderFrames - 1) + ']')
                  .beConstantValueOf(1);
            })
            .then(() => task.done());
      });

      audit.define('linear', (task, should) => {
        let suspendFrame = 128;
        createGraph({
          suspendFrame: suspendFrame,
          method: 'linearRampToValueAtTime',
          initialGain: 1,
          arg0: 0.5
        })
            .then(function(resultBuffer) {
              // Just verify that the cosine wave actually started at
              // suspendFrame.
              let result = resultBuffer.getChannelData(0);

              should(
                  result.slice(0, suspendFrame),
                  'linear: Output[0-' + (suspendFrame - 1) + ']')
                  .beConstantValueOf(1);
              should(
                  result.slice(suspendFrame),
                  'linear: Output[' + suspendFrame + '-' + (renderFrames - 1) +
                      ']')
                  .beConstantValueOf(0.5);

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

      audit.define('exponential', (task, should) => {
        let suspendFrame = 128;
        createGraph({
          suspendFrame: suspendFrame,
          method: 'exponentialRampToValueAtTime',
          initialGain: 1,
          arg0: 0.5
        })
            .then(function(resultBuffer) {
              // Just verify that the cosine wave actually started at
              // suspendFrame.
              let result = resultBuffer.getChannelData(0);

              should(
                  result.slice(0, suspendFrame),
                  'exponential: Output[0-' + (suspendFrame - 1) + ']')
                  .beConstantValueOf(1);
              should(
                  result.slice(suspendFrame),
                  'exponential: Output[' + suspendFrame + '-' +
                      (renderFrames - 1) + ']')
                  .beConstantValueOf(0.5);
            })
            .then(() => task.done());
      });

      audit.define('setTarget', (task, should) => {
        let suspendFrame = 128;
        createGraph({
          suspendFrame: suspendFrame,
          method: 'setTargetAtTime',
          initialGain: 1,
          arg0: 0.5,
          moreArgs: 0.1
        })
            .then(function(resultBuffer) {
              // Just verify that the cosine wave actually started at
              // suspendFrame.
              let result = resultBuffer.getChannelData(0);

              should(
                  result.slice(0, suspendFrame),
                  'setTarget: Output[0-' + (suspendFrame - 1) + ']')
                  .beConstantValueOf(1);
              // For the samples past the suspend time, we only care that first
              // value is 1 and that the rest are not zero.
              should(
                  result[suspendFrame],
                  'setTarget: Output[' + suspendFrame + ']')
                  .beEqualTo(1);

              let positive = result.slice(suspendFrame + 1).every(x => x > 0);
              should(
                  positive,
                  'Output[' + (suspendFrame + 1) + '-' + (renderFrames - 1) +
                      '] contains only positive values')
                  .beEqualTo(true);
            })
            .then(() => task.done());
      });

      audit.define('setValueCurve', (task, should) => {
        let suspendFrame = 128;
        createGraph({
          suspendFrame: suspendFrame,
          method: 'setValueCurveAtTime',
          initialGain: 1,
          arg0: Float32Array.from([2, 3]),
          moreArgs: 0.1
        })
            .then(function(resultBuffer) {
              // Just verify that the cosine wave actually started at
              // suspendFrame.
              let result = resultBuffer.getChannelData(0);

              should(
                  result.slice(0, suspendFrame),
                  'setValueCurve: Output[0-' + (suspendFrame - 1) + ']')
                  .beConstantValueOf(1);

              // The selected curve contains values greater than or equal to 2.
              // Just verify that all values are greater than or equal to 2.
              let biggerThan2 = result.slice(suspendFrame).every(x => x >= 2);
              should(
                  biggerThan2,
                  'setValueCurve: Output[' + suspendFrame + '-' +
                      (renderFrames - 1) + ']')
                  .beEqualTo(true);
            })
            .then(() => task.done());
      });


      // Create the test graph consisting of a constant source followed by a
      // gain node.  The gain node automations will be tested.  |options|
      // specifies the parameters for the test including
      //
      //   suspendFrame: time at which we schedule the automation call
      //   method: the name of automation method to be tested
      //   initialGain: the initial gain at time 0 for the gain node
      //   arg0: the first argument to be supplied to the automation method.
      //   moreArgs: An array of any additional arguments for the automation
      //   method.
      function createGraph(options) {
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);

        let cosineWave = new PeriodicWave(context, {real: [0, 1]});

        let src = new OscillatorNode(
            context, {periodicWave: cosineWave, frequency: 0});

        // The gain node whose automations we're testing.
        let gain = new GainNode(context, {gain: 0});

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

        gain.gain.setValueAtTime(options.initialGain, 0);

        // Suspend rendering so that we can call the automation method at the
        // right time.  |startTime| is the time for the automation method. It
        // must be some time before the suspend time.
        let suspendFrame = options.suspendFrame;
        let startTime = (suspendFrame / 2) / context.sampleRate;
        context.suspend(suspendFrame / context.sampleRate)
            .then(function() {
              // Call the appropriate automation method with the desired
              // automation value, time, and any other arguments needed.
              gain.gain[options.method](
                  ...[options.arg0, startTime, options.moreArgs]);
            })
            .then(context.resume.bind(context));

        // Start the source and begin rendering, returning the promise from
        // rendering.
        src.start();

        return context.startRendering();
      }

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