Start · Sprachen · JavaScript · Referenz · OfflineAudioContext.suspend()

OfflineAudioContext.suspend()

Methode

Plant eine Pause des Offline-Renderings zu einem bestimmten Zeitpunkt; das zurückgegebene Promise wird erfüllt, sobald der Kontext an dieser Stelle angehalten hat.

seit JavaScript Web Audio API; Chrome/Edge seit Langem, Safari 14. Kategorie: webapi

Signatur

OfflineAudioContext.prototype.suspend(suspendTime)

Beschreibung

suspend() plant für einen OfflineAudioContext, dass das Rendering bei einer bestimmten Audiozeit (in Sekunden, gemessen an currentTime) angehalten wird. Das Promise wird erfüllt, sobald der Kontext genau an dieser Stelle steht. Während der Pause läuft keine Audioverarbeitung, sodass Sie den Audio-Graphen gezielt verändern können: Knoten verbinden oder trennen, Parameter setzen, neue Quellen starten. Mit resume() wird das Rendering fortgesetzt.

Anders als beim Echtzeit-AudioContext, wo suspend() sofort anhält, bekommt die Offline-Variante einen Pflichtparameter für den Zeitpunkt. Dadurch lassen sich sample-genaue, reproduzierbare Eingriffe in ein Offline-Rendering umsetzen, zum Beispiel beim Export, bei Audio-Analysen oder in automatisierten Tests.

Typische Anwendungsfälle:

  • den Audio-Graphen zu festen Zeitpunkten umbauen (Effekte ein- oder ausschalten, Quellen austauschen),
  • den Fortschritt melden, indem man in regelmäßigen Abständen pausiert,
  • Zwischenstände mit einem AnalyserNode auslesen.

Pausen können Sie vor dem Aufruf von startRendering() oder während des Renderings einplanen. Der Zeitpunkt wird auf die Grenze eines Render-Quantums abgerundet. Ein Render-Quantum umfasst normalerweise 128 Sample-Frames.

Parameter

Name Typ Default Beschreibung
$suspendTime Pflicht number Zeitpunkt in Sekunden (Audiozeit des Kontexts), zu dem das Rendering angehalten werden soll. Er wird auf ein Vielfaches der Render-Quantum-Größe abgerundet (128 / sampleRate Sekunden).

Rückgabewert

Typ
Promise<void>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald der Kontext am geplanten Zeitpunkt angehalten hat. Es wird mit einem InvalidStateError (DOMException) abgelehnt, wenn der Zeitpunkt ungültig ist.

Beispiele

Lautstärke bei 1 Sekunde während des Offline-Renderings ändern

const sampleRate = 44100;
const ctx = new OfflineAudioContext(2, sampleRate * 3, sampleRate);

const osc = new OscillatorNode(ctx, { frequency: 440 });
const gain = new GainNode(ctx, { gain: 1 });
osc.connect(gain).connect(ctx.destination);
osc.start();

// Pause bei 1 s einplanen, Graph anpassen, danach weiterrendern
ctx.suspend(1).then(() => {
  console.log('Pausiert bei', ctx.currentTime.toFixed(3), 's');
  gain.gain.value = 0.2; // ab hier leiser
  return ctx.resume();
});

const buffer = await ctx.startRendering();
console.log('Fertig:', buffer.duration, 's');
Pausiert bei 0.998 s Fertig: 3 s

Fortschrittsanzeige für einen langen Export

const renderWithProgress = async (ctx, onProgress, steps = 10) => {
  const total = ctx.length / ctx.sampleRate;
  for (let i = 1; i < steps; i++) {
    const t = (total / steps) * i;
    ctx.suspend(t).then(() => {
      onProgress(Math.round((i / steps) * 100));
      ctx.resume();
    });
  }
  const buffer = await ctx.startRendering();
  onProgress(100);
  return buffer;
};

const ctx = new OfflineAudioContext(1, 48000 * 5, 48000);
const src = new OscillatorNode(ctx);
src.connect(ctx.destination);
src.start();

await renderWithProgress(ctx, (p) => console.log(`${p} %`), 4);
25 % 50 % 75 % 100 %

Ungültige Zeitpunkte abfangen

const ctx = new OfflineAudioContext(1, 44100, 44100); // 1 Sekunde

const trySuspend = async (t) => {
  try {
    await ctx.suspend(t);
    await ctx.resume();
  } catch (err) {
    console.log(`suspend(${t}) fehlgeschlagen:`, err.name);
  }
};

trySuspend(-1);   // negativ
trySuspend(2);    // hinter dem Renderende
trySuspend(0.5);
trySuspend(0.5);  // gleiche Zeit doppelt

await ctx.startRendering();
suspend(-1) fehlgeschlagen: InvalidStateError suspend(2) fehlgeschlagen: InvalidStateError suspend(0.5) fehlgeschlagen: InvalidStateError

// Wichtig · Fallstricke

  • Kein automatisches Fortsetzen: Wenn Sie nach dem Erfüllen des Promise nicht resume() aufrufen, bleibt das Rendering stehen. Dann wird auch das Promise von startRendering() nie erfüllt.
  • InvalidStateError tritt auf, wenn der abgerundete Zeitpunkt negativ ist, nicht nach currentTime liegt, bei oder hinter der Gesamtdauer des Renderings liegt oder wenn für dasselbe Render-Quantum bereits eine Pause geplant ist.
  • Abrunden: Durch das Abrunden auf Render-Quantum-Grenzen liegt currentTime in der Pause oft minimal vor dem gewünschten Wert. Planen Sie zwei Pausen nicht dichter als 128 / sampleRate Sekunden.
  • Die Pause ist nur so präzise wie ein Render-Quantum. Für sample-genaue Parameteränderungen eignen sich AudioParam.setValueAtTime() und verwandte Methoden besser.
  • Kompatibilität: Chromium-Browser und Safari unterstützen die Methode. Firefox hat sie lange nicht angeboten. Prüfen Sie deshalb vorher mit typeof OfflineAudioContext.prototype.suspend === 'function'.