<!DOCTYPE html>

<html class="a">
  <head>
    <title>MediaStreamAudioSourceNode</title>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
  </head>
  <body class="a">
    <div id="log"></div>
    <script>
      function binIndexForFrequency(frequency, analyser) {
        return (
          1 +
          Math.round(
            (frequency * analyser.fftSize) / analyser.context.sampleRate
          )
        );
      }

      const t = async_test(
        "MediaStreamAudioSourceNode captures the right track."
      );
      t.step(function() {
          const ac = new AudioContext();
          // Test that the right track is captured. Set up a MediaStream that has two
          // tracks, one with a tone at 100Hz and one with a tone at 1000Hz.
          const dest0 = ac.createMediaStreamDestination();
          const dest1 = ac.createMediaStreamDestination();
          const osc0 = ac.createOscillator();
          const osc1 = ac.createOscillator();
          osc0.frequency.value = 100;
          osc1.frequency.value = 1000;
          osc0.connect(dest0);
          osc1.connect(dest1);
          osc0.start(0);
          osc1.start(0);
          const track0 = dest0.stream.getAudioTracks()[0];
          const track0id = track0.id;
          const track1 = dest1.stream.getAudioTracks()[0];
          const track1id = track1.id;

          let ids = [track0id, track1id];
          ids.sort();
          let targetFrequency;
          let otherFrequency;
          if (ids[0] == track0id) {
              targetFrequency = 100;
              otherFrequency = 1000;
          } else {
              targetFrequency = 1000;
              otherFrequency = 100;
          }

          let twoTrackMediaStream = new MediaStream();
          twoTrackMediaStream.addTrack(track0);
          twoTrackMediaStream.addTrack(track1);

          const twoTrackSource = ac.createMediaStreamSource(twoTrackMediaStream);
          const analyser = ac.createAnalyser();
          // Don't do smoothing so that the frequency data changes quickly
          analyser.smoothingTimeConstant = 0;

          twoTrackSource.connect(analyser);

          const indexToCheckForHighEnergy = binIndexForFrequency(
              targetFrequency,
              analyser
          );
          const indexToCheckForLowEnergy = binIndexForFrequency(
              otherFrequency,
              analyser
          );
          let frequencyData = new Float32Array(1024);
          let checkCount = 0;
          let numberOfRemovals = 0;
          let stopped = false;
          function analyse() {
              analyser.getFloatFrequencyData(frequencyData);
              // there should be high energy in the right bin, higher than 40dbfs because
              // it's supposed to be a sine wave at 0dbfs
              if (frequencyData[indexToCheckForHighEnergy] > -40 && !stopped) {
                  assert_true(true, "Correct track routed to the AudioContext.");
                  checkCount++;
              }
              if (stopped && frequencyData[indexToCheckForHighEnergy] < -40) {
                  assert_true(
                      true,
                      `After stopping the track, low energy is found in the
              same bin`
                  );
                  checkCount++;
              }
              if (checkCount > 5 && checkCount < 20) {
                  twoTrackMediaStream.getAudioTracks().forEach(track => {
                      if (track.id == ids[0]) {
                          numberOfRemovals++;
                          window.removedTrack = track;
                          twoTrackMediaStream.removeTrack(track);
                      }
                  });
                  assert_true(
                      numberOfRemovals == 1,
                      `The mediastreamtrack can only be
        removed once from the mediastream`
                  );
              } else if (checkCount >= 20 && checkCount < 30) {
                  window.removedTrack.stop();
                  stopped = true;
              } else if (checkCount >= 30) {
                  assert_true(
                      numberOfRemovals == 1,
                      `After removing the track from the
        mediastream, it's still routed to the graph.`
                  );
                  // After some time, consider that it worked.
                  t.done();
                  return;
              }

              t.step_timeout(analyse, 100);
          }
          t.step_timeout(analyse, 100);
      });
    </script>
  </body>
</html>
