28

当我启动振荡器时,停止它,然后再启动它;我收到以下错误:

Uncaught InvalidStateError: Failed to execute 'start' on 'OscillatorNode': cannot call start more than once.

显然我可以gain用来“停止”音频,但这让我觉得这是一种糟糕的做法。在能够再次启动振荡器的同时停止振荡器的更有效方法是什么?

代码(jsfiddle

var ctx = new AudioContext();
var osc = ctx.createOscillator();

osc.frequency.value = 8000;

osc.connect(ctx.destination);

function startOsc(bool) {
    if(bool === undefined) bool = true;
    
    if(bool === true) {
        osc.start(ctx.currentTime);
    } else {
        osc.stop(ctx.currentTime);
    }
}

$(document).ready(function() {
    $("#start").click(function() {
       startOsc(); 
    });
    $("#stop").click(function() {
       startOsc(false); 
    });
});

当前解决方案(问题时):http: //jsfiddle.net/xbqbzgt2/2/

最终解决方案:http: //jsfiddle.net/xbqbzgt2/3/

4

3 回答 3

38

更好的方法是启动一次振荡器节点,并在需要时从图中连接/断开振荡器节点,即:

var ctx = new AudioContext();
var osc = ctx.createOscillator();   
osc.frequency.value = 8000;    
osc.start();    
$(document).ready(function() {
    $("#start").click(function() {
         osc.connect(ctx.destination);
    });
    $("#stop").click(function() {
         osc.disconnect(ctx.destination);
    });
});

这是如何在使 thermin 静音时完成静音(mozilla web audio api 文档)

于 2015-11-15T19:01:36.367 回答
10

到目前为止,我发现的最佳解决方案是在每次需要使用它audioContext的时候重新创建它时保持相同。oscillator

http://jsfiddle.net/xbqbzgt2/3/

audioContext仅供参考,每个浏览器页面生命周期(或至少每个我的硬件)只能创建 6 个对象:

Uncaught NotSupportedError: Failed to construct 'AudioContext': The number of hardware contexts provided (6) is greater than or equal to the maximum bound (6).
于 2015-08-24T13:00:43.757 回答
3

据我所知,振荡器只能播放一次,原因与精确度有关,而且从来没有人很好地解释过。决定使用这种“只播放一次”模式的人可能会认为使用零音量设置在序列中间插入静音是一种很好的做法。毕竟,它确实是断开连接并重新创建方法的唯一替代方法。

于 2019-08-13T23:26:41.310 回答