Signatur
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
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);
});
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);
// Wichtig · Fallstricke
- Arrays gleich lang:
realundimagmüssen gleich lang und mindestens 2 Einträge lang sein. Sonst wirft der Browser einenIndexSizeError. - Index 0 wird ignoriert: Ein Gleichanteil lässt sich über
PeriodicWavenicht erzeugen. Dafür nimmst du einen zusätzlichenConstantSourceNode. typenicht direkt setzen: NachsetPeriodicWave()hatosc.typeden Wert"custom". Wenn dutype = "custom"direkt zuweist, wirft der Browser einenInvalidStateError.- Normalisierung: Ohne
disableNormalizationklingen 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 ducreatePeriodicWave(). Wegen der Autoplay-Regeln kommt Ton erst nach einer Nutzerinteraktion undctx.resume().