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

BaseAudioContext.createPanner()

Methode

Erzeugt einen neuen <code>PannerNode</code>, mit dem ein eingehender Audiostrom im 3D-Raum relativ zum <code>AudioListener</code> positioniert wird.

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

Signatur

BaseAudioContext.prototype.createPanner()

Beschreibung

createPanner() ist eine Fabrikmethode von BaseAudioContext und damit sowohl auf AudioContext als auch auf OfflineAudioContext verfügbar. Sie liefert einen PannerNode, der ein Audiosignal räumlich einordnet: Position, Ausrichtung, Entfernungsdämpfung und Richtcharakteristik (Schallkegel) der Quelle lassen sich einstellen, jeweils relativ zum AudioListener des Kontexts (context.listener).

Du brauchst den Knoten für Spiele, VR-/WebXR-Anwendungen, interaktive Klanginstallationen oder überall dort, wo Klänge von einem bestimmten Ort im Raum kommen sollen. Für einfaches Links-Rechts-Panning in Stereo ist der deutlich leichtere StereoPannerNode (createStereoPanner()) die bessere Wahl.

Die Methode ist gleichwertig zum Konstruktor new PannerNode(context, options). Mit dem Konstruktor kannst du alle Eigenschaften gleich beim Erzeugen setzen, zum Beispiel panningModel, distanceModel, positionX oder coneInnerAngle. Moderner Code bevorzugt deshalb meist den Konstruktor. Position und Ausrichtung sind AudioParams (positionX/Y/Z, orientationX/Y/Z) und lassen sich somit auch zeitgenau automatisieren.

Rückgabewert

Typ
PannerNode
Beschreibung
Ein neuer PannerNode mit Standardwerten: panningModel = "equalpower", distanceModel = "inverse", Position (0, 0, 0), Ausrichtung (1, 0, 0), refDistance = 1, maxDistance = 10000, rolloffFactor = 1, coneInnerAngle = coneOuterAngle = 360.

Beispiele

Oszillator im 3D-Raum rechts vom Hörer platzieren

const ctx = new AudioContext();
const osc = ctx.createOscillator();
const panner = ctx.createPanner();

panner.panningModel = 'HRTF';   // realistischer Klang über Kopfhörer
panner.distanceModel = 'inverse';
panner.positionX.value = 3;      // 3 Einheiten rechts
panner.positionY.value = 0;
panner.positionZ.value = -1;     // leicht vor dem Hörer

osc.connect(panner).connect(ctx.destination);

document.querySelector('#play').addEventListener('click', async () => {
  await ctx.resume();            // Autoplay-Sperre aufheben
  osc.start();
  osc.stop(ctx.currentTime + 2);
});

Klangquelle kreisförmig um den Hörer bewegen (Automatisierung)

const ctx = new AudioContext();
const panner = ctx.createPanner();
panner.panningModel = 'HRTF';

const osc = new OscillatorNode(ctx, { frequency: 330 });
osc.connect(panner).connect(ctx.destination);

const radius = 4;
const start = ctx.currentTime;
for (let i = 0; i <= 80; i++) {
  const t = start + i * 0.05;       // 4 Sekunden gesamt
  const angle = (i / 80) * 2 * Math.PI;
  panner.positionX.linearRampToValueAtTime(Math.sin(angle) * radius, t);
  panner.positionZ.linearRampToValueAtTime(-Math.cos(angle) * radius, t);
}

osc.start(start);
osc.stop(start + 4);

Lautsprecher mit Richtcharakteristik in einem Spiel

const ctx = new AudioContext();
const response = await fetch('/sounds/radio.mp3');
const buffer = await ctx.decodeAudioData(await response.arrayBuffer());

const source = new AudioBufferSourceNode(ctx, { buffer, loop: true });
const panner = ctx.createPanner();

// Schallkegel: nach vorne laut, hinten stark gedämpft
panner.coneInnerAngle = 60;
panner.coneOuterAngle = 180;
panner.coneOuterGain = 0.1;
panner.orientationX.value = 0;
panner.orientationZ.value = 1;   // zeigt in Richtung +Z
panner.refDistance = 1;
panner.maxDistance = 50;
panner.rolloffFactor = 1.5;
panner.positionZ.value = -5;

source.connect(panner).connect(ctx.destination);
source.start();

// Hörer bewegt sich (z. B. aus der Spielschleife)
const movePlayer = (x, z) => {
  ctx.listener.positionX.setValueAtTime(x, ctx.currentTime);
  ctx.listener.positionZ.setValueAtTime(z, ctx.currentTime);
};
movePlayer(0, 2);

// Wichtig · Fallstricke

  • Veraltete API: panner.setPosition(), panner.setOrientation() sowie listener.setPosition() sind veraltet. Verwende stattdessen die AudioParams positionX/Y/Z und orientationX/Y/Z. Firefox unterstützt die AudioParam-Eigenschaften am AudioListener teilweise noch nicht, deshalb bei Bedarf per Feature-Erkennung auf setPosition() zurückfallen.
  • Leistung: "HRTF" klingt deutlich realistischer (vor allem über Kopfhörer), rechnet aber viel mehr als "equalpower". Bei vielen gleichzeitigen Quellen spürbar.
  • Der Knoten gibt immer ein Stereo-Signal aus. Die Eingabe ist auf maximal 2 Kanäle begrenzt (channelCountMode = "clamped-max").
  • Das Koordinatensystem ist rechtshändig: Der Hörer blickt standardmäßig in Richtung −Z. Positive Z-Werte liegen also hinter ihm.
  • maxDistance wirkt nur bei distanceModel = "linear" als harte Grenze. Bei "inverse" und "exponential" wird die Dämpfung ab dieser Entfernung nicht weiter verstärkt.
  • Wegen der Autoplay-Richtlinien startet ein AudioContext oft im Zustand "suspended". Ruf ctx.resume() nach einer Nutzeraktion auf.