Signatur
Beschreibung
Das AudioProcessingEvent wird im Ereignis audioprocess eines ScriptProcessorNode übergeben. Es enthält den aktuellen Block an Audiodaten (inputBuffer), einen zu befüllenden Ausgabepuffer (outputBuffer) und den Zeitpunkt, zu dem der Block abgespielt wird (playbackTime). So lassen sich Audiosamples direkt in JavaScript analysieren oder verändern, etwa für Pegelmessung, Effekte oder Rauschgeneratoren.
Die Eigenschaften im Überblick:
inputBuffer(AudioBuffer, nur lesbar): die Eingangsdaten mit so vielen Kanälen, wie beicreateScriptProcessor()angegeben.outputBuffer(AudioBuffer, nur lesbar): der Puffer, in den die Ausgabedaten geschrieben werden müssen.playbackTime(number, nur lesbar): Zeit in Sekunden im Koordinatensystem vonAudioContext.currentTime, zu der der Block hörbar wird.
Da der Handler im Hauptthread läuft, konkurriert die Audioverarbeitung mit Layout, Rendering und sonstigem JavaScript – das führt leicht zu Knacksern und Aussetzern. Deshalb ist ScriptProcessorNode samt AudioProcessingEvent veraltet; für neuen Code sollte AudioWorklet mit AudioWorkletProcessor verwendet werden, das in einem eigenen Audio-Thread läuft.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, üblicherweise "audioprocess" (nur beim Konstruktor new AudioProcessingEvent(type, options)). |
|
| $options Pflicht | { inputBuffer: AudioBuffer, outputBuffer: AudioBuffer, playbackTime: number } | Objekt mit den Pflichtfeldern inputBuffer, outputBuffer und playbackTime sowie optional den Feldern aus EventInit (bubbles, cancelable, composed). |
Rückgabewert
inputBuffer, outputBuffer und playbackTime; in der Praxis wird es vom Browser erzeugt und an den audioprocess-Handler übergeben.Beispiele
Lautstärke halbieren mit onaudioprocess
const ctx = new AudioContext();
const osc = ctx.createOscillator();
const processor = ctx.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (event) => {
const input = event.inputBuffer.getChannelData(0);
const output = event.outputBuffer.getChannelData(0);
for (let i = 0; i < input.length; i++) {
output[i] = input[i] * 0.5; // Pegel halbieren
}
};
osc.connect(processor);
processor.connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 2);
Mikrofon-Pegel (RMS) per addEventListener messen
const ctx = new AudioContext();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = ctx.createMediaStreamSource(stream);
const processor = ctx.createScriptProcessor(2048, 1, 1);
const onProcess = (event) => {
const data = event.inputBuffer.getChannelData(0);
let sum = 0;
for (const sample of data) sum += sample * sample;
const rms = Math.sqrt(sum / data.length);
console.log(`Pegel: ${rms.toFixed(3)} @ ${event.playbackTime.toFixed(2)} s`);
};
processor.addEventListener('audioprocess', onProcess);
source.connect(processor);
processor.connect(ctx.destination); // nötig, damit das Ereignis feuert
// Nach 5 Sekunden aufräumen
setTimeout(() => {
processor.removeEventListener('audioprocess', onProcess);
source.disconnect();
processor.disconnect();
stream.getTracks().forEach((t) => t.stop());
}, 5000);
Weißes Rauschen erzeugen und Ereignis manuell konstruieren
const ctx = new AudioContext();
const noise = ctx.createScriptProcessor(4096, 0, 2);
noise.onaudioprocess = ({ outputBuffer }) => {
for (let ch = 0; ch < outputBuffer.numberOfChannels; ch++) {
const out = outputBuffer.getChannelData(ch);
for (let i = 0; i < out.length; i++) out[i] = Math.random() * 2 - 1;
}
};
noise.connect(ctx.destination);
// Konstruktor, z. B. für Tests
const buf = ctx.createBuffer(1, 128, ctx.sampleRate);
const evt = new AudioProcessingEvent('audioprocess', {
inputBuffer: buf,
outputBuffer: buf,
playbackTime: 0
});
console.log(evt.type, evt.inputBuffer.length);
// Wichtig · Fallstricke
- Veraltet:
ScriptProcessorNodeundAudioProcessingEventsind deprecated. Browser unterstützen sie weiterhin, neue Projekte sollten aberAudioWorkletnutzen. - Hauptthread: Aufwendige Berechnungen im Handler verursachen Knackser. Größere Puffer (z. B. 4096) sind stabiler, erhöhen aber die Latenz. Gültige Puffergrößen sind 256 bis 16384 (Zweierpotenzen) oder
0für die Wahl durch den Browser. - Keine Auslösung ohne Verbindung: In Chrome feuert
audioprocessnur, wenn der Knoten mit einem Ziel (z. B.ctx.destination) verbunden ist. - Ausgabe immer schreiben: Wird
outputBuffernicht befüllt, bleibt er stumm (Nullen). Für reine Analyse ist das in Ordnung, sonst ist Stille die Folge. - Autoplay-Regeln: Ein
AudioContextstartet oft im Zustandsuspended;ctx.resume()erst nach einer Benutzerinteraktion aufrufen. - Die Puffer werden zwischen den Aufrufen wiederverwendet – Referenzen auf
getChannelData()nicht über den Handler hinaus aufbewahren, sondern bei Bedarf kopieren (Float32Array.from()).