Signatur
Beschreibung
Die Methode createBufferSource() von BaseAudioContext (und damit von AudioContext und OfflineAudioContext) erzeugt einen AudioBufferSourceNode. Dieser Knoten spielt Audiodaten ab, die als AudioBuffer vollständig im Speicher liegen – etwa nach decodeAudioData() oder per createBuffer() selbst erzeugt.
Typische Einsatzfälle sind kurze, latenzkritische Klänge: Soundeffekte in Spielen, Klicks, Drum-Samples oder präzise zeitgesteuerte Wiedergabe über start(when, offset, duration). Für lange Musikstücke oder Streams eignet sich dagegen eher ein <audio>-Element in Verbindung mit createMediaElementSource(), da ein AudioBuffer dekodierte PCM-Daten enthält und entsprechend viel Speicher belegt.
Wichtig: Ein AudioBufferSourceNode ist ein Wegwerf-Objekt. start() kann pro Knoten nur einmal aufgerufen werden. Wer einen Klang mehrfach abspielen will, erzeugt jedes Mal einen neuen Knoten – das ist günstig, weil der eigentliche AudioBuffer wiederverwendet werden kann. Eigenschaften wie loop, loopStart, loopEnd, playbackRate und detune steuern die Wiedergabe.
Alternativ kann der Knoten direkt über den Konstruktor new AudioBufferSourceNode(context, options) erzeugt werden, was Optionen wie buffer und loop gleich beim Anlegen erlaubt.
Rückgabewert
AudioBufferSourceNode ohne zugewiesenen Puffer (buffer ist null).Beispiele
Audiodatei laden 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 () => {
// Autoplay-Richtlinie: Kontext nach Nutzerinteraktion fortsetzen
if (ctx.state === 'suspended') await ctx.resume();
const buffer = await loadSound('/sounds/klick.mp3');
const source = ctx.createBufferSource();
source.buffer = buffer;
source.connect(ctx.destination);
source.start();
source.addEventListener('ended', () => console.log('Wiedergabe beendet'));
});
Soundeffekt mehrfach abspielen (neuer Knoten pro Wiedergabe)
const ctx = new AudioContext();
let shotBuffer = null;
const init = async () => {
const res = await fetch('/sounds/schuss.wav');
shotBuffer = await ctx.decodeAudioData(await res.arrayBuffer());
};
const playShot = (rate = 1) => {
if (!shotBuffer) return;
const source = ctx.createBufferSource();
source.buffer = shotBuffer; // Puffer wird wiederverwendet
source.playbackRate.value = rate; // Tonhöhe variieren
const gain = ctx.createGain();
gain.gain.value = 0.5;
source.connect(gain).connect(ctx.destination);
source.start();
};
await init();
playShot();
playShot(1.2); // gleichzeitig, leicht höher
Selbst erzeugtes Rauschen in Schleife abspielen
const ctx = new AudioContext();
const seconds = 2;
const buffer = ctx.createBuffer(1, ctx.sampleRate * seconds, ctx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < data.length; i++) {
data[i] = Math.random() * 2 - 1; // weißes Rauschen
}
const source = ctx.createBufferSource();
source.buffer = buffer;
source.loop = true;
source.connect(ctx.destination);
source.start();
// Nach 5 Sekunden stoppen
source.stop(ctx.currentTime + 5);
console.log(source.buffer.duration);
// Wichtig · Fallstricke
- Nur einmal startbar: Ein zweiter Aufruf von
start()auf demselben Knoten wirft einenInvalidStateError. Für jede Wiedergabe einen neuen Knoten erzeugen; denAudioBufferdagegen cachen. - Autoplay-Richtlinien: Browser starten einen
AudioContextoft im Zustandsuspended. Erst nach einer Nutzergeste (Klick, Tastendruck)ctx.resume()aufrufen, sonst bleibt es stumm. - Speicherbedarf:
AudioBufferenthalten dekodierte 32-Bit-Float-Samples. Eine Minute Stereo bei 48 kHz belegt ca. 23 MB – für lange Titel liebercreateMediaElementSource()verwenden. - Der Puffer kann nur einmal gesetzt werden: Eine erneute Zuweisung eines anderen, nicht-
nullPuffers anbufferwirft einen Fehler. - CORS: Beim Laden fremder Audiodateien per
fetch()muss der Server passende CORS-Header senden. - Kompatibilität: In allen modernen Browsern verfügbar; sehr alte Safari-Versionen benötigten
webkitAudioContext.