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

The correct way to run other codes alongside the synth.triggerAttackRelease #1153

Closed lukewys closed 1 year ago

lukewys commented 1 year ago

Hi,

First, thanks for much for the great library!

Currently, I am building a project that involves playing a MIDI, showing the animation of the piano alongside the metronome. I found that there are some synchronization issues if I use Tone.Transport.scheduleOnce. Specifically:

  1. If I use synth.triggerAttackRelease(note.name, note.duration, note.time + now, note.velocity) to play a series of notes start from now, they will be played on time.
  2. In my project, I would like to show some animation (e.g. highlight piano key) when playing the note. I implement that via: Tone.Transport.scheduleOnce(time => { myAnimationCode() }, now + note.time);

However, I found that there would be a ~0.1 second of delay for Tone.Transport.scheduleOnce. That is, it will be triggered later than the designated time.

  1. The effect in 2# is more obvious if I use Tone.Transport.scheduleOnce to play a note: Tone.Transport.scheduleOnce(time => { synth.triggerAttackRelease(note.name, note.duration, time, note.velocity); }, now + note.time);

I would like to know then what is the right way to run some code that is synchronized to synth.triggerAttackRelease? Many thanks in advance!

braebo commented 1 year ago

Hey-- you're going to want to use Tone.draw(() => { ...animationCode }) inside of your scheduleOnce.

https://tonejs.github.io/docs/14.7.77/Draw

lukewys commented 1 year ago

Many thanks for the pointer! That is exactly what I am looking for!