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

new ConvolverNode()

Methode

Erzeugt einen <code>ConvolverNode</code>, der ein Audiosignal mit einer Impulsantwort faltet, z. B. für Hall oder Raumsimulation.

seit JavaScript Baseline: alle modernen Browser (Konstruktor seit Kategorie: webapi

Signatur

new ConvolverNode(context, options)

Beschreibung

Der Konstruktor new ConvolverNode() erstellt einen Audioknoten der Web Audio API, der eine lineare Faltung berechnet. Dabei wird das Eingangssignal mit einer Impulsantwort (Impulse Response, IR) verrechnet, die in einem AudioBuffer liegt. So klingt ein trockenes Signal, als wäre es in einer Kirche, einem Konzertsaal oder durch einen Gitarrenlautsprecher aufgenommen worden.

Anders als die ältere Fabrikmethode BaseAudioContext.createConvolver() kann der Konstruktor Puffer und Normalisierung gleich beim Erzeugen über ein options-Objekt setzen. Beide Wege liefern dasselbe Ergebnis. Der Konstruktor ist der moderne, empfohlene Weg.

Typischerweise lädt man eine IR-Datei (WAV) per fetch(), dekodiert sie mit decodeAudioData() und übergibt den so entstandenen AudioBuffer. Für einen regelbaren Hall schaltet man den Convolver meist parallel zu einem trockenen Signalweg und mischt beide über GainNodes (Dry/Wet-Mischung).

Parameter

Name Typ Default Beschreibung
$context Pflicht BaseAudioContext Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehört.
$options ConvolverOptions {} Optionales Objekt mit folgenden Feldern:
  • buffer (AudioBuffer | null, Standard null): Impulsantwort mit 1, 2 oder 4 Kanälen.
  • disableNormalization (boolean, Standard false): bei true wird die IR nicht normalisiert. Die Eigenschaft normalize ist das Gegenteil davon.
  • channelCount, channelCountMode, channelInterpretation: allgemeine AudioNode-Optionen (eingeschränkt: channelCount max. 2, channelCountMode nicht "max").

Beispiele

Hall mit geladener Impulsantwort

const ctx = new AudioContext();

const loadImpulse = async (url) => {
  const response = await fetch(url);
  const data = await response.arrayBuffer();
  return ctx.decodeAudioData(data);
};

const impulse = await loadImpulse('/audio/ir/konzertsaal.wav');
const reverb = new ConvolverNode(ctx, { buffer: impulse });

const audioEl = document.querySelector('audio');
const source = new MediaElementAudioSourceNode(ctx, { mediaElement: audioEl });

source.connect(reverb).connect(ctx.destination);
console.log(reverb.buffer.duration.toFixed(2), 's IR');
2.40 s IR

Synthetische Impulsantwort (abklingendes Rauschen)

const ctx = new AudioContext();

const createImpulse = (seconds = 2, decay = 3) => {
  const length = ctx.sampleRate * seconds;
  const buffer = ctx.createBuffer(2, length, ctx.sampleRate);
  for (let ch = 0; ch < 2; ch++) {
    const data = buffer.getChannelData(ch);
    for (let i = 0; i < length; i++) {
      data[i] = (Math.random() * 2 - 1) * (1 - i / length) ** decay;
    }
  }
  return buffer;
};

const reverb = new ConvolverNode(ctx, {
  buffer: createImpulse(2.5, 4),
  disableNormalization: false
});
console.log(reverb.normalize);
true

Dry/Wet-Mischung für regelbaren Hall

const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { type: 'sawtooth', frequency: 220 });

const reverb = new ConvolverNode(ctx); // Puffer später setzen
const dry = new GainNode(ctx, { gain: 0.7 });
const wet = new GainNode(ctx, { gain: 0.3 });

osc.connect(dry).connect(ctx.destination);
osc.connect(reverb).connect(wet).connect(ctx.destination);

const res = await fetch('/audio/ir/raum.wav');
reverb.buffer = await ctx.decodeAudioData(await res.arrayBuffer());

osc.start();
// Hallanteil per Schieberegler steuern
document.querySelector('#hall').addEventListener('input', (e) => {
  const v = Number(e.target.value);
  wet.gain.setTargetAtTime(v, ctx.currentTime, 0.05);
  dry.gain.setTargetAtTime(1 - v, ctx.currentTime, 0.05);
});

// Wichtig · Fallstricke

  • Reihenfolge bei normalize: Die Normalisierung wird angewandt, wenn der Puffer gesetzt wird. Wer normalize nachträglich ändert, muss buffer danach neu zuweisen, sonst hat die Änderung keine Wirkung. Mit dem Konstruktor und disableNormalization umgeht man dieses Problem.
  • Der AudioBuffer muss dieselbe Abtastrate wie der Kontext haben und 1, 2 oder 4 Kanäle besitzen. Sonst wird ein NotSupportedError geworfen. decodeAudioData() rechnet automatisch auf die Kontext-Rate um.
  • channelCount größer als 2 oder channelCountMode: \"max\" lösen einen NotSupportedError aus.
  • Leistung: Lange Impulsantworten (mehrere Sekunden, Stereo oder vier Kanäle) kosten viel Rechenzeit. Auf Mobilgeräten lieber kürzere IRs verwenden.
  • IR-Dateien von fremden Domains brauchen passende CORS-Header, sonst schlägt fetch() fehl.
  • Browser starten einen AudioContext oft im Zustand suspended. Er muss nach einer Nutzeraktion mit ctx.resume() gestartet werden.
  • Kompatibilität: Der Konstruktor funktioniert in allen aktuellen Browsern. Sehr alte Safari-Versionen (vor 14.1) kennen nur createConvolver().