2014-06-22 9 views
5

Ich erstelle Sounds mit Oszillator-Knoten und möchte eine Frequenzvisualisierung auf einer Leinwand zeichnen. Wenn der Oszillator spielt, sieht die Visualisierung so aus (Standard-Oszillator-Einstellungen, siehe Code unten). http://i58.tinypic.com/wtvwgz.pngWeb-Audio - Analysator Frequenzdaten nicht 0 während Stille

Nachdem der Oszillator aufgehört hat zu spielen (vollständige Stille!), Das ist, was ich bekomme. Das genaue Ergebnis ändert sich von Lauf zu Lauf, manchmal ändern sich die Werte nach dem Stopp sogar leicht. http://i62.tinypic.com/2duji81.png

Ich verstehe nicht, warum die Frequenzdaten für alle Bins nicht Null ist, wenn der Ton nicht spielt.

Getestet auf Firefox 30.0 und Eisen 34.0.1850.0 (Chrom)

Hier ist mein Beispielcode:

<!DOCTYPE html> 
<html> 
    <head> 
     <title></title> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <script type="text/javascript"> 
      window.onload = function() { 
       var ctx = document.getElementById("canvas").getContext("2d"); 
       var audioContext = new (window.AudioContext 
        || window.webkitAudioContext || window.mozAudioContext)(); 

       var analyser = audioContext.createAnalyser(); 
       analyser.fftSize = 512; 
       analyser.connect(audioContext.destination); 
       var frequencyBins = new Uint8Array(analyser.frequencyBinCount); 

       var osc = audioContext.createOscillator(); 
       osc.connect(analyser); 
       osc.start(audioContext.currentTime + 2); 
       osc.stop(audioContext.currentTime + 4); 

       var WIDTH = 512; 
       var HEIGHT = 100; 
       var value, h, w; 

       function draw() { 
        ctx.clearRect(0, 0, WIDTH, HEIGHT); 

        for (var i = 0; i < frequencyBins.length; i++) { 
         value = frequencyBins[i]; 
         h = HEIGHT * (value/255); 
         w = WIDTH/frequencyBins.length; 
         ctx.fillRect(i * w, HEIGHT - 1, w, -h); 
        } 
       }; 

       function animate() { 
        analyser.getByteFrequencyData(frequencyBins); 
        draw(); 
        requestAnimationFrame(animate); 
       } 

       requestAnimationFrame(animate); 
      }; 
     </script> 
    </head> 
    <body> 
     <canvas id="canvas" width="512" height="100"></canvas> 
    </body> 
</html> 
+1

Interessante Beobachtung. Das Visualisieren der Eingabedaten durch Ersetzen von "getByteFrequencyData" durch "getByteTimeDomainData" legt nahe, dass der Eingangspuffer für die Frequenzanalyse nach dem Stoppen des Oszillators tatsächlich nicht auf Null gesetzt wird. Auf der anderen Seite sieht das Frequenzdiagramm so aus, als ob die Zeitbereichsdaten in der Mitte abgeschnitten wären. Wenn ich auf meinem MacBook die osc-Zeit auf ungefähr 15s einstelle, sehe ich am Ende ein konstant abfallendes Frequenzdiagramm. Haben Sie das Verhalten mit anderen Eingabequellen verifiziert? –

+1

Interessant in der Tat. Ich habe mich gefragt, ob der Lärmpegel aufgehoben wurde. Ich habe Ihren Code in jsfiddle eingefügt und hinzugefügt den Wert minDecible geändert, so dass wir das Grundrauschen sehen können. Es scheint nicht so zu sein wie Lärm. http://jsfiddle.net/notthetup/7759c/2/ – notthetup

+0

Es scheint, wenn der Oszillator keine neuen Audiodaten mehr ausgibt, wird der letzte Datenrahmen beibehalten und verwendet, um die Zeit- und Frequenzbereichsdaten durch den Analyseknoten zurückzugeben. http://jsfiddle.net/notthetup/7759c/3/ – notthetup

Antwort

2

Ich fand eine Lösung, die für mich funktioniert.

Anstatt den Oszillator direkt an den Analysator anzuschließen, gebe ich die Frequenzen zuerst durch einen Hochpassfilter. Es scheint, dass der Wert für die Grenzfrequenz beliebig niedrig eingestellt werden kann, solange er nicht 0 ist. Selbst bei einem Cutoff von 0,00000001 ist die Visualisierung während der Stille leer.

http://jsfiddle.net/a2ZL9/3/

var analyser = audioContext.createAnalyser(); 
analyser.fftSize = 512; 
analyser.connect(audioContext.destination); 
var frequencyBins = new Uint8Array(analyser.frequencyBinCount); 

var filter = audioContext.createBiquadFilter(); 
filter.type = "highpass"; 
filter.frequency.value = 0.0001; 
filter.connect(analyser); 

var osc = audioContext.createOscillator(); 
osc.connect(filter); 
osc.start(audioContext.currentTime + 2); 
osc.stop(audioContext.currentTime + 4); 
+1

Das Ergebnis meines Analysators während der Stille war ein wenig anders - es war eine konstante Größe über alle Frequenzen. Trotzdem hat diese Methode es für mich gelöst (danke), obwohl ich immer noch nicht verstehe, wie die Anwendung eines Hochpassfilters geholfen hat – Vanlalhriata

2

Es ist kein Grundrauschen. Es passiert auch mit Audiopuffern. Es ist ein Fehler.

0

hatte ich das gleiche Problem. Es war analyserNode.smoothingTimeConstant, es hat standardmäßig einen sehr hohen Wert. Versuchen Sie es mit analyserNode.smoothingTimeConstant = 0; // oder 0.2 Es wird es beheben