<!DOCTYPE html>
<html>
  <head>
    <title>
      Test AnalyserNode getFloatTimeDomainData
    </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">
      // Use a power of two to eliminate any round-off in the computation of the
      // times for context.suspend().
      let sampleRate = 32768;

      // The largest FFT size for the analyser node is 32768.  We want to render
      // longer than this so that we have at least one complete buffer of data
      // of 32768 samples.
      let renderFrames = 2 * 32768;
      let renderDuration = renderFrames / sampleRate;

      let audit = Audit.createTaskRunner();

      // Test that getFloatTimeDomainData handles short and long vectors
      // correctly.
      audit.define('short and long vector', (task, should) => {
        let fftSize = 32;
        let graphInfo = createGraph(fftSize);
        let context = graphInfo.context;
        let analyser = graphInfo.analyser;
        let signalBuffer = graphInfo.signalBuffer;
        let signal = signalBuffer.getChannelData(0);

        let success = true;
        let sampleFrame = 128;

        context.suspend(sampleFrame / sampleRate)
            .then(function() {
              let shortData = new Float32Array(8);
              // Initialize the array to Infinity to represent uninitialize
              // data.
              shortData.fill(Infinity);

              analyser.getFloatTimeDomainData(shortData);

              // The short array should be filled with the expected data, with
              // no errors thrown.

              let expected =
                  signal.subarray(sampleFrame - fftSize, sampleFrame);
              should(shortData, shortData.length + '-element time domain data')
                  .beEqualToArray(expected.subarray(0, shortData.length));

              let longData = new Float32Array(2 * fftSize);
              // Initialize the array to Infinity to represent uninitialize
              // data.
              longData.fill(Infinity);

              analyser.getFloatTimeDomainData(longData);

              // The long array should filled with the expected data but the
              // extra elements should be untouched.
              should(
                  longData.subarray(0, fftSize),
                  'longData.subarray(0, ' + fftSize + ')')
                  .beEqualToArray(expected);

              should(
                  longData.subarray(fftSize),
                  'Unfilled elements longData.subarray(' + fftSize + ')')
                  .beConstantValueOf(Infinity);
            })
            .then(context.resume.bind(context));

        context.startRendering().then(() => task.done());
      });

      let success = true;

      // Generate tests for all valid FFT sizes for an AnalyserNode.
      for (let k = 5; k < 16; ++k) {
        let fftSize = Math.pow(2, k);
        (function(n) {
          // We grab a sample at (roughly) half the rendering duration.
          audit.define('fftSize ' + n, (task, should) => {
            runTest(n, renderDuration / 2, should).then(() => task.done());
          });
        })(fftSize);
      }

      // Special case for a large size, but the sampling point is early.  The
      // initial part of the buffer should be filled with zeroes.

      audit.define('initial zeroes', (task, should) => {
        // Somewhat arbitrary size for the analyser.  It should be greater than
        // one rendering quantum.
        let fftSize = 2048;
        let graphInfo = createGraph(fftSize);
        let context = graphInfo.context;
        let analyser = graphInfo.analyser;
        let signalBuffer = graphInfo.signalBuffer;

        let data = new Float32Array(fftSize);

        success = true;
        // Suspend every rendering quantum and examine the analyser data.
        for (let k = 128; k <= fftSize; k += 128) {
          context.suspend(k / sampleRate)
              .then(function() {
                analyser.getFloatTimeDomainData(data);
                let sampleFrame = context.currentTime * sampleRate;

                // Verify that the last k frames are not zero, but the first
                // fftSize - k frames are.
                let prefix =
                    'At frame ' + (sampleFrame - 1) + ': data.subarray';
                if (sampleFrame < fftSize) {
                  should(
                      data.subarray(0, fftSize - sampleFrame),
                      prefix + '(0, ' + (fftSize - sampleFrame) + ')')
                          .beConstantValueOf(0) &&
                      success;
                }

                let signal = signalBuffer.getChannelData(0);
                should(
                    data.subarray(fftSize - sampleFrame, fftSize),
                    prefix + '(' + (fftSize - sampleFrame) + ', ' + fftSize +
                        ')')
                        .beEqualToArray(signal.subarray(0, sampleFrame)) &&
                    success;
              })
              .then(context.resume.bind(context));
        }

        context.startRendering().then(() => task.done());
      });

      audit.run();

      // Run test of an AnalyserNode with fftSize of |fftSize|, and with the
      // data from the node being requested at time |sampletime|.  The result
      // from the analyser node is compared against the expected data.  The
      // result of startRendering() is returned.
      function runTest(fftSize, sampleTime, should) {
        let graphInfo = createGraph(fftSize);
        let context = graphInfo.context;
        let analyser = graphInfo.analyser;
        let signalBuffer = graphInfo.signalBuffer;

        // Grab the data at the requested time.
        context.suspend(sampleTime)
            .then(function() {
              let lastFrame = Math.floor(context.currentTime * sampleRate);

              // Grab the time domain data from the analyzer and compare against
              // the expected result.
              let actualFloatData = new Float32Array(fftSize);
              analyser.getFloatTimeDomainData(actualFloatData);

              // Compare against the expected result.
              let signal = signalBuffer.getChannelData(0);
              let message =
                  actualFloatData.length + '-point analyser time domain data';
              should(actualFloatData, message)
                      .beEqualToArray(signal.subarray(
                          lastFrame - actualFloatData.length, lastFrame)) &&
                  success;
            })
            .then(context.resume.bind(context));

        return context.startRendering();
      }

      // Create the audio graph with an AnalyserNode with fftSize |fftSize|.  A
      // simple integer-valued linear ramp is the source so we can easily verify
      // the results.  A dictionary consisting of the context, the analyser
      // node, and the signal is returned.
      function createGraph(fftSize) {
        let context = new OfflineAudioContext(1, renderFrames, sampleRate);

        let src = context.createBufferSource();

        // Use a simple linear ramp as the source.  For simplicity of inspecting
        // results, the ramp starts at 1 with an increment of 1.
        let signalBuffer =
            context.createBuffer(1, renderFrames, context.sampleRate);
        let data = signalBuffer.getChannelData(0);
        for (let k = 0; k < data.length; ++k) {
          data[k] = k + 1;
        }

        src.buffer = signalBuffer;

        let analyser = context.createAnalyser();
        analyser.fftSize = fftSize;

        src.connect(analyser);
        analyser.connect(context.destination);
        src.start();

        return {
          context: context,
          analyser: analyser,
          signalBuffer: signalBuffer
        };
      }
    </script>
  </body>
</html>
