Signatur
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
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);
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);
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`);
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
frequencyBinCountwird im nicht-strikten Modus stillschweigend ignoriert und löst im Strict Mode einenTypeErroraus. Um den Wert zu ändern, setzt manfftSize(Zweierpotenz zwischen 32 und 32768). - Puffergröße nach Änderung anpassen: Wenn
fftSizezur 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ößefftSize, nichtfrequencyBinCount. - 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
AudioContextoft im Zustandsuspended, bis eine Nutzerinteraktion erfolgt (Autoplay-Richtlinie). Solange er pausiert ist, bleiben die Frequenzdaten bei Null.