Skip to content

Timing issue with Tone.js #1360

@gipik

Description

@gipik

Hello Sirs,

I am trying to create a sequencer that sends MIDI messages on events.
The most simple example is a metronome that plays closed hi-hats every 16n on chan 10:

var seq = new Tone.Sequence(function(time, note){
  midiout_dev.send([ 153, note, 64 ])
}, [42], "16n").start('+0.1');

where midiout_dev is the output MIDI device provided by Web MIDI API.
The result is an audible timing problem, the events are not precise.
If I use a professional MIDI sequencer the problem does not happens, so is not a problem of my own setup.
The same result happens also using Tone.Part, and also if I try to use the time variable:

midiout_dev.send([ 153, 42, 64 ],time*1000)

I also tried to set lookahead in this way:

Tone.setContext(new Tone.Context({ latencyHint : "playback", lookAhead : 0 }))

but this line works only with Tone.js v13.4.9 (with other Tone versions I got no event) but no luck.

I tried different Tone versions (also from cdn "http://unpkg.com/tone") but with same results.

I also verified that this is not a browser problem, because if I try make the same without Tone, I have no problem and the metronome plays well:

for(var i=0;i<128;i++) {
    midiout_dev.send([ 153, 42, 64 ],window.performance.now() + 1000.0 + (0.125*i*1000) );
}

I checked https://github.com/Tonejs/Tone.js/wiki/Accurate-Timing but no luck.

Using Linux and Chromium Version 129.0.6668.89 (Official Build) (64-bit) and the same happens with Firefox 140.0.4 (64-bit).

I also setted
self.crossOriginIsolated=true
as said in https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp but no luck.


You can check the problem using this simple code, just change the midiout device name:

<html>
<title>EVENT PLAYER</title>
<script src="http://unpkg.com/tone"></script>
<script>
var midiout="MOTU Express  128-0"
var midiout_dev=null
window.onload=async function() {
    await navigator.requestMIDIAccess({sysex: true}).then(
        function(midiAccess) {
            MIDI_Access=midiAccess
            for(var mididev of MIDI_Access['outputs']) {
                if(mididev[1].name===midiout) {
                    console.log('FOUND midiout',midiout)
                    midiout_dev=mididev[1]
                }
            }
            // this works
            //for(var i=0;i<128;i++) {
            //    midiout_dev.send([ 153, 42, 64 ],window.performance.now() + 1000.0 + (0.125*i*1000) );
            //}

            // this doesn't work
            var seq = new Tone.Sequence(function(time, note){
                midiout_dev.send([ 153, note, 64 ])
                // midiout_dev.send([ 153, note, 64 ],(time) * 1000)
            }, [42], "16n").start('+0.1');
        }
    )
}
</script>
<button onclick="Tone.Transport.start('+0.1')">START</button>
<button onclick="Tone.Transport.stop('+0.1')">STOP</button><br>
</html>

Any idea about the problem ?
Thank you in advance,
Best regards,
Giacomo

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions