From 06a6b9f2c950ea694c2ccd144c2483b40f4dde29 Mon Sep 17 00:00:00 2001 From: aeiou879 <76179088+aeiou879@users.noreply.github.com> Date: Tue, 30 Mar 2021 21:54:23 -0700 Subject: [PATCH] Fix lag on large midis This provides a fix for https://github.com/grimmdude/MidiPlayerJS/issues/25 where only one event per track could play each playLoop interval. This means that if there are multiple simultaneous events, they won't play all at the same time, which can be seen when playing black midis. This fix works by doing playLoops until there are no more events to play. This might not be the most efficient way to solve the issue, because it now needs to do a playLoop twice every time there's an event, but it's better than setting sampleRate to 0 which just makes the issue require more events to see. --- src/player.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/player.js b/src/player.js index b571890..d3fee66 100644 --- a/src/player.js +++ b/src/player.js @@ -192,6 +192,7 @@ class Player { * @return {undefined} */ playLoop(dryRun) { + var hadEvent = false; if (!this.inLoop) { this.inLoop = true; this.tick = this.getCurrentTick(); @@ -204,6 +205,8 @@ class Player { this.stop(); } else { let event = track.handleEvent(this.tick, dryRun); + + if (event) hadEvent = true; if (dryRun && event) { if (event.hasOwnProperty('name') && event.name === 'Set Tempo') { @@ -236,6 +239,7 @@ class Player { if (!dryRun) this.triggerPlayerEvent('playing', {tick: this.tick}); this.inLoop = false; } + return hadEvent; } /** @@ -269,7 +273,9 @@ class Player { // Start play loop //window.requestAnimationFrame(this.playLoop.bind(this)); - this.setIntervalId = setInterval(this.playLoop.bind(this), this.sampleRate); + this.setIntervalId = setInterval(() => { + while (this.playLoop()) {} + }, this.sampleRate); //this.setIntervalId = this.loop(); return this; }