Start · Sprachen · JavaScript · Referenz · PannerNode

PannerNode

Schnittstelle

Der <code>PannerNode</code> positioniert eine Audioquelle im dreidimensionalen Raum und berechnet daraus Richtung, Entfernungsdämpfung und Klangkegel relativ zum <code>AudioListener</code>.

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

Signatur

interface PannerNode extends AudioNode

Beschreibung

Ein PannerNode ist ein Verarbeitungsknoten der Web Audio API, der ein Eingangssignal so verräumlicht, als käme es von einem bestimmten Punkt im 3D-Raum. Position (positionX/Y/Z) und Ausrichtung (orientationX/Y/Z) der Quelle werden mit Position und Ausrichtung des AudioContext.listener verrechnet. Heraus kommt immer ein Stereosignal, und zwar mit genau zwei Kanälen.

Wichtige Eigenschaften:

  • panningModel: "equalpower" ist einfach und spart Rechenleistung. "HRTF" nutzt kopfbezogene Übertragungsfunktionen und klingt über Kopfhörer deutlich räumlicher.
  • distanceModel: "linear", "inverse" (Standard) oder "exponential". Zusammen mit refDistance, maxDistance und rolloffFactor legt es fest, wie stark die Lautstärke mit der Entfernung abnimmt.
  • coneInnerAngle, coneOuterAngle, coneOuterGain: Damit strahlt eine Quelle gerichtet ab, zum Beispiel ein Lautsprecher oder eine sprechende Figur.
  • positionX/Y/Z, orientationX/Y/Z: Das sind AudioParam-Objekte. Du kannst sie also sampelgenau automatisieren, etwa mit setValueAtTime oder linearRampToValueAtTime.

Du erzeugst den Knoten entweder mit dem Konstruktor new PannerNode(context, options) oder mit der Fabrikmethode context.createPanner(). Typische Einsatzgebiete sind Spiele, WebXR/VR, interaktive Audio-Installationen und räumliche Videokonferenzen. Für einfaches Links-Rechts-Panning ohne 3D-Berechnung reicht StereoPannerNode, der auch weniger Rechenleistung braucht.

Parameter

Name Typ Default Beschreibung
$context Pflicht BaseAudioContext Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehört.
$options PannerOptions {} Optionales Objekt mit Startwerten: panningModel, distanceModel, positionX/Y/Z (Standard 0), orientationX/Y/Z (Standard 1, 0, 0), refDistance (1), maxDistance (10000), rolloffFactor (1), coneInnerAngle (360), coneOuterAngle (360), coneOuterGain (0) sowie die allgemeinen AudioNodeOptions.

Rückgabewert

Typ
PannerNode
Beschreibung
Ein neuer PannerNode. Er ist noch nicht verbunden und muss per connect() in den Audiographen eingehängt werden.

Beispiele

PannerNode per Konstruktor erzeugen und Quelle rechts vorne platzieren

const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { frequency: 440 });

const panner = new PannerNode(ctx, {
  panningModel: 'HRTF',
  distanceModel: 'inverse',
  positionX: 3,   // rechts
  positionY: 0,
  positionZ: -2,  // vor dem Hörer (Blickrichtung -Z)
  refDistance: 1,
  rolloffFactor: 1
});

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

document.querySelector('#play').addEventListener('click', async () => {
  await ctx.resume(); // Autoplay-Richtlinie
  osc.start();
  osc.stop(ctx.currentTime + 2);
  console.log(panner.panningModel, panner.positionX.value);
});
HRTF 3

Quelle mit Automatisierung von links nach rechts bewegen

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

const response = await fetch('/sounds/auto.mp3');
const buffer = await ctx.decodeAudioData(await response.arrayBuffer());
const source = new AudioBufferSourceNode(ctx, { buffer });

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

const t = ctx.currentTime;
panner.positionZ.value = -1;
panner.positionX.setValueAtTime(-10, t);
panner.positionX.linearRampToValueAtTime(10, t + buffer.duration);

source.start(t);

Gerichtete Quelle mit Klangkegel (z. B. Lautsprecher)

const ctx = new AudioContext();
const panner = new PannerNode(ctx, {
  positionZ: -5,
  orientationX: 0,
  orientationY: 0,
  orientationZ: 1,       // zeigt zum Hörer
  coneInnerAngle: 60,    // volle Lautstärke im 60°-Kegel
  coneOuterAngle: 180,
  coneOuterGain: 0.1     // außerhalb: 10 % Lautstärke
});

// Lautsprecher langsam wegdrehen
const t = ctx.currentTime;
panner.orientationZ.setValueAtTime(1, t);
panner.orientationZ.linearRampToValueAtTime(-1, t + 4);
console.log(panner.coneOuterGain);
0.1

Hörer im Spiel mitbewegen

const ctx = new AudioContext();
const { listener } = ctx;

const updateListener = (player) => {
  const t = ctx.currentTime;
  if (listener.positionX) {
    listener.positionX.setValueAtTime(player.x, t);
    listener.positionY.setValueAtTime(player.y, t);
    listener.positionZ.setValueAtTime(player.z, t);
  } else {
    // Fallback für ältere Browser
    listener.setPosition(player.x, player.y, player.z);
  }
};

updateListener({ x: 0, y: 1.7, z: 0 });

// Wichtig · Fallstricke

  • Kanäle: Die Ausgabe ist immer stereo. channelCount darf höchstens 2 sein, und channelCountMode darf nicht "max" sein, sonst wird ein NotSupportedError geworfen.
  • Veraltete Methoden: setPosition() und setOrientation() sind veraltet. Verwende stattdessen die AudioParam-Eigenschaften positionX/Y/Z und orientationX/Y/Z. Diese fehlen im Firefox auf dem AudioListener teilweise noch, deshalb solltest du dort eine Feature-Erkennung einbauen.
  • Wertebereiche: Ein negativer Wert für refDistance oder rolloffFactor sowie ein Wert ≤ 0 für maxDistance lösen einen RangeError aus. Beim Modell "linear" wird rolloffFactor auf den Bereich 0–1 begrenzt.
  • Leistung: "HRTF" braucht deutlich mehr Rechenleistung als "equalpower". Bei vielen gleichzeitigen Quellen, etwa auf Mobilgeräten, solltest du das berücksichtigen.
  • Koordinatensystem: Es ist rechtshändig. Der Hörer blickt standardmäßig in Richtung −Z, +Y zeigt nach oben.
  • Autoplay: Ein AudioContext startet oft im Zustand "suspended". Du musst resume() nach einer Nutzeraktion aufrufen, zum Beispiel in einem Klick-Handler.