Web Audio y 3D Soundscapes Introducción

En este tutorial, analizaremos de cerca los elementos fundamentales de Web Audio que se utilizan para construir paisajes sonoros 3D para aplicaciones interactivas inmersivas que incluyen, entre otros, juegos 3D..

La API de Web Audio y la terminología que utiliza a veces pueden ser confusas, pero este tutorial pretende eliminar la complejidad y proporcionar una explicación más simple de los elementos de Web Audio y cómo funcionan juntos para formar un paisaje sonoro 3D..

Demostración

Esta demostración contiene tres sonidos que giran alrededor de un oyente, La dirección del oyente está indicada por la flecha. Si te imaginas mirar hacia abajo a un personaje del juego (el oyente), los sonidos giratorios podrían representar fácilmente a amigos o enemigos que rodean al personaje..

El código fuente de la demostración y los recursos se adjuntan a este tutorial..

AudioContext

los AudioContext La interfaz es el corazón y el alma de Web Audio; proporciona las funciones necesarias para crear varios elementos de audio web, además de proporcionar una forma de enviar todo el audio al hardware y, posteriormente, a los altavoces o auriculares de alguien..

var audioContext = null if (window.AudioContext! == undefined) audioContext = new AudioContext ()

Es importante asegurarse de que AudioContext La interfaz está disponible porque Web Audio todavía es bastante nuevo y es posible que no esté disponible en algunos navegadores web.

Además de proporcionar las funciones necesarias para crear varios elementos de audio web, el AudioContext La interfaz tiene dos propiedades importantes; destino y oyente que son de solo lectura. los destino La propiedad se puede considerar como la conexión al hardware de audio, es donde finalmente terminará todo el audio generado. los oyente propiedad (veremos como esto con más detalle más adelante) representa la cosa es escuchar todo el audio, por ejemplo, Un personaje, o más precisamente una cámara, en un juego..

Buffers

los AudioBuffer y AudioBufferSourceNode Las interfaces nos permiten reproducir audio.. AudioBuffer los objetos contienen el audio en bruto (muestras de sonido) que se modifican, trituran y trituran a medida que pasan por Web Audio antes de llegar a los parlantes o audífonos de alguien.. AudioBufferSourceNode Los objetos se utilizan para iniciar y detener el audio contenido en AudioBuffer objetos.

La forma estándar de cargar audio en un AudioBuffer objeto es utilizar un XMLHttpRequest objeto con su tipo de respuesta ajustado a arraybuffer. Cuando el archivo de audio se ha cargado, el array buffer se envía a la AudioContext objeto para la decodificación y, si la decodificación es exitosa, se nos proporcionará un AudioBuffer objeto.

var loader = new XMLHttpRequest () loader.open ("GET", "massive-explosion.ogg") loader.responseType = "arraybuffer" loader.onload = whenLoaded loader.send () función whenLoaded (evento) var data = loader .response if (data === null) // Hubo un problema al cargar el archivo. return // Decodificar los datos. audioContext.decodeAudioData (data, whenDecoded) cuando whenDecoded (audioBuffer) // "audioBuffer" es un objeto AudioBuffer. 

los decodeAudioData () La función también tiene un tercer parámetro que acepta una segunda devolución de llamada, esa devolución de llamada se llama cuando el archivo de audio cargado no se puede decodificar.

decodeAudioData (datos, whenDecoded, whenFailed)

No todos los navegadores web admiten los mismos formatos de audio, aquí se puede encontrar una buena tabla de formatos compatibles, por lo que es posible que desee utilizar la segunda devolución de llamada para retroceder a un formato de audio alternativo si es necesario. Por ejemplo, Internet Explorer no admite OGG Vorbis, pero sí es compatible con MP3. El único problema real con MP3 es que no permite el audio en bucle sin interrupciones como lo hace OGG Vorbis.

Cuando tienes un AudioBuffer objeto disponible puede jugarlo usando una AudioBufferSourceNode objeto.

var source = audioContext.createBufferSource () // Adjuntar un objeto AudioBuffer. source.buffer = audioBuffer // Conecte el objeto "origen" al objeto "destino". source.connect (audioContext.destination) // Opcionalmente, diga a "source" que haga un bucle de audio continuamente. source.loop = false // Inicia el audio. source.start ()

Es importante recordar AudioBufferSourceNode los objetos son reproductores de audio de un solo disparo, en otras palabras, solo puede utilizar el comienzo() funcionar una vez. Necesitará crear un AudioBufferSourceNode objeto y conectarlo (directa o indirectamente) a la destino objeto expuesto por el AudioContext objeto siempre que quiera reproducir audio desde una AudioBuffer objeto.

Podría simplificar un poco la vida creando una pequeña función de utilidad que crea, conecta y comienza una AudioBufferSourceNode objeto para ti.

play play (audioBuffer, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer source.connect (audioContext.destination) source.start () play (audioBuffer01, audioContext) play (audioBuffer02, audioContext) , audioContext)

Cuando un AudioBufferSourceCode el objeto termina de reproducirse, y si no tiene referencias al objeto en ninguna parte (por ejemplo, no las tiene almacenadas en una matriz), Web Audio desconectará automáticamente el objeto por usted. Esto es extremadamente útil cuando solo necesitas disparar y olvidar efectos de sonido cortos, etc..

Si decides bucear el audio, usa el AudioBufferSourceNode lazo propiedad, tendrá que mantener una referencia a la AudioBufferSourceNode objeto en algún lugar para que pueda detener() la reproducción de audio.

source.stop ()

Así que en este punto estamos usando buffers para reproducir audio, pero el audio se está reproduciendo directamente sin que se aplique ninguna panorámica o espacialización. Aquí es donde PannerNode los objetos entran en juego.

  • Especificación W3C AudioBuffer.
  • Especificación W3C AudioBufferSourceNode.

Panners

PannerNode Los objetos nos permiten colocar el audio en el espacio 3D, dentro de un sistema de coordenadas cartesiano. Aquí es donde ocurre la mayor parte de la magia 3D..

UNA PannerNode El objeto tiene bastantes propiedades que nos permiten ajustar el comportamiento del audio, pero para este tutorial solo nos interesan dos de ellas; distancia maxima y PanningModel. los distancia maxima propiedad es la distancia de la oyente en cuyo punto el volumen de audio será cero. Este es un valor arbitrario y solo tendrá significado dentro de su aplicación, pero por defecto es de 10000. PanningModel le dice a Web Audio cómo procesar el audio que pasa a través de un PannerNode objeto. Para paisajes sonoros 3D, probablemente querrá establecer el valor en HRTF (función de transferencia relacionada con la cabeza).

Para establecer la posición de un AudioBufferSourceNode usamos el posición de ajuste() función expuesta por un PannerNode objeto.

var panner = audioContext.createPanner () panner.panningModel = "HRTF" // Establece la posición 3D (x, y, z). panner.setPosition (1, 2, 3) // Conecta el objeto "fuente" al objeto "panner". source.connect (panner) // Conecta el objeto "panner" al objeto "destino". panner.connect (audioContext.destination) // Inicia el audio. source.start ()

Para aclarar un poco las cosas, actualicemos la función de utilidad que creamos anteriormente.

reproducción de función (audioBuffer, x, y, z, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer var panner = audioContext.createPanner () panner.panningModel = "HRTF" panner.setPosition (x, y, z) source.connect (panner) panner.connect (audioContext.destination) source.start () play (audioBuffer01, 1, 2, 3, audioContext) play (audioBuffer02, 4, 5, 6, audioContext) play (audioBuffer03, 7, 8, 9, audioContext)

En este punto, estamos reproduciendo el audio y posicionándolo en el espacio 3D, pero hay un elemento más importante que debemos observar; el oyente de audio.

  • Especificación W3C PannerNode.

El oyente de audio

Cada AudioContext objeto expone un oyente Objeto que representa la posición y orientación de la cosa Eso es escuchar el audio. Usualmente el cosa sería una cámara virtual que se adjunta a la cabeza de un personaje del juego, al parachoques de un automóvil, a la cola de un avión, o cualquier otra cosa que tenga sentido para el espectador desde su perspectiva.

los oyente objeto tiene un posición de ajuste() función y un setOrientation () función. los posición de ajuste() función coloca al oyente en algún lugar dentro del espacio 3D, y la setOrientation () rota al oyente (imagina una cámara girando y girando).

los posición de ajuste() La función funciona exactamente de la misma manera que la PannerNode posición de ajuste() Funciona y acepta tres coordenadas..

audioContext.listener.setPosition (x, y, z)

los setOrientation () La función es un poco más compleja, acepta dos vectores unitarios. El primer vector representa la rotación del oyente (la dirección hacia la que apunta la cámara), y el segundo vector representa la rotación del oyente arriba Dirección (apunta fuera de la parte superior de la cámara)..

audioContext.listener.setOrientation (x1, y1, z1, x2, y2, z2)

Si solo necesita rotar el oyente alrededor de un eje, los cálculos vectoriales son relativamente simples. Por ejemplo, si está utilizando el mismo sistema de coordenadas que utiliza WebGL donde es positivo X Apunta a la derecha de la pantalla, positivo. y apunta a la parte superior de la pantalla, y positivo z señala fuera de la pantalla, entonces puede girar el oyente alrededor de la y eje (panear la cámara) usando uno cos () función de llamada y uno pecado() Llamada de función.

// La posición del oyente (podría ser cualquier cosa). var x = 50 var y = 100 var z = 0 audioContext.listener.setPosition (x, y, z) // Calcula el vector de rotación. // rad = rotación, en radianes var rad = 0.10 var v1 = Math.cos (rad) // x var v2 = 0 // y var v3 = Math.sin (rad) // z // El vector "arriba" var v4 = 0 // x var v5 = 1 // y var v6 = 0 // z audioContext.listener.setOrientation (v1, v2, v3, v4, v5, v6)

La demostración de este tutorial (se adjunta el código fuente) hace algo similar y gira el PannerNode objetos alrededor de un solo eje.

  • Especificación W3C AudioListener.

Conclusión

En este tutorial echamos un vistazo a los elementos fundamentales de Web Audio que se utilizan para construir paisajes sonoros 3D para aplicaciones interactivas inmersivas que incluyen, entre otros, juegos 3D. Esperamos que este tutorial le haya sido de utilidad y le haya brindado suficiente información para que comprenda cómo los buffers, paners y oyentes de audio trabajan juntos para producir paisajes sonoros 3D..

Si tiene algún comentario o alguna pregunta, no dude en publicar un comentario a continuación.

Recursos

  • Especificación de audio web W3C
  • Documentación de audio web MDN
  • Vectores 3D (Euclidianos)

El siguiente paso: Implementación

En el siguiente tutorial, Web Audio y paisajes sonoros 3D: Implementación, tomaremos todo lo anterior (y más) y lo incluiremos en una API simplificada. El enfoque principal del siguiente tutorial serán los juegos en 3D, pero la API será lo suficientemente genérica para usarla en varias aplicaciones interactivas inmersivas.