Start · Sprachen · JavaScript · Referenz · BiquadFilterNode.getFrequencyResponse()

BiquadFilterNode.getFrequencyResponse()

Methode

Berechnet für die aktuellen Filtereinstellungen Amplitudengang und Phasengang an den übergebenen Frequenzen und schreibt die Werte in zwei <code>Float32Array</code>s.

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

Signatur

BiquadFilterNode.prototype.getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput)

Beschreibung

getFrequencyResponse() wertet die Übertragungsfunktion eines BiquadFilterNode aus, und zwar mit dem aktuellen Filtertyp und den aktuellen Werten von frequency, Q, gain und detune. Für jede Frequenz (in Hertz) im Eingabe-Array berechnet die Methode zwei Werte: die Amplitude als linearen Faktor (1 = unverändert, 0,5 ≈ −6 dB) und die Phasenverschiebung im Bogenmaß.

Die Methode liefert nichts zurück. Die Ergebnisse landen in den beiden übergebenen Ausgabe-Arrays, die der Aufrufer vorher anlegen muss. So lassen sich Arrays wiederverwenden, und es entsteht bei häufigen Aufrufen, etwa pro Animationsframe, kein neuer Speicher.

Typische Einsätze sind das Zeichnen von Equalizer- und Filterkurven in Audio-Editoren, die Anzeige der Wirkung eines Filters in der Oberfläche oder die Prüfung von Filterparametern in Tests. Das Audiosignal wird dabei nicht verarbeitet. Die Methode rechnet nur mathematisch und funktioniert auch, wenn der AudioContext pausiert ist oder gerade kein Audio fließt.

Parameter

Name Typ Default Beschreibung
$frequencyArray Pflicht Float32Array Die Frequenzen in Hertz, für die der Frequenzgang berechnet werden soll.
$magResponseOutput Pflicht Float32Array Ausgabe-Array für die Amplitudenwerte als linearer Faktor, nicht in dB. Muss genauso lang sein wie frequencyArray.
$phaseResponseOutput Pflicht Float32Array Ausgabe-Array für die Phasenverschiebung im Bogenmaß (Radiant). Muss genauso lang sein wie frequencyArray.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Die Ergebnisse werden in magResponseOutput und phaseResponseOutput geschrieben.

Beispiele

Tiefpass an einigen Frequenzen auswerten

const ctx = new AudioContext();
const filter = new BiquadFilterNode(ctx, {
  type: 'lowpass',
  frequency: 1000,
  Q: 1
});

const freqs = new Float32Array([100, 500, 1000, 2000, 8000]);
const mag = new Float32Array(freqs.length);
const phase = new Float32Array(freqs.length);

filter.getFrequencyResponse(freqs, mag, phase);

freqs.forEach((f, i) => {
  const db = 20 * Math.log10(mag[i]);
  console.log(`${f} Hz: ${db.toFixed(1)} dB, Phase ${phase[i].toFixed(2)} rad`);
});
100 Hz: 0.0 dB, Phase -0.09 rad 500 Hz: 0.8 dB, Phase -0.53 rad 1000 Hz: 0.0 dB, Phase -1.57 rad 2000 Hz: -11.6 dB, Phase -2.52 rad 8000 Hz: -36.1 dB, Phase -3.02 rad (Werte ungefähr, sie hängen von der Abtastrate ab)

Filterkurve logarithmisch auf ein Canvas zeichnen

const ctx = new AudioContext();
const filter = ctx.createBiquadFilter();
filter.type = 'peaking';
filter.frequency.value = 2000;
filter.gain.value = 12;
filter.Q.value = 2;

const canvas = document.querySelector('#eq');
const g = canvas.getContext('2d');
const n = canvas.width;

// Frequenzen logarithmisch von 20 Hz bis zur Nyquist-Frequenz verteilen
const nyquist = ctx.sampleRate / 2;
const freqs = new Float32Array(n);
for (let i = 0; i < n; i++) {
  freqs[i] = 20 * Math.pow(nyquist / 20, i / (n - 1));
}
const mag = new Float32Array(n);
const phase = new Float32Array(n);

const draw = () => {
  filter.getFrequencyResponse(freqs, mag, phase);
  g.clearRect(0, 0, n, canvas.height);
  g.beginPath();
  for (let i = 0; i < n; i++) {
    const db = 20 * Math.log10(mag[i]);
    // Bereich −24 dB bis +24 dB auf die Canvas-Höhe abbilden
    const y = canvas.height / 2 - (db / 24) * (canvas.height / 2);
    i === 0 ? g.moveTo(i, y) : g.lineTo(i, y);
  }
  g.stroke();
};

draw();

Kurve bei Reglerbewegung neu berechnen

const ctx = new AudioContext();
const filter = new BiquadFilterNode(ctx, { type: 'highpass', frequency: 200 });

const freqs = new Float32Array([50, 100, 200, 400]);
const mag = new Float32Array(4);
const phase = new Float32Array(4);

const slider = document.querySelector('#cutoff');
slider.addEventListener('input', () => {
  filter.frequency.value = Number(slider.value);
  // Arrays wiederverwenden: kein neuer Speicher pro Ereignis
  filter.getFrequencyResponse(freqs, mag, phase);
  console.log([...mag].map((m) => (20 * Math.log10(m)).toFixed(1) + ' dB'));
});
z. B. ["-24.1 dB", "-12.3 dB", "-3.0 dB", "-0.3 dB"]

// Wichtig · Fallstricke

  • Alle drei Argumente müssen Float32Arrays sein. Normale Arrays oder Float64Array führen zu einem TypeError. Sind die Arrays unterschiedlich lang, wirft die Methode einen InvalidAccessError (DOMException).
  • Für Frequenzen außerhalb von [0, sampleRate / 2] (Nyquist) wird NaN in beide Ausgabe-Arrays geschrieben. Negative Werte und Werte oberhalb der Nyquist-Frequenz sollte man daher vorher herausfiltern.
  • Die Amplitude ist linear. Für eine Anzeige in Dezibel rechnet man 20 * Math.log10(mag) um. Bei einer Amplitude von 0 ergibt das -Infinity.
  • Maßgeblich sind die Parameterwerte zum Zeitpunkt des Aufrufs, also der aktuelle .value. Geplante Automationen wie linearRampToValueAtTime() und Modulation über angeschlossene AudioNodes werden nur mit ihrem momentanen Wert berücksichtigt.
  • Die Methode wird von allen modernen Browsern unterstützt. Das ältere Präfix webkitAudioContext spielt nur noch für sehr alte Safari-Versionen eine Rolle. Für Filter mit beliebigen Koeffizienten gibt es die gleiche Methode auch bei IIRFilterNode.