Tonejs / Tone.js

A Web Audio framework for making interactive music in the browser.
https://tonejs.github.io
MIT License
13.37k stars 976 forks source link

Tone.js getting stuck when switching between tabs on iPhone iOS #1114

Open wspringer opened 1 year ago

wspringer commented 1 year ago

When playing notes with Tone.js, if I'm opening the page in two different tabs, switch between them while clicking the play button, then Tone seems to get in a state where it no longer plays the notes nor executes the functions I schedule through Tone.Draw.schedule(…).

To Reproduce

I have been able to reproduce it with this codesandbox. Just open two tabs in iOS Safari, direct both of them to https://7d0j7j.csb.app/ and keep clicking the play button and switch to the other tab. At some point, it will enter the play() method, but schedule(…) and triggerAttackRelease(…) no longer seem to have an effect. (As a consequence the button will stay disabled.)

For added convenience, this is the source code:

const sampler = new Tone.Sampler({
  urls: {
    E1: "./bass-e.mp3",
    A2: "./bass-a.mp3",
    D2: "./bass-d.mp3",
    G2: "./bass-g.mp3"
  },
  release: 1
}).toDestination();

const pitches = ["E1", "A2", "D2", "G2"];

export default function App() {
  const [enabled, setEnabled] = useState(false);
  const play = () => {
    Tone.start().then(() => {      
      setEnabled(false);
      const now = Tone.now();
      pitches.forEach((pitch, index) => {
        sampler.triggerAttackRelease(pitch, "4n", now + index * 0.5);
      });
      Tone.Draw.schedule(() => {
        setEnabled(true);
      }, now + pitches.length * 0.5);
    });
  };
  useEffect(() => {
    Tone.loaded().then(() => {
      setEnabled(true);
    });
  }, []);

  return (
    <div className="App">
      <p>{enabled ? "enabled": "disabled"}</p>      
      <button disabled={!enabled} onClick={play}>
        Play
      </button>
    </div>
  );
}

Expected behavior What I expect to happen is that everything just keeps working fine.

What I've tried I dug a bit deeper into the source code, but I couldn't figure out why it would stop working altogether without throwing errors in the console.

davidfloegel commented 1 year ago

I have a similar issue. I'm building a PWA and if the user leaves the app and comes back to it, more often than not, the sound just doesn't work anymore..

Have you had any luck fixing this?

mrclay commented 4 days ago

I suspect we need to detect when the document transitions to visible and destroy and rebuild some set of Tone resources.