grimmdude / MidiPlayerJS

♬ MIDI parser & player engine for browser or Node. As a parser converts MIDI events into JSON. Works well with single or multitrack MIDI files.
https://grimmdude.com/MidiPlayerJS/
MIT License
357 stars 52 forks source link

MIDIs that change tempo more than once don't play properly #28

Closed ghost closed 4 years ago

ghost commented 6 years ago

This MIDI plays extremely slowly. https://files.catbox.moe/4j9uzi.mid I believe this MIDI starts out at 210 bpm and then ends at 20 bpm; or something like that… But from what I see, the player first does a dry run and sets the tempo on any "Set Tempo" events, which means the last Set Tempo overwrites all the previous ones. So my app has to respond to "Set Tempo" events with Player.setTempo(event.data) for the MIDI to play correctly. The player should do this.

grimmdude commented 6 years ago

Hi @ledlamp,

Thanks for the issue. You're right, I believe currently this player will only handle the first tempo change correctly. I will take a look at this when I have some time. Pull requests are always welcome!

-Garrett

JudeOsborn commented 6 years ago

FWIW, we are having a similar problem.

ghost commented 6 years ago

Yes. I have the same problem. When changing tempo mid-way through a song, it lags and does some other weird stuff.

JudeOsborn commented 6 years ago

The problem seems to be with the "tick". When tempo changes the tick calculation also changes, which confuses the loop. For example, when slowing down there is a pause in the music while the tick value is catching back up to where it left off.

I noticed the demo used to use setTempo on its own. That was commented out, and replaced with a pause, setTempo and then play.

This appears to work in the demo, but for some reason does not work for me. Pausing zeroes out the startingTick, which causes all kinds of issues. Not sure how it works in the demo.

On Thu, May 24, 2018, 4:54 AM BopItFreak notifications@github.com wrote:

Yes. I have the same problem. When changing tempo mid-way through a song, it lags and does some other weird stuff.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/grimmdude/MidiPlayerJS/issues/28#issuecomment-391458574, or mute the thread https://github.com/notifications/unsubscribe-auth/AAPkJsZIW-ibQb_1vims57dKMO9dCDOwks5t1bBjgaJpZM4TzhSX .

ghost commented 6 years ago

Hi. I actually figured that out myself, and it works! This is a problem with some other functions as well, but if you add the pause and play, it works for me.

JudeOsborn commented 6 years ago

In my case, if I pause, setTempo and play the midi file does not apply the new tempo. Instead it plays at a ridiculously fast tempo. The .tempo variable says the tempo is correct, but what I actually here is way, way too fast.

JudeOsborn commented 6 years ago

Looks like the problem has to do with changing tempo too soon after playing a song. If I add even a 500ms delay before setTempo can be run it works fine. If I do not and setTempo is run too soon the song seems to get stuck on a very fast tempo. I have tried waiting for validate() and isPlaying(), but no affect. But a short artificial delay seems to help.

grimmdude commented 4 years ago

Hi @JudeOsborn & @ghost,

Just published 2.0.12 which automatically changes player tempo based on tempo events. I think this should fix the issue for you.

-Garrett