Javascript MIDI Player

  • Tutorial
We will make a .mid file player for Javascript and Web Audio API.

image

The end result may look like this .

image

For what


Making your player makes sense for interactive music applications as full control over playback will be possible (change of instruments, editing notes in real time, precise positioning, etc.).

For ordinary background music, regular mp3 is more suitable.

Components


The file with notes needs to be read somehow, loaded the used tools, to synthesize a sound and send it to an audio output.

Everything is simple.

Reading files


A simple search on GitHub gives us a bunch of projects for reading MIDI events from files.

Choose https://github.com/nfroidure/MIDIFile . It produces an array of events from a program change, noteOn / noteOff, etc.

For convenience, you will have to modify it a bit to immediately receive notes with time and duration:

image

Downloading musical instruments


The WebAudioFont library is used for sound , loading the tools in it is done with just a couple of lines, something like this:

for (var i = 0; i < song.tracks.length; i++) {
	var nn = findFirstIns(player, song.tracks[i].program);
	var info = player.loader.instrumentInfo(nn);
	player.loader.startLoad(audioContext, info.url, info.variable);
	}

Sound synthesis


You can send all notes to the playback queue at once. But there are thousands of them, even in small musical fragments, and such a size will "hang" the audio subsystem. Exit - send in small pieces through the regular setInterval function:

setInterval(function () {
	if (audioContext.currentTime > nextStepTime - stepDuration) {
		sendNotes(song, songStart, currentSongTime, currentSongTime + stepDuration, audioContext, input, player);
		currentSongTime = currentSongTime + stepDuration;
		nextStepTime = nextStepTime + stepDuration;
	}
}, 22);

You can read about the parameters of the function of sending sounds to the playback queue on the WebAudioFont project page .

Interactive


At any time, you can determine where the file is currently playing. In the demo player it looks like this:

function showPosition(song, currentSongTime) {
	var o = document.getElementById('position');
	o.value = 100 * currentSongTime / song.duration;
	document.getElementById('tmr').innerHTML = '' + Math.round(100 * currentSongTime / song.duration) + '%';
}

A tool change looks something like this:

var nn=selectIns.value;
var info = player.loader.instrumentInfo(nn);					
player.loader.startLoad(audioContext, info.url, info.variable);
player.loader.waitLoad(function () {
	console.log('loaded');
	song.tracks[i].info = info;
});

- Just a few lines and everything is loaded by itself.

Source


An example of a player is available at the link

All code takes a little less than 300 lines.

Also popular now: