Signatur
Beschreibung
AudioBufferSourceNode ist ein Quellknoten der Web Audio API. Er spielt Audiodaten ab, die bereits vollständig dekodiert als AudioBuffer im Speicher liegen. Er hat keinen Eingang und genau einen Ausgang mit so vielen Kanälen, wie der zugewiesene Buffer hat. Den Zeitplan steuern die geerbten Methoden start() und stop() sowie das Ereignis ended von AudioScheduledSourceNode.
Typische Einsatzgebiete sind kurze, zeitkritische Klänge: Soundeffekte in Spielen, Klicks in der Oberfläche, Drum-Samples oder Klänge, die exakt auf der Zeitleiste des AudioContext liegen müssen. Für lange Musikstücke oder Streams eignet sich MediaElementAudioSourceNode meist besser, weil ein AudioBuffer das komplette, unkomprimierte PCM-Audio im Arbeitsspeicher hält.
Wichtige Eigenschaften:
buffer: der abzuspielendeAudioBuffer(kann nur einmal auf einen Wert ungleichnullgesetzt werden).loop,loopStart,loopEnd: Wiederholung des ganzen Buffers oder eines Ausschnitts.playbackRate(AudioParam, a-rate-Verhalten wie k-rate): Abspielgeschwindigkeit, verändert auch die Tonhöhe.detune(AudioParam): Verstimmung in Cent.
Ein AudioBufferSourceNode ist ein Wegwerf-Objekt: start() darf pro Knoten nur einmal aufgerufen werden. Für jede Wiedergabe erzeugt man einen neuen Knoten – das ist günstig, denn der eigentliche AudioBuffer kann beliebig oft wiederverwendet werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | BaseAudioContext | Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehört (Konstruktor new AudioBufferSourceNode(context, options)). |
|
| $options.buffer | AudioBuffer|null | null | Der abzuspielende Buffer. |
| $options.loop | boolean | false | Ob der Buffer (bzw. der Loop-Bereich) endlos wiederholt wird. |
| $options.loopStart | number | 0 | Startpunkt der Schleife in Sekunden. |
| $options.loopEnd | number | 0 | Endpunkt der Schleife in Sekunden; 0 bedeutet Buffer-Ende. |
| $options.playbackRate | number | 1 | Anfangswert der Abspielgeschwindigkeit. |
| $options.detune | number | 0 | Anfangswert der Verstimmung in Cent. |
Rückgabewert
context.createBufferSource() erzeugbar.Beispiele
Sample laden und abspielen
const ctx = new AudioContext();
const loadSound = async (url) => {
const res = await fetch(url);
const data = await res.arrayBuffer();
return ctx.decodeAudioData(data);
};
document.querySelector('#play').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Sperre aufheben
const buffer = await loadSound('/sounds/klick.mp3');
const source = new AudioBufferSourceNode(ctx, { buffer });
source.connect(ctx.destination);
source.addEventListener('ended', () => console.log('Wiedergabe beendet'));
source.start();
});
Wiederverwendbarer Soundeffekt mit Tonhöhenvariation
const ctx = new AudioContext();
let shotBuffer;
const init = async () => {
const res = await fetch('/sounds/schuss.wav');
shotBuffer = await ctx.decodeAudioData(await res.arrayBuffer());
};
// Für jede Wiedergabe ein neuer Knoten – der Buffer wird geteilt
const playShot = () => {
const src = ctx.createBufferSource();
src.buffer = shotBuffer;
src.playbackRate.value = 0.9 + Math.random() * 0.2;
src.connect(ctx.destination);
src.start();
};
init().then(() => {
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') playShot();
});
});
Weißes Rauschen erzeugen und als Schleife abspielen
const ctx = new AudioContext();
const seconds = 2;
const buffer = ctx.createBuffer(1, ctx.sampleRate * seconds, ctx.sampleRate);
const channel = buffer.getChannelData(0);
for (let i = 0; i < channel.length; i++) {
channel[i] = Math.random() * 2 - 1;
}
const gain = new GainNode(ctx, { gain: 0.1 });
const noise = new AudioBufferSourceNode(ctx, { buffer, loop: true });
noise.connect(gain).connect(ctx.destination);
noise.start();
// Nach 5 Sekunden stoppen (Zeit auf der Kontext-Zeitleiste)
noise.stop(ctx.currentTime + 5);
console.log(buffer.duration);
Ausschnitt verzögert starten
const ctx = new AudioContext();
const playSegment = (buffer) => {
const src = new AudioBufferSourceNode(ctx, { buffer });
src.connect(ctx.destination);
// start(when, offset, duration): in 0,5 s starten, ab Sekunde 3, für 2 s
src.start(ctx.currentTime + 0.5, 3, 2);
};
// Wichtig · Fallstricke
- Nur einmal startbar: Ein zweiter Aufruf von
start()auf demselben Knoten wirft einenInvalidStateError. Für jede Wiedergabe einen neuen Knoten erzeugen; denAudioBufferwiederverwenden. - Buffer nur einmal setzbar: Wurde
buffereinmal auf einen Buffer gesetzt, führt eine erneute Zuweisung eines anderen Buffers zu einemInvalidStateError. - Autoplay-Richtlinien: Browser starten einen
AudioContextoft im Zustand"suspended". Erst nach einer Nutzeraktionctx.resume()aufrufen, sonst bleibt es still. - Speicherbedarf: Dekodierte Buffer sind unkomprimiertes 32-Bit-Float-PCM (ca. 10 MB pro Minute Stereo bei 44,1 kHz). Für lange Tracks besser
MediaElementAudioSourceNodeverwenden. playbackRateändert Geschwindigkeit und Tonhöhe gleichzeitig; eine Zeitdehnung ohne Tonhöhenänderung bietet der Knoten nicht.- Ohne
loopendet die Wiedergabe am Buffer-Ende, undendedwird ausgelöst; beiloop: truenur nachstop(). - Der Konstruktor
new AudioBufferSourceNode()wird von allen modernen Browsern unterstützt; in sehr alten Safari-Versionen nurcreateBufferSource()(teils mit PräfixwebkitAudioContext).