Start · Sprachen · JavaScript · Referenz · BaseAudioContext.currentTime

BaseAudioContext.currentTime

Eigenschaft

Liefert die schreibgeschützte, monoton steigende Audiozeit des Kontextes in Sekunden – die Basis für sample-genaues Planen von Audioereignissen.

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

Signatur

BaseAudioContext.currentTime

Beschreibung

Die schreibgeschützte Eigenschaft currentTime gibt eine Gleitkommazahl (double) zurück. Sie zeigt an, wie viele Sekunden seit dem Start der Audiotimeline des Kontextes vergangen sind. Beim Erzeugen eines AudioContext steht sie auf 0 und steigt in Blöcken der Audio-Hardware an, sobald der Kontext läuft (state === "running"). Solange der Kontext angehalten (suspended) oder geschlossen (closed) ist, bleibt der Wert stehen.

Wichtig ist sie vor allem für das Planen von Audioereignissen. Methoden wie AudioScheduledSourceNode.start() und stop() sowie Automationsmethoden wie AudioParam.setValueAtTime() oder linearRampToValueAtTime() erwarten Zeitangaben in genau dieser Zeitbasis. Mit ctx.currentTime + 0.5 plant man also ein Ereignis eine halbe Sekunde in der Zukunft, und zwar sample-genau und unabhängig von Verzögerungen im Haupt-Thread.

Die Audiouhr ist nicht an Date.now() oder performance.now() gekoppelt. Sie läuft im Takt der Audio-Hardware und kann leicht von der Systemuhr abweichen. Wer Audio und Grafik synchronisieren will, nutzt beim AudioContext besser getOutputTimestamp(). Bei einem OfflineAudioContext läuft currentTime nur während des Renderns und steigt dabei schneller als in Echtzeit.

Rückgabewert

Typ
number
Beschreibung
Die Zeit in Sekunden seit dem Start der Audiotimeline des Kontextes als Gleitkommazahl (≥ 0). Der Wert ist schreibgeschützt und nimmt nie ab.

Beispiele

Aktuelle Audiozeit auslesen

const ctx = new AudioContext();
console.log(ctx.currentTime); // direkt nach dem Erzeugen

document.querySelector('#start').addEventListener('click', async () => {
  await ctx.resume(); // Autoplay-Richtlinie: erst nach einer Benutzeraktion
  setTimeout(() => {
    console.log(`Audiozeit: ${ctx.currentTime.toFixed(3)} s`);
  }, 1000);
});
0 Audiozeit: 1.003 s

Ton exakt planen: Start in 0,5 s, Dauer 1 s

const ctx = new AudioContext();

const playBeep = (frequency = 440) => {
  const osc = ctx.createOscillator();
  const gain = ctx.createGain();
  osc.frequency.value = frequency;
  osc.connect(gain).connect(ctx.destination);

  const t = ctx.currentTime + 0.5; // Startzeitpunkt in der Audiotimeline
  gain.gain.setValueAtTime(0, t);
  gain.gain.linearRampToValueAtTime(0.3, t + 0.05); // sanftes Einblenden
  gain.gain.linearRampToValueAtTime(0, t + 1);      // Ausblenden

  osc.start(t);
  osc.stop(t + 1);
};

document.querySelector('#beep').addEventListener('click', () => playBeep(660));

Metronom mit Look-ahead-Planung

const ctx = new AudioContext();
const bpm = 120;
const interval = 60 / bpm;   // Sekunden pro Schlag
const lookAhead = 0.1;       // so weit im Voraus planen (s)
let nextNote = ctx.currentTime + 0.1;

const click = (time) => {
  const osc = ctx.createOscillator();
  osc.frequency.value = 1000;
  osc.connect(ctx.destination);
  osc.start(time);
  osc.stop(time + 0.03);
};

// Der Timer im Haupt-Thread darf ungenau sein, weil die Töne
// über currentTime sample-genau geplant werden.
const scheduler = () => {
  while (nextNote < ctx.currentTime + lookAhead) {
    click(nextNote);
    nextNote += interval;
  }
};
const timerId = setInterval(scheduler, 25);

// Stoppen: clearInterval(timerId);

currentTime im OfflineAudioContext

const offline = new OfflineAudioContext(1, 44100 * 2, 44100); // 2 s Mono
const osc = offline.createOscillator();
osc.connect(offline.destination);
osc.start(0);

console.log('Vor dem Rendern:', offline.currentTime);
const buffer = await offline.startRendering();
console.log('Nach dem Rendern:', offline.currentTime);
console.log('Pufferlänge:', buffer.duration, 's');
Vor dem Rendern: 0 Nach dem Rendern: 2 Pufferlänge: 2 s

// Wichtig · Fallstricke

  • Autoplay-Richtlinien: Ein ohne Benutzeraktion erzeugter AudioContext startet in vielen Browsern im Zustand suspended. Dann bleibt currentTime auf 0 stehen, bis resume() aufgerufen wird.
  • Nicht in der Vergangenheit planen: Liegt eine Zeitangabe für start() oder setValueAtTime() unter currentTime, wird das Ereignis sofort ausgeführt. Deshalb immer einen kleinen Vorlauf einplanen (z. B. + 0.05).
  • Blockweise Aktualisierung: Der Wert springt in Schritten eines Render-Quantums (meist 128 Samples, bei 48 kHz etwa 2,7 ms) oder in noch größeren Hardware-Puffern weiter. Für Grafik-Synchronisation eignen sich AudioContext.getOutputTimestamp() und outputLatency besser.
  • Datenschutz: Wegen Fingerprinting- und Timing-Angriffen runden manche Browser (z. B. Firefox mit privacy.reduceTimerPrecision) den Wert gröber.
  • Kein setInterval-Ersatz: setTimeout und setInterval sind für das Timing von Audio zu ungenau. Sie eignen sich nur, um Ereignisse vorab über currentTime einzuplanen (Look-ahead-Muster).
  • Wird unterstützt in allen aktuellen Browsern (Chrome, Edge, Firefox, Safari inkl. iOS). Sehr alte Safari-Versionen benötigten webkitAudioContext.