Signatur
Beschreibung
Die Methode getFloatFrequencyData() eines AnalyserNode führt eine schnelle Fourier-Transformation (FFT) auf die zuletzt verarbeiteten Audiodaten aus und schreibt das Ergebnis in das übergebene Float32Array. Jedes Element enthält die Lautstärke eines Frequenzbereichs (Bins) in Dezibel (dB). Das sind typischerweise negative Werte, etwa zwischen -100 und 0; Stille ergibt -Infinity.
Die Anzahl der Frequenz-Bins entspricht analyser.frequencyBinCount (also fftSize / 2). Jeder Bin deckt eine Bandbreite von sampleRate / fftSize Hertz ab. Bin i steht ungefähr für die Frequenz i * sampleRate / fftSize.
Verwende die Methode, wenn du das Spektrum mit voller Genauigkeit brauchst, zum Beispiel für Tonhöhen- oder Frequenzanalysen, Messwerkzeuge oder eine exakte dB-Skala. Für einfache Visualisierungen reicht oft getByteFrequencyData(). Diese Variante liefert Werte zwischen 0 und 255, die schon auf minDecibels/maxDecibels skaliert sind.
Die Glättung zwischen aufeinanderfolgenden Aufrufen steuert smoothingTimeConstant. Die Methode gibt nichts zurück, sondern verändert das übergebene Array direkt. Deshalb solltest du ein Array einmal anlegen und in jedem Animations-Frame wiederverwenden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $array Pflicht | Float32Array | Ziel-Array, in das die Frequenzwerte in dB geschrieben werden. Hat es weniger Elemente als frequencyBinCount, werden überzählige Werte verworfen. Hat es mehr, bleiben die restlichen Elemente unverändert. |
Beispiele
Spektrum eines Oszillators auslesen
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { frequency: 440 });
const analyser = new AnalyserNode(ctx, { fftSize: 2048 });
osc.connect(analyser).connect(ctx.destination);
osc.start();
const data = new Float32Array(analyser.frequencyBinCount);
setTimeout(() => {
analyser.getFloatFrequencyData(data);
// Bin mit dem höchsten Pegel suchen
let maxIndex = 0;
for (let i = 1; i < data.length; i++) {
if (data[i] > data[maxIndex]) maxIndex = i;
}
const hz = maxIndex * ctx.sampleRate / analyser.fftSize;
console.log(`Dominante Frequenz: ~${hz.toFixed(0)} Hz`);
osc.stop();
}, 500);
Echtzeit-Spektrum auf ein Canvas zeichnen
const canvas = document.querySelector('canvas');
const g = canvas.getContext('2d');
const start = async () => {
const ctx = new AudioContext();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = ctx.createMediaStreamSource(stream);
const analyser = ctx.createAnalyser();
analyser.fftSize = 1024;
source.connect(analyser);
const data = new Float32Array(analyser.frequencyBinCount);
const { minDecibels, maxDecibels } = analyser;
const draw = () => {
requestAnimationFrame(draw);
analyser.getFloatFrequencyData(data);
g.fillStyle = '#000';
g.fillRect(0, 0, canvas.width, canvas.height);
const barWidth = canvas.width / data.length;
data.forEach((db, i) => {
// dB-Wert auf 0..1 normieren (−Infinity abfangen)
const v = Math.max(0, (db - minDecibels) / (maxDecibels - minDecibels));
const h = v * canvas.height;
g.fillStyle = `hsl(${(i / data.length) * 300}, 80%, 55%)`;
g.fillRect(i * barWidth, canvas.height - h, barWidth, h);
});
};
draw();
};
document.querySelector('#start').addEventListener('click', start);
Pegel eines Frequenzbands ermitteln (z. B. Bass)
const bandLevel = (analyser, data, fromHz, toHz) => {
analyser.getFloatFrequencyData(data);
const binHz = analyser.context.sampleRate / analyser.fftSize;
const from = Math.floor(fromHz / binHz);
const to = Math.min(data.length - 1, Math.ceil(toHz / binHz));
let sum = 0;
for (let i = from; i <= to; i++) {
// dB in lineare Leistung umrechnen, mitteln, zurück in dB
sum += 10 ** (data[i] / 10);
}
return 10 * Math.log10(sum / (to - from + 1));
};
// Nutzung: const bass = bandLevel(analyser, data, 20, 150);
// console.log(`Bass: ${bass.toFixed(1)} dB`);
// Wichtig · Fallstricke
- Werte sind Dezibel und meist negativ: Bei Stille oder bevor Audio fließt, enthält das Array
-Infinity. Fange das vor Rechnungen oder beim Zeichnen ab, zum Beispiel mitMath.max()oderNumber.isFinite(). minDecibels/maxDecibelswirken hier nicht: Die beiden Eigenschaften skalieren nurgetByteFrequencyData(). Die Float-Werte sind ungeklemmte Rohwerte in dB.- Das Array muss ein
Float32Arraysein: Andere Typen (etwaArrayoderFloat64Array) lösen einenTypeErroraus. - Performance: Lege das Array einmal an und verwende es wieder, statt es in jedem Frame neu zu erzeugen. Ein größeres
fftSizegibt eine feinere Frequenzauflösung, reagiert aber träger und kostet mehr Rechenzeit. - Autoplay-Richtlinie: Ein
AudioContextstartet oft im Zustandsuspendedund muss nach einer Nutzeraktion mitctx.resume()gestartet werden. Bis dahin liefert die Methode nur-Infinity. - Browser-Unterstützung: Die Methode läuft in allen modernen Browsern. Sehr alte WebKit-Versionen brauchten
webkitAudioContext.