Signatur
Beschreibung
startRendering() startet die Offline-Verarbeitung eines OfflineAudioContext. Anders als beim AudioContext wird der Ton dabei nicht an die Lautsprecher ausgegeben, sondern so schnell berechnet, wie die CPU es erlaubt. Alle Knoten, Verbindungen und geplanten Parameteränderungen (z. B. setValueAtTime(), linearRampToValueAtTime()) werden berücksichtigt.
Die Methode gibt ein Promise zurück, das mit einem AudioBuffer erfüllt wird. Dessen Länge, Kanalzahl und Abtastrate entsprechen den Werten, die dem OfflineAudioContext-Konstruktor übergeben wurden. Zusätzlich löst der Kontext am Ende das Ereignis complete aus (oncomplete), dessen OfflineAudioCompletionEvent.renderedBuffer denselben Puffer enthält.
Typische Einsatzgebiete sind das Exportieren von Effektketten als Datei (z. B. WAV), das Vorberechnen von Klängen, Wellenform-Analysen, Normalisierung, Resampling oder automatisierte Audio-Tests, bei denen deterministische Ergebnisse benötigt werden.
Wichtig: Der Graph muss vor dem Aufruf vollständig aufgebaut und alle Quellen per start() eingeplant sein. Ein Kontext kann nur einmal gerendert werden.
Rückgabewert
AudioBuffer erfüllt wird. Es wird mit einer InvalidStateError-DOMException abgelehnt, wenn bereits gerendert wurde oder der Kontext geschlossen ist.Beispiele
Einen Sinuston offline erzeugen
const sampleRate = 44100;
const ctx = new OfflineAudioContext({ numberOfChannels: 1, length: sampleRate * 2, sampleRate });
const osc = new OscillatorNode(ctx, { type: 'sine', frequency: 440 });
const gain = new GainNode(ctx, { gain: 0 });
// Fade-in über 0,5 s, danach Fade-out
gain.gain.linearRampToValueAtTime(0.8, 0.5);
gain.gain.linearRampToValueAtTime(0, 2);
osc.connect(gain).connect(ctx.destination);
osc.start(0);
const buffer = await ctx.startRendering();
console.log(buffer.duration, buffer.numberOfChannels, buffer.length);
Audiodatei mit Filter bearbeiten und im normalen Kontext abspielen
const response = await fetch('/audio/stimme.mp3');
const arrayBuffer = await response.arrayBuffer();
// Zum Dekodieren genügt ein temporärer Offline-Kontext
const decoder = new OfflineAudioContext(2, 1, 44100);
const source = await decoder.decodeAudioData(arrayBuffer);
const offline = new OfflineAudioContext(
source.numberOfChannels,
source.length,
source.sampleRate
);
const player = new AudioBufferSourceNode(offline, { buffer: source });
const lowpass = new BiquadFilterNode(offline, { type: 'lowpass', frequency: 1200 });
player.connect(lowpass).connect(offline.destination);
player.start();
const rendered = await offline.startRendering();
// Ergebnis in Echtzeit wiedergeben
const live = new AudioContext();
const out = new AudioBufferSourceNode(live, { buffer: rendered });
out.connect(live.destination);
out.start();
Spitzenpegel ermitteln und complete-Ereignis nutzen
const ctx = new OfflineAudioContext(1, 44100, 44100);
const osc = new OscillatorNode(ctx, { type: 'square', frequency: 220 });
const gain = new GainNode(ctx, { gain: 0.5 });
osc.connect(gain).connect(ctx.destination);
osc.start();
ctx.addEventListener('complete', (event) => {
console.log('Fertig, Samples:', event.renderedBuffer.length);
});
try {
const buffer = await ctx.startRendering();
const data = buffer.getChannelData(0);
const peak = data.reduce((max, v) => Math.max(max, Math.abs(v)), 0);
console.log('Spitzenpegel:', peak.toFixed(2));
} catch (err) {
console.error('Rendern fehlgeschlagen:', err.name);
}
// Wichtig · Fallstricke
- Nur einmal aufrufbar: Ein zweiter Aufruf führt zu einem abgelehnten Promise mit
InvalidStateError. Für einen neuen Durchlauf einen neuenOfflineAudioContexterzeugen. - Feste Länge: Die Ausgabelänge wird im Konstruktor festgelegt (
lengthin Samples, nicht Sekunden). Audio nach dem Ende wird abgeschnitten, Stille am Ende wird nicht entfernt. - Veraltete Callback-Variante: Ältere Implementierungen gaben
voidzurück und lieferten das Ergebnis nur überoncomplete. Heute unterstützen alle modernen Browser das Promise; in sehr alten WebKit-Versionen hieß der KonstruktorwebkitOfflineAudioContext. - Speicherbedarf: Lange Renderings mit vielen Kanälen erzeugen große
Float32Arrays (4 Byte pro Sample und Kanal) – eine Stunde Stereo bei 48 kHz entspricht etwa 1,4 GB. - Blockierung: Das Rendern läuft zwar asynchron im Audio-Thread,
ScriptProcessorNodeundAudioWorklet-Code können es aber stark verlangsamen. Mitsuspend(zeit)lässt sich das Rendern an bestimmten Stellen anhalten, um den Graphen zu ändern.