Start · Sprachen · JavaScript · Referenz · new IIRFilterNode()

new IIRFilterNode()

Methode

Erzeugt einen <code>IIRFilterNode</code>, der einen allgemeinen IIR-Filter (unendliche Impulsantwort) mit frei wählbaren Feedforward- und Feedback-Koeffizienten auf ein Audiosignal anwendet.

seit JavaScript Baseline: alle modernen Browser (seit 2021) Kategorie: webapi

Signatur

new IIRFilterNode(context, options)

Beschreibung

Der Konstruktor IIRFilterNode() erzeugt einen Audio-Knoten, der einen allgemeinen IIR-Filter umsetzt. Anders als beim BiquadFilterNode gibt es keine vorgefertigten Filtertypen wie lowpass oder peaking. Stattdessen legst du die Übertragungsfunktion direkt über zwei Koeffizienten-Arrays fest: feedforward für den Zähler (b-Koeffizienten) und feedback für den Nenner (a-Koeffizienten).

Der Filter berechnet für jedes Sample y[n] = (Σ b[k]·x[n−k] − Σ a[k]·y[n−k]) / a[0]. Das eignet sich für Filter höherer Ordnung, für Nachbauten klassischer Analogschaltungen oder für Koeffizienten, die du mit einem Filterdesign-Werkzeug (etwa MATLAB oder SciPy) berechnet hast.

Die Koeffizienten werden einmalig beim Erzeugen festgelegt und lassen sich danach nicht mehr ändern. Anders als beim Biquad gibt es keine AudioParam-Eigenschaften zur Automation. Wenn sich die Filterkurve im Lauf der Zeit ändern soll, erzeugst du einen neuen Knoten und blendest zwischen den beiden über. Mit getFrequencyResponse() kannst du Betrag und Phase des Frequenzgangs abfragen, zum Beispiel für eine Visualisierung.

Gleichwertig zum Konstruktor ist die Fabrikmethode BaseAudioContext.createIIRFilter(feedforward, feedback). Der Konstruktor hat den Vorteil, dass er zusätzlich die allgemeinen AudioNodeOptions wie channelCount annimmt.

Parameter

Name Typ Default Beschreibung
$context Pflicht BaseAudioContext Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehören soll.
$options Pflicht IIRFilterOptions Ein Objekt mit den Filter-Koeffizienten. Es ist Pflicht, weil feedforward und feedback angegeben werden müssen.
$options.feedforward Pflicht number[] Die Zähler-Koeffizienten (bk) der Übertragungsfunktion. Erlaubt sind 1 bis 20 Werte, von denen mindestens einer ungleich 0 sein muss.
$options.feedback Pflicht number[] Die Nenner-Koeffizienten (ak). Erlaubt sind 1 bis 20 Werte. Der erste Wert (a[0]) darf nicht 0 sein.
$options.channelCount number 2 Die Kanalanzahl für das Up- und Downmixing am Eingang (aus AudioNodeOptions).
$options.channelCountMode "max" | "clamped-max" | "explicit" "max" Legt fest, wie sich die Kanalanzahl am Eingang ergibt.
$options.channelInterpretation "speakers" | "discrete" "speakers" Legt fest, wie Kanäle beim Mischen aufeinander abgebildet werden.

Rückgabewert

Typ
IIRFilterNode
Beschreibung
Ein neuer IIRFilterNode mit einem Eingang und einem Ausgang, der das Signal mit den übergebenen Koeffizienten filtert.

Beispiele

Einfacher Tiefpass erster Ordnung

const ctx = new AudioContext();

// y[n] = 0.1·x[n] + 0.9·y[n-1]  →  sanfter Tiefpass
const lowpass = new IIRFilterNode(ctx, {
  feedforward: [0.1],
  feedback: [1, -0.9]
});

const osc = new OscillatorNode(ctx, { type: 'sawtooth', frequency: 220 });
osc.connect(lowpass).connect(ctx.destination);

// Audio startet erst nach einer Nutzeraktion
document.querySelector('#play').addEventListener('click', async () => {
  await ctx.resume();
  osc.start();
  osc.stop(ctx.currentTime + 2);
});

Frequenzgang abfragen

const ctx = new AudioContext();
const filter = new IIRFilterNode(ctx, {
  feedforward: [0.1],
  feedback: [1, -0.9]
});

const freqs = new Float32Array([100, 1000, 5000, 10000]);
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`);
});
100 Hz: 0.0 dB 1000 Hz: -3.5 dB 5000 Hz: -12.3 dB 10000 Hz: -14.5 dB (Werte ungefähr, abhängig von der Abtastrate)

Offline-Rendering mit extern berechneten Koeffizienten

// Koeffizienten z. B. aus scipy.signal.butter(2, 0.1)
const b = [0.02008337, 0.04016673, 0.02008337];
const a = [1, -1.56101808, 0.64135154];

const render = async (inputBuffer) => {
  const off = new OfflineAudioContext(
    inputBuffer.numberOfChannels,
    inputBuffer.length,
    inputBuffer.sampleRate
  );
  const src = new AudioBufferSourceNode(off, { buffer: inputBuffer });
  const iir = new IIRFilterNode(off, { feedforward: b, feedback: a });
  src.connect(iir).connect(off.destination);
  src.start();
  return off.startRendering(); // Promise<AudioBuffer>
};

try {
  new IIRFilterNode(new OfflineAudioContext(1, 1, 44100), {
    feedforward: [1],
    feedback: [0, 1] // a[0] = 0 ist ungültig
  });
} catch (e) {
  console.log(e.name);
}
InvalidStateError

// Wichtig · Fallstricke

  • Die Koeffizienten sind unveränderlich: Nach dem Erzeugen lassen sie sich nicht mehr ändern. Für Automation oder Filter-Sweeps nimmst du einen BiquadFilterNode oder tauschst den Knoten mit einer Überblendung aus.
  • Fehler: Ein NotSupportedError tritt auf, wenn ein Array leer ist oder mehr als 20 Werte hat. Ein InvalidStateError tritt auf, wenn alle feedforward-Werte 0 sind oder feedback[0] 0 ist.
  • Stabilität: Der Browser prüft nicht, ob die Koeffizienten einen stabilen Filter ergeben. Instabile Filter (Pole außerhalb des Einheitskreises) können sich aufschaukeln und laute Übersteuerungen oder NaN-Werte erzeugen. Prüfe deine Koeffizienten deshalb vorher.
  • Abtastrate: Die Koeffizienten gelten für eine bestimmte Abtastrate. Wenn ctx.sampleRate abweicht (44,1 kHz statt 48 kHz), verschiebt sich der Frequenzgang.
  • Browser-Kompatibilität: Der Konstruktor wird in allen aktuellen Browsern unterstützt (Chrome 55+, Firefox 53+, Safari 14.1+). Für ältere Safari-Versionen greifst du auf ctx.createIIRFilter() zurück.
  • Die Wiedergabe über einen AudioContext setzt wegen der Autoplay-Richtlinien der Browser meist eine Nutzeraktion voraus.