使用getElementById和addEventListener停止Web音频鼓循环

时间:2013-06-10 02:36:59

标签: javascript for-loop getelementbyid addeventlistener web-audio

我正在尝试制作一个慢慢提升速度的节拍器,让我可以在不必停止播放的情况下完成手持式节拍器。我正在使用一个循环来播放每个小节,我正在尝试使用document.getElementByIdaddEventListener来停止按钮,以便在循环的每次传递中查找停止按钮的单击。使用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);
    }

1 个答案:

答案 0 :(得分:1)

你不能直接采用这种方法,因为你的一般方法是一次安排一个测量值的节拍,当你这样做时,你忘记了BufferSourceNode对象(即,你是不保持对它们的引用 - 新创建的对象在playSound()的末尾超出范围。这是一种方便播放即发声的方法,但它对您的应用程序来说并不是一个好兆头。你可以做以下两件事之一:

1)采取更及时的方法来安排节拍,所以你没有一个完整的措施值得缓和。请阅读我在年初编写的关于Web Audio中的日程安排的文章:http://www.html5rocks.com/en/tutorials/audio/scheduling/

2)保持指向缓冲区源节点的指针,以便你可以断开它们,或者(相当容易)连接()它们通过一个你可以静音的增益节点(当你点击“停止”时设置.gain.value为0)。我认为你错过了一堆代码,也是为了提高速度并且不仅仅是两个措施,对吧?这将开始变得有点混乱,因为你当然希望我的文章中详细介绍相同的方法 - 你需要决定何时放入更多的事件。

希望这有帮助!