Javascript setInterval metronome doesn't work on mobile

135 Views Asked by At

I'm pretty new to Javascript and coding in general so go easy on me!

I've made a (very) simple metronome in HTML, JS, etc using setInterval - I'm aware there are limitations to this, and that it's not the most accurate method of doing so etc. With that being said, on the various desktop browsers it seems to work relatively well. However:

  • On desktop Safari (15.1) the audio doesn't seem to play properly - it's audible but muffled.

  • On every mobile browser I've tried (Safari, Firefox, Chrome - unsure which versions) it doesn't seem to work at all.

Any help with this would be greatly appreciated - I've included the code for the actual metronome part below. I have to assume the issues relate to setInterval somehow, I'm just hoping someone can shed some light on why exactly it doesn't work.

Cheers!

  const sound = document.querySelector('audio');
  const powerButton = document.querySelector('.on-button');
  let poweredOn = false;
  let metronome;
  let milliseconds;

  function playSound() {
      if (milliseconds != Infinity) {
        sound.currentTime = 0;
        sound.play();
      }
    }

  function setMilliseconds() {
    let tempo = document.querySelector('.tempo').value;
    milliseconds = 60000 / tempo;


    if (poweredOn == true) {
      clearInterval(metronome);
      if (milliseconds >= 100) {
        playSound();
        metronome = setInterval(playSound, milliseconds);
        }
    }

    if ((!tempo || milliseconds < 100) && poweredOn == true) {
      poweredOn = false;
      clearInterval(metronome);
      powerButton.classList.remove('switched-on');
    }
  }

  function activate() {
    if (milliseconds) {
      let tempo = document.querySelector('.tempo').value;
      poweredOn = poweredOn ? false : true ;
      if (poweredOn && milliseconds) {
        if (milliseconds < 100 || !milliseconds || !tempo) {
          this.classList.add('invalid');
          setTimeout(() => {
            this.classList.remove('invalid');
          }, 100)
          poweredOn = false;
        } else {
          this.classList.add('switched-on');
          playSound();
          metronome = setInterval(playSound, milliseconds);
        }
      } else {
        this.classList.remove('switched-on');
        clearInterval(metronome);
      }
    } else {
      this.classList.add('invalid');
      setTimeout(() => {
        this.classList.remove('invalid');
      }, 100)
    }
  }

EDIT - I've added all of the JS from the metronome, rather than just the one function. I've since changed it to use a recurring setTimeout rather than setInterval, so that I can adjust the interval as I go to compensate for drift - debugging that is suggesting that the issue could be with the audio playing on mobile, rather than the intervals themselves. Any thoughts?

0

There are 0 best solutions below