Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

164
Vistas
Implement 360 degree rotation audio using Web Audio API

What I'm currently trying to implement is 360 degree rotation audio (I don't know the exact term for it--maybe 8d audio?) using PannerNode.

As far as I think, what I need to do is just rotate the position of PannerNode around y axis, with AudioListener being at (0, 0, 0).

But the result sounds like the audio is not changed at all. The below is my code.

const $fileInput = document.createElement('input');
$fileInput.setAttribute('type', 'file');
document.body.appendChild($fileInput);

const $audio = document.createElement('audio');
$audio.setAttribute('controls', true);
document.body.appendChild($audio);

$fileInput.addEventListener('change', async (e) => {
  const file = $fileInput.files[0];
  const arrayBuffered = await file.arrayBuffer();
  const actx = new (window.AudioContext || window.webkitAudioContext)({ latencyHint: 'interactive', sampleRate: 44100 });
  const decoded = await actx.decodeAudioData(arrayBuffered);
  const oactx = new OfflineAudioContext({ numberOfChannels: 2, length: decoded.length, sampleRate: actx.sampleRate });
  const absn = new AudioBufferSourceNode(oactx, { buffer: decoded });
  const pn = new PannerNode(oactx, {
    panningModel: 'equalpower',
    distanceModel: 'inverse',
    positionX: 0,
    positionY: 0,
    positionZ: 0,
    orientationX: 1,
    orientationY: 0,
    orientationZ: 0,
    refDistance: 1,
    maxDistance: 10000,
    rolloffFactor: 1,
    coneInnerAngle: 360,
    coneOuterAngle: 360,
    coneOuterGain: 0
  });

  oactx.listener.positionX.value = 0;
  oactx.listener.positionY.value = 0;
  oactx.listener.positionZ.value = 0;
  oactx.listener.forwardX.value = 0;
  oactx.listener.forwardY.value = 0;
  oactx.listener.forwardZ.value = -1;
  oactx.listener.upX.value = 0;
  oactx.listener.upY.value = 1;
  oactx.listener.upZ.value = 0;

  // rotation
  for (let t = 0; t < decoded.duration; t++) {
    const rad = t * Math.PI / 180;
    const x = pn.positionX.value * Math.cos(rad) - pn.positionZ.value * Math.sin(rad);
    const z = pn.positionX.value * Math.sin(rad) + pn.positionZ.value * Math.cos(rad);

    pn.positionX.setValueAtTime(x, t);
    pn.positionZ.setValueAtTime(z, t);
  }

  absn.connect(pn);
  pn.connect(oactx.destination);
  absn.start();
  
  const resultBuffer = await oactx.startRendering();
  const test = new AudioBufferSourceNode(actx, { buffer: resultBuffer });
  test.connect(actx.destination);
  test.start();
});
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

// from
PannerNode.positionX: 0
// to
PannerNode.positionX: 1

// from
for (let t = 0; t < decoded.duration; t++) {
  const rad = t * Math.PI / 180;
}
// to
for (let t = 0; t < decoded.duration; t += 0.01) {
  const rad = 100 * t * Math.PI / 180;
}

I set PannerNode.positionX to 1 because in order for PannerNode to rotate around AudioListener, PannerNode needs to be have some distance from AudioListener.

I change for statement because I want a fast, smoothly changing effect.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda