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

AnalyserNode.getFloatTimeDomainData()

Methode

Kopiert die aktuelle Wellenform (Zeitbereichsdaten) des Audiosignals als Gleitkommawerte zwischen -1 und 1 in ein übergebenes <code>Float32Array</code>.

seit JavaScript Baseline: alle modernen Browser (Safari ab 14.1) Kategorie: webapi

Signatur

AnalyserNode.prototype.getFloatTimeDomainData(array)

Beschreibung

Die Methode getFloatTimeDomainData() eines AnalyserNode liefert eine Momentaufnahme der aktuellen Wellenform. Jeder Eintrag im Zielarray ist ein Abtastwert (Sample) als Gleitkommazahl, normalerweise im Bereich -1.0 bis 1.0. Das ist genau das Format, in dem die Web Audio API intern rechnet. Es gibt also keinen Genauigkeitsverlust wie bei der 8-Bit-Variante getByteTimeDomainData().

Typische Einsatzzwecke sind Oszilloskop-Anzeigen, Pegelmesser (RMS- oder Spitzenwert), Stille-Erkennung bei Mikrofonaufnahmen und die Tonhöhenerkennung per Autokorrelation (z. B. für Stimmgeräte). Für solche Berechnungen braucht man die genauen Float-Werte.

Die Methode gibt nichts zurück. Sie schreibt die Werte in das übergebene Array. Es werden so viele Samples kopiert, wie analyser.fftSize angibt. Das Array sollte deshalb genau fftSize Einträge haben. Achtung: Die richtige Größe ist fftSize, nicht frequencyBinCount. Legt man das Array einmal an und nutzt es in jedem Animationsframe wieder, spart man Speicherbereinigung (Garbage Collection).

Parameter

Name Typ Default Beschreibung
$array Pflicht Float32Array Zielarray, in das die Zeitbereichs-Samples kopiert werden. Ist es kürzer als fftSize, werden nur so viele Werte geschrieben, wie hineinpassen. Ist es länger, bleiben die übrigen Einträge unverändert.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das übergebene Float32Array wird direkt beschrieben.

Beispiele

Oszilloskop auf einem Canvas zeichnen

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

const osc = audioCtx.createOscillator();
osc.frequency.value = 220;
osc.connect(analyser).connect(audioCtx.destination);

const data = new Float32Array(analyser.fftSize); // Größe = fftSize!
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

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

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  const step = canvas.width / data.length;
  data.forEach((v, i) => {
    const y = (1 - v) * canvas.height / 2; // -1..1 auf Canvas-Höhe abbilden
    i === 0 ? ctx.moveTo(0, y) : ctx.lineTo(i * step, y);
  });
  ctx.stroke();
};

document.querySelector('button').addEventListener('click', () => {
  audioCtx.resume();
  osc.start();
  draw();
});

Mikrofonpegel (RMS in dBFS) messen

const startMeter = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const audioCtx = new AudioContext();
  const source = audioCtx.createMediaStreamSource(stream);
  const analyser = audioCtx.createAnalyser();
  analyser.fftSize = 1024;
  source.connect(analyser); // nicht an destination -> keine Rückkopplung

  const buf = new Float32Array(analyser.fftSize);

  setInterval(() => {
    analyser.getFloatTimeDomainData(buf);
    let sum = 0;
    for (const s of buf) sum += s * s;
    const rms = Math.sqrt(sum / buf.length);
    const db = 20 * Math.log10(rms || 1e-8);
    console.log(`Pegel: ${db.toFixed(1)} dBFS`);
  }, 200);
};

document.querySelector('#start').addEventListener('click', startMeter);
Pegel: -42.3 dBFS Pegel: -18.7 dBFS

Stille erkennen über den Spitzenwert

const isSilent = (analyser, buffer, threshold = 0.01) => {
  analyser.getFloatTimeDomainData(buffer);
  const peak = buffer.reduce((max, s) => Math.max(max, Math.abs(s)), 0);
  return peak < threshold;
};

const audioCtx = new AudioContext();
const analyser = audioCtx.createAnalyser();
const buffer = new Float32Array(analyser.fftSize);

// Ohne angeschlossene Quelle ist das Signal still
console.log(isSilent(analyser, buffer));
true

// Wichtig · Fallstricke

  • Arraygröße: Die Zeitbereichsdaten umfassen fftSize Samples. Wer das Array versehentlich mit frequencyBinCount anlegt (das ist fftSize / 2), bekommt nur die Hälfte der Wellenform.
  • Typ: Das Array muss ein Float32Array sein. Ein normales Array oder ein Uint8Array löst einen TypeError aus. Für 8-Bit-Werte gibt es getByteTimeDomainData().
  • Wertebereich: Die Werte liegen meist zwischen -1 und 1. Bei übersteuerten Signalen (z. B. durch einen GainNode mit Verstärkung größer als 1) können sie auch darüber hinausgehen. Beim Zeichnen sollte man solche Werte begrenzen.
  • AudioContext im Zustand „suspended“: Wegen der Autoplay-Regeln der Browser startet der Kontext oft angehalten. Dann liefert die Methode nur Nullen. Den Kontext deshalb nach einer Nutzeraktion mit audioCtx.resume() starten.
  • Keine Glättung: smoothingTimeConstant gilt nur für Frequenzdaten, nicht für Zeitbereichsdaten.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Safari kann die Methode erst seit Version 14.1, ältere Safari-Versionen haben nur getByteTimeDomainData(). Für das Mikrofon ist ein sicherer Kontext (HTTPS) nötig.