Signatur
Beschreibung
AudioScheduledSourceNode ist eine abstrakte Basisschnittstelle der Web Audio API. Sie erbt von AudioNode und bündelt die gemeinsame Planungslogik aller Quellknoten, die zu einem bestimmten Zeitpunkt der Audio-Zeitachse starten und stoppen. Dazu gehören AudioBufferSourceNode, OscillatorNode und ConstantSourceNode.
Die Schnittstelle stellt drei Bausteine bereit:
start(when?): startet die Wiedergabe zum Zeitpunktwhen, gemessen in Sekunden auf der UhrAudioContext.currentTime.stop(when?): beendet die Wiedergabe zum angegebenen Zeitpunkt.ended: Ereignis, das feuert, sobald die Wiedergabe endet. Das passiert durchstop()oder, bei Puffern, am Ende der Daten. Man kann es mitaddEventListener("ended", …)oder über die Eigenschaftonendedabonnieren.
Man erzeugt AudioScheduledSourceNode nie direkt. Stattdessen nutzt man eine der abgeleiteten Klassen, entweder mit einem Konstruktor wie new OscillatorNode(ctx) oder mit einer Fabrikmethode wie ctx.createOscillator(). Die zeitgenaue Planung ist wichtig für Sequenzer, Metronome, Spiele-Soundeffekte und Synthesizer. Die Zeitpunkte gelten auf der Audio-Uhr und sind deshalb sehr viel genauer als setTimeout.
Jeder Quellknoten ist ein Einweg-Objekt: start() darf pro Knoten nur einmal aufgerufen werden. Wer einen Ton erneut abspielen will, erzeugt einen neuen Knoten. Das ist günstig und so vorgesehen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $when | number | 0 | Gilt für start(when) und stop(when): Zeitpunkt in Sekunden auf der Uhr AudioContext.currentTime. Liegt der Wert in der Vergangenheit oder ist er 0, wird sofort gestartet bzw. gestoppt. Negative Werte lösen einen RangeError aus. |
Rückgabewert
start() und stop() geben undefined zurück. Das Ende der Wiedergabe meldet das Ereignis ended. Bei AudioBufferSourceNode.start() sind zusätzlich die Parameter offset und duration möglich.Beispiele
Oszillator erzeugen und für eine Sekunde abspielen
const ctx = new AudioContext();
// OscillatorNode erbt von AudioScheduledSourceNode
const osc = new OscillatorNode(ctx, { type: 'sine', frequency: 440 });
osc.connect(ctx.destination);
const now = ctx.currentTime;
osc.start(now); // sofort starten
osc.stop(now + 1); // nach genau 1 Sekunde stoppen
console.log(osc instanceof AudioScheduledSourceNode);
Ende der Wiedergabe mit addEventListener und onended erkennen
const ctx = new AudioContext();
const playBeep = (freq, duration) => new Promise((resolve) => {
const osc = ctx.createOscillator();
osc.frequency.value = freq;
osc.connect(ctx.destination);
osc.addEventListener('ended', () => {
osc.disconnect(); // Ressourcen freigeben
resolve(freq);
}, { once: true });
osc.start();
osc.stop(ctx.currentTime + duration);
});
// Alternative: on-Property
const c = ctx.createConstantSource();
c.onended = () => console.log('ConstantSource beendet');
c.start();
c.stop(ctx.currentTime + 0.1);
document.querySelector('#play').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Richtlinie
const f = await playBeep(660, 0.3);
console.log(`Ton ${f} Hz fertig`);
});
Metronom: Klicks exakt auf der Audio-Zeitachse planen
const ctx = new AudioContext();
const scheduleClick = (time, accent) => {
const osc = new OscillatorNode(ctx, { frequency: accent ? 1500 : 1000 });
const gain = new GainNode(ctx, { gain: 0.5 });
osc.connect(gain).connect(ctx.destination);
// Jeder Klick ist ein neuer Knoten, weil start() nur einmal erlaubt ist
osc.start(time);
osc.stop(time + 0.05);
};
const bpm = 120;
const beat = 60 / bpm;
const startAt = ctx.currentTime + 0.1;
for (let i = 0; i < 8; i++) {
scheduleClick(startAt + i * beat, i % 4 === 0);
}
console.log(`8 Klicks geplant, Abstand ${beat} s`);
// Wichtig · Fallstricke
- Nur ein
start()pro Knoten: Ein zweiter Aufruf wirft einenInvalidStateError. Einstop()vorstart()wirft ebenfalls einenInvalidStateError. Für eine erneute Wiedergabe erzeugt man einen neuen Knoten. Gestoppte Knoten ohne Verbindung und ohne Referenz räumt der Garbage Collector ab. - Mehrere
stop()-Aufrufe: Ein späterer Aufruf ersetzt den zuvor geplanten Stoppzeitpunkt. So lässt sich eine Note verlängern oder vorzeitig beenden. - Autoplay-Richtlinien: Browser starten einen
AudioContextoft im Zustand"suspended". Man ruftctx.resume()in einem Handler für eine Nutzeraktion auf, zum Beispiel einem Klick. Sonst bleibt die Wiedergabe stumm, obwohlstart()fehlerfrei durchläuft. - Zeitbasis:
whenbezieht sich aufAudioContext.currentTime, nicht aufperformance.now()oderDate.now(). Man plant am besten etwas in die Zukunft, zum Beispiel mitcurrentTime + 0.05, damit es keine Knackser und keine verschluckten Starts gibt. - Knacksen vermeiden: Ein hartes
stop()kann ein Klicken erzeugen. Deshalb blendet man die Lautstärke vorher über einenGainNodeaus, etwa mitlinearRampToValueAtTime. - Kompatibilität: Alle modernen Browser unterstützen das Interface. Ältere Safari-Versionen brauchten
webkitAudioContext, und sehr alte Implementierungen kanntennoteOn()/noteOff()stattstart()/stop(). Den KonstruktorAudioScheduledSourceNodekann man nicht direkt aufrufen, er wirft einenTypeError.