<!DOCTYPE html>
<html>
  <head>
    <title>
      Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothing
    </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/realtimeanalyser-testing.js"></script>
    <script src="../resources/fft.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();

      // Do one basic test of smoothing of the FFT data.
      audit.define('smoothing test', (task, should) => {
        // Test only 512-point FFT.  The size isn't too important as long as
        // it's greater than 128 (a rendering quantum).
        let options = {order: 9, smoothing: 0.5, floatRelError: 5.9207e-6};

        let success = true;

        let graph = createGraph(options);

        context = graph.context;
        analyser = graph.analyser;

        let smoothedFloatResult = new Float32Array(analyser.frequencyBinCount);
        smoothedFloatResult.fill(0);

        // Stop after one analyser frame to get the initial FFT
        let suspendFrame = analyser.fftSize;
        context.suspend(suspendFrame / sampleRate)
            .then(function() {
              let timeData = new Float32Array(analyser.fftSize);
              let freqData = new Float32Array(analyser.frequencyBinCount);
              analyser.getFloatTimeDomainData(timeData);
              analyser.getFloatFrequencyData(freqData);

              let expectedFreq = computeFFTMagnitude(timeData, options.order);
              smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing);

              let message = 'First ' + analyser.fftSize +
                  '-point FFT at frame ' + (context.currentTime * sampleRate);
              let comparison = compareFloatFreq(
                  message, freqData, smoothedFloatResult.map(linearToDb),
                  should, options);
              success = success && comparison.success;

              // Test the byte frequency data.
              let byteFreqData = new Uint8Array(analyser.frequencyBinCount);
              analyser.getByteFrequencyData(byteFreqData);

              // Convert the expected float frequency data to byte data.
              let expectedByteData = convertFloatToByte(
                  smoothedFloatResult.map(linearToDb), analyser.minDecibels,
                  analyser.maxDecibels);

              should(byteFreqData, analyser.fftSize + '-point byte FFT')
                  .beCloseToArray(expectedByteData, 0);

            })
            .then(context.resume.bind(context));

        // Skip an analyser frame and grab another to verify that the smoothing
        // is done correctly.
        suspendFrame += 2 * analyser.fftSize;
        context.suspend(suspendFrame / sampleRate)
            .then(function() {
              let timeData = new Float32Array(analyser.fftSize);
              let freqDataInDb = new Float32Array(analyser.frequencyBinCount);

              // Grab the time domain and frequency domain data
              analyser.getFloatTimeDomainData(timeData);
              analyser.getFloatFrequencyData(freqDataInDb);

              let newFreqData = computeFFTMagnitude(timeData, options.order);
              // Smooth the data together

              smoothFFT(smoothedFloatResult, newFreqData, options.smoothing);
              let message = 'Smoothed ' + analyser.fftSize +
                  '-point FFT at frame ' + (context.currentTime * sampleRate);
              let comparison = compareFloatFreq(
                  message, freqDataInDb, smoothedFloatResult.map(linearToDb),
                  should, {
                    order: options.order,
                    smoothing: options.smoothing,
                    floatRelError: 2.5332e-5
                  });
              success = success && comparison.success;

              // Test the byte frequency data.
              let byteFreqData = new Uint8Array(analyser.frequencyBinCount);
              analyser.getByteFrequencyData(byteFreqData);

              // Convert the expected float frequency data to byte data.
              let expectedByteData = convertFloatToByte(
                  smoothedFloatResult.map(linearToDb), analyser.minDecibels,
                  analyser.maxDecibels);

              should(byteFreqData, analyser.fftSize + '-point byte FFT')
                  .beCloseToArray(expectedByteData, 0);

            })
            .then(context.resume.bind(context));

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

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