<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Negative AudioParam.exponentialRampToValueAtTime
    </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">
      let sampleRate = 48000;

      let audit = Audit.createTaskRunner();

      audit.define('both negative values', (task, should) => {
        let renderDuration = 0.125;

        // Create context with two channels.  Channel 0 contains the
        // positive-valued exponential and channel 1 contains the
        // negative-valued exponential.  We'll compare the two channels to
        // verify that they're the same, as they should be.
        let context =
            new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate);
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;

        // Gain node gp is for the positive-valued exponential ramp, and gn is
        // for the negative-valued exponential ramp.
        let gp = context.createGain();
        let gn = context.createGain();
        let merger = context.createChannelMerger(2);

        source.connect(gp).connect(merger, 0, 0);
        source.connect(gn).connect(merger, 0, 1);
        merger.connect(context.destination);

        gp.gain.setValueAtTime(1, 0);
        gp.gain.exponentialRampToValueAtTime(2, renderDuration);

        gn.gain.setValueAtTime(-1, 0);
        gn.gain.exponentialRampToValueAtTime(-2, renderDuration);

        source.start();

        context.startRendering()
            .then(function(resultBuffer) {
              // Verify that channels have the same values, except for the sign.
              let expected = resultBuffer.getChannelData(0);
              let actual = resultBuffer.getChannelData(1);
              let inverted = expected.map(sample => -sample);

              should(actual, 'Negative exponential ramp from -1 to -2')
                  .beEqualToArray(inverted);
            })
            .then(() => task.done());
      });

      audit.define('negative-end', (task, should) => {
        // Positive start value and negative end value should just do nothing.
        let renderDuration = 0.125;
        let context =
            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;

        // Gain node gp is for the positive-valued exponential ramp, and gn is
        // for the negative-valued exponential ramp.
        let g = context.createGain();

        g.gain.setValueAtTime(2, 0);
        g.gain.exponentialRampToValueAtTime(-1, renderDuration);

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

        source.start();

        context.startRendering()
            .then(function(resultBuffer) {
              let actual = resultBuffer.getChannelData(0);

              should(actual, 'Exponential ramp from 2 to -1')
                  .beConstantValueOf(2);
            })
            .then(() => task.done());
      });

      audit.define('positive-end', (task, should) => {
        // Positive start value and negative end value should just do nothing.
        let renderDuration = 0.125;
        let context =
            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;

        let g = context.createGain();

        g.gain.setValueAtTime(-1, 0);
        g.gain.exponentialRampToValueAtTime(1, renderDuration);

        source.connect(g).connect(context.destination);
        source.start();

        context.startRendering()
            .then(function(resultBuffer) {
              let actual = resultBuffer.getChannelData(0);

              should(actual, 'Exponential ramp from -1 to 1')
                  .beConstantValueOf(-1);
            })
            .then(() => task.done());
      });

      audit.define('propagate', (task, should) => {
        // Test propagation of ramp if the exponential ramp start and end values
        // have opposite sign.
        let renderDuration = 0.125;
        let linearRampEnd = renderDuration / 4;
        let exponentialRampEnd = renderDuration / 2;

        let context =
            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;

        let g = context.createGain();

        g.gain.setValueAtTime(2, 0);
        g.gain.linearRampToValueAtTime(-1, linearRampEnd);
        g.gain.exponentialRampToValueAtTime(1, exponentialRampEnd);

        source.connect(g).connect(context.destination);
        source.start();

        context.startRendering()
            .then(function(resultBuffer) {
              let actual = resultBuffer.getChannelData(0);

              // Since the start value of the exponential ramp is -1 and the end
              // value is 1, the ramp should just propagate -1 to the end of
              // the exponential ramp, and then propagate the exponential ramp
              // value "forever" afterwards.
              const linearEndFrame = Math.ceil(linearRampEnd * sampleRate);
              const expoEndFrame = Math.ceil(exponentialRampEnd * sampleRate);
              should(
                  actual.slice(linearEndFrame, expoEndFrame),
                  'Exponential ramp from -1 to 1 after the end of the linear ramp')
                  .beConstantValueOf(-1);
              should(
                  actual.slice(expoEndFrame),
                  'Exponential ramp after end of ramp')
                  .beConstantValueOf(1);
            })
            .then(() => task.done());
      });

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