The MIDI Forum

  1. Jonas
  2. Sherlock Holmes
  3. Creating with MIDI
  4. Monday, 29 March 2021
  5.  Subscribe via email
i come up with a scheme to correct timings, but it is hard to assess if it will work, and have not dared to try it.
copyEv is an array of timing distances between notes. "TIME"
plannedTime=0;
LoadTIME=performance.now();
STARTPLAY();
function STARTPLAY(){
if (keepGoing) {
stopRec=setTimeout(STARTPLAY,copyEv[playPos]);
//While still notes
if (playPos<copyEv.length) {
//******* CORRECT, THE FUTURE TIMING OF NEXT EVENT
//copyEv[] is an array of setTimeut timings between notes
plannedTime=copyEv[playpos]+plannedTime;
latency=plannedTime-(performance.now()-LoadTIME);
copyEv[playpos+1]=copyEv[playpos+1]-latency;
//*******************************************************
if (echo && mode=="Play";){
pianoKeypressOut();
}
outportarr[outportindex].send(noteMessage[playPos]);
playPos++;
} else { stop();}
}
}
Basicly the scheme look at the current note and its "realtime playup time performance.now()-LoadTIME" compare it with the "planned/scheduled time" and remove the assesed latency time from next note planned to play.
At least that is my initial thought about what it should do.

And i think i see that i am really should not compare with current note "playpos", because that is planned in the future it must be playpos-1 that have latency.
Well the logic of passed and future events gets rather hairy.
Comment
There are no comments made yet.
Accepted Answer Pending Moderation
0
Votes
Undo
https://jonasth.github.io/
Anyone with good temporal and spatial abilities "logic", that can correct "my scheme to correct the note time", "check URL for realtime, animationtime and notetime"

function STARTPLAY(){
if (keepGoing) {
stopRec=setTimeout(STARTPLAY,copyEv[playPos]);
//While still notes
if (playPos<copyEv.length) {
//******THIS CODE WILL CORRECT, THE FUTURE TIMING OF NEXT EVENT ***IN THE FUTURE
//The realtime that passed is performance.now()-browserLoadTIME
//The scheduled time is the note timings passedTime=copyEv[playPos]+passedTime;
//Realtime-scheduledtime is our latency.
//calculate latency=performance.now()-browserLoadTIME-passedTime;
//calculate new position copyEv[playPos]=copyEv[playPos]-latency;
passedTime=copyEv[playPos]+passedTime;
copyEv[playPos]=copyEv[playPos]-(performance.now()-browserLoadTIME-passedTime);
outportarr[outportindex].send(noteMessage[playPos]);
playPos++;
if (echo && mode=="Play";){
pianoKeypressOut();
}

} else { stop();}
}
}

I think the logic is rather straight but the issue is what note to compare with realtime clock, and what note to update.
Comment
There are no comments made yet.
  1. more than a month ago
  2. Creating with MIDI
  3. # 1
Accepted Answer Pending Moderation
0
Votes
Undo
I was hoping that someone else would raise this, but no-one has.

Surely, if you add 'timing data' to a link that suffers from 'latency' (whatever that is in your specific circumstances) then the timing data would also suffer from 'latency' and be also useless? If each connected device is generating it's one timing, then you have the problem of co-ordinating the different timings? This too might be affected by the 'latency' problem you refer to?

I would have though that it would be far better to try to determine WHAT is causing the 'latency' you've got, and fix the problem at source. MIDI alone should not suffer from latency. Maybe it's coming from the OS, which is doing too many other 'tasks' at the same time. Maybe drivers (etc) are inefficient, of badly installed. Maybe the USB link is carring other (non-midi) data (like Audio data) as well, and the location of the data in the stream is interfering with the midi timing.

Maybe a piece of software that checks the data stream and compares the midi timing with the actual/real time and reports of the data passing and the time disparity might be a big help is determining what is causing the problem.

Geoff
Comment
There are no comments made yet.
  1. more than a month ago
  2. Creating with MIDI
  3. # 2
Accepted Answer Pending Moderation
0
Votes
Undo
I remove timing data from setTimout(copyEv[playPos]) which is the scheduled point in future when next note is playedup, so i do not add anything i hope. stopRec=setTimeout(STARTPLAY,copyEv[playPos]);

So this do remove time from that "future event" making copyEv(position) a smaller timing value above.
copyEv[playPos]=copyEv[playPos]-(performance.now()-browserLoadTIME-passedTime);

Copy Ev is the original distance in time to next note, then i remove (realtime-passedtime) which is the latency. And here passedtime is the "scheduled time" "by adding up notes", so the time that passed "realtime" is larger then "scheduled" time played up thus far, as one can see."The scheduled time "sum" is less then realtime during playup" because latency addup.
And that is a +latency and it will be postive value right.

Geoff i have the RT it is performance.now()-browserLoadTIME in the recursion and calculation.

So the latency=R(T)-NOTE(T) the added scheduled times, which become late cause of latency and actually is the current latency when inspecting visual.

So we want to correct when copyEv will be played up.
Now we take our copyEv-latency and get a new time for copyEv that is "shorter/closer/smaller" to previous event by remove the bulked up latency, so next call is fired/moved closer in time.

You probably did look at first example and i probably turned things around there.
Comment
There are no comments made yet.
  1. more than a month ago
  2. Creating with MIDI
  3. # 3
Accepted Answer Pending Moderation
0
Votes
Undo
Geoff what causing the latency is Javascript in itself doing things during timeOut it is not threaded and simply not suitable for realtime processing. "From what i can understand".
The javascript gurus say that every setTimeout can vary upto 5 ms before executed, so note latency in seconds add up pretty fast "if not handled".

Maybe you midi guys find my code confusing since it not quantised into ticks PPQ, but use the realtime recording values.
I will fix my code to allow for PPQ quantisation, i guess otherwise things like tempochange just become some percentage.

So my playup code do not quantise playup into PPQ intervals, it just set timeOuts, so if you want to change tempo it is basicly a percentage of the recorded time.

But the basic point of my problem is we have an array of temporal distances "time" between events. Somehow these events not played according to the R(T) clock.
So after each note played "before next note should be scheduled", we check how much was the sum of scheduled notes "drifting", relative the realtime clock.

"And right there i see a problem with my code i must compare playPos -1 with the realtime clock" that could be it. Thanks for listening to my ranting anyhow.


And then i try to remove how much it drifted.

Well in a nutshell.
Comment
There are no comments made yet.
  1. more than a month ago
  2. Creating with MIDI
  3. # 4
Accepted Answer Pending Moderation
0
Votes
Undo
Geoff, well the problem is already known javascript is single threaded and not accurate enough using setTimeout, what i try to do is find out strategies to deal with it.
Unfortunately it seem like the variable updates using setTimout and recursion is broken.
Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this post yet.
Be one of the first to reply to this post!