2016-06-08 2 views
0

Я пытаюсь заставить осциллятор играть, когда мышь на холсте, и остановитесь, когда это не так. Тем не менее, с текущим кодом, он работает только один раз после загрузки страницы, при наведении курсора мыши на холст ошибке второго раза происходит:Перезапустить осциллятор в javascript

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

var ac = new window.AudioContext() || new window.webkitAudioContext(); 
var osc = ac.createOscillator(); 
var canvas1 = document.getElementById("canvas1"); 
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

function playosc() { 
    osc.frequency.value = 440; 
    osc.connect(ac.destination); 
    osc.start(); 
} 

function stoposc() { 
    osc.stop(); 
} 

Как перезапустить генератор? Благодарю.

ответ

1

Вам нужно будет создавать объект Oscillator каждый раз, поскольку OscillatorNodes не могут использоваться повторно. Пример:

var canvas1 = document.getElementById("canvas1"); 
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

var ac = new window.AudioContext() || new window.webkitAudioContext(); 
var osc; 

function playosc() { 
    osc = ac.createOscillator() 
    osc.frequency.value = 440; 
    osc.connect(ac.destination); 
    osc.start(); 
} 

function stoposc() { 
    osc.stop(); 
} 

Пожалуйста, обратитесь к этому excellent blog post для получения дополнительных указаний.

+1

@ K3N действительно, спасибо, я просто скопировал это из OP. –

+0

@digeridoo Пожалуйста, обратите внимание на правильность этого ответа (нажав на серый галочку в левом верхнем углу этого ответа), если это касается ваших проблем. –

0

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

var ac = new window.AudioContext() || new window.webkitAudioContext(); 
var osc = ac.createOscillator(); 
var gain = ac.createGain(); 
var canvas1 = document.getElementById("canvas1"); 
canvas1.addEventListener("mouseover", playosc); 
canvas1.addEventListener("mouseout", stoposc); 

gain.gain.value = 0; 
osc.connect(ac.gain); 
gain.connect(ac.destination); 
osc.start(); 

function playosc() { 
    osc.frequency.value = 440; 
    gain.gain.value = 1; 
} 

function stoposc() { 
    gain.gain.value = 0; 
} 

Вы также можете (и должны) использовать линейное изменение. Кроме того, вы можете модулировать усиление дальше (например, на основе положения мыши в холсте) и так далее.

Да, он будет использовать больше использования ЦП (поскольку генератор всегда работает). Однако набирайте узлы значений при 0 читах и ​​на самом деле не умножайте их, они просто выплевывают массивы нулей.