Signatur
Beschreibung
createWaveShaper() ist eine Fabrikmethode von BaseAudioContext und damit sowohl auf AudioContext als auch auf OfflineAudioContext verfügbar. Sie gibt einen neuen WaveShaperNode zurück, der jeden Eingangs-Samplewert (Bereich −1 bis 1) über eine frei definierbare Kurve (curve, ein Float32Array) auf einen Ausgangswert abbildet.
Typische Einsatzgebiete sind Gitarren-Verzerrer, warme Röhren- oder Band-Sättigung, Bitcrusher-ähnliche Effekte und Soft-Clipping, damit Pegelspitzen nicht hart abgeschnitten werden. Ohne gesetzte Kurve reicht der Knoten das Signal unverändert durch.
Mit der Eigenschaft oversample ("none", "2x", "4x") lässt sich Aliasing reduzieren, das bei starker Verzerrung durch neu entstehende Obertöne auftritt. Höheres Oversampling klingt sauberer, kostet aber mehr Rechenzeit.
Gleichwertig ist der Konstruktor new WaveShaperNode(context, { curve, oversample }), der Optionen direkt bei der Erzeugung annimmt und in modernem Code oft vorgezogen wird.
Rückgabewert
WaveShaperNode mit curve = null und oversample = "none", der noch mit anderen Knoten verbunden werden muss.Beispiele
Einfacher Distortion-Effekt auf einen Oszillator
const ctx = new AudioContext();
// Klassische Verzerrungskurve erzeugen
const makeDistortionCurve = (amount = 50, samples = 44100) => {
const curve = new Float32Array(samples);
const deg = Math.PI / 180;
for (let i = 0; i < samples; i++) {
const x = (i * 2) / samples - 1;
curve[i] = ((3 + amount) * x * 20 * deg) / (Math.PI + amount * Math.abs(x));
}
return curve;
};
const osc = ctx.createOscillator();
const shaper = ctx.createWaveShaper();
shaper.curve = makeDistortionCurve(400);
shaper.oversample = '4x';
osc.connect(shaper).connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 1);
console.log(shaper.curve.length, shaper.oversample);
Gitarren-Overdrive für Mikrofon-Eingang mit regelbarer Stärke
const ctx = new AudioContext();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = ctx.createMediaStreamSource(stream);
const shaper = ctx.createWaveShaper();
const output = ctx.createGain();
output.gain.value = 0.5;
// Soft-Clipping per tanh
const setDrive = (drive) => {
const n = 2048;
const curve = new Float32Array(n);
for (let i = 0; i < n; i++) {
const x = (i / (n - 1)) * 2 - 1;
curve[i] = Math.tanh(drive * x);
}
shaper.curve = curve; // Kurve komplett neu zuweisen
};
setDrive(5);
source.connect(shaper).connect(output).connect(ctx.destination);
document.querySelector('#drive').addEventListener('input', (e) => {
setDrive(Number(e.target.value));
});
Offline-Rendering mit OfflineAudioContext
const offline = new OfflineAudioContext(1, 44100, 44100);
const osc = offline.createOscillator();
const shaper = offline.createWaveShaper();
// Hartes Clipping: alles über ±0.5 wird begrenzt
shaper.curve = new Float32Array([-0.5, -0.5, 0, 0.5, 0.5]);
osc.connect(shaper).connect(offline.destination);
osc.start();
const buffer = await offline.startRendering();
const data = buffer.getChannelData(0);
console.log(Math.max(...data.slice(0, 1000)).toFixed(2));
// Wichtig · Fallstricke
- Kurve nicht in place ändern: Beim Setzen von
curvekopiert der Browser das Array intern. Spätere Änderungen am ursprünglichenFloat32Arrayhaben keine Wirkung. Weise stattdessen ein neues Array zu. - Die Kurve braucht mindestens 2 Werte, sonst wirft der Browser einen
InvalidStateError. Eingangswerte außerhalb von −1…1 werden auf den ersten bzw. letzten Kurvenwert begrenzt. - Starke Verzerrung erhöht den Pegel deutlich. Setze danach einen
GainNode, um das Gehör und die Lautsprecher zu schützen. - Oversampling mit
"4x"braucht spürbar mehr CPU. Bei vielen parallelen Knoten auf Mobilgeräten sparsam einsetzen. - Autoplay-Richtlinien: Ein
AudioContextstartet in vielen Browsern im Zustand"suspended", bis der Nutzer etwas angeklickt oder getippt hat. Rufe dannctx.resume()auf. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Sehr alte Safari-Versionen kennen nur
webkitAudioContext.