<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Sampling of Oscillator Start Times
    </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">
      // Experimentation indicates that this sample rate with a 440 Hz
      // oscillator makes for a large difference in the difference signal if the
      // oscillator start isn't sampled correctly.
      let defaultSampleRate = 24000;
      let renderDuration = 1;
      let renderFrames = renderDuration * defaultSampleRate;

      let audit = Audit.createTaskRunner();

      audit.define(
          {
            label: 'basic test small',
            description: 'Start oscillator slightly past a sample frame'
          },
          function(task, should) {
            testStartSampling(should, 1.25, {
              error: 1.0880e-4,
              snrThreshold: 84.054
            }).then(task.done.bind(task));
          });

      audit.define(
          {
            label: 'basic test big',
            description: 'Start oscillator slightly before a sample frame'
          },
          function(task, should) {
            testStartSampling(should, 1.75, {
              error: 1.0844e-4,
              snrThreshold: 84.056
            }).then(task.done.bind(task));
          });

      audit.define(
          {
            label: 'diff big offset',
            description:
                'Test sampling with start offset greater than 1/2 sampling frame'
          },
          function(task, should) {
            // With a sample rate of 24000 Hz, and an oscillator frequency of
            // 440 Hz (the default), a quarter wave delay is 13.636363...
            // frames.  This tests the case where the starting time is more than
            // 1/2 frame from the preceding sampling frame.  This tests one path
            // of the internal implementation.
            testStartWithGain(should, defaultSampleRate, {
              error: 1.9521e-6,
              snrThreshold: 128.12
            }).then(task.done.bind(task));
          });

      audit.define(
          {
            label: 'diff small offset',
            description:
                'Test sampling with start offset less than 1/2 sampling frame'
          },
          function(task, should) {
            // With a sample rate of 48000 Hz, and an oscillator frequency of
            // 440 Hz (the default), a quarter wave delay is 27.2727... frames.
            // This tests the case where the starting time is less than 1/2
            // frame from the preceding sampling frame.  This tests one path of
            // the internal implementation.
            testStartWithGain(should, 48000, {
              error: 1.9521e-6,
              snrThreshold: 122.92
            }).then(task.done.bind(task));
          });

      function testStartSampling(should, startFrame, thresholds) {
        // Start the oscillator in the middle of a sample frame and compare
        // against the theoretical result.
        let context =
            new OfflineAudioContext(1, renderFrames, defaultSampleRate);
        let osc = context.createOscillator();
        osc.connect(context.destination);
        osc.start(startFrame / context.sampleRate);

        return context.startRendering().then(function(result) {
          let actual = result.getChannelData(0);
          let expected = new Array(actual.length);
          expected.fill(0);

          // The expected curve is
          //
          //   sin(2*pi*f*(t-t0))
          //
          // where f is the oscillator frequency and t0 is the start time.
          let actualStart = Math.ceil(startFrame);
          let omega = 2 * Math.PI * osc.frequency.value / context.sampleRate;
          for (let k = actualStart; k < actual.length; ++k) {
            expected[k] = Math.sin(omega * (k - startFrame));
          }

          let prefix = 'Oscillator.start(' + startFrame + ' frames)';
          should(actual, prefix).beCloseToArray(expected, {
            absoluteThreshold: thresholds.error
          });
          let snr = 10 * Math.log10(computeSNR(actual, expected));
          should(snr, prefix + ': SNR (dB)')
              .beGreaterThanOrEqualTo(thresholds.snrThreshold);
        })
      }

      function testStartWithGain(should, sampleRate, thresholds) {
        // Test consists of starting a cosine wave with a quarter wavelength
        // delay and comparing that with a sine wave that has the initial
        // quarter wavelength zeroed out.  These should be equal.

        let context = new OfflineAudioContext(3, renderFrames, sampleRate);
        let osc = context.createOscillator();

        let merger = context.createChannelMerger(3);
        merger.connect(context.destination);

        // Start the cosine oscillator at this time.  This means the wave starts
        // at frame 13.636363....
        let quarterWaveTime = (1 / 4) / osc.frequency.value;

        // Sine wave oscillator with gain term to zero out the initial quarter
        // wave length of the output.
        let g = context.createGain();
        g.gain.setValueAtTime(0, 0);
        g.gain.setValueAtTime(1, quarterWaveTime);
        osc.connect(g);
        g.connect(merger, 0, 2);
        g.connect(merger, 0, 0);

        // Cosine wave oscillator with starting after a quarter wave length.
        let osc2 = context.createOscillator();
        // Creates a cosine wave.
        let wave = context.createPeriodicWave(
            Float32Array.from([0, 1]), Float32Array.from([0, 0]));
        osc2.setPeriodicWave(wave);

        osc2.connect(merger, 0, 1);

        // A gain inverter so subtract the two waveforms.
        let inverter = context.createGain();
        inverter.gain.value = -1;
        osc2.connect(inverter);
        inverter.connect(merger, 0, 0);

        osc.start();
        osc2.start(quarterWaveTime);

        return context.startRendering().then(function(result) {
          // Channel 0 = diff
          // Channel 1 = osc with start
          // Channel 2 = osc with gain

          // Channel 0 should be very close to 0.
          // Channel 1 should match channel 2 very closely.
          let diff = result.getChannelData(0);
          let oscStart = result.getChannelData(1);
          let oscGain = result.getChannelData(2);
          let snr = 10 * Math.log10(computeSNR(oscStart, oscGain));

          let prefix =
              'Sample rate ' + sampleRate + ': Delayed cosine oscillator';
          should(oscStart, prefix).beCloseToArray(oscGain, {
            absoluteThreshold: thresholds.error
          });
          should(snr, prefix + ': SNR (dB)')
              .beGreaterThanOrEqualTo(thresholds.snrThreshold);
        });
      }

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