Signatur
Beschreibung
currentFrame ist eine globale, schreibgeschützte Eigenschaft innerhalb des AudioWorkletGlobalScope, also in dem Skript, das Sie per audioContext.audioWorklet.addModule() laden. Sie gibt den Index des ersten Sample-Frames des Audio-Blocks an, der gerade verarbeitet wird. Der Wert beginnt bei 0, wenn der Kontext startet, und wächst mit jedem sogenannten Render-Quantum (in der Regel 128 Frames) weiter.
Die Eigenschaft ist das Gegenstück zu currentTime, allerdings in Samples statt in Sekunden: Es gilt currentTime === currentFrame / sampleRate. Weil der Wert eine Ganzzahl ist, eignet er sich besonders für sample-genaues Timing, etwa für Metronome, Sequenzer, das Planen von Ereignissen auf ein bestimmtes Sample oder das Messen von Zeitabständen ohne Rundungsfehler durch Gleitkommazahlen.
Typischerweise liest man currentFrame in der Methode process() eines AudioWorkletProcessor. Da während der Verarbeitung eines Blocks alle Prozessoren denselben Wert sehen, eignet er sich auch zur Synchronisierung mehrerer Prozessoren im selben Kontext.
Rückgabewert
process() um die Blockgröße (meist 128).Beispiele
currentFrame in process() auslesen und an den Haupt-Thread melden
// frame-logger.js (AudioWorklet-Modul)
class FrameLogger extends AudioWorkletProcessor {
constructor() {
super();
this.lastReport = 0;
}
process(inputs, outputs) {
// Etwa einmal pro Sekunde melden
if (currentFrame - this.lastReport >= sampleRate) {
this.lastReport = currentFrame;
this.port.postMessage({ frame: currentFrame, time: currentTime });
}
return true;
}
}
registerProcessor('frame-logger', FrameLogger);
// main.js (Haupt-Thread)
const ctx = new AudioContext();
await ctx.audioWorklet.addModule('frame-logger.js');
const node = new AudioWorkletNode(ctx, 'frame-logger');
node.port.onmessage = ({ data }) => console.log(data);
node.connect(ctx.destination);
Sample-genaues Metronom (Klick jede halbe Sekunde)
// metronome.js
class Metronome extends AudioWorkletProcessor {
constructor() {
super();
this.interval = Math.round(sampleRate * 0.5); // 0,5 s in Frames
this.clickLength = 200;
}
process(inputs, outputs) {
const channel = outputs[0][0];
for (let i = 0; i < channel.length; i++) {
const frame = currentFrame + i; // absoluter Frame-Index des Samples
const pos = frame % this.interval;
channel[i] = pos < this.clickLength
? Math.sin(2 * Math.PI * 1000 * pos / sampleRate) * 0.5
: 0;
}
return true;
}
}
registerProcessor('metronome', Metronome);
Ereignis auf einen bestimmten Frame planen
// scheduler.js
class Scheduler extends AudioWorkletProcessor {
constructor() {
super();
this.targetFrame = null;
this.port.onmessage = ({ data }) => {
// Sekunden (AudioContext.currentTime-Basis) in Frames umrechnen
this.targetFrame = Math.round(data.at * sampleRate);
};
}
process(inputs, outputs) {
const blockSize = outputs[0][0].length;
if (this.targetFrame !== null &&
this.targetFrame >= currentFrame &&
this.targetFrame < currentFrame + blockSize) {
const offset = this.targetFrame - currentFrame;
this.port.postMessage(`Ereignis in Block ab ${currentFrame}, Offset ${offset}`);
this.targetFrame = null;
}
return true;
}
}
registerProcessor('scheduler', Scheduler);
// main.js
// node.port.postMessage({ at: ctx.currentTime + 2 });
// Wichtig · Fallstricke
- Nur im AudioWorklet-Kontext:
currentFrameexistiert ausschließlich imAudioWorkletGlobalScope. Im Haupt-Thread gibt es dafür keine Entsprechung; dort verwenden SieAudioContext.currentTimeund rechnen mitsampleRateum. - Block-Granularität: Der Wert bezeichnet nur den ersten Frame des aktuellen Blocks. Für das einzelne Sample innerhalb von
process()addieren Sie den Schleifenindex (currentFrame + i). - Blockgröße nicht fest einprogrammieren: Nutzen Sie die Länge der Ausgabe-Arrays statt der Zahl 128 – künftige Versionen der Web Audio API sehen einstellbare Render-Quantum-Größen vor.
- Angehaltener Kontext: Ist der
AudioContextim Zustandsuspended, wirdprocess()nicht aufgerufen undcurrentFramewächst nicht weiter. - Genauigkeit: Als Ganzzahl bleibt der Wert auch bei langen Laufzeiten exakt (sicher bis
Number.MAX_SAFE_INTEGER), während Gleitkomma-Rechnungen mitcurrentTimeRundungsfehler ansammeln können. - Kompatibilität: Unterstützt in Chrome/Edge 66+, Firefox 76+ und Safari 14.1+. AudioWorklets setzen einen sicheren Kontext (HTTPS) voraus.