Tone.js Transport Stop and Restart Scheduled Events
When working with web audio in Tone.js, understanding how the
timeline behaves during playback control is essential. This article
explains what happens to scheduled events when
Tone.Transport is stopped and subsequently restarted,
highlighting how event scheduling persists on the timeline and how the
playhead position changes.
Scheduled Events Persist in Memory
When you schedule an event using
Tone.Transport.schedule(),
Tone.Transport.scheduleRepeat(), or
Tone.Transport.scheduleOnce(), the event is bound to a
specific time or tick on the Transport’s timeline.
Stopping and restarting the Transport does not delete or
clear these scheduled events. They remain in the Transport’s
queue until you explicitly remove them using
Tone.Transport.clear(id) or clear the entire timeline using
Tone.Transport.cancel().
What Happens
When You Call Tone.Transport.stop()?
Calling Tone.Transport.stop() affects the timeline and
playing events in the following ways:
- Playback Halts: The internal timeline clock stops ticking, and no further scheduled events will be triggered.
- Playhead Resets to Zero: The Transport’s position
(the virtual playhead) is immediately reset back to
0(the beginning of the timeline). - Active Synths and Effects: Any synthesizers or samplers that were triggered right before the stop will continue their release phase or ring out unless they are explicitly muted or released.
What Happens
When You Call Tone.Transport.start()?
When you restart the Transport after stopping it, the timeline behaves as follows:
- Playhead Starts at Zero: Because stopping resets
the timeline, calling
start()begins playback from time0(unless you pass a specific start offset argument, such asTone.Transport.start("+0.1", "1m")). - Events Re-trigger: As the playhead moves forward
from
0, any events scheduled at or after the start position will trigger again as the playhead reaches their designated time stamps.
Stopping vs. Pausing
It is important to distinguish between stopping and pausing, as they handle scheduled events differently upon restart:
Tone.Transport.stop(): Resets the position to0. When you restart, all scheduled events from the very beginning of the timeline will play again.Tone.Transport.pause(): Freezes the playhead at its current position. When you callTone.Transport.start()after pausing, playback resumes exactly where it left off, and only future scheduled events will trigger.