Visualización del espectro

% Completo

Descripción

El Nodo Analizador proporciona en tiempo real datos de la fuente de audio en el dominio del tiempo y en el de la frecuencia. Estos nodos no modifican el sonido y pueden ser colocados donde queramos en nuestra cadena de audio.

El Análisis de audio nos ayuda a comprender mejor cómo será el sonido que vamos a escuchar, de hecho una de las aplicaciones principales de el Nodo Analizador es visualizar el sonido.

Los resultados que muestra están basados en un análisis FFT de un tamaño de buffer determinado. Éstos son los principales métodos y atributos del nodo analizador:

  •  Volumen:

     x 1+0dB

  •  Zoom 

    Tamaño de la muestra de frecuencia 2*∫ x 

Atributos

  • Tamaño de la FFT: será tamaño de la transformada de Fourier que utilicemos para hacer el análisis en el dominio de la frecuencia. Deberá ser potencia de 2, de 32 a 2048.
  • Porciones de frecuencia: FrecuencyBinCount, los datos de frecuencia disponibles, la mitad del valor del tamaño de la FFT.
  • Decibelios; Min y Max: El mínimo  y máximo nivel de potencia en el rango de la escala de la FFT para la conversión de valores de byte sin signo.
  • Constante de suavizado: Un valor entre 0 y 1 que representa el promedio de tiempo entre una muestra  del analizador y la siguiente. Nos servirá para visualizar el audio en frecuencia de forma más suave, entre otras cosas.

Métodos y Parámetros

  • getFloatFrequencyData: Copia los datos de audio en un array de flotantes. El tamaño de la Proción será el mismo que el valor del atributo frequencyBinCount. El parámetro array será donde se copien los datos de frecuencia.
  • getByteFrequencyData: Este método copia los datos de frecuencia en un array o vector de bytes de enteros, de longitud FrequencyBinCount  también contará con su parámetro array, para acceder al valor.
  • getTimeDomainData: Copia los datos de la forma de onda en el dominio del tiempo en una cadena de bytes de enteros, el tamaño será el de el atributo fftSize, o tamaño de la transformada.

Para visualizar el sonido podemos declarar un elemento <canvas> HTML sobre el que imprimir valores en pantalla. Deberíamos estar recorriendo el array de datos del buffer constantemente y aplicar estos valores a nuestro gráfico HTML. Una forma de hacer esto con JavaScript es mediante los métodos nativos setInterval o setTimeout, en milisegundos. La Web Audio API cuenta, no obstante, con un método más eficiente y que proporciona mejores resultados de procesado, el requestAnimationFrame. La API permite entonces al navegador incorporar una función propia de dibujo, y ejecutarla en el tiempo que establezcamos.

Dicho esto, para graficar los valores de nuestra cadena de datos creamos una función de dibujo utilizando el elemento <canvas> que recorra este array de datos y los imprima en pantalla. La API requestAnimationFrame es la encargada de realizar las tareas de dibujo.

Esta interfaz nos permite crear funciones de dibujo de forma eficiente, ya que funciona con las mismas coordenadas de tiempo que nuestro contextoDeAudio, una vez la invocamos, podemos hacer que se ejecute indefinidamente, conforme lo hace la señal de audio, extrayendo valores de la señal en tiempo real

Una forma de declaración sería la sigueinte:


//API request animation frame para distintos navegadores
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})(); 
          
           

Una vez definida la función requestAnimationFrame, podemos utilizarla para extraer del nodo analizador la información requerida.

En este ejemplo, en el gráfico de audio, conectamos el Nodo Analizador después de un Nodo de Ganancia.Los datos extraídos del nodo analizador manejados por la función dibujarEspectro nos permiten visualizar el espectro de la señal.

El siguiente fragmento de códifgo muestra una abreviación del código fuente, a la hora de reproducir el archivo de audio, enrutarlo y extraer sus datos.


function Play(){
//Creamos la fuente de datos de audio
var fuentedeaudio = contextoDeAudio.createBufferSource();
//La hacemos pasar por nuestra cadena de audio
fuentedeaudio = cadenaDeAudio(fuentedeaudio);
//llamamos a la función Dibujar espectro mediante elrequestAnimationFrame
requestAnimationFrame(dibujaEspectro.bind(this))
}

El método getByteFrequencyData copia los datos de frecuencia al array que le pasemos. En este caso un array de 512 valores enteros cuantificados con 8 Bits, la mitad del tamaño de nuestra resolución de la FFT (1024) y obtenido a partir del atributo del analizador frequencyBinCount. El cual nos devuelve una constante: el valor de la FFT/2. Cada muestra se almacena en un Byte (256 niveles). El piso es 0 = 0dB.

Una vez establecida la cadena de audio y su contexto, demntro de la función de dibujo, podremos escribir el código necesario para obtener un vector con los datos de frecuencia. Sería algo como esto:


 var datos_frecuencia = new Uint8Array(contextoDeAudio.analizador.frequencyBinCount);
 contextoDeAudio.analizador.getByteFrequencyData(datos_frecuencia);