<!DOCTYPE html>
<html>
  <head>
    <title>
      Test OscillatorNode with Negative Frequency
    </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">
      // Some arbitrary sample rate for the offline context. But it MUST be
      // at least twice the oscillator frequency that we're using for the
      // test. (Currently 440 Hz.)
      let sampleRate = 16000;

      // A fairly arbitrary duration that should have at least 1-2 sample
      // periods of the oscillator (at a nominal 440 Hz).
      let renderDuration = 0.1;
      let renderFrames = renderDuration * sampleRate;

      let audit = Audit.createTaskRunner();

      audit.define('sine', (task, should) => {
        runTest(should, {
          message: 'Sum of positive and negative frequency sine oscillators',
          type: 'sine',
          threshold: 1.5349e-6
        }).then(() => task.done());
      });

      audit.define('square', (task, should) => {
        runTest(should, {
          message: 'Sum of positive and negative frequency square oscillators',
          type: 'square',
          threshold: 1.1496e-5
        }).then(() => task.done());
      });

      audit.define('sawtooth', (task, should) => {
        runTest(should, {
          message:
              'Sum of positive and negative frequency sawtooth oscillators',
          type: 'sawtooth',
          threshold: 1.1506e-5
        }).then(() => task.done());
      });

      audit.define('triangle', (task, should) => {
        runTest(should, {
          message:
              'Sum of positive and negative frequency triangle oscillators',
          type: 'triangle',
          threshold: 1.0133e-5
        }).then(() => task.done());
      });

      audit.define('auto-sawtooth', (task, should) => {
        runTest(should, {
          message:
              'Sum of positive and negative frequency-ramped sawtooth oscillators',
          type: 'sawtooth',
          automation: {
            type: 'linearRampToValueAtTime',
            startTime: 0,
            endTime: renderDuration / 2,
            startFrequency: 440,
            endFrequency: sampleRate / 4
          },
          threshold: 1.2368e-6
        }).then(() => task.done());
      });

      audit.define('periodic-wave', (task, should) => {
        // Test negative frequencies for a custom oscillator.  Two channels are
        // needed for the context; one for the expected result, and one for the
        // actual, as explained below.
        let context = new OfflineAudioContext(2, renderFrames, sampleRate);

        let oscPositive = context.createOscillator();
        let oscNegative = context.createOscillator();

        // The Fourier coefficients for our custom oscillator.  The actual
        // values not important.  The waveform for our custom oscillator is
        //
        //   x(t) = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
        //          + sum(imag[k]*sin(2*%pi*f*k/Fs), k, 0)
        //
        // With a negative frequency we have
        //
        //   x(t) = sum(real[k]*cos(2*%pi*(-f)*k/Fs), k, 1)
        //          + sum(imag[k]*sin(2*%pi*(-f)*k/Fs), k, 0)
        //
        //        = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
        //          + sum((-imag[k])*sin(2*%pi*f*k/Fs), k, 0)
        //
        // That is, when the frequency is inverted, it behaves as if the
        // coefficients of the imaginary part are inverted.
        //
        // Thus, the test is to create two custom oscillators.  The second
        // osillator uses the same PeriodicWave as the first except the
        // imaginary coefficients are inverted.  This second oscillator also
        // gets a negative frequency.  The combination of the two results in an
        // oscillator that is the same as the first with gain of 2.
        let real = [0, 1, 1];
        let imag = [0, 1, 1];

        let wavePositive = context.createPeriodicWave(
            Float32Array.from(real), Float32Array.from(imag));
        let waveNegative = context.createPeriodicWave(
            Float32Array.from(real), Float32Array.from(imag.map(x => -x)));

        oscPositive.setPeriodicWave(wavePositive);
        oscNegative.setPeriodicWave(waveNegative);

        oscPositive.frequency.value = 440;
        oscNegative.frequency.value = -oscPositive.frequency.value;

        let merger = context.createChannelMerger(2);
        let gain = context.createGain();

        // As explained above, the expected result should be positive frequency
        // oscillator but with a gain of 2.
        gain.gain.value = 2;
        oscPositive.connect(gain);
        gain.connect(merger, 0, 0);

        // Sum the positive and negative frequency oscillators by using the same
        // input to the merger.
        oscPositive.connect(merger, 0, 1);
        oscNegative.connect(merger, 0, 1);

        merger.connect(context.destination);

        oscPositive.start();
        oscNegative.start();

        context.startRendering()
            .then(function(buffer) {
              let expected = buffer.getChannelData(0);
              let actual = buffer.getChannelData(1);

              should(
                  actual,
                  'Sum of positive and negative frequency custom oscillators')
                  .beCloseToArray(expected, {absoluteThreshold: 2.2352e-6});
            })
            .then(() => task.done());
      });

      audit.run();

      function runTest(should, options) {
        // To test if negative frequencies work, create two oscillators.  One
        // has a positive frequency and the other has a negative frequency.
        // Sum the oscillator outputs; the output should be zero because all of
        // the builtin oscillator types are odd functions of frequency.
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);

        let oscPositive = context.createOscillator();
        let oscNegative = context.createOscillator();

        oscPositive.type = options.type;
        oscNegative.type = oscPositive.type;

        if (options.automation) {
          let {type, startTime, endTime, startFrequency, endFrequency} =
              options.automation;
          oscPositive.frequency.setValueAtTime(startFrequency, startTime);
          oscPositive.frequency[type](endFrequency, endTime)

          oscNegative.frequency.setValueAtTime(-startFrequency, startTime);
          oscNegative.frequency[type](-endFrequency, endTime)
        } else {
          oscPositive.frequency.value = 440;
          oscNegative.frequency.value = -oscPositive.frequency.value;
        }

        oscPositive.connect(context.destination);
        oscNegative.connect(context.destination);

        oscPositive.start();
        oscNegative.start();

        return context.startRendering().then(function(buffer) {
          let result = buffer.getChannelData(0);

          should(result, options.message)
              .beCloseToArray(
                  new Float32Array(result.length),
                  {absoluteThreshold: options.threshold || 0});
        });
      }
    </script>
  </body>
</html>
