<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Constructor: PeriodicWave
    </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/audionodeoptions.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      let context;

      let audit = Audit.createTaskRunner();

      audit.define('initialize', (task, should) => {
        context = initializeContext(should);
        task.done();
      });

      audit.define('invalid constructor', (task, should) => {
        testInvalidConstructor(should, 'PeriodicWave', context);
        task.done();
      });

      audit.define('default constructor', (task, should) => {
        should(() => {
          node = new PeriodicWave(context);
        }, 'node = new PeriodicWave(context)').notThrow();

        task.done();
      });

      audit.define('constructor with options', (task, should) => {
        let node1;
        let options = {real: [1, 1]};
        should(
            () => {
              node1 = new PeriodicWave(context, options);
            },
            'node = new PeriodicWave(context, ' + JSON.stringify(options) + ')')
            .notThrow();
        should(node1 instanceof PeriodicWave, 'node1 instanceof PeriodicWave')
            .beEqualTo(true);

        let node2;
        options = {imag: [1, 1]};
        should(
            () => {
              node2 = new PeriodicWave(context, options);
            },
            'node2 = new PeriodicWave(context, ' + JSON.stringify(options) +
                ')')
            .notThrow();
        should(node2 instanceof PeriodicWave, 'node2 instanceof PeriodicWave')
            .beEqualTo(true);

        let node3;
        options = {real: [1, 2], imag: [1, 1]};
        should(
            () => {
              node3 = new PeriodicWave(context, options);
            },
            'node3 = new PeriodicWave(context, ' + JSON.stringify(options) +
                ')')
            .notThrow();
        should(node3 instanceof PeriodicWave, 'node3 instanceof PeriodicWave')
            .beEqualTo(true);

        task.done();
      });

      // The following test that the correct waveforms are produced when various
      // possible PeriodicWave options are used.  These are needed because it's
      // the only way to tell if the various options were correctly applied.

      // TODO(rtoy): These functionality tests should be moved out to a separate
      // file.
      audit.define('1: real periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {real: [0, 2]}, generateReference(Math.cos), 2.7143e-5)
            .then(() => task.done());
      });

      audit.define('2: real periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {real: [0, 2], disableNormalization: false},
            generateReference(Math.cos), 2.7143e-5)
            .then(() => task.done());
      });

      audit.define('3: real periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {real: [0, 2], disableNormalization: true},
            generateReference(x => 2 * Math.cos(x)), 5.4285e-5)
            .then(() => task.done());
      });

      audit.define('1: imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {imag: [0, 2]}, generateReference(Math.sin), 2.7262e-5)
            .then(() => task.done());
      });

      audit.define('2: imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {imag: [0, 2], disableNormalization: false},
            generateReference(Math.sin), 2.7262e-5)
            .then(() => task.done());
      });

      audit.define('3: imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {imag: [0, 2], disableNormalization: true},
            generateReference(x => 2 * Math.sin(x)), 5.4524-5)
            .then(() => task.done());
      });

      audit.define('1: real/imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {
              real: [0, 1],
              imag: [0, 1],
            },
            generateReference(x => Math.SQRT1_2 * (Math.sin(x) + Math.cos(x))),
            3.8371e-5)
            .then(() => task.done());
      });

      audit.define('2: real/imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {real: [0, 1], imag: [0, 1], disableNormalization: false},
            generateReference(x => Math.SQRT1_2 * (Math.sin(x) + Math.cos(x))),
            2.7225e-5)
            .then(() => task.done());
      });

      audit.define('3: real/imag periodicwave test', (task, should) => {
        verifyPeriodicWaveOutput(
            should, {real: [0, 1], imag: [0, 1], disableNormalization: true},
            generateReference(x => Math.sin(x) + Math.cos(x)), 3.8501e-5)
            .then(() => task.done());
      });

      // Returns a function that generates the expected reference array where
      // the samples are generated by the function |gen|.
      function generateReference(gen) {
        return (length, freq, sampleRate) => {
          let expected = new Float32Array(length);
          let omega = 2 * Math.PI * freq / sampleRate;
          for (let k = 0; k < length; ++k) {
            expected[k] = gen(omega * k);
          }
          return expected;
        };
      }

      // Verify that an oscillator constructed from the given periodic wave
      // produces the expected result.
      function verifyPeriodicWaveOutput(
          should, waveOptions, expectedFunction, threshold) {
        let node;
        // Rather arbitrary sample rate and render length. Length doesn't have
        // to be very long.
        let sampleRate = 48000;
        let renderLength = 0.25;
        let testContext =
            new OfflineAudioContext(1, renderLength * sampleRate, sampleRate);

        let options = {
          periodicWave: new PeriodicWave(testContext, waveOptions)
        };
        node = new OscillatorNode(testContext, options);

        // Create the graph
        node.connect(testContext.destination);
        node.start();

        return testContext.startRendering().then(function(resultBuffer) {
          let actual = resultBuffer.getChannelData(0);
          let expected = expectedFunction(
              actual.length, node.frequency.value, testContext.sampleRate);
          // Actual must match expected to within the (experimentally)
          // determined threshold.
          let message = '';
          if (waveOptions.disableNormalization != undefined)
            message =
                'disableNormalization: ' + waveOptions.disableNormalization;
          if (waveOptions.real) {
            if (message.length > 0)
              message += ', '
              message += 'real: [' + waveOptions.real + ']';
          }
          if (waveOptions.imag) {
            if (message.length > 0)
              message += ', '
              message += 'imag: [' + waveOptions.imag + ']';
          }
          should(actual, 'Oscillator with periodicWave {' + message + '}')
              .beCloseToArray(expected, {absoluteThreshold: threshold});
        });
      }

      // Verify that the default PeriodicWave produces a sine wave. Use a
      // 2-channel context to verify this.
      function sineWaveTest(should, waveFun, message) {
        // Channel 0 is the output from the PeriodicWave, and channel 1 is the
        // reference oscillator output.
        let context = new OfflineAudioContext(2, 40000, 40000);
        let oscRef =
            new OscillatorNode(context, {type: 'sine', frequency: 440});
        let wave = waveFun(context);
        let oscTest =
            new OscillatorNode(context, {frequency: 440, periodicWave: wave});

        let merger = new ChannelMergerNode(context, {numberOfInputs: 2});

        oscRef.connect(merger, 0, 1);
        oscTest.connect(merger, 0, 0);

        merger.connect(context.destination);

        oscRef.start();
        oscTest.start();

        return context.startRendering().then(output => {
          // The output from the two channels MUST match exactly.
          let actual = output.getChannelData(0);
          let ref = output.getChannelData(1);

          should(actual, message).beEqualToArray(ref);
        });
      }

      audit.define('default wave', (task, should) => {
        // Verify that the default PeriodicWave produces a sine wave.
        sineWaveTest(
            should, (context) => new PeriodicWave(context),
            'new PeriodicWave(context) output')
            .then(() => task.done());
      });

      audit.define('default wave (with dict)', (task, should) => {
        // Verify that the default PeriodicWave produces a sine wave when the
        // PeriodicWaveOptions dictionary is given, but real and imag members
        // are not set.
        sineWaveTest(
            should, (context) => new PeriodicWave(context, {foo: 42}),
            'new PeriodicWave(context, {foo: 42}) output')
            .then(() => task.done());
      });

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