<!DOCTYPE html>
<html>

<head>
  <title>Test AudioBufferSourceNode premature loop stop</title>
  <script src="../resources/js-test.js"></script>
  <script src="resources/compatibility.js"></script>
  <script src="resources/audio-testing.js"></script>
</head>

<body>
  <script>
    description("Test if AudioBufferSourceNode stops prematurely after the loop attribute change.");
    window.jsTestIsAsync = true;

    // Reasonably low sample rate for the optimum test speed.
    var sampleRate = 4096;

    var audit = Audit.createTaskRunner();

    // Task: Create a buffer with 3 regions filled with constant value of [1, 2,
    // 3]. Then set a loop range over the second region. Start the loop and
    // disable it in the middle of looping. Verify the rendered buffer has the
    // entire content including the looped region.
    audit.defineTask('premature-loop-stop', function (done) {
      var regionValues = [1, 2, 3];

      // The region length is 2 * render quantum size to be able to suspend the
      // rendering at the half of the region.
      var regionLength = 256;

      // The test will repeat the second region 3 times, thus the rendered audio
      // have the length of 5 * regionLength.
      var context = new OfflineAudioContext(1, 5 * regionLength, sampleRate);

      // Create 3 constant buffers of [1, 2, 3] and concatenate them together:
      // | 1 | 2 | 3 |
      var testBuffer = context.createBuffer(1, 3 * regionLength, sampleRate);
      var testChannel = testBuffer.getChannelData(0);
      for (var i = 0; i < regionValues.length; i++) {
        var region = createConstantBuffer(context, regionLength, regionValues[i]);
        testChannel.set(region.getChannelData(0), regionLength * i);;
      }

      var source = context.createBufferSource();
      source.connect(context.destination);

      source.buffer = testBuffer;
      source.loop = true;

      // Set loop points over the region 2.
      source.loopStart = regionLength/sampleRate;
      source.loopEnd = 2 * regionLength/sampleRate;

      source.start();

      // Disengage the loop at |3.5 * regionLength / sampleRate| which is the
      // end of 7th rendering quantum and also the half of the third iteration
      // of region #2.
      context.suspend(3.5 * regionLength/sampleRate).then(function () {
        source.loop = false;
        context.resume();
      });

      context.startRendering().then(function (renderedBuffer) {
        var channel = renderedBuffer.getChannelData(0);

        // Verify if the rendered buffer has the following structure:
        // | 1 | 2 | 2 | 2 | 3 |
        var region1 = channel.subarray(0, regionLength - 1);
        var region2 = channel.subarray(regionLength, 4 * regionLength - 1);
        var region3 = channel.subarray(4 * regionLength, 5 * regionLength - 1);

        Should('Region #1', region1).beConstantValueOf(1);
        Should('Region #2 (looped)', region2).beConstantValueOf(2);
        Should('Region #3', region3).beConstantValueOf(3);
      }).then(done);
    });

    audit.defineTask('finish', function (done) {
      finishJSTest();
      done();
    });

    audit.runTasks();

    successfullyParsed = true;
  </script>
</body>

</html>
