Start · Sprachen · JavaScript · Referenz · BaseAudioContext.createBufferSource()

BaseAudioContext.createBufferSource()

Methode

Erzeugt einen neuen <code>AudioBufferSourceNode</code>, mit dem sich Audiodaten aus einem <code>AudioBuffer</code> im Speicher abspielen lassen.

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

Signatur

BaseAudioContext.prototype.createBufferSource()

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

Typ
AudioBufferSourceNode
Beschreibung
Ein neuer, noch nicht gestarteter 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'));
});
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);
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 dagegen cachen.
  • Autoplay-Richtlinien: Browser starten einen AudioContext oft im Zustand suspended. Erst nach einer Nutzergeste (Klick, Tastendruck) ctx.resume() aufrufen, sonst bleibt es stumm.
  • Speicherbedarf: AudioBuffer enthalten dekodierte 32-Bit-Float-Samples. Eine Minute Stereo bei 48 kHz belegt ca. 23 MB – für lange Titel lieber createMediaElementSource() verwenden.
  • Der Puffer kann nur einmal gesetzt werden: Eine erneute Zuweisung eines anderen, nicht-null Puffers an buffer wirft 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.