<!DOCTYPE html>
<html>
  <head>
    <title>
      Updating of Value Attribute from Timeline
    </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/audio-param.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      // This should be a power of two so that all time computations have no
      // round-off errors.
      let sampleRate = 32768;
      let renderQuantumSize = 128;
      // How many tests to run.
      let renderLoops = 20;
      let renderFrames = renderLoops * renderQuantumSize;
      let renderDuration = renderFrames / sampleRate;

      let audit = Audit.createTaskRunner();

      audit.define('linear', (task, should) => {
        // Test the value attribute from a linearRamp event
        runTest(should, function(g, v0, t0, v1, t1) {
          g.gain.linearRampToValueAtTime(v1, t1);
          return {
            expectedValue: function(testTime) {
              return audioParamLinearRamp(testTime, v0, t0, v1, t1);
            },
            message: 'linearRamp(' + v1 + ', ' + t1 + ')',
            errorThreshold: 1.1650e-6
          };
        }).then(() => task.done());
      });

      audit.define('exponential', (task, should) => {
        // Test the value attribute from an exponentialRamp event
        runTest(should, function(g, v0, t0, v1, t1) {
          g.gain.exponentialRampToValueAtTime(v1, t1);
          return {
            expectedValue: function(testTime) {
              return audioParamExponentialRamp(testTime, v0, t0, v1, t1);
            },
            message: 'exponentialRamp(' + v1 + ', ' + t1 + ')',
            errorThreshold: 7.4601e-7
          };
        }).then(() => task.done());
      });

      audit.define('setTarget', (task, should) => {
        // Test the value attribute from a setTargetAtTime event
        runTest(should, function(g, v0, t0, v1, t1) {
          let timeConstant = 0.1;
          let vFinal = 0;
          g.gain.setTargetAtTime(vFinal, t0, timeConstant);
          return {
            expectedValue: function(testTime) {
              return audioParamSetTarget(
                  testTime, v0, t0, vFinal, timeConstant);
            },
            message: 'setTargetAtTime(' + vFinal + ', ' + t0 + ', ' +
                timeConstant + ')',
            errorThreshold: 2.2599e-6
          };
        }).then(() => task.done());
      });

      audit.define('setValueCurve', (task, should) => {
        // Test the value attribute from a setValueCurve event
        runTest(should, function(g, v0, t0, v1, t1) {
          let curve = [1, 1.5, 4];
          let duration = t1 - t0;
          g.gain.setValueCurveAtTime(Float32Array.from(curve), t0, duration);
          return {
            expectedValue: function(testTime) {
              return audioParamSetValueCurve(testTime, curve, t0, duration);
            },
            message: 'setValueCurveAtTime([' + curve + '], ' + t0 + ', ' +
                duration + ')',
            errorThreshold: 7.9577e-8
          };
        }).then(() => task.done());
      });

      audit.run();

      // Test that the .value getter has the correct value when a timeline is
      // running. The |testFunction| is the underlying test to be run.
      function runTest(should, testFunction) {
        // Create a simple graph consisting of a constant source and a gain node
        // where the automations are run.  A setValueAtTime event starts things
        // off.
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);
        let source = context.createBufferSource();
        source.buffer = createConstantBuffer(context, 1, 1);
        source.loop = true;
        let gain = context.createGain();

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

        // Start the timeline with setValueAtTime(v0, t0).
        let v0 = 0.25;
        let t0 = 0;
        // End value and time, for those that need it.  The end time is less
        // than the rendering duration so we can test that the final values of
        // the automation (if any) are also correct.
        let v1 = 100;
        let t1 = renderDuration - 5 * renderQuantumSize / sampleRate;

        gain.gain.setValueAtTime(v0, t0);

        // Run the desired automation test.  The test function returns a
        // dictionary consisting of the following properties:
        //
        // |message|        an informative message about the automation being
        // tested. |errorThreshold| error threshold to determine if the test
        // passes or not. |expectedValue|  a function that compute the expected
        // value at time |t|.
        let test = testFunction(gain, v0, t0, v1, t1);

        // Print an informative message about the test being run.
        // testPassed("Initialize " + test.message + " with setValueAtTime(" +
        // v0 + ", " + t0 + ").");
        should(true, 'Initialize')
            .message(
                test.message + ' with setValueAtTime(' + v0 + ', ' + t0 + ')',
                '');

        let success = true;

        // Max relative error found for this test. This is printed if the test
        // fails so that setting the thresholds is easier.
        let maxError = 0;

        // For every rendering quantum (except the first), suspend the context
        // so the we can inspect the value attribute and compare it with the
        // expected value.
        for (let k = 1; k < renderLoops; ++k) {
          let time = k * renderQuantumSize / sampleRate;
          context.suspend(time)
              .then(function() {
                // The context is supsended at time |time|, which is just before
                // the rendering quantum starts.  Thus, the value of the
                // attribute is actually 1 frame before the current context
                // time.
                let sampleTime = context.currentTime - 1 / sampleRate;

                // Compute the max relative error
                let expected = test.expectedValue(sampleTime);
                let relError =
                    Math.abs(expected - gain.gain.value) / Math.abs(expected);
                maxError = Math.max(relError, maxError);

                success =
                    should(
                        gain.gain.value,
                        test.message + ' at frame ' + (sampleRate * sampleTime))
                        .beCloseTo(
                            expected, {threshold: test.errorThreshold || 0});
              })
              .then(context.resume.bind(context));
        }

        source.start();

        return context.startRendering().then(function(resultBuffer) {
          // Just print a final pass (or fail) message.
          should(success, 'Gain .value attribute for ' + test.message)
              .message(
                  'correctly updated during automation',
                  'not correctly updated during automation; max error = ' +
                      maxError);
        });
      }
    </script>
  </body>
</html>
