📜 ⬆️ ⬇️

Javascript MIDI Player

We will make a player .mid files on Javascript and Web Audio API.

image

The end result might look like this .

image

For what


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

For normal background music, regular mp3 is more suitable.
')

Components


The file with notes must somehow be read, the instruments used are loaded, the sound is synthesized and sent to the audio output.

It's 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 gives an array of events from the change of the program, noteOn / noteOff, etc.

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

image

Download musical instruments


For sound, the WebAudioFont library is used , the loading of tools in it is literally done in a couple of lines, 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 the notes to the queue at once. But there are thousands of them even in small musical fragments and such a size will “hang” the audio subsystem. Output - send in small chunks through the usual 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); 

The parameters of the function of sending sounds to the playback queue can be found on the WebAudioFont project page .

Interactive


At any time, you can determine where the file is now 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) + '%'; } 

Tool change looks 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 loads itself.

Source


Sample player is available by reference.

All code takes just under 300 lines.

Source: https://habr.com/ru/post/353036/


All Articles