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

IIRFilterNode.getFrequencyResponse()

Methode

Berechnet aus den Koeffizienten eines <code>IIRFilterNode</code> Betrag und Phase der Frequenzantwort für die angegebenen Frequenzen und schreibt sie in zwei Ausgabe-Arrays.

seit JavaScript Baseline: alle modernen Browser (Chrome 49+, Firef Kategorie: webapi

Signatur

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

Beschreibung

getFrequencyResponse() wertet die Übertragungsfunktion eines IIR-Filters (Infinite Impulse Response) für eine Liste von Frequenzen aus. Die Grundlage sind die Koeffizienten feedforward und feedback, die beim Erzeugen des Knotens mit AudioContext.createIIRFilter() oder new IIRFilterNode() festgelegt wurden. Für jede Frequenz in frequencyArray schreibt die Methode den linearen Betrag (Verstärkungsfaktor) in magResponseOutput und die Phasenverschiebung im Bogenmaß in phaseResponseOutput.

Typische Anwendungsfälle sind die Visualisierung von Filterkurven (z. B. Equalizer-Anzeigen auf einem <canvas>), das Prüfen selbst berechneter Koeffizienten vor dem Einsatz sowie der Vergleich verschiedener Filterentwürfe. Die Methode verarbeitet kein Audiosignal – sie rechnet rein mathematisch und funktioniert daher auch in einem angehaltenen AudioContext oder in einem OfflineAudioContext.

Anders als beim BiquadFilterNode lassen sich die Koeffizienten eines IIRFilterNode nach der Erzeugung nicht mehr ändern. Die Frequenzantwort eines Knotens ist deshalb konstant; sie muss nur einmal berechnet werden. Für eine andere Kurve erzeugt man einen neuen Knoten.

Parameter

Name Typ Default Beschreibung
$frequencyArray Pflicht Float32Array Frequenzen in Hertz, für die die Antwort berechnet werden soll. Sinnvoll ist der Bereich von 0 bis zur Nyquist-Frequenz (sampleRate / 2).
$magResponseOutput Pflicht Float32Array Ausgabe-Array, das mit dem linearen Betrag (Verstärkungsfaktor, nicht dB) je Frequenz befüllt wird. Muss genauso lang sein wie frequencyArray.
$phaseResponseOutput Pflicht Float32Array Ausgabe-Array, das mit der Phasenverschiebung im Bogenmaß (−π bis π) je Frequenz befüllt wird. Muss genauso lang sein wie frequencyArray.

Rückgabewert

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

Beispiele

Frequenzantwort eines einpoligen Tiefpasses berechnen

// Einpoliger Tiefpass: y[n] = 0.1·x[n] + 0.9·y[n-1]
const ctx = new OfflineAudioContext(1, 1, 48000);
const filter = ctx.createIIRFilter([0.1], [1, -0.9]);

const freqs = new Float32Array([0, 1000, 24000]);
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: ${mag[i].toFixed(3)} (${db.toFixed(2)} dB)`);
});
console.log(`Phase bei 1000 Hz: ${phase[1].toFixed(3)} rad`);
0 Hz: 1.000 (0.00 dB) 1000 Hz: 0.627 (-4.05 dB) 24000 Hz: 0.053 (-25.58 dB) Phase bei 1000 Hz: -0.829 rad

Filterkurve logarithmisch auf ein Canvas zeichnen

const ctx = new AudioContext();
const filter = new IIRFilterNode(ctx, {
  feedforward: [0.0675, 0.1349, 0.0675],
  feedback: [1, -1.1430, 0.4128]
});

const canvas = document.querySelector('#kurve');
const g = canvas.getContext('2d');
const { width, height } = canvas;

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

// Bereich +12 dB (oben) bis -48 dB (unten)
const dbToY = (db) => ((12 - db) / 60) * height;
g.clearRect(0, 0, width, height);
g.beginPath();
mag.forEach((m, x) => {
  const y = dbToY(20 * Math.log10(Math.max(m, 1e-6)));
  x === 0 ? g.moveTo(x, y) : g.lineTo(x, y);
});
g.strokeStyle = '#0a7';
g.stroke();

Randfälle: ungültige Frequenzen und falsche Array-Längen

const ctx = new OfflineAudioContext(1, 1, 44100);
const filter = ctx.createIIRFilter([0.1], [1, -0.9]);

// Frequenzen außerhalb von [0, Nyquist] liefern NaN
const freqs = new Float32Array([-100, 30000]);
const mag = new Float32Array(2);
const phase = new Float32Array(2);
filter.getFrequencyResponse(freqs, mag, phase);
console.log(mag, phase);

// Unterschiedliche Längen werfen eine Ausnahme
try {
  filter.getFrequencyResponse(freqs, new Float32Array(1), phase);
} catch (err) {
  console.log(err.name);
}
Float32Array(2) [NaN, NaN] Float32Array(2) [NaN, NaN] InvalidAccessError