Start · Sprachen · JavaScript · Referenz · BaseAudioContext

BaseAudioContext

Schnittstelle

Abstrakte Basis der Web Audio API für <code>AudioContext</code> und <code>OfflineAudioContext</code>. Stellt Fabrikmethoden für Audioknoten, den Zeitgeber und das Ziel des Audiographen bereit.

seit JavaScript Baseline: alle modernen Browser (seit 2021 als eig Kategorie: webapi

Signatur

interface BaseAudioContext extends EventTarget

Beschreibung

BaseAudioContext ist die gemeinsame Grundlage aller Audio-Kontexte der Web Audio API. Das Interface lässt sich nicht direkt instanziieren. Man arbeitet immer mit einer der beiden Unterklassen: AudioContext für die Wiedergabe in Echtzeit über die Audioausgabe des Geräts oder OfflineAudioContext, um Audio schneller als in Echtzeit in einen AudioBuffer zu rendern, z. B. für Export oder Analyse.

Das Interface bündelt alles, was beide Kontextarten brauchen:

  • Eigenschaften: currentTime (Audio-Uhr in Sekunden, auf Abtastwerte genau), destination (der AudioDestinationNode als Endpunkt des Graphen), listener (der AudioListener für räumliches Audio), sampleRate, state ("suspended", "running" oder "closed") und audioWorklet.
  • Fabrikmethoden: createOscillator(), createGain(), createBiquadFilter(), createBufferSource(), createAnalyser(), createDelay(), createDynamicsCompressor(), createConvolver(), createPanner(), createStereoPanner(), createWaveShaper(), createChannelSplitter()/createChannelMerger(), createConstantSource(), createIIRFilter(), createPeriodicWave(), createBuffer().
  • Dekodierung: decodeAudioData(arrayBuffer) wandelt komprimierte Audiodaten (MP3, AAC, Ogg, WAV …) in einen AudioBuffer um und gibt ein Promise zurück.
  • Ereignis: statechange (bzw. onstatechange) wird ausgelöst, sobald sich state ändert.

Wenn du Hilfsfunktionen schreibst, die mit beiden Kontextarten funktionieren sollen, z. B. Effektketten oder Synthesizer-Stimmen, typisiere den Parameter als BaseAudioContext. Dann läuft derselbe Code live im Browser und auch beim Offline-Rendern.

Rückgabewert

Typ
BaseAudioContext
Beschreibung
Wird nicht direkt erzeugt. Instanzen entstehen über new AudioContext() oder new OfflineAudioContext().

Beispiele

Kontext erzeugen und einen Ton abspielen

// AudioContext erbt von BaseAudioContext
const ctx = new AudioContext();
console.log(ctx instanceof BaseAudioContext);

document.querySelector('#play').addEventListener('click', async () => {
  if (ctx.state === 'suspended') await ctx.resume();

  const osc = ctx.createOscillator();
  const gain = ctx.createGain();
  osc.frequency.value = 440;
  gain.gain.setValueAtTime(0.2, ctx.currentTime);
  gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 1);

  osc.connect(gain).connect(ctx.destination);
  osc.start();
  osc.stop(ctx.currentTime + 1);
});
true

Wiederverwendbare Effektkette für beide Kontextarten

// Funktioniert mit AudioContext UND OfflineAudioContext
const createLowpassChain = (/** @type {BaseAudioContext} */ ctx, cutoff = 800) => {
  const filter = ctx.createBiquadFilter();
  filter.type = 'lowpass';
  filter.frequency.value = cutoff;
  const out = ctx.createGain();
  out.gain.value = 0.8;
  filter.connect(out).connect(ctx.destination);
  return filter; // Eingang der Kette
};

// Offline 2 Sekunden Stereo mit 44,1 kHz rendern
const offline = new OfflineAudioContext(2, 44100 * 2, 44100);
const input = createLowpassChain(offline, 1200);
const osc = offline.createOscillator();
osc.type = 'sawtooth';
osc.connect(input);
osc.start();

const rendered = await offline.startRendering();
console.log(rendered.duration, rendered.numberOfChannels);
2 2

Audiodatei laden, dekodieren und abspielen

const ctx = new AudioContext();

const loadSound = async (url) => {
  const res = await fetch(url);
  const data = await res.arrayBuffer();
  return ctx.decodeAudioData(data); // Promise<AudioBuffer>
};

const buffer = await loadSound('/sounds/klick.mp3');
console.log(`Dauer: ${buffer.duration.toFixed(2)} s, Rate: ${buffer.sampleRate} Hz`);

const source = ctx.createBufferSource();
source.buffer = buffer;
source.connect(ctx.destination);
source.start();
Dauer: 0.35 s, Rate: 44100 Hz

Zustandsänderungen beobachten

const ctx = new AudioContext();

const onState = () => console.log('Zustand:', ctx.state);
ctx.addEventListener('statechange', onState);

await ctx.resume();   // nach einer Nutzeraktion
await ctx.suspend();

ctx.removeEventListener('statechange', onState);
// Alternative über die on-Property:
ctx.onstatechange = () => console.log('neu:', ctx.state);
await ctx.close();
Zustand: running Zustand: suspended neu: closed

// Wichtig · Fallstricke

  • Nicht instanziierbar: new BaseAudioContext() wirft einen TypeError. Verwende stattdessen AudioContext oder OfflineAudioContext.
  • Autoplay-Richtlinien: Browser starten einen AudioContext oft im Zustand "suspended". Rufe resume() erst nach einer Nutzeraktion auf, etwa einem Klick. resume(), suspend() und close() gehören übrigens zu AudioContext, nicht zu BaseAudioContext. Beim OfflineAudioContext gibt es zusätzlich startRendering().
  • Knoten sind an ihren Kontext gebunden: Knoten aus verschiedenen Kontexten lassen sich nicht miteinander verbinden. Ein Versuch löst einen InvalidAccessError aus.
  • Ressourcen: Jeder AudioContext belegt System-Audioressourcen, und manche Browser begrenzen die Anzahl. Verwende einen Kontext pro Anwendung und gib ihn mit close() frei.
  • decodeAudioData: Die Methode übernimmt den übergebenen ArrayBuffer (er wird „detached“) und ist danach nicht mehr nutzbar. Die veraltete Callback-Variante sollte man nicht mehr verwenden. Beim Laden von fremden Ursprüngen gelten die CORS-Regeln.
  • Zeitplanung: Plane Ereignisse immer relativ zu currentTime, nicht mit setTimeout. Nur so bleibt das Timing auf Abtastwerte genau.
  • Kompatibilität: Das Interface ist in allen modernen Browsern verfügbar. In älteren Safari-Versionen gab es nur webkitAudioContext, ohne eigenständiges BaseAudioContext. audioWorklet setzt einen sicheren Kontext (HTTPS) voraus.