4

我正在尝试了解 Web Audio API 计时和调度方法。

但是我仍然没有完全理解振荡器节点的stop()方法。

在这里,我正在尝试安排以 120 BPM 的速度播放 4 个振荡器。

但似乎只要该stop()方法在发布时间开始,它就会停止所有振荡器。

这是代码:

var context = new webkitAudioContext();
var now = context.currentTime;
var tempo = 120;
var releaseTime = 0.5;
var secondsPerBeat = 60.0 / tempo;

for(var i = 0; i < 4; i++){
    var now = context.currentTime;
    var osc = context.createOscillator();
    osc.connect(context.destination);
    osc.start(now + (i*secondsPerBeat));
    var now = context.currentTime;
    osc.stop(now + releaseTime);
}

为什么会发生这种情况,我该如何防止这种情况发生?

谢谢

4

2 回答 2

2

首先,关于 Javascript:Js 中没有块作用域,因此将所有 vars 定义放在当前执行上下文的开头可能会更清楚。
其次,你确实会延迟开始你的声音,但同时停止它们,这不是你想要的。
第三,在 for 循环中 currentTime 几乎是相同的:你不能依赖 for 循环来引起延迟。

var context = new webkitAudioContext();
var tempo = 120;
var releaseTime = 0.5;
var secondsPerBeat = 60.0 / tempo;

var now = context.currentTime;
var i = 0, startTime=0, osc = null;

for(i = 0; i < 4; i++) {
    startTime = now + (i*secondsPerBeat) ;
    osc = context.createOscillator();
    osc.connect(context.destination);
    osc.start();
    osc.stop(startTime + releaseTime);
} 

很快你就会想写一个函数来创建你的振荡器来进一步清理代码。

编辑:关于对象的生命周期,最好查看规格:
https
://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html 查看 4.2.3。终身部分。

总结一下:如果播放或连接到引用的上下文,他们将生存,否则死亡。

您可以:
- 保持相同的上下文,并将 4 个振荡器存储在一个数组中,以便在需要时启动/停止它们。
- 或者每次都重新创建一个新的上下文 + 新的振荡器。

(但是您不能在相同的上下文中继续创建新的振荡器,否则它们会堆积起来,因为它们仍然是连接的,并且使用了太多的内存)。

于 2013-07-12T09:15:14.330 回答
1

我也遇到了类似的问题。我发现您需要同时使用stop() 每个 disconnect()振荡器(或其他缓冲区生成节点类型)实例,否则实例将持续存在并干扰任何新实例的播放。

于 2016-11-25T23:56:40.310 回答