Signatur
Beschreibung
Die Eigenschaft buffer legt fest, welche Audiodaten ein AudioBufferSourceNode abspielt. Der zugewiesene AudioBuffer liegt vollständig im Arbeitsspeicher. Deshalb eignet sich der Knoten gut für kurze Klänge mit geringer Verzögerung, etwa Soundeffekte in Spielen, Klicks in der Oberfläche, Samples oder selbst erzeugte Signale wie Rauschen.
Einen Puffer bekommst du meist, indem du eine Audiodatei mit fetch() lädst und mit BaseAudioContext.decodeAudioData() dekodierst. Alternativ legst du mit AudioContext.createBuffer() oder new AudioBuffer() einen leeren Puffer an und füllst ihn selbst mit Samples. Den Puffer kannst du vor oder nach start() zuweisen. Ist beim Start noch kein Puffer gesetzt, gibt der Knoten Stille aus, bis einer zugewiesen wird.
Wichtig: Einen AudioBufferSourceNode kannst du nur einmal starten. Einen Puffer (nicht null) kannst du ihm nur einmal zuweisen. Willst du einen Klang mehrfach abspielen, erzeugst du für jede Wiedergabe einen neuen, günstigen Quellknoten und verwendest denselben AudioBuffer wieder. Das Dekodieren ist der teure Teil.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | AudioBuffer | null | null | Der Puffer, der abgespielt werden soll (beim Setzen). Er enthält einen oder mehrere Kanäle mit Float32-Samples. |
Rückgabewert
AudioBuffer oder null, wenn noch keiner gesetzt wurde.Beispiele
Audiodatei laden, dekodieren und abspielen
const ctx = new AudioContext();
const loadSound = async (url) => {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
return ctx.decodeAudioData(arrayBuffer);
};
document.querySelector('#play').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Sperre aufheben
const audioBuffer = await loadSound('/sounds/klick.mp3');
const source = ctx.createBufferSource();
source.buffer = audioBuffer;
source.connect(ctx.destination);
source.start();
console.log(`Dauer: ${source.buffer.duration.toFixed(2)} s`);
});
Einen dekodierten Puffer mehrfach abspielen
const ctx = new AudioContext();
const response = await fetch('/sounds/schuss.wav');
const shotBuffer = await ctx.decodeAudioData(await response.arrayBuffer());
// Für jede Wiedergabe einen neuen Quellknoten, denselben Puffer
const playShot = () => {
const source = new AudioBufferSourceNode(ctx, { buffer: shotBuffer });
source.connect(ctx.destination);
source.start();
};
playShot();
setTimeout(playShot, 200); // überlappend möglich
Weißes Rauschen erzeugen und in Schleife abspielen
const ctx = new AudioContext();
const seconds = 2;
const noise = ctx.createBuffer(1, ctx.sampleRate * seconds, ctx.sampleRate);
const data = noise.getChannelData(0);
for (let i = 0; i < data.length; i++) {
data[i] = Math.random() * 2 - 1; // Werte zwischen -1 und 1
}
const source = ctx.createBufferSource();
console.log(source.buffer); // noch kein Puffer
source.buffer = noise;
source.loop = true;
source.connect(ctx.destination);
source.start();
source.stop(ctx.currentTime + 5);
Zweites Zuweisen löst einen Fehler aus
const ctx = new AudioContext();
const a = ctx.createBuffer(1, 44100, 44100);
const b = ctx.createBuffer(1, 44100, 44100);
const source = ctx.createBufferSource();
source.buffer = a;
try {
source.buffer = b;
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Nur einmal zuweisen: Hat der Knoten schon einen Puffer erhalten (nicht
null), wirft jede weitere Zuweisung eines Puffers eineInvalidStateError-DOMException. Das gilt auch, wenn du zwischendurchnullsetzt. - Einmal starten:
start()kannst du pro Knoten nur einmal aufrufen. Für wiederholte Wiedergabe erzeugst du neue Knoten. Das ist so vorgesehen und kostet wenig. - Speicherverbrauch: Ein
AudioBufferhält dekodierte PCM-Daten (32-Bit-Float) im Arbeitsspeicher. Eine Minute Stereo bei 48 kHz belegt etwa 23 MB. Für lange Musikstücke eignen sich<audio>mitMediaElementAudioSourceNodebesser. - Abtastrate: Weicht die Abtastrate des Puffers von der des Kontexts ab, rechnet der Browser sie automatisch um (Resampling).
- Autoplay: Browser starten einen
AudioContextoft im Zustandsuspended. Rufectx.resume()nach einer Nutzeraktion auf. - CORS: Audiodateien von fremden Servern lassen sich mit
fetch()nur laden, wenn der Server passende CORS-Header sendet. - Die Eigenschaft wird in allen aktuellen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Sehr alte Safari-Versionen benötigten
webkitAudioContext.