Start · Sprachen · JavaScript · Referenz · AudioScheduledSourceNode.start()

AudioScheduledSourceNode.start()

Methode

Legt fest, zu welchem Zeitpunkt auf der Uhr des <code>AudioContext</code> eine Audioquelle wie <code>OscillatorNode</code> oder <code>AudioBufferSourceNode</code> anfängt zu spielen.

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

Signatur

AudioScheduledSourceNode.prototype.start(when)

Beschreibung

start() ist auf allen Knoten verfügbar, die von AudioScheduledSourceNode erben. Dazu gehören OscillatorNode, AudioBufferSourceNode und ConstantSourceNode. Die Methode spielt nicht unbedingt sofort ab. Sie plant den Start zu einem Zeitpunkt auf der Uhr des Audio-Kontexts (AudioContext.currentTime, in Sekunden). Dadurch lassen sich Klänge auf das Sample genau timen, zum Beispiel für Metronome, Sequenzer oder Spiel-Soundeffekte. setTimeout ist dafür zu ungenau.

Übergibt man keinen Zeitpunkt oder einen Wert, der kleiner oder gleich currentTime ist, startet die Wiedergabe sofort. Wie lange die Quelle spielt, steuert man mit stop(). Das Ende der Wiedergabe meldet das Ereignis ended.

Wichtig: Jeder Quellknoten lässt sich nur einmal starten. Quellknoten sind als billige Wegwerf-Objekte gedacht: Für jeden neuen Ton erzeugt man einen neuen Knoten. Teure Daten wie ein AudioBuffer lassen sich dabei wiederverwenden.

AudioBufferSourceNode überschreibt die Methode mit der erweiterten Signatur start(when, offset, duration). Damit kann man ab einer bestimmten Stelle im Puffer abspielen und die Spieldauer begrenzen.

Parameter

Name Typ Default Beschreibung
$when number 0 Zeitpunkt in Sekunden auf der Uhr des Kontexts (AudioContext.currentTime), zu dem die Wiedergabe beginnt. Bei 0 oder einem Wert kleiner als currentTime startet die Wiedergabe sofort. Negative Werte lösen einen RangeError aus.
$offset number 0 Nur bei AudioBufferSourceNode: Stelle im Puffer in Sekunden, ab der abgespielt wird.
$duration number Nur bei AudioBufferSourceNode: Wie lange abgespielt wird, in Sekunden. Ohne Angabe läuft die Wiedergabe bis zum Ende des Puffers bzw. bis stop() aufgerufen wird.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Einen Ton sofort starten und nach einer Sekunde stoppen

const ctx = new AudioContext();

const playBeep = () => {
  const osc = new OscillatorNode(ctx, { type: 'sine', frequency: 440 });
  osc.connect(ctx.destination);

  osc.start();                       // sofort
  osc.stop(ctx.currentTime + 1);     // nach 1 Sekunde
  osc.addEventListener('ended', () => console.log('Ton beendet'));
};

// Wegen der Autoplay-Regeln nur nach einer Nutzeraktion
document.querySelector('#play').addEventListener('click', async () => {
  if (ctx.state === 'suspended') await ctx.resume();
  playBeep();
});
Ton beendet

Metronom: Klicks exakt im Voraus planen

const ctx = new AudioContext();

const scheduleClicks = (bpm = 120, count = 8) => {
  const interval = 60 / bpm;
  const startAt = ctx.currentTime + 0.1; // kleiner Puffer

  for (let i = 0; i < count; i++) {
    const t = startAt + i * interval;
    const osc = new OscillatorNode(ctx, { frequency: i % 4 === 0 ? 1000 : 800 });
    const gain = new GainNode(ctx, { gain: 0.5 });
    osc.connect(gain).connect(ctx.destination);

    osc.start(t);          // exakt geplanter Startzeitpunkt
    osc.stop(t + 0.05);    // kurzer Klick
  }
  console.log(`${count} Klicks geplant ab ${startAt.toFixed(2)} s`);
};

document.querySelector('#metronome').addEventListener('click', async () => {
  await ctx.resume();
  scheduleClicks();
});
8 Klicks geplant ab 0.10 s

Ausschnitt aus einer Audiodatei abspielen (AudioBufferSourceNode)

const ctx = new AudioContext();

const loadBuffer = async (url) => {
  const res = await fetch(url);
  const data = await res.arrayBuffer();
  return ctx.decodeAudioData(data);
};

const playSnippet = (buffer, offset, duration) => {
  // Für jede Wiedergabe einen NEUEN Quellknoten erzeugen
  const src = new AudioBufferSourceNode(ctx, { buffer });
  src.connect(ctx.destination);
  src.start(ctx.currentTime, offset, duration);
};

document.querySelector('#snippet').addEventListener('click', async () => {
  await ctx.resume();
  const buffer = await loadBuffer('/audio/song.mp3');
  playSnippet(buffer, 30, 5); // ab Sekunde 30, für 5 Sekunden
});

Fehler beim zweiten start()-Aufruf

const ctx = new AudioContext();
const osc = ctx.createOscillator();
osc.connect(ctx.destination);

osc.start();
try {
  osc.start(); // nicht erlaubt
} catch (err) {
  console.log(err.name);
}
osc.stop();
InvalidStateError

// Wichtig · Fallstricke

  • Nur einmal pro Knoten: Ein zweiter Aufruf von start() auf demselben Knoten löst eine InvalidStateError-DOMException aus. Das gilt auch nach stop(). Für jede neue Wiedergabe erzeugt man einen neuen Knoten.
  • Negative Werte für when, offset oder duration lösen einen RangeError aus.
  • Autoplay-Regeln: Wird ein AudioContext ohne Nutzeraktion erzeugt, ist er in vielen Browsern zunächst im Zustand "suspended". start() wirft dann keinen Fehler, aber es ist nichts zu hören. Deshalb nach einem Klick oder Tastendruck await ctx.resume() aufrufen.
  • Zeitbasis: when bezieht sich auf AudioContext.currentTime. Die Werte von Date.now() oder performance.now() passen nicht dazu. Relative Zeitpunkte daher immer als ctx.currentTime + x angeben.
  • Ältere WebKit-Versionen kannten stattdessen noteOn(). Diese Methode ist veraltet. Alle aktuellen Browser unterstützen start().
  • Bei AudioBufferSourceNode mit loop = true und ohne duration endet die Wiedergabe erst mit stop().