Start · Sprachen · JavaScript · Referenz · PeriodicWave

PeriodicWave

Schnittstelle

Beschreibt eine frei definierbare periodische Wellenform über Fourier-Koeffizienten, die per <code>OscillatorNode.setPeriodicWave()</code> als Klangquelle dient.

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

Signatur

interface PeriodicWave

Beschreibung

PeriodicWave ist Teil der Web Audio API und steht für eine eigene, periodisch wiederholte Wellenform. Statt der eingebauten Typen "sine", "square", "sawtooth" und "triangle" eines OscillatorNode kannst du damit beliebige Klangfarben festlegen, etwa Orgel-, Glocken- oder Synthesizer-Sounds.

Die Wellenform gibst du im Frequenzbereich an, und zwar als zwei Arrays mit Fourier-Koeffizienten: real (Kosinus-Anteile) und imag (Sinus-Anteile). Index 0 ist der Gleichanteil (DC-Offset) und wird ignoriert, Index 1 ist der Grundton, Index 2 die erste Oberwelle (doppelte Frequenz) und so weiter. Aus diesen Werten erzeugt der Browser intern eine Wellentabelle.

Ein PeriodicWave-Objekt legst du entweder mit new PeriodicWave(context, options) oder mit der Fabrikmethode BaseAudioContext.createPeriodicWave(real, imag, constraints) an. Die Schnittstelle selbst hat keine eigenen Eigenschaften oder Methoden. Sie ist ein undurchsichtiges Objekt, das du mit oscillator.setPeriodicWave(wave) an einen oder mehrere Oszillatoren übergibst.

Standardmäßig normalisiert der Browser die Wellenform auf einen Spitzenwert von 1. Mit disableNormalization: true übernimmt er die Amplituden dagegen unverändert. Das ist wichtig, wenn mehrere Wellen im Pegel zueinander passen müssen.

Parameter

Name Typ Default Beschreibung
$context Pflicht BaseAudioContext Der AudioContext oder OfflineAudioContext, zu dem die Welle gehört.
$options object {} Optionales Objekt (PeriodicWaveOptions) mit folgenden Feldern: real, imag und disableNormalization.
$options.real Float32Array|number[] [0, 0] Kosinus-Koeffizienten. Index 0 (Gleichanteil) wird ignoriert.
$options.imag Float32Array|number[] [0, 1] Sinus-Koeffizienten. Muss genauso lang sein wie real. Fehlen beide Arrays, entsteht eine Sinuswelle.
$options.disableNormalization boolean false Bei true werden die Amplituden nicht auf den Spitzenwert 1 normalisiert.

Rückgabewert

Typ
PeriodicWave
Beschreibung
Ein neues PeriodicWave-Objekt, das du an OscillatorNode.setPeriodicWave() übergeben kannst.

Beispiele

Konstruktor: einfache Welle mit Oberwellen

const ctx = new AudioContext();

// Grundton + 2. und 3. Harmonische (Sinus-Anteile)
const wave = new PeriodicWave(ctx, {
  real: new Float32Array([0, 0, 0, 0]),
  imag: new Float32Array([0, 1, 0.5, 0.25])
});

const osc = new OscillatorNode(ctx, { frequency: 220 });
osc.setPeriodicWave(wave);
osc.connect(ctx.destination);

// Nur nach einer Nutzerinteraktion starten (Autoplay-Regeln)
document.querySelector('#play').addEventListener('click', async () => {
  await ctx.resume();
  osc.start();
  osc.stop(ctx.currentTime + 1);
  console.log(wave instanceof PeriodicWave);
});
true

Fabrikmethode: orgelähnlicher Klang

const ctx = new AudioContext();

// Orgel: Grundton und ungerade Harmonische
const harmonics = 16;
const real = new Float32Array(harmonics);
const imag = new Float32Array(harmonics);
for (let n = 1; n < harmonics; n += 2) {
  imag[n] = 1 / n;
}

const organ = ctx.createPeriodicWave(real, imag);

const playNote = (freq, duration = 0.5) => {
  const osc = ctx.createOscillator();
  const gain = ctx.createGain();
  osc.setPeriodicWave(organ);
  osc.frequency.value = freq;
  gain.gain.setValueAtTime(0.3, ctx.currentTime);
  gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + duration);
  osc.connect(gain).connect(ctx.destination);
  osc.start();
  osc.stop(ctx.currentTime + duration);
};

document.addEventListener('keydown', async () => {
  await ctx.resume();
  playNote(261.63); // C4
});

Pegel exakt kontrollieren ohne Normalisierung

const ctx = new AudioContext();

// Leise Sinuswelle mit Amplitude 0.2 – ohne automatische Normalisierung
const quiet = ctx.createPeriodicWave(
  [0, 0],
  [0, 0.2],
  { disableNormalization: true }
);

const osc = new OscillatorNode(ctx, { frequency: 440 });
osc.setPeriodicWave(quiet);
console.log(osc.type);
custom

// Wichtig · Fallstricke

  • Arrays gleich lang: real und imag müssen gleich lang und mindestens 2 Einträge lang sein. Sonst wirft der Browser einen IndexSizeError.
  • Index 0 wird ignoriert: Ein Gleichanteil lässt sich über PeriodicWave nicht erzeugen. Dafür nimmst du einen zusätzlichen ConstantSourceNode.
  • type nicht direkt setzen: Nach setPeriodicWave() hat osc.type den Wert "custom". Wenn du type = "custom" direkt zuweist, wirft der Browser einen InvalidStateError.
  • Normalisierung: Ohne disableNormalization klingen alle Wellen ungefähr gleich laut. Das Mischungsverhältnis der Harmonischen bleibt dabei erhalten, die absolute Amplitude nicht.
  • Aliasing: Sehr viele hohe Harmonische bei hohen Grundfrequenzen können über der Nyquist-Frequenz liegen. Browser begrenzen das Band intern, trotzdem solltest du die Zahl der Koeffizienten sinnvoll halten, auch wegen der Performance.
  • Wiederverwendung: Ein PeriodicWave-Objekt kannst du beliebig vielen Oszillatoren desselben Kontexts zuweisen. Lege es nicht für jede Note neu an.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Den Konstruktor new PeriodicWave() gibt es erst seit neueren Versionen (Safari ab 14.1). In älteren Umgebungen nimmst du createPeriodicWave(). Wegen der Autoplay-Regeln kommt Ton erst nach einer Nutzerinteraktion und ctx.resume().