Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tone.js: How to know when triggerRelease has finished

I want to update my UI when a note has finished playing with tone.js

const now = Tone.now()
synth.triggerAttack("G3", now);
synth.triggerRelease("G3", now + 60 / this.tempo)

How can I get a callback or add a listener to the triggerRelease so I can update the UI?

like image 951
etayluz Avatar asked Nov 01 '25 13:11

etayluz


1 Answers

I have never used the library but reviewing its documentation it seems that the API defines an onsilence callback that you could use for your purpose.

You can provide that callback when creating the Synth instance passing the appropriate configuration option:

const synth = new Tone.Synth({
  onsilence: () => console.log('I am invoked after the release has finished') // update the UI as appropriate
}).toDestination();
const now = Tone.now()
synth.triggerAttack("G3", now);
synth.triggerRelease(now + 60 / this.tempo);

The API provides some tests related to it as well.

As you indicated in your comments the onsilence callback seems to be invoked only when the instrument is completely in silence, but you need to perform some action when a note ends.

Probably the way to go would be working with the different events offered by the library.

The library documentation provides different related examples that exemplifies how to use them.

Consider for instance review this one and the companion wiki page that try explaining how to sync visuals, or this other one, close to the per note callback you are looking for.

These two examples can be found in the tone.js repository.

With these in mind, consider for instance this code, based on the second example provided when describing the Part event and the snippet of code provided in the aforementioned article about performance and how to sync visuals:

import * as Tone from 'tone';

const synth = new Tone.Synth().toDestination();
// use an array of objects as long as the object has a "time" attribute
const part = new Tone.Part(
  (time, value) => {
    // the value is an object which contains both the note and the velocity
    synth.triggerAttackRelease(value.note, '8n', time);

    Tone.Draw.schedule(function () {
      //this callback is invoked from a requestAnimationFrame
      //and will be invoked close to AudioContext time
      document.getElementById('app').innerHTML += ' ' + value.note;
    }, time);
  },
  [
    { time: 0, note: 'C3' },
    { time: '0:2', note: 'C4' },
  ]
).start(0);
Tone.Transport.start();

Please, reload the preview page in Stackblitz, you should see every note.

Finally, you have several ways if you need to access the parent context this object as indicated in your comments: the exact way will depend on your actual code. Please, consider for instance review this related SO question, I think it could be of help.

like image 151
jccampanero Avatar answered Nov 04 '25 05:11

jccampanero



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!