<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <script src="resources/audio-testing.js"></script>
    <script src="resources/note-grain-on-testing.js"></script>
    <script src="../resources/js-test-pre.js"></script>
  </head>

  <body>
    <div id="description"></div>
    <div id="console"></div>

    <script>
      description("Test noteGrainOn offset rendering.");

      // To test noteGrainOn, a single ramp signal is created.
      // Various sections of the ramp are rendered by noteGrainOn() at
      // different times, and we verify that the actual output
      // consists of the correct section of the ramp at the correct
      // time.
      
      var linearRampBuffer;

      // Array of the grain offset used for each ramp played.
      var grainOffsetTime = [];

      // Verify the received signal is a ramp from the correct section
      // of our ramp signal.
      function verifyGrain(renderedData, startFrame, endFrame, grainIndex) {
          var grainOffsetFrame = timeToSampleFrame(grainOffsetTime[grainIndex], sampleRate);
          var grainFrameLength = endFrame - startFrame;
          var ramp = linearRampBuffer.getChannelData(0);
          var isCorrect = true;

          var expected;
          var actual;
          var frame;
      
          for (var k = 0; k < grainFrameLength; ++k) {
              if (renderedData[startFrame + k] != ramp[grainOffsetFrame + k]) {
                  expected = ramp[grainOffsetFrame + k];
                  actual = renderedData[startFrame + k];
                  frame = startFrame + k;
                  isCorrect = false;
                  break;
              }
          }
          return { verified: isCorrect,
                   expected : expected ,
                   actual : actual,
                   frame : frame };
      }
      
      function checkResult(event) {
          var buffer = event.renderedBuffer;
          renderedData = buffer.getChannelData(0);
          var nSamples = renderedData.length;

          var success = true;

          // Number of grains that we found that have incorrect data.
          var invalidGrainDataCount = 0;
      
          var startEndFrames = findStartAndEndSamples(renderedData);

          // Verify the start and stop times.  Not strictly needed for
          // this test, but it's useful to know that if the ramp data
          // appears to be incorrect.
          success = success && verifyStartAndEndFrames(startEndFrames);

          // Loop through each of the rendered grains and check that
          // each grain contains our expected ramp.
          for (var k = 0; k < startEndFrames.start.length; ++k) {
              // Verify that the rendered data matches the expected
              // section of our ramp signal.
              var result = verifyGrain(renderedData, startEndFrames.start[k], startEndFrames.end[k], k);

              if (!result.verified) {
                  testFailed("Grain " + k + " incorrect.  Expected " + result.expected + " but received " + result.actual + " at sample frame " + result.frame);
                  ++invalidGrainDataCount;
                  success = false;
              }
          }
          
          if (!invalidGrainDataCount) {
              testPassed("All " + numberOfTests + " grains contained the correct data.");
          } else {
              testFailed(invalidGrainDataCount + " grains out of " + numberOfTests + " did not contain the expected data.");
              success = false;
          }
      
          if (success) {
              testPassed("noteGrainOn offset rendering tests passed.");
          } else {
              testFailed("noteGrainOn offset rendering tests failed.");
          }

          finishJSTest();
      }

      function runTest() {
          if (window.testRunner) {
              testRunner.dumpAsText();
              testRunner.waitUntilDone();
          }

          window.jsTestIsAsync = true;

          // Create offline audio context.
          context = new webkitOfflineAudioContext(2, sampleRate * renderTime, sampleRate);

          // Create a linear ramp for testing noteGrainOn.
          linearRampBuffer = createSignalBuffer(context,
                                                function(k) {
                                                    // Want the ramp to start
                                                    // with 1, not 0.
                                                    return k + 1;
                                                });    

          var grainInfo = playAllGrains(context, linearRampBuffer, numberOfTests);

          grainOffsetTime = grainInfo.grainOffsetTimes;

          context.oncomplete = checkResult;
          context.startRendering();
      }
      
      runTest();
      successfullyParsed = true;

    </script>

    <script src="../resources/js-test-post.js"></script>
  </body>
</html>
