2016-06-08 4 views
0

Ich versuche, Oszillator spielen zu machen, wenn die Maus auf Leinwand ist und zu stoppen, wenn es nicht ist. Doch mit aktuellem Code, es funktioniert nur einmal nach dem Laden Seite, wenn die Maus auf Leinwand zweiten Zeitfehler ist auftritt:Neustart Oszillator in 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(); 
} 

Wie Oszillator neu gestartet werden? Vielen Dank.

Antwort

1

Sie müssten jedes Mal ein Oscillator-Objekt erstellen, da die OscillatorNodes nicht wiederverwendbar sind. Beispiel:

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(); 
} 

finden Sie in diesem excellent blog post für mehr Orientierung.

+1

@ K3N in der Tat, danke, ich habe das nur vom OP kopiert. –

+0

@digeridoo Bitte beachten Sie, dass Sie diese Antwort als korrekt markieren (indem Sie auf das graue Häkchen oben links in dieser Antwort klicken), wenn Ihre Bedenken berücksichtigt wurden. –

0

Ein einfacherer Weg ist, den Oszillator zu starten und an einen Verstärkungsknoten anzuschließen, den Sie zwischen 0 und 1 modulieren, um zu bestimmen, ob der Oszillator ausgibt oder nicht.

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; 
} 

Sie können auch (und sollten) die Ramping. Außerdem können Sie die Verstärkung weiter modulieren (z. B. basierend auf der Mausposition innerhalb der Arbeitsfläche) und so weiter.

Ja, es wird mehr CPU-Auslastung verwenden (da der Oszillator immer läuft). Allerdings erhöhen Gewinnknoten von Werten bei 0 und multiplizieren nicht tatsächlich, sie spucken nur Nullenarrays aus.