Start · Sprachen · JavaScript · Referenz · AnalyserNode.getByteFrequencyData()

AnalyserNode.getByteFrequencyData()

Methode

Kopiert die aktuellen Frequenzdaten (Spektrum) des <code>AnalyserNode</code> als Byte-Werte von 0–255 in ein übergebenes <code>Uint8Array</code>.

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

Signatur

AnalyserNode.prototype.getByteFrequencyData(array)

Beschreibung

getByteFrequencyData() liefert eine Momentaufnahme des Frequenzspektrums des Audiosignals, das gerade durch den AnalyserNode läuft. Intern wird eine schnelle Fourier-Transformation (FFT) berechnet. Jeder Eintrag im Array steht für einen Frequenzbereich („Bin“), der Wert ist die Lautstärke in diesem Bereich, auf 0–255 abgebildet.

Typische Einsatzzwecke sind Audio-Visualisierungen (Balken-Equalizer, Spektrumanzeigen), Pegelanzeigen und einfache Klanganalysen, etwa ob Bässe oder Höhen gerade dominieren. Normalerweise ruft man die Methode in einer requestAnimationFrame-Schleife auf und zeichnet das Ergebnis auf ein <canvas>.

Das Array sollte analyser.frequencyBinCount Einträge haben (entspricht fftSize / 2). Bin i deckt ungefähr die Frequenz i * sampleRate / fftSize ab. Die Umrechnung der dB-Werte in Bytes hängt von minDecibels und maxDecibels ab: Werte unter minDecibels ergeben 0, Werte über maxDecibels ergeben 255. Mit smoothingTimeConstant werden die Werte zusätzlich über die Zeit geglättet.

Brauchst du mehr Genauigkeit, nimm getFloatFrequencyData(), das die Werte direkt in Dezibel als Float32Array liefert.

Parameter

Name Typ Default Beschreibung
$array Pflicht Uint8Array Ziel-Array, in das die Frequenzdaten geschrieben werden. Ist es länger als frequencyBinCount, bleiben die überzähligen Einträge unverändert. Ist es kürzer, werden die überzähligen Bins verworfen.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Die Daten werden direkt in das übergebene Array geschrieben.

Beispiele

Einmalige Spektrum-Momentaufnahme eines Oszillators

const ctx = new AudioContext();
const osc = ctx.createOscillator();
const analyser = ctx.createAnalyser();
analyser.fftSize = 2048;

osc.frequency.value = 440; // Kammerton A
osc.connect(analyser).connect(ctx.destination);
osc.start();

const data = new Uint8Array(analyser.frequencyBinCount);

setTimeout(() => {
  analyser.getByteFrequencyData(data);
  // Bin mit dem höchsten Wert suchen
  let maxIndex = 0;
  data.forEach((v, i) => { if (v > data[maxIndex]) maxIndex = i; });
  const hz = maxIndex * ctx.sampleRate / analyser.fftSize;
  console.log(`Stärkste Frequenz: ca. ${Math.round(hz)} Hz`);
  osc.stop();
}, 500);
Stärkste Frequenz: ca. 445 Hz (je nach sampleRate leicht abweichend)

Balken-Visualisierung auf einem Canvas

const canvas = document.querySelector('canvas');
const g = canvas.getContext('2d');
const audioEl = document.querySelector('audio');

const ctx = new AudioContext();
const source = ctx.createMediaElementSource(audioEl);
const analyser = ctx.createAnalyser();
analyser.fftSize = 256;
analyser.smoothingTimeConstant = 0.8;
source.connect(analyser).connect(ctx.destination);

const data = new Uint8Array(analyser.frequencyBinCount);

const draw = () => {
  requestAnimationFrame(draw);
  analyser.getByteFrequencyData(data);

  g.fillStyle = '#111';
  g.fillRect(0, 0, canvas.width, canvas.height);

  const barWidth = canvas.width / data.length;
  data.forEach((value, i) => {
    const h = (value / 255) * canvas.height;
    g.fillStyle = `hsl(${(i / data.length) * 300}, 80%, 50%)`;
    g.fillRect(i * barWidth, canvas.height - h, barWidth - 1, h);
  });
};

audioEl.addEventListener('play', async () => {
  await ctx.resume(); // Autoplay-Richtlinie
  draw();
});

Mikrofonpegel als einfacher Lautstärkewert

const startMeter = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const ctx = new AudioContext();
  const analyser = ctx.createAnalyser();
  analyser.fftSize = 512;
  ctx.createMediaStreamSource(stream).connect(analyser);

  const data = new Uint8Array(analyser.frequencyBinCount);
  setInterval(() => {
    analyser.getByteFrequencyData(data);
    const avg = data.reduce((sum, v) => sum + v, 0) / data.length;
    console.log(`Pegel: ${Math.round((avg / 255) * 100)} %`);
  }, 250);
};

document.querySelector('#start').addEventListener('click', startMeter);
Pegel: 12 % Pegel: 37 % …

// Wichtig · Fallstricke

  • Autoplay-Richtlinie: Ein AudioContext startet in vielen Browsern im Zustand suspended. Solange er nicht per Nutzeraktion mit ctx.resume() gestartet wurde, bestehen die Daten nur aus Nullen.
  • Array wiederverwenden: Lege das Uint8Array einmal an und nicht in jedem Frame neu. Sonst erzeugst du unnötige Arbeit für die Speicherbereinigung.
  • Nur Nullen trotz Ton? Prüfe, ob die Quelle wirklich mit dem Analyser verbunden ist. Bei createMediaElementSource mit Medien von fremden Servern ohne passende CORS-Header gibt der Browser aus Sicherheitsgründen nur Stille aus. Dann hilft crossorigin="anonymous" am <audio>-Element zusammen mit korrekten CORS-Headern auf dem Server.
  • Auflösung: Byte-Werte sind grob (256 Stufen) und hängen von minDecibels und maxDecibels ab. Für genaue Messungen ist getFloatFrequencyData() besser.
  • Folgen zwei Aufrufe innerhalb desselben Render-Quantums (128 Samples) aufeinander, liefern sie dieselben Daten.
  • Die Frequenzachse ist linear. Für eine gehörrichtige Darstellung solltest du die Bins logarithmisch gruppieren.
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Sehr alte Safari-Versionen brauchten webkitAudioContext.