- PVSM.RU - https://www.pvsm.ru -
Регулярно появляются статьи о создании кода Javascript который издаёт звуки в браузере. В них объясняется чем частота ноты До отличается от частоты ноты Ля, примеры кода исправно издают «бип-бип».
Сделаем что-то подобное, но с результатом больше похожим на музыку. И относительно наглядной нотацией в духе ABC [1], примерно вот так:
Запустить код и прослушать можно здесь:
https://jsbin.com/nosojaz/edit?html,output [2]
Для воспроизведения используется технология WebAudioFont [3].
Скрипты иснструментов берутся непосредственно из проекта на GitHub [4]
Ноты с длительностью забиваются в массив, каждый элемент которого это функция вида
function bass(pitch, duration) {
return {
preset : _tone_Rubber_32Bass000079_461_460_45127,
pitch : pitch,
duration : duration
};
}
т.е. просто возврат объекта содержащего пресет (инструмент, если в терминах WebAudioFont [3]), высоту и длительность ноты.
Для наглядности высоту будем задавать в заранее заданных константах (var C = 0; var Cs= 1; var D = 2; и т.д.), а длительность — в долях от полной ноты.
Естественно, для ударных высота с длительностью не имеют смысла и поэтому задаются одинаковыми значениями.
Для вывода звука перебираем массив в цикле и ставим каждый пресет в очередь воспроизведения:
function beats(notes) {
for (var n = 0; n < notes.length; n++) {
var beat = notes[n];
for (var i = 0; i < beat.length; i++) {
if (beat[i]) {
player.queueWaveTable(audioContext
, audioContext.destination
, beat[i].preset
, startTime + n * beatLen
, beat[i].pitch
, beat[i].duration);
}
}
}
}
Отправляем массив в плеер бесконечно с определённым интервалом:
setInterval(function () {
if (audioContext.currentTime > startTime - 1 / 4 * N) {
nextPiece();
startTime = startTime + pieceLen;
}
}, 20);
После каждой отправки увеличиваем переменную startTime, в которой хранится время начала текущего куска.
Предупреждение: в современных браузерах при переводе фокуса в другое окно функции setTimeout и setInterval принудительно замедляются и мелодия будет «заедать».
Всё примерно то же самое, но нот побольше и инструменты воспроизводятся каждый через собственный GainNode для корректировки уровня громкости:
Запустить и прослушать пример можно тут: https://jsfiddle.net/sss1024/c53Lwete/2/ [5]
В JSFiddle, в отличии от JSBin, можно ограничиться чистым JS-кодом без HTML, а скрипты инструментов и плеера WebAudioFont [3] указать в левой части редактора в разделе External Resources.
Предупреждение для начинающих гитаристов: если в музыкальном магазине проверяете гитару перед покупкой и машинально начинаете наигрывать «Дым над водой» — сразу взимается штраф 150 руб.
Примеры работаеют и в мобильных браузерах, но редактировать код на маленьких экранах телефонов не очень удобно.
Автор: musicriffstudio
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/206392
Ссылки в тексте:
[1] ABC: https://ru.wikipedia.org/wiki/ABC_(%D0%BD%D0%BE%D1%82%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C)
[2] https://jsbin.com/nosojaz/edit?html,output: https://jsbin.com/nosojaz/edit?html,output
[3] WebAudioFont: https://habrahabr.ru/post/313886/
[4] проекта на GitHub: https://github.com/surikov/webaudiofont
[5] https://jsfiddle.net/sss1024/c53Lwete/2/: https://jsfiddle.net/sss1024/c53Lwete/2/
[6] Источник: https://habrahabr.ru/post/314472/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.