Start · Sprachen · JavaScript · Referenz · BaseAudioContext.createOscillator()

BaseAudioContext.createOscillator()

Methode

Erzeugt einen <code>OscillatorNode</code>, eine Audioquelle, die eine periodische Wellenform (Sinus, Rechteck, Sägezahn, Dreieck oder eigene Welle) erzeugt.

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

Signatur

BaseAudioContext.prototype.createOscillator()

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

Typ
OscillatorNode
Beschreibung
Ein neuer, noch nicht gestarteter 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 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);
1 44100

// Wichtig · Fallstricke

  • Nur ein Start: Rufst du start() ein zweites Mal auf, wird ein InvalidStateError ausgelöst. Für jeden Ton erzeugst du einen neuen Oszillator. Gestoppte Knoten ohne Verbindungen gibt der Garbage Collector frei.
  • Autoplay-Richtlinien: Browser starten einen AudioContext oft im Zustand "suspended". Rufe ctx.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 GainNode mit 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 GainNode herunter (z. B. 0.1–0.3).
  • type = "custom" darfst du nicht direkt setzen, das löst einen InvalidStateError aus. Verwende stattdessen setPeriodicWave().
  • Kompatibilität: Die Methode wird in allen modernen Browsern unterstützt. Sehr alte WebKit-Versionen brauchten das Präfix webkitAudioContext und die alten Methoden noteOn()/noteOff(). In Node.js gibt es die Web Audio API nicht nativ, dafür brauchst du Pakete wie node-web-audio-api.