1

我正在尝试制作一个可以慢慢提高速度的节拍器,让我可以在不必停止演奏来打开我的手持节拍器的情况下进行锻炼。我正在使用一个循环来播放每个小节,并试图让一个停止按钮工作,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);
    }
4

1 回答 1

1

您不能真正直接采用这种方法,因为您的一般方法是一次安排一个度量值的节拍,当您这样做时,您忘记了 BufferSourceNode 对象(即,您没有维护引用对他们来说——新创建的对象在 playSound() 结束时超出范围。这是一种即发即弃声音播放的便捷方式,但对您的应用程序来说并不是一个好兆头。您可以执行以下两项操作之一:

1) 采用更及时的方法来安排节拍,这样就不会缓冲整个小节的节拍。去阅读我年初写的关于网络音频调度的文章:http: //www.html5rocks.com/en/tutorials/audio/scheduling/

2)维护指向缓冲区源节点的指针,以便您可以断开它们,或者(相当容易)通过增益节点连接()它们,当您点击“停止”时,您可以静音(将.gain.value设置为0)。我想您还缺少一堆代码,以继续提高速度并播放不止两个措施,对吗?这将开始变得有点混乱,因为您当然想要我的文章中详述的相同类型的方法 - 您需要决定何时放入更多事件。

希望这可以帮助!

于 2013-06-11T17:45:08.747 回答