Start · Sprachen · JavaScript · Referenz · BaseAudioContext.createAnalyser()

BaseAudioContext.createAnalyser()

Methode

Erstellt einen <code>AnalyserNode</code>, der Zeit- und Frequenzdaten eines Audiosignals für Analysen und Visualisierungen bereitstellt.

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

Signatur

BaseAudioContext.prototype.createAnalyser()

Beschreibung

Die Methode createAnalyser() eines AudioContext oder OfflineAudioContext erzeugt einen AnalyserNode. Dieser Knoten reicht das Audiosignal unverändert weiter und stellt gleichzeitig per schneller Fourier-Transformation (FFT) berechnete Frequenzdaten sowie die rohe Wellenform (Zeitbereich) bereit.

Typische Einsatzzwecke sind Spektrum-Anzeigen, Oszilloskop-Darstellungen, Pegelmesser (VU-Meter), Sprachaktivitätserkennung oder einfache Tonhöhenerkennung. Den Knoten hängt man zwischen eine Quelle (z. B. MediaElementAudioSourceNode oder MediaStreamAudioSourceNode) und das Ziel. Ein Anschluss an destination ist nicht zwingend nötig, wenn nur analysiert werden soll.

Die Daten liest man üblicherweise in einer requestAnimationFrame-Schleife mit getByteFrequencyData(), getFloatFrequencyData(), getByteTimeDomainData() oder getFloatTimeDomainData() aus. Über fftSize, smoothingTimeConstant, minDecibels und maxDecibels steuert man Auflösung und Glättung.

Alternativ lässt sich der Knoten direkt mit dem Konstruktor new AnalyserNode(context, options) erzeugen. Damit können die Optionen gleich beim Erzeugen gesetzt werden.

Rückgabewert

Typ
AnalyserNode
Beschreibung
Ein neuer AnalyserNode mit Standardwerten: fftSize = 2048, frequencyBinCount = 1024, smoothingTimeConstant = 0.8, minDecibels = -100, maxDecibels = -30.

Beispiele

Analyser erzeugen und konfigurieren

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

analyser.fftSize = 512;               // Zweierpotenz von 32 bis 32768
analyser.smoothingTimeConstant = 0.6; // 0 = keine Glättung, 1 = maximal

console.log(analyser.frequencyBinCount); // halbe fftSize
console.log(analyser.minDecibels, analyser.maxDecibels);
256 -100 -30

Frequenzspektrum eines <audio>-Elements auf Canvas zeichnen

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

const ctx = new AudioContext();
const source = ctx.createMediaElementSource(audio);
const analyser = ctx.createAnalyser();
analyser.fftSize = 256;

// Quelle -> Analyser -> Lautsprecher
source.connect(analyser).connect(ctx.destination);

const data = new Uint8Array(analyser.frequencyBinCount);

const draw = () => {
  requestAnimationFrame(draw);
  analyser.getByteFrequencyData(data);
  g.clearRect(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 * 2}, 80%, 50%)`;
    g.fillRect(i * barWidth, canvas.height - h, barWidth - 1, h);
  });
};

// AudioContext erst nach Nutzerinteraktion starten
audio.addEventListener('play', async () => {
  await ctx.resume();
  draw();
}, { once: true });

Mikrofon-Pegel (RMS) messen

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

  const buffer = new Float32Array(analyser.fftSize);

  const tick = () => {
    analyser.getFloatTimeDomainData(buffer);
    const rms = Math.sqrt(buffer.reduce((sum, s) => sum + s * s, 0) / buffer.length);
    const db = 20 * Math.log10(rms || 1e-8);
    console.log(`Pegel: ${db.toFixed(1)} dBFS`);
    setTimeout(tick, 500);
  };
  tick();
};

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

// Wichtig · Fallstricke

  • Autoplay-Richtlinie: Ein AudioContext startet in vielen Browsern im Zustand "suspended". Rufen Sie ctx.resume() erst nach einer Nutzerinteraktion auf, sonst liefert der Analyser nur Nullen bzw. Stille.
  • fftSize muss eine Zweierpotenz zwischen 32 und 32768 sein, sonst wird ein IndexSizeError geworfen. Die Länge des Arrays für Frequenzdaten entspricht frequencyBinCount (halbe fftSize), für Zeitdaten dagegen fftSize.
  • CORS: Bei createMediaElementSource() mit Audiodateien von fremden Domains liefert der Analyser ohne passende CORS-Header (und crossorigin="anonymous" am Element) nur Nullwerte.
  • Ein MediaElementSourceNode kann pro <audio>-Element nur einmal erzeugt werden. Ein zweiter Aufruf wirft einen InvalidStateError.
  • Den Mikrofon-Eingang nicht an destination anschließen, sonst entsteht eine Rückkopplung.
  • Leistung: Legen Sie die typisierten Arrays einmal an und verwenden Sie sie wieder, statt sie in jedem Frame neu zu erzeugen. Große fftSize-Werte kosten Rechenzeit und verringern die zeitliche Auflösung.
  • Der Knoten wird von allen modernen Browsern unterstützt. Ältere Safari-Versionen benötigten webkitAudioContext.