webaudiofont
Version:
Soundfonts for web. About of 2000 musical instruments. GM MIDI compatible.
291 lines (284 loc) • 11.4 kB
HTML
<html>
<head>
<!--
<script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
-->
<script src='../npm/dist/WebAudioFontPlayer.js'></script>
<script src='MIDIFile.js'></script>
</head>
<body>
<div id='cntls'>
<p><input type="file" id="filesinput" name="filesarr[]" />v1.16</p>
<ul>
<li>Dave Brubeck Take Five - <a href='midi/brubeck_dave-take_five.mid'>download</a> | <a href='#' onclick='handleExample("midi/brubeck_dave-take_five.mid")'>open</a></li>
<li>Jerry Lee Lewis - Great Balls of Fire - <a href='midi/Jerry_Lee_Lewis_-_Great_Balls_of_Fire.mid'>download</a> | <a href='#' onclick='handleExample("midi/Jerry_Lee_Lewis_-_Great_Balls_of_Fire.mid")'>open</a></li>
<li>Mission: Impossible - <a href='midi/Movie_Themes_-_Mission_Impossible.mid'>download</a> | <a href='#' onclick='handleExample("midi/Movie_Themes_-_Mission_Impossible.mid")'>open</a></li>
<li>Mozart Symphony No.40 p.1 - <a href='midi/sym40-1.mid'>download</a> | <a href='#' onclick='handleExample("midi/sym40-1.mid")'>open</a></li>
<li>Nirvana - Come As You Are - <a href='midi/Nirvana_-_Come_As_You_Are.mid'>download</a> | <a href='#' onclick='handleExample("midi/Nirvana_-_Come_As_You_Are.mid")'>open</a></li>
<li>Pirates of the Caribbean - <a href='midi/Hans_Zimmer_-_Pirates_Of_The_Caribbean.mid'>download</a> | <a href='#' onclick='handleExample("midi/Hans_Zimmer_-_Pirates_Of_The_Caribbean.mid")'>open</a></li>
<li>Psycho - <a href='midi/Movie_Themes_-_Psycho.mid'>download</a> | <a href='#' onclick='handleExample("midi/Movie_Themes_-_Psycho.mid")'>open</a></li>
<li>The Good, the Bad and the Ugly - <a href='midi/GoodTheBadAndTheUgly.mid'>download</a> | <a href='#' onclick='handleExample("midi/GoodTheBadAndTheUgly.mid")'>open</a></li>
<li>The Phantom of the Opera - <a href='midi/Movie_Themes_-_Phantom_Of_The_Opera.mid'>download</a> | <a href='#' onclick='handleExample("midi/Movie_Themes_-_Phantom_Of_The_Opera.mid")'>open</a></li>
<li>U96 Das Boot - <a href='midi/DasBoot.mid'>download</a> | <a href='#' onclick='handleExample("midi/DasBoot.mid")'>open</a></li>
</ul>
</div>
<hr />
<p><a href="https://surikov.github.io/webaudiofont/">source</a></p>
<script>
console.log('start');
var audioContext = null;
var player = null;
var reverberator = null;
var equalizer = null;
var songStart = 0;
var input = null;
var currentSongTime = 0;
var nextStepTime = 0;
var nextPositionTime = 0;
var loadedsong = null;
function go() {
document.getElementById('tmr').innerHTML = 'starting...';
try {
startPlay(loadedsong);
document.getElementById('tmr').innerHTML = 'playing...';
} catch (expt) {
document.getElementById('tmr').innerHTML = 'error ' + expt;
}
}
function startPlay(song) {
currentSongTime = 0;
songStart = audioContext.currentTime;
nextStepTime = audioContext.currentTime;
var stepDuration = 44 / 1000;
tick(song, stepDuration);
}
function tick(song, stepDuration) {
if (audioContext.currentTime > nextStepTime - stepDuration) {
sendNotes(song, songStart, currentSongTime, currentSongTime + stepDuration, audioContext, input, player);
currentSongTime = currentSongTime + stepDuration;
nextStepTime = nextStepTime + stepDuration;
if (currentSongTime > song.duration) {
currentSongTime = currentSongTime - song.duration;
sendNotes(song, songStart, 0, currentSongTime, audioContext, input, player);
songStart = songStart + song.duration;
}
}
if (nextPositionTime < audioContext.currentTime) {
var o = document.getElementById('position');
o.value = 100 * currentSongTime / song.duration;
document.getElementById('tmr').innerHTML = '' + Math.round(100 * currentSongTime / song.duration) + '%';
nextPositionTime = audioContext.currentTime + 3;
}
window.requestAnimationFrame(function (t) {
tick(song, stepDuration);
});
}
function sendNotes(song, songStart, start, end, audioContext, input, player) {
for (var t = 0; t < song.tracks.length; t++) {
var track = song.tracks[t];
for (var i = 0; i < track.notes.length; i++) {
if (track.notes[i].when >= start && track.notes[i].when < end) {
var when = songStart + track.notes[i].when;
var duration = track.notes[i].duration;
if (duration > 3) {
duration = 3;
}
var instr = track.info.variable;
var v = track.volume / 7;
player.queueWaveTable(audioContext, input, window[instr], when, track.notes[i].pitch, duration, v, track.notes[i].slides);
}
}
}
for (var b = 0; b < song.beats.length; b++) {
var beat = song.beats[b];
for (var i = 0; i < beat.notes.length; i++) {
if (beat.notes[i].when >= start && beat.notes[i].when < end) {
var when = songStart + beat.notes[i].when;
var duration = 1.5;
var instr = beat.info.variable;
var v = beat.volume / 2;
player.queueWaveTable(audioContext, input, window[instr], when, beat.n, duration, v);
}
}
}
}
function startLoad(song) {
console.log(song);
var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContextFunc();
player = new WebAudioFontPlayer();
equalizer = player.createChannel(audioContext);
reverberator = player.createReverberator(audioContext);
//input = reverberator.input;
input = equalizer.input;
equalizer.output.connect(reverberator.input);
reverberator.output.connect(audioContext.destination);
for (var i = 0; i < song.tracks.length; i++) {
var nn = player.loader.findInstrument(song.tracks[i].program);
var info = player.loader.instrumentInfo(nn);
song.tracks[i].info = info;
song.tracks[i].id = nn;
player.loader.startLoad(audioContext, info.url, info.variable);
}
for (var i = 0; i < song.beats.length; i++) {
var nn = player.loader.findDrum(song.beats[i].n);
var info = player.loader.drumInfo(nn);
song.beats[i].info = info;
song.beats[i].id = nn;
player.loader.startLoad(audioContext, info.url, info.variable);
}
player.loader.waitLoad(function () {
console.log('buildControls');
buildControls(song);
resetEqlualizer();
});
}
function resetEqlualizer(){
equalizer.band32.gain.setTargetAtTime(2,0,0.0001);
equalizer.band64.gain.setTargetAtTime(2,0,0.0001);
equalizer.band128.gain.setTargetAtTime(1,0,0.0001);
equalizer.band256.gain.setTargetAtTime(0,0,0.0001);
equalizer.band512.gain.setTargetAtTime(-1,0,0.0001);
equalizer.band1k.gain.setTargetAtTime(5,0,0.0001);
equalizer.band2k.gain.setTargetAtTime(4,0,0.0001);
equalizer.band4k.gain.setTargetAtTime(3,0,0.0001);
equalizer.band8k.gain.setTargetAtTime(-2,0,0.0001);
equalizer.band16k.gain.setTargetAtTime(2,0,0.0001);
}
function buildControls(song) {
audioContext.resume();
var o = document.getElementById('cntls');
var html = '<h2 id="wrng">Refresh browser page to load another song</h2>';
html = html + '<p id="tmr"><button onclick="go();">Play</button></p>';
html = html + '<p><input id="position" type="range" min="0" max="100" value="0" step="1" /></p>';
html = html + '<h3>Channels</h3>';
for (var i = 0; i < song.tracks.length; i++) {
var v = 100 * song.tracks[i].volume;
html = html + '<p>' + chooserIns(song.tracks[i].id, i) + '<input id="channel' + i + '" type="range" min="0" max="100" value="' + v + '" step="1" /></p>';
}
html = html + '<h3>Drums</h3>';
for (var i = 0; i < song.beats.length; i++) {
var v = 100 * song.beats[i].volume;
html = html + '<p>' + chooserDrum(song.beats[i].id, i) + '<input id="drum' + i + '" type="range" min="0" max="100" value="' + v + '" step="1" /></p>';
}
o.innerHTML = html;
console.log('Loaded');
var pos = document.getElementById('position');
pos.oninput = function (e) {
if (loadedsong) {
player.cancelQueue(audioContext);
var next = song.duration * pos.value / 100;
songStart = songStart - (next - currentSongTime);
currentSongTime = next;
}
};
console.log('Tracks');
for (var i = 0; i < song.tracks.length; i++) {
setVolumeAction(i, song);
}
console.log('Drums');
for (var i = 0; i < song.beats.length; i++) {
setDrVolAction(i, song);
}
loadedsong = song;
}
function setVolumeAction(i, song) {
var vlm = document.getElementById('channel' + i);
vlm.oninput = function (e) {
player.cancelQueue(audioContext);
var v = vlm.value / 100;
if (v < 0.000001) {
v = 0.000001;
}
song.tracks[i].volume = v;
};
var sl = document.getElementById('selins' + i);
sl.onchange = function (e) {
var nn = sl.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;
song.tracks[i].id = nn;
});
};
}
function setDrVolAction(i, song) {
var vlm = document.getElementById('drum' + i);
vlm.oninput = function (e) {
player.cancelQueue(audioContext);
var v = vlm.value / 100;
if (v < 0.000001) {
v = 0.000001;
}
song.beats[i].volume = v;
};
var sl = document.getElementById('seldrm' + i);
sl.onchange = function (e) {
var nn = sl.value;
var info = player.loader.drumInfo(nn);
player.loader.startLoad(audioContext, info.url, info.variable);
player.loader.waitLoad(function () {
console.log('loaded');
song.beats[i].info = info;
song.beats[i].id = nn;
});
};
}
function chooserIns(n, track) {
var html = '<select id="selins' + track + '">';
for (var i = 0; i < player.loader.instrumentKeys().length; i++) {
var sel = '';
if (i == n) {
sel = ' selected';
}
html = html + '<option value="' + i + '"' + sel + '>' + i + ': ' + player.loader.instrumentInfo(i).title + '</option>';
}
html = html + '</select>';
return html;
}
function chooserDrum(n, beat) {
var html = '<select id="seldrm' + beat + '">';
for (var i = 0; i < player.loader.drumKeys().length; i++) {
var sel = '';
if (i == n) {
sel = ' selected';
}
html = html + '<option value="' + i + '"' + sel + '>' + i + ': ' + player.loader.drumInfo(i).title + '</option>';
}
html = html + '</select>';
return html;
}
function handleFileSelect(event) {
console.log(event);
var file = event.target.files[0];
console.log(file);
var fileReader = new FileReader();
fileReader.onload = function (progressEvent) {
console.log(progressEvent);
var arrayBuffer = progressEvent.target.result;
console.log(arrayBuffer);
var midiFile = new MIDIFile(arrayBuffer);
var song = midiFile.parseSong();
startLoad(song);
};
fileReader.readAsArrayBuffer(file);
}
function handleExample(path) {
console.log(path);
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("GET", path, true);
xmlHttpRequest.responseType = "arraybuffer";
xmlHttpRequest.onload = function (e) {
var arrayBuffer = xmlHttpRequest.response;
var midiFile = new MIDIFile(arrayBuffer);
var song = midiFile.parseSong();
startLoad(song);
};
xmlHttpRequest.send(null);
}
document.getElementById('filesinput').addEventListener('change', handleFileSelect, false);
</script>
</body>
</html>