(API веб-аудио) Ошибка узла осциллятора: нельзя запускать запуск более одного раза

Когда я включу свой генератор, остановите его, а затем снова запустите; Я получаю следующую ошибку:

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/

Ответ 1

Лучше всего было бы запустить осцилляторNode один раз и подключить/отключить осцилляторNode из графика, когда это необходимо, то есть:

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)

Ответ 2

Лучшее решение, которое я нашел до сих пор, заключается в том, чтобы сохранить audioContext при воссоздании oscillator каждый раз, когда вам нужно его использовать.

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

FYI. Вы можете создавать только 6 объектов audioContext каждого audioContext страницы браузера (или, по крайней мере, для моего оборудования):

Uncaught NotSupportedError: Failed to construct 'AudioContext': The number of hardware contexts provided (6) is greater than or equal to the maximum bound (6).

Ответ 3

Из того, что я знаю, осциллятор может быть воспроизведен только один раз, по причинам, связанным с точностью, и никогда еще никто не объяснил. Кто бы ни выбрал эту модель "играть только один раз", вероятно, будет хорошей практикой использовать настройку с нулевой громкостью, чтобы вставить тишину в середину последовательности. В конце концов, это действительно единственная альтернатива методу отключения и восстановления.