Signatur
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
AnalyserNodeauslesen.
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
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');
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);
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();
// 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 vonstartRendering()nie erfüllt. InvalidStateErrortritt auf, wenn der abgerundete Zeitpunkt negativ ist, nicht nachcurrentTimeliegt, 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
currentTimein der Pause oft minimal vor dem gewünschten Wert. Planen Sie zwei Pausen nicht dichter als128 / sampleRateSekunden. - 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'.