Start · Sprachen · JavaScript · Referenz · AnalyserNode.frequencyBinCount

AnalyserNode.frequencyBinCount

Eigenschaft

Schreibgeschützte Ganzzahl mit der Anzahl der Frequenzbänder (Bins) eines <code>AnalyserNode</code>, immer die Hälfte von <code>fftSize</code>.

seit JavaScript Baseline: alle modernen Browser (Web Audio API) Kategorie: webapi

Signatur

AnalyserNode.frequencyBinCount

Beschreibung

frequencyBinCount gibt an, wie viele Datenpunkte die Frequenzanalyse eines AnalyserNode liefert. Der Wert ist immer genau die Hälfte von fftSize. Eine FFT mit N Abtastwerten liefert zwar N komplexe Werte, sie sind aber symmetrisch. Deshalb sind nur die ersten N/2 Werte (von 0 Hz bis zur Nyquist-Frequenz sampleRate / 2) aussagekräftig.

In der Praxis bestimmt die Eigenschaft die Größe der typisierten Arrays, die man an getByteFrequencyData() oder getFloatFrequencyData() übergibt. Bei Visualisierungen wie Spektrum-Balken oder Equalizer-Anzeigen legt sie außerdem fest, über wie viele Werte man iteriert.

Jeder Bin deckt einen Frequenzbereich von sampleRate / fftSize Hertz ab. Bin i entspricht also etwa der Frequenz i * sampleRate / fftSize. Mit einem größeren fftSize steigt die Frequenzauflösung, dafür sinkt die zeitliche Auflösung und der Rechenaufwand wächst.

Rückgabewert

Typ
number
Beschreibung
Eine vorzeichenlose Ganzzahl (unsigned long), gleich fftSize / 2. Beim Standardwert fftSize = 2048 ist das 1024.

Beispiele

Wert auslesen und Zusammenhang mit fftSize prüfen

const audioCtx = new AudioContext();
const analyser = audioCtx.createAnalyser();

console.log(analyser.fftSize);           // Standardwert
console.log(analyser.frequencyBinCount); // halbe fftSize

analyser.fftSize = 256;
console.log(analyser.frequencyBinCount);
2048 1024 128

Puffer für Frequenzdaten richtig dimensionieren

const audioCtx = new AudioContext();
const osc = audioCtx.createOscillator();
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 512;

osc.connect(analyser).connect(audioCtx.destination);
osc.start();

// Array exakt in der Größe von frequencyBinCount anlegen
const data = new Uint8Array(analyser.frequencyBinCount);

setTimeout(() => {
  analyser.getByteFrequencyData(data);
  console.log(`Bins: ${data.length}`);
  osc.stop();
}, 200);
Bins: 256

Spektrum-Balken auf einem Canvas zeichnen

const canvas = document.querySelector('canvas');
const ctx2d = canvas.getContext('2d');

const start = async () => {
  const audioCtx = new AudioContext();
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const source = audioCtx.createMediaStreamSource(stream);
  const analyser = audioCtx.createAnalyser();
  analyser.fftSize = 256;
  source.connect(analyser);

  const binCount = analyser.frequencyBinCount;
  const data = new Uint8Array(binCount);
  const barWidth = canvas.width / binCount;

  const draw = () => {
    requestAnimationFrame(draw);
    analyser.getByteFrequencyData(data);
    ctx2d.clearRect(0, 0, canvas.width, canvas.height);
    data.forEach((value, i) => {
      const h = (value / 255) * canvas.height;
      ctx2d.fillStyle = `hsl(${(i / binCount) * 300}, 80%, 50%)`;
      ctx2d.fillRect(i * barWidth, canvas.height - h, barWidth - 1, h);
    });
  };
  draw();
};

document.querySelector('button').addEventListener('click', start);

Frequenz eines Bins berechnen

const audioCtx = new AudioContext({ sampleRate: 48000 });
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;

const hzPerBin = audioCtx.sampleRate / analyser.fftSize;
const binToHz = (i) => i * hzPerBin;

console.log(`Auflösung: ${hzPerBin.toFixed(2)} Hz pro Bin`);
console.log(`Letzter Bin: ${binToHz(analyser.frequencyBinCount - 1).toFixed(0)} Hz`);
Auflösung: 23.44 Hz pro Bin Letzter Bin: 23977 Hz

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung an frequencyBinCount wird im nicht-strikten Modus stillschweigend ignoriert und löst im Strict Mode einen TypeError aus. Um den Wert zu ändern, setzt man fftSize (Zweierpotenz zwischen 32 und 32768).
  • Puffergröße nach Änderung anpassen: Wenn fftSize zur Laufzeit geändert wird, muss das Daten-Array neu angelegt werden. Ist es zu groß, bleiben die überzähligen Einträge unverändert. Ist es zu klein, werden die restlichen Werte abgeschnitten. In keinem der beiden Fälle gibt es eine Fehlermeldung.
  • Nicht verwechseln: Für getByteTimeDomainData() bzw. getFloatTimeDomainData() (Wellenform) ist die passende Größe fftSize, nicht frequencyBinCount.
  • Die Bins sind linear über die Frequenz verteilt. Das Gehör nimmt Tonhöhen aber logarithmisch wahr, deshalb wirken die tiefen Frequenzen in einer linearen Darstellung gestaucht.
  • Browser starten einen AudioContext oft im Zustand suspended, bis eine Nutzerinteraktion erfolgt (Autoplay-Richtlinie). Solange er pausiert ist, bleiben die Frequenzdaten bei Null.