10

我正在尝试启动和停止声音。那行得通。但我无法再次启动声音。

我真的需要再制造一个振荡器吗?这似乎非常不直观。一定会有更好的办法。

这就是我所拥有的一切:

oscillator1.noteOn(0);
oscillator1.noteOff(0);

再次调用 noteOn 没有任何作用。为什么?超出了我的范围。

我还尝试将音量或在 Web Audio 人的上下文中设置为“增益”,等于零。但是由于某种原因,零增益会发出声音。什么增益值不会发出任何声音?

伙计,我不敢相信这是多么困难:/

4

2 回答 2

8

实际上,是的,您必须创建一个新的振荡器节点。API 的设计和优化可以与该模式一起使用。

Taoist 代码中的断开模式基本上是一种创建新振荡器的复杂方式(每次运行 oscOn 时都会这样做)。它永远不会在断开连接的旧振荡器上显式调用 noteOff,因此它可能仍在后台运行(不确定网络音频如何处理此问题),尽管由于它与音频链断开连接而听不见。因此,它可能会在后台堆叠正在运行并耗尽 CPU 的振荡器。

这是相同的代码,尽管正确使用了 noteOff()。http://codepen.io/Theodeus/pen/afgqk

这是相同的代码,虽然使用增益节点来控制振荡器,因此始终只使用相同的振荡器(尽管不建议这样做,最好为每个音符创建一个新的振荡器,我认为)http://codepen .io/Theodeus/pen/aKFje

编辑 2015 年 4 月
由于代码示例似乎在网络空间中丢失,这是我写的关于振荡器的教程,其中包含显示振荡器的一次性性质的代码示例。它与上面引用的代码并不完全相同,但它显示了相同的概念。http://codepen.io/Theodeus/blog/web-audio-synth-part-1-generating-sound - 它的要点是:

//This won't work. Can't call play twice.
var context = new AudioContext(),
    oscillator = context.createOscillator();

oscillator.connect(context.destination);
oscillator.start(context.currentTime);
oscillator.stop(context.currentTime + 0.5);
oscillator.start(context.currentTime + 1);
oscillator.stop(context.currentTime + 1.5);


//this will work!
var context = new AudioContext(),
    oscillator;

function playOscillator(startTime, endTime) {
    oscillator = context.createOscillator();
    oscillator.connect(context.destination);
    oscillator.start(startTime);
    oscillator.stop(endTime);
}

playOscillator(context.currentTime, context.currentTime + 0.5);
playOscillator(context.currentTime + 1, context.currentTime + 1.5);
于 2013-03-07T11:19:59.253 回答
3

您必须使用 .disconnect() 方法(除非规范最近发生了变化)。

我在这里写了这个:

http://en.wikiaudio.org/Web_Audio_API:Toggle_oscillator_on_and_off

编辑

当我只是想了解 Web Audio API 的工作原理时,这个响应是旧的。您不需要使用断开连接。

于 2013-03-07T00:50:31.387 回答