实际上,是的,您必须创建一个新的振荡器节点。 API 经过设计和优化以适应该模式。
道家代码中的断开模式基本上是一种创建新振荡器的复杂方式(每次运行 oscOn 时都会这样做)。它从未在断开连接的旧振荡器上显式调用 noteOff,因此它可能仍在后台运行(不确定网络音频如何处理此问题),但由于它与音频链断开连接所以听不到它的声音。因此,它可能会在后台堆叠正在运行并耗尽 CPU 的振荡器。
Here's the same code, though using noteOff() properly. http://codepen.io/Theodeus/pen/afgqk
Here's the same code, though adapted using the gain node to control the oscillator and thus only using the same oscillator all the time (though this is not recommended, better to create a new oscillator for each note, I think) http://codepen.io/Theodeus/pen/aKFje
2015年4月编辑
由于代码示例似乎在网络空间中丢失,因此这是我编写的关于振荡器的教程,其中包含显示振荡器一次性性质的代码示例。它与上面引用的代码并不完全相同,但它显示了相同的概念。http://codepen.io/Theodeus/blog/web-audio-synth-part-1-generate-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);