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.