danigb / soundfont-player

Quick soundfont loader and player for browser
MIT License
453 stars 60 forks source link

Play MIDI files #107

Open page200 opened 1 year ago

page200 commented 1 year ago

Since there's no "Discussions" tab in this repo (and this discussion affects potential add-ons and bugfixes), I'm opening this issue to discuss how to play MIDI files. This discussion started at https://github.com/mudcube/MIDI.js/issues/268#issuecomment-1368694753 and https://github.com/mudcube/MIDI.js/issues/268#issuecomment-1368701177 with @urobot2011 in the repo of MIDI.js, whose SoundFont loader soundfont-player replaces.

The readme of soundfont-player says "It is a much simpler and lightweight replacement for MIDI.js soundfont loader (MIDI.js is much bigger, capable of play midi files, for example, but it weights an order of magnitude more).". Therefore:

Another thing: When I tried the official demo of MidiPlayerJS months ago, which uses soundfont-player, it had unstable playback, for example when switching quickly between windows. When I tried today, it seemed to use wrong instruments and the rhythm didn't seem perfect. I wonder whether that problem is due to MidiPlayerJS or soundfont-player. It might be due to soundfont-player because that webpage says "This MIDI player was built using MidiPlayerJS to read the file, and soundfont-player to load and play the sounds". I also wonder whether those are the fatal flaws that @urobot2011 mentioned at https://github.com/mudcube/MIDI.js/issues/268#issuecomment-1368701177 and https://github.com/grimmdude/MidiPlayerJS/issues/94, or whether @urobot2011 meant another one.

I wonder what the change was compared to MIDI.js that affected the timing.

mk-pmb commented 1 year ago

Thank you for summarizing!

page200 commented 1 year ago

To sum up several discussions: The only approach that works well so far (correct instruments, perfect rhythm, can play in the background) is the latest official branch of MIDI.js (named "abcjs"), except for the first seconds of the first time a song is played. That problem is described at https://github.com/mudcube/MIDI.js/issues/268#issuecomment-1367335200. Solving that seems like the most promising plan. Feel free to have a look into that.

urobot2011 commented 1 year ago

Thanks for your help!

urobot2011 commented 1 year ago

But when i click the 'play' button on my Kalimba-sheet-music-writer project the sound is fine (there is a little sound jitter but i don't mind that). What I'm wondering is if it's possible to know the length of a note in advance before the 'note off' event fires. I didn't get the answer from MidiPlayerJS's official documentation. Here is a test page for my Kalimba-sheet-music-writer project: Test Page

page200 commented 1 year ago

@urobot2011 Hm, I'd like to play MIDI files without jitter. And regarding note durations, I suspect that some JavaScript MIDI players don't care about matching "Note On" MIDI messages with the respective "Note Off" messages. If you don't want to "reinvent" that matching, then apps that visualize that matching (for example as piano rolls) might serve as inspiration. Tag me at https://github.com/urobot2011/Kalimba-sheet-music-writer/discussions or so if you want me to list them and some of their properties. I don't know whether MidiPlayerJS performs that matching. https://musiclab.chromeexperiments.com/Piano-Roll/ (https://github.com/googlecreativelab/chrome-music-lab/tree/master/pianoroll) uses an interval tree to rewind the song efficiently.

urobot2011 commented 1 year ago

@page200 I looked at Color Piano and thought this might be possible with MIDI.JS. Is this possible with MIDI.JS?

page200 commented 1 year ago

@urobot2011 Color Piano uses MIDI.js, but probably an old branch of MIDI.js that doesn't play all instruments correctly. (Color Piano only plays the piano.) As discussed at https://github.com/mudcube/MIDI.js/issues/268, it seems more promosing to fix the first seconds of the new "abcjs" branch than the entire instrument support in the old "master" branch.

urobot2011 commented 1 year ago

@page200 my workspace

urobot2011 commented 1 year ago

Hmm, I know this is just weird. But is there any way to fix this? Or, is it possible with midi.js(adc.js)?