Search code examples
javascriptweb-audio-apitone.js

Tone JS - Transport.stop(); does not work with scheduled events


I am using Tone JS for a project and I am using Transport.scheduleOnce to schedule events with the Sampler. Here is what I have so far, also here is a fiddle of it (you may need to click run a couple times to hear the audio come through when fiddle initially loads)

My code:

const sound = 'https://archive.org/download/testmp3testfile/mpthreetest.mp3';
let samplerBuffer;

const sampler = new Promise((resolve, reject) => {
   samplerBuffer = new Tone.Sampler(
    { 
      A1: sound
    },
    {
      onload: () => {
        resolve()
      }}
  ).toMaster();
})


sampler.then(() => {
  Tone.Transport.scheduleOnce(() => {
    samplerBuffer.triggerAttack(`A1`, `0:0`)
  });

  Tone.Transport.start();
  
  setTimeout(() => {
    console.log('Now should be stopping');
    Tone.Transport.stop();
  },1000)
})

I am trying to stop the audio from playing after 1 second using the Transport.stop() method however it does not seem to work. I think I have followed the docs as I should so where am I going wrong?


Solution

  • Tone.Transport is triggering your sample.
    What you want to do is either use the Tone.Player if you only want to play sounds like a "jukebox".

    If you really need a sampler, then should to look into Envelopes because the Sampler uses one.

    In short: The Tone.Transport like the maestro in a concert. Transport is only setting the time (only the BPM not the playback speed). Tone.Transport.start() will trigger all registered instruments (in your case the Sampler) to start doing whatever you programmed them to do. If you want to stop the Sampler from playing in this mode. You can do samplerBuffer.releaseAll()

    const sound = 'https://archive.org/download/testmp3testfile/mpthreetest.mp3';
    let samplerBuffer;
    
    const sampler = new Promise((resolve, reject) => {
       samplerBuffer = new Tone.Sampler(
        { 
          A1: sound
        },
        {
          onload: () => {
            resolve()
          }}
      ).toMaster();
    })
    
    
    sampler.then(() => {
      Tone.Transport.scheduleOnce(() => {
        samplerBuffer.triggerAttack(`A1`, `0:0`)
      });
    
      Tone.Transport.start();
      setTimeout(function() {
        console.log('Now should be stopping');
        samplerBuffer.releaseAll();
        // samplerBuffer.disconnect();
      },1000)
    })
    

    https://jsfiddle.net/9zns7jym/6/