我按照这篇文章中的指示制作了一个Javascript节拍器。它使用Web音频API,并且核心是
audioContext.currentTime
,用于精确计时。
我的版本可以在这个Plunker上找到,它是原版的极简化版本,由Chris Wilson制作,原版在这里。为了让我的版本工作正常,因为它使用实际的音频文件而不是通过振荡器合成声音,你需要下载Plunker和这个音频文件,将其放置在根文件夹中(它是一个节拍器“滴答”声音,但你也可以使用任何你想要的声音)。
如果没有用户最小化窗口,这个节拍器非常准确地运行得很好。但是一旦用户将窗口最小化,该节拍器就会立即出现严重的问题,我真的不明白这里的问题在哪里。
Javascript
var context, request, buffer;
var tempo = 120;
var tickTime;
function ticking() {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(tickTime);
}
function scheduler() {
while (tickTime < context.currentTime + 0.1) { //while there are notes to schedule, play the last scheduled note and advance the pointer
ticking();
tickTime += 60 / tempo;
}
}
function loadTick() {
request = new XMLHttpRequest(); //Asynchronous http request (you'll need a local server)
request.open('GET', 'tick.wav', true); //You need to download the file @ http://s000.tinyupload.com/index.php?file_id=89415137224761217947
request.responseType = 'arraybuffer';
request.onload = function () {
context.decodeAudioData(request.response, function (theBuffer) {
buffer = theBuffer;
});
};
request.send();
}
function start() {
tickTime = context.currentTime;
scheduleTimer = setInterval(function () {
scheduler();
}, 25);
}
window.onload = function () {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
context = new AudioContext();
loadTick();
start();
};