Signatur
Beschreibung
createOscillator() ist eine Fabrikmethode von BaseAudioContext und steht damit sowohl in AudioContext (Echtzeit-Wiedergabe) als auch in OfflineAudioContext (Rendern ohne Ausgabe) zur Verfügung. Die Methode liefert einen neuen OscillatorNode, der standardmäßig einen Sinuston mit 440 Hz erzeugt.
Oszillatoren eignen sich für Synthesizer, Signal- und Warntöne, Testtöne, Stimmgeräte und als Modulationsquelle (LFO) für andere AudioParam-Werte, etwa für Vibrato oder Tremolo. Über die Eigenschaften type, frequency und detune steuerst du Wellenform und Tonhöhe. Mit setPeriodicWave() lassen sich eigene Klangfarben festlegen.
Ein Oszillator erzeugt erst Ton, wenn er mit connect() an ein Ziel (z. B. context.destination oder einen GainNode) angeschlossen und mit start() gestartet wurde. Ein OscillatorNode kann nur einmal gestartet werden. Für jeden neuen Ton erzeugst du einen neuen Knoten. Das ist so vorgesehen und kostet kaum Leistung.
Als moderne Alternative gibt es den Konstruktor new OscillatorNode(context, options), mit dem du Anfangswerte direkt übergeben kannst.
Rückgabewert
OscillatorNode mit type = "sine", frequency.value = 440 und detune.value = 0.Beispiele
Einfacher Piepton nach Klick
const ctx = new AudioContext();
document.querySelector('#beep').addEventListener('click', async () => {
// Autoplay-Richtlinie: Kontext erst nach einer Nutzeraktion fortsetzen
if (ctx.state === 'suspended') await ctx.resume();
const osc = ctx.createOscillator();
osc.type = 'square';
osc.frequency.value = 880; // A5
osc.connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 0.2); // 200 ms Ton
osc.onended = () => console.log('Ton beendet');
});
Ton ohne Knacken mit Hüllkurve über GainNode
const ctx = new AudioContext();
const playNote = (freq, duration = 0.5) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const now = ctx.currentTime;
osc.type = 'triangle';
osc.frequency.setValueAtTime(freq, now);
// Weiches Ein- und Ausblenden verhindert Klickgeräusche
gain.gain.setValueAtTime(0, now);
gain.gain.linearRampToValueAtTime(0.3, now + 0.02);
gain.gain.exponentialRampToValueAtTime(0.001, now + duration);
osc.connect(gain).connect(ctx.destination);
osc.start(now);
osc.stop(now + duration);
};
// C-Dur-Dreiklang nacheinander
[261.63, 329.63, 392.0].forEach((f, i) =>
setTimeout(() => playNote(f), i * 300)
);
Vibrato mit einem zweiten Oszillator als LFO
const ctx = new AudioContext();
const carrier = ctx.createOscillator();
carrier.frequency.value = 440;
const lfo = ctx.createOscillator();
lfo.frequency.value = 5; // 5 Hz Modulation
const lfoDepth = ctx.createGain();
lfoDepth.gain.value = 10; // ±10 Hz Tonhöhenschwankung
// LFO moduliert den frequency-AudioParam des Trägers
lfo.connect(lfoDepth).connect(carrier.frequency);
carrier.connect(ctx.destination);
lfo.start();
carrier.start();
carrier.stop(ctx.currentTime + 2);
lfo.stop(ctx.currentTime + 2);
Offline rendern und Samples prüfen
const offline = new OfflineAudioContext(1, 44100, 44100); // 1 s, Mono
const osc = offline.createOscillator();
osc.frequency.value = 1000;
osc.connect(offline.destination);
osc.start();
const buffer = await offline.startRendering();
console.log(buffer.duration, buffer.getChannelData(0).length);
// Wichtig · Fallstricke
- Nur ein Start: Rufst du
start()ein zweites Mal auf, wird einInvalidStateErrorausgelöst. Für jeden Ton erzeugst du einen neuen Oszillator. Gestoppte Knoten ohne Verbindungen gibt der Garbage Collector frei. - Autoplay-Richtlinien: Browser starten einen
AudioContextoft im Zustand"suspended". Rufectx.resume()innerhalb einer Nutzeraktion auf (Klick, Tastendruck), sonst bleibt es still. - Knackgeräusche: Wenn du abrupt startest oder stoppst, entstehen hörbare Klicks. Blende deshalb die Lautstärke über einen
GainNodemit Rampen ein und aus. - Lautstärke: Ein Oszillator liefert volle Amplitude (±1). Rechteck- und Sägezahnwellen klingen dabei sehr laut. Regle die Lautstärke mit einem
GainNodeherunter (z. B. 0.1–0.3). type = "custom"darfst du nicht direkt setzen, das löst einenInvalidStateErroraus. Verwende stattdessensetPeriodicWave().- Kompatibilität: Die Methode wird in allen modernen Browsern unterstützt. Sehr alte WebKit-Versionen brauchten das Präfix
webkitAudioContextund die alten MethodennoteOn()/noteOff(). In Node.js gibt es die Web Audio API nicht nativ, dafür brauchst du Pakete wienode-web-audio-api.