11

我已经按照本教程提出了该代码:

context = new AudioContext();
play(frequency) {
    const o = this.context.createOscillator();
    const g = this.context.createGain();
    o.connect(g);
    g.connect(this.context.destination);
    g.gain.exponentialRampToValueAtTime(
      0.00001, this.context.currentTime + 1
    );
    o.frequency.value = frequency;
    o.start(0);
  }

这样我可以通过传递值来播放教程表中的任何音符11752794

我决定创建一个音符数组,然后play在循环中调用我的函数,但它只是没有工作,因为所有音符只是一次播放而没有延迟。

你将如何按顺序演奏一系列音符?

我也在查看那篇文章,但仍然无法弄清楚如何使上面的代码适应它。

4

2 回答 2

6

您可以在播放功能中使用附加参数时间按顺序播放音符。这样您可以控制序列中每个音符的开始时间和结束时间。

  var context = new AudioContext();

  var notes = [1175, 2794];
  var duration = 1;
  var interval = 2;

  function play(frequency, time) {
    var o = context.createOscillator();
    var g = context.createGain();
    o.connect(g);
    g.connect(context.destination);
    g.gain.exponentialRampToValueAtTime(
      0.00001, context.currentTime + duration + time
    );
    o.frequency.value = frequency;
    o.start(time);
  }

  for (var i = 0; i < notes.length; i++) {
    play(notes[i], i * interval);
  }

但是,如果您需要更精确/更强大的调度器,您可以使用WAAClock.js 之类的库或从 Chris Wilson节拍器中获取灵感来构建自己的。

于 2017-09-18T08:26:33.430 回答
0

发生这种情况是因为您正在执行的操作在 JavaScript 中是非阻塞的。在这些之间强制延迟的最直接方法是使用 setInterval 和 setTimeout。我在这篇关于使用 AudioContext的文章中找到了使用示例。

MDN 上的setInterval MDN 上的 setTimeout

不同之处在于 setTimeout 在延迟后执行一次,而 setInterval 重复执行,直到您告诉它停止。

于 2017-09-15T15:03:08.433 回答