我正在尝试制作一个慢慢提升速度的节拍器,让我可以在不必停止播放的情况下完成手持式节拍器。我正在使用一个循环来播放每个小节,我正在尝试使用document.getElementById
和addEventListener
来停止按钮,以便在循环的每次传递中查找停止按钮的单击。使用console.log
,我可以看到停止按钮的每次点击都会显示,但是当我尝试使用source.noteOff(context.currentTime)
停止节拍循环时,我什么都没得到。任何有正确方向的建议或观点都将受到赞赏。
html是:
<html>
<script type="text/javascript" src="file:///Users/katri/rails_projects/metronome/metronome2.js"></script>
<script type="text/javascript" src="file:///Users/katri/rails_projects/metronome/buffer-loader.js"></script>
<input type="button" onClick="startLoop();" value="Play Loop!">
<input type="button" id="stop" value="Stop Loop!">
</html>
并且有问题的javascript是:
var startTime = context.currentTime;
var tempo = 80; // BPM (beats per minute)
var eighthNoteTime = (60 / tempo) / 2;
var totalTime = startTime;
for (var bar = 0; bar < 2; bar++) {
document.getElementById('stop').addEventListener('click', function() {
source.noteOff(context.currentTime);
});
eighthNoteTime = (60 / tempo) / 2;
// Play the bass (kick) drum on beats 1, 3, 4, 5 & 7
playSound(kick, totalTime);
playSound(kick, totalTime + 1 * eighthNoteTime);
playSound(kick, totalTime + 3 * eighthNoteTime);
playSound(kick, totalTime + 4 * eighthNoteTime);
playSound(kick, totalTime + 5 * eighthNoteTime);
playSound(kick, totalTime + 7 * eighthNoteTime);
// Play the snare drum on beats 3, 7
playSound(snare, totalTime + 2 * eighthNoteTime);
playSound(snare, totalTime + 6 * eighthNoteTime);
totalTime = totalTime + 8 * eighthNoteTime;
tempo = tempo+5;
}
}
function playSound(soundIndex, time) {
var source = context.createBufferSource();
source.buffer = bufferLoader.bufferList[soundIndex];
source.connect(context.destination);
source.noteOn(time);
}
答案 0 :(得分:1)
你不能直接采用这种方法,因为你的一般方法是一次安排一个测量值的节拍,当你这样做时,你忘记了BufferSourceNode对象(即,你是不保持对它们的引用 - 新创建的对象在playSound()的末尾超出范围。这是一种方便播放即发声的方法,但它对您的应用程序来说并不是一个好兆头。你可以做以下两件事之一:
1)采取更及时的方法来安排节拍,所以你没有一个完整的措施值得缓和。请阅读我在年初编写的关于Web Audio中的日程安排的文章:http://www.html5rocks.com/en/tutorials/audio/scheduling/。
2)保持指向缓冲区源节点的指针,以便你可以断开它们,或者(相当容易)连接()它们通过一个你可以静音的增益节点(当你点击“停止”时设置.gain.value为0)。我认为你错过了一堆代码,也是为了提高速度并且不仅仅是两个措施,对吧?这将开始变得有点混乱,因为你当然希望我的文章中详细介绍相同的方法 - 你需要决定何时放入更多的事件。
希望这有帮助!