MIDI.js icon indicating copy to clipboard operation
MIDI.js copied to clipboard

Play a MIDI file note by note?

Open raul4740 opened this issue 7 years ago • 7 comments

Is there a way to make a MIDI file playable note by note? What i intend to do is a musical piano game where you play the song note by note with keyboard events. What would be the simplest way to do this? With the player functions i can only play pause and resume the loaded midi.

raul4740 avatar Nov 16 '17 21:11 raul4740

Please check demos on main page of MIDI.js, some are similar to your requirement. Especially Piano Typewriter and Color Piano

shivrajsa avatar Nov 17 '17 03:11 shivrajsa

But is there a way to take a look at the code? Or do you have a basic/sample implementation or playing the midi file note by note? Thanks for replying, I appreciate it.

raul4740 avatar Nov 17 '17 04:11 raul4740

Here is the one http://mudcu.be/midi-js/ with code https://github.com/mudcube/MIDI.js/blob/master/examples/MIDIPlayer.html It is basic example of player from this repository

shivrajsa avatar Nov 17 '17 06:11 shivrajsa

But that player just plays the whole midi file and implements a pause/resume function. Is there a way to make it only play the first note of the midi? I managed to load it using MIDI.Player.loadFile("Final Fantasy - Prelude.mid", MIDI.Player.start); But it plays the whole song through. Also how exactly is your example loading the midi file? Do I need to implement it like you did? image

raul4740 avatar Nov 17 '17 15:11 raul4740

Take a look at below code from same example, especially data.note which gives you note value of each note

player.addListener(function(data) {
					var pianoKey = data.note - 21;
					var d = colorElements[pianoKey];
					if (d) {
						if (data.message === 144) {
							var map = colorMap[data.note - 27];
							if (map) d.style.background = map.hex;
							d.style.color = "#fff";
						} else {
							d.style.background = "";
							d.style.color = "";
						}
					}
				});

And below are available properties of data

MIDI.Player.addListener(function(data) { // set it to your own function!
    var now = data.now; // where we are now
    var end = data.end; // time when song ends
    var channel = data.channel; // channel note is playing on
    var message = data.message; // 128 is noteOff, 144 is noteOn
    var note = data.note; // the note
    var velocity = data.velocity; // the velocity of the note
    // then do whatever you want with the information!
});

It is mentioned on the project page.

shivrajsa avatar Nov 21 '17 10:11 shivrajsa

Check this issue https://github.com/mudcube/MIDI.js/issues/225 , it may help to solve your question

shivrajsa avatar Dec 08 '17 05:12 shivrajsa

Something like the following plays notes one by one:

MIDI.loadPlugin({
  soundfontUrl: "./soundfont/",
  instrument: "acoustic_grand_piano",
  onsuccess: function() {
    var time = 0;
    var velocity = 120;
    MIDI.setVolume(0, velocity);
    
    MIDI.noteOn(0, 60, velocity, time);
    MIDI.noteOff(0, 60, time + 1);
    
    MIDI.noteOn(0, 64, velocity, time+2);
    MIDI.noteOff(0, 64, time + 3);
  }
});

To get the sequence of notes in a midi file, you can use:

MIDI.loadPlugin({
  soundfontUrl: "./soundfont/",
  onsuccess: function() {
    MIDI.Player.loadFile('u-s-s-r.midi', function() {
      console.log(MIDI.Player.data);
    });
  }
});

The logged data contains the midi event sequence, which contains the notes. See this example.

duhaime avatar Sep 26 '21 14:09 duhaime