- PVSM.RU - https://www.pvsm.ru -

MIDI-проигрыватель на Javascript

Будем делать проигрыватель файлов .mid на Javascript и Web Audio API.

image

Конечный результат может выглядеть вот так — https://surikov.github.io/webaudiofont/examples/midiplayer.html [1]

image

Для чего

Делать свой плеер имеет смысл для интерактивных музыкальных приложений т.к. будет возможен полный контроль за воспроизведением (смена инструментов, редактирование нот в рилтайме, точное позиционирование и т.п.).
Для обычной фоновой музыки больше подходит обычный mp3.

Составные части

Файл с нотами надо как-то прочитать, загрузить используемые инструменты, синтезировать звук и отправить его в аудиовыход.

Всё просто.

Чтение файлов

Простой поиск по GitHub даёт нам кучу проектов для чтения MIDI-событий из файлов.

Выберем https://github.com/nfroidure/MIDIFile [2]. Он выдаёт массив событий от смены программы, noteOn/noteOff и пр.

Для удобства придётся его немного модифицировать чтоб сразу получать ноты со временем и длительностью:
image

Загрузка музыкальных инструментов

Для звука используется библиотека WebAudioFont [3], загрузка инструментов в ней делается буквально парой строчек, примерно так:

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);
	}

Синтез звука

Можно отправить в очередь воспроизведения все ноты сразу. Но их тысячи даже в небольших музыкальных фрагментах и такой размер «повесит» аудио подсистему. Выход — отправлять небольшими кусками через обычную функцию setInterval:

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

О параметрах функции отправки звуков в очередь воспроизведения можно прочитать на странице проекта WebAudioFont [3].

Интерактив

В любой момент можно определить в каком месте файла сейчас находится воспроизведения. В демо-плеере это выглядит так:

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) + '%';
}

Исходный код

Пример плеера доступен по ссылке https://surikov.github.io/webaudiofont/examples/midiplayer.html [1]

Весь код занимает чуть менее 300 строк.

Автор: musicriffstudio

Источник [4]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/277306

Ссылки в тексте:

[1] https://surikov.github.io/webaudiofont/examples/midiplayer.html: https://surikov.github.io/webaudiofont/examples/midiplayer.html

[2] https://github.com/nfroidure/MIDIFile: https://github.com/nfroidure/MIDIFile

[3] WebAudioFont: https://github.com/surikov/webaudiofont

[4] Источник: https://habrahabr.ru/post/353036/?utm_source=habrahabr&utm_medium=rss&utm_campaign=353036