En los últimos meses, la API de Web Audio de WebKit se ha convertido en una plataforma atractiva para juegos y aplicaciones de audio en la Web. A medida que los desarrolladores se familiarizan con él, escucho preguntas similares una y otra vez. Esta actualización rápida es un intento de responder algunas de las preguntas más frecuentes para que tu experiencia con la API de Web Audio sea más placentera.
P.: ¡Ayuda! No puedo emitir sonidos.
R.: Si es la primera vez que usas la API de Web Audio, consulta el instructivo de introducción o la receta de Eric para reproducir audio según la interacción del usuario.
P.: ¿Cuántos contextos de audio debo tener?
R.: Por lo general, debes incluir un AudioContext
por página, y un solo contexto de audio puede admitir muchos nodos conectados a él. Aunque puedes incluir varios AudioContexts en una sola página, esto puede generar un impacto en el rendimiento.
P.: Tengo un AudioBufferSourceNode que acabo de reproducir con noteOn()
y quiero volver a reproducirlo, pero noteOn()
no hace nada. Ayuda,
R.: Una vez que un nodo de origen termina de reproducirse, no puede reproducir más contenido. Para volver a reproducir el búfer subyacente, debes crear un AudioBufferSourceNode
nuevo y llamar a noteOn()
.
Si bien volver a crear el nodo de origen puede parecer ineficiente, los nodos de origen están muy optimizados para este patrón. Además, si conservas un identificador del AudioBuffer, no es necesario que realices otra solicitud al activo para volver a reproducir el mismo sonido. Si necesitas repetir este patrón, encapsula la reproducción con una función auxiliar simple, como playSound(buffer)
.
P.: Cuando se reproduce un sonido, ¿por qué se debe crear un nuevo nodo de origen cada vez?
A: La idea de esta arquitectura es desacoplar el recurso de audio del estado de reproducción. Tomando una analogía con un tocadiscos, los búferes son análogos a los registros y las fuentes a las cabezas de reproducción. Este patrón es esencial porque muchas aplicaciones incluyen varias versiones del mismo búfer que se reproducen de forma simultánea.
P.: ¿Cómo puedo procesar el sonido de las etiquetas audio
y video
?
A: MediaElementAudioSourceNode
está en desarrollo. Cuando esté disponible, funcionará de la siguiente manera (agregar un efecto de filtro a una muestra que se reproduce a través de la etiqueta de audio):
<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);
Se realiza un seguimiento de esta función en este crbug. Ten en cuenta que, en esta configuración, no es necesario llamar a mediaSourceNode.noteOn()
, ya que la etiqueta de audio controla la reproducción.
P.: ¿Cuándo puedo obtener sonido de un micrófono?
R.: La parte de entrada de audio se implementará como parte de WebRTC con getUserMedia
y estará disponible como un nodo de fuente especial en la API de Web Audio. Funcionará junto con createMediaElementSource
.
P.: ¿Cómo puedo verificar cuándo terminó de reproducirse un AudioSourceNode
?
R.: Actualmente, debes usar un temporizador de JavaScript, ya que la API de Web Audio no admite esta funcionalidad. El siguiente fragmento del instructivo de introducción a la API de Web Audio es un ejemplo de esto en acción:
// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
console.log('playback finished');
}, buffer.duration * 1000);
Hay un error abierto para que la API de Web Audio implemente una devolución de llamada más precisa.
P.: La carga de sonidos hace que todo el subproceso de IU se bloquee y la IU deje de responder. ¡Ayuda!**
A: Usar la API de decodeAudioData
para la carga asíncrona y evitar bloquear el subproceso principal Consulta este ejemplo.
P.: ¿Se puede usar la API de Web Audio para procesar sonidos más rápido que en tiempo real?
R.: Sí, se está trabajando en una solución. Manténte actualizado.
P.: Hice una aplicación increíble de la API de Web Audio, pero cada vez que la pestaña en la que se ejecuta pasa a segundo plano, los sonidos se vuelven muy extraños.
R.: Es probable que se deba a que usas setTimeouts
, que se comporta de manera diferente si la página se ejecuta en segundo plano. En el futuro, la API de Web Audio podrá realizar una devolución de llamada en momentos específicos con el temporizador interno de audio web (atributo context.currentTime
). Para obtener más información, consulta esta solicitud de función.
En general, es una buena idea detener la reproducción cuando la app pasa a segundo plano. Puedes detectar cuándo una página pasa a segundo plano con la API de visibilidad de páginas.
P.: ¿Cómo puedo cambiar el tono de un sonido con la API de Web Audio?
A: Cambiar el playbackRate
en el nodo de origen
P.: ¿Puedo cambiar el tono sin cambiar la velocidad?
R.: La API de Web Audio podría tener un PitchNode en el contexto de audio, pero es difícil de implementar. Esto se debe a que no hay un algoritmo de cambio de tono sencillo en la comunidad de audio. Las técnicas conocidas crean artefactos, en especial en los casos en que el cambio de tono es grande. Existen dos tipos de enfoques para abordar este problema:
- Algoritmos de dominio de tiempo, que generan artefactos de ecos de segmentos repetidos
- Técnicas de dominio de frecuencia, que causan artefactos de sonido reverberante
Aunque no hay un nodo nativo para realizar estas técnicas, puedes hacerlo con un JavaScriptAudioNode
. Este fragmento de código puede servir como punto de partida.
P.: ¿Cómo puedo crear un AudioContext con la tasa de muestreo que elija?
R: Por el momento, no se admite esta función, pero estamos investigando el tema. Consulta esta solicitud de función.
Si tienes más preguntas, no dudes en hacerlas en StackOverflow con la etiqueta web-audio.