Start · Sprachen · JavaScript · Referenz · AudioBufferSourceNode

AudioBufferSourceNode

Schnittstelle

Audioquelle der Web Audio API, die im Speicher liegende Audiodaten aus einem <code>AudioBuffer</code> abspielt – ideal für kurze Klänge, Soundeffekte und Samples.

seit JavaScript Baseline: alle modernen Browser (Web Audio API) Kategorie: webapi

Signatur

interface AudioBufferSourceNode extends AudioScheduledSourceNode

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 abzuspielende AudioBuffer (kann nur einmal auf einen Wert ungleich null gesetzt 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

Typ
AudioBufferSourceNode
Beschreibung
Ein neuer, noch nicht gestarteter Quellknoten. Alternativ per Fabrikmethode 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();
});
Wiedergabe beendet

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);
2

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 einen InvalidStateError. Für jede Wiedergabe einen neuen Knoten erzeugen; den AudioBuffer wiederverwenden.
  • Buffer nur einmal setzbar: Wurde buffer einmal auf einen Buffer gesetzt, führt eine erneute Zuweisung eines anderen Buffers zu einem InvalidStateError.
  • Autoplay-Richtlinien: Browser starten einen AudioContext oft im Zustand "suspended". Erst nach einer Nutzeraktion ctx.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 MediaElementAudioSourceNode verwenden.
  • playbackRate ändert Geschwindigkeit und Tonhöhe gleichzeitig; eine Zeitdehnung ohne Tonhöhenänderung bietet der Knoten nicht.
  • Ohne loop endet die Wiedergabe am Buffer-Ende, und ended wird ausgelöst; bei loop: true nur nach stop().
  • Der Konstruktor new AudioBufferSourceNode() wird von allen modernen Browsern unterstützt; in sehr alten Safari-Versionen nur createBufferSource() (teils mit Präfix webkitAudioContext).