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
359 stars 52 forks source link

endOfFile event never fires #7

Closed robertvorthman closed 6 years ago

robertvorthman commented 7 years ago

Also getTotalTicks() would always return 0. The 'playing' event fires continuously even after the midi has ended, so as a workaround I check for endOfFile using this code instead:

player.on('playing', (event) => {
    if (player.getSongPercentRemaining() <= 0) {
        console.log('song ended');
        player.stop();
    }
});

If I don't call stop(), the getSongPercentRemaining() function returns larger and larger negative percentages (-10%, -20%, etc...) after the tracks finish.

grimmdude commented 7 years ago

Hi @robertvorthman,

Thanks for the note, I made a few changes on the last release which I believe are related. Will try to get to this later today or tomorrow.

-Garrett

grimmdude commented 6 years ago

Hi @robertvorthman,

endOfFile event and getSongPercentRemaining() method should be working correctly now in 1.1.3. For total ticks, use static variable Player.totalTicks instead since that function is called once during file load, then once playback starts may not be accurate.

-Garrett

robertvorthman commented 6 years ago

Wow, thanks for the quick response. I'm still having the same issue. Maybe I'm doing something wrong, I'm a bit of a node.js novice because I mostly do front-end JavaScript. Either way, it's not a big deal. I'm still able to make my Christmas light show work using the rest of the player methods. This library is awesome. I'm going to have the best Christmas lights in the neighborhood because they will be blinking like crazy with every note event in the midi files.

With this code, isPlaying() still returns false even while playing, and the endOfFile event never fires. My full code is here: https://github.com/robertvorthman/neopixel-music/blob/master/index.js#L61

midiParser.on('playing', (event)=>{

    if(midiParser.getSongPercentRemaining() <= 0){
        console.log('song ended');
        stop();
    }else{
        console.log(midiParser.totalTicks, midiParser.isPlaying());
    }
});

midiParser.on('endOfFile', (event)=>{
    console.log('endOfFile', event);
    console.log('midiParser.isPlaying()', midiParser.isPlaying());
});

Console output:

screen shot 2017-11-09 at 9 20 51 am
grimmdude commented 6 years ago

Hi @robertvorthman,

OK I see what was happening, node returns an object from setInterval() whereas browser returns a number. This should be fixed no in 1.1.4.

-Garrett

grimmdude commented 6 years ago

@robertvorthman,

BTW your christmas light idea is killer, I gotta see this!

robertvorthman commented 6 years ago

@grimmdude Thanks for fixing these issues so quickly.

robertvorthman commented 6 years ago

@grimmdude Here is a video of the Christmas lights I made with your library. The 5 meter LED strip has 100 individually addressable pixels. I used d3.js to assign each note a range of pixels on the LED strip.

https://www.youtube.com/watch?v=jAAgjaXRgyM

grimmdude commented 6 years ago

Ha @robertvorthman that's amazing, great job! Can I include a link to this on the README of this repo?

robertvorthman commented 6 years ago

@grimmdude Ya that'd be awesome