Signatur
Beschreibung
Der Konstruktor PeriodicWave() der Web Audio API legt eine Wellenform an, die sich periodisch wiederholt. Beschrieben wird sie über zwei Arrays mit Fourier-Koeffizienten: real enthält die Kosinus-Anteile, imag die Sinus-Anteile. Index 0 steht für den Gleichanteil (DC-Offset) und wird ignoriert, Index 1 für die Grundschwingung, Index 2 und alle weiteren für die Obertöne.
Man braucht das, wenn die eingebauten Oszillatortypen ("sine", "square", "sawtooth", "triangle") klanglich nicht reichen, etwa für Orgelregister, eigene Synthesizer-Klangfarben oder nachgebildete Instrumentenspektren. Die fertige Welle hängst du mit OscillatorNode.setPeriodicWave() an einen Oszillator oder übergibst sie beim Erzeugen über die Option periodicWave an new OscillatorNode().
Der Konstruktor macht dasselbe wie die ältere Fabrikmethode BaseAudioContext.createPeriodicWave(), nimmt die Werte aber als Options-Objekt entgegen. Standardmäßig wird die Wellenform normalisiert, damit ihr Spitzenwert bei 1 liegt. Mit disableNormalization: true bleiben die Amplituden genau so, wie du sie angegeben hast.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | BaseAudioContext | Der AudioContext oder OfflineAudioContext, zu dem die Welle gehört. |
|
| $options | object | {} | Optionales Objekt mit den Feldern real, imag und disableNormalization. Fehlen real und imag, entsteht eine Sinuswelle. |
| $options.real | Float32Array|number[] | Kosinus-Koeffizienten. Muss genauso lang sein wie imag, wenn beide angegeben sind. Ist nur eines angegeben, wird das andere mit Nullen gleicher Länge ergänzt. |
|
| $options.imag | Float32Array|number[] | Sinus-Koeffizienten. Muss mindestens 2 Einträge haben. | |
| $options.disableNormalization | boolean | false | Mit true wird die Wellenform nicht auf den Spitzenwert 1 normalisiert. |
Rückgabewert
PeriodicWave-Objekt. Es hat keine eigenen Eigenschaften oder Methoden und wird nur an einen OscillatorNode übergeben.Beispiele
Eigene Klangfarbe aus Obertönen
const ctx = new AudioContext();
// Index 0 = Gleichanteil (wird ignoriert), 1 = Grundton, 2 und folgende = Obertöne
const real = new Float32Array([0, 0, 0, 0, 0]);
const imag = new Float32Array([0, 1, 0.5, 0.25, 0.125]);
const wave = new PeriodicWave(ctx, { real, imag });
const osc = new OscillatorNode(ctx, { frequency: 220 });
osc.setPeriodicWave(wave);
osc.connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 1);
Welle direkt an den OscillatorNode übergeben
const playOrgan = async () => {
const ctx = new AudioContext();
await ctx.resume(); // nötig, wenn der Browser den Kontext angehalten hat (Autoplay-Sperre)
// Orgelartig: nur ungerade Obertöne
const imag = [0, 1, 0, 0.33, 0, 0.2, 0, 0.14];
const wave = new PeriodicWave(ctx, { imag });
const osc = new OscillatorNode(ctx, {
type: 'custom',
periodicWave: wave,
frequency: 261.63 // C4
});
const gain = new GainNode(ctx, { gain: 0.3 });
osc.connect(gain).connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 2);
};
document.querySelector('#play').addEventListener('click', playOrgan);
Normalisierung abschalten
const ctx = new OfflineAudioContext(1, 44100, 44100);
// Leise Welle: Amplitude 0.2 bleibt ohne Normalisierung erhalten
const wave = new PeriodicWave(ctx, {
real: [0, 0],
imag: [0, 0.2],
disableNormalization: true
});
const osc = new OscillatorNode(ctx, { frequency: 440 });
osc.setPeriodicWave(wave);
osc.connect(ctx.destination);
osc.start();
const buffer = await ctx.startRendering();
const peak = Math.max(...buffer.getChannelData(0));
console.log(peak.toFixed(2));
// Wichtig · Fallstricke
- Gleiche Länge: Gibst du
realundimagbeide an, müssen sie gleich lang sein. Sonst wirft der Konstruktor einenIndexSizeError. Das gilt auch, wenn ein Array weniger als 2 Einträge hat. - Index 0 wird ignoriert: Ein Gleichanteil (DC-Offset) lässt sich so nicht erzeugen. Dafür nimmst du einen
ConstantSourceNode. - Normalisierung: Standardmäßig wird die Lautstärke angeglichen. Wenn du Koeffizienten änderst, klingt die Welle deshalb unter Umständen nicht lauter oder leiser als vorher. Um die Lautstärke gezielt zu steuern, setzt du
disableNormalization: trueund regelst mit einemGainNode. - Keine Änderung möglich: Eine einmal erzeugte
PeriodicWavelässt sich nicht mehr verändern. Für eine andere Klangfarbe erzeugst du eine neue Welle und rufstsetPeriodicWave()erneut auf. - Kompatibilität: Der Konstruktor wird von aktuellen Versionen von Chrome, Edge, Firefox und Safari (ab 14.1) unterstützt. Ältere Safari-Versionen kennen nur
createPeriodicWave()aufwebkitAudioContext. Wegen der Autoplay-Sperre der Browser sollte die Wiedergabe durch eine Nutzeraktion ausgelöst werden.