Universitat Oberta de Catalunya

Introducción a Audio API de HTML5

Introducción

Una de las nuevas prestaciones que ofrece el estándar web de HTML5 es la etiqueta <audio>, que permite la incorporación de sonidos y música en los navegadores web. Esta ha supuesto un gran avance para el desarrollo web y lo que puede ofrecer al usuario final. Algunas de sus posibilidades son la de incorporación de música en contenidos web; no obstante, puede ir más allá. Puede ser la oportunidad para añadir efectos de sonidos a videojuegos y/o algo bastante interesante como la síntesis de sonido directamente en el navegador. En otras palabras, se pueden llegar a desarrollar aplicaciones web para la producción musical como secuenciadores de audio en la nube o sintetizadores personalizados.

En este articulo haré una pequeña introducción a la API de audio para la web. Mi intención no es usar la etiqueta de HTML5 <audio> sino mostrar el potencial de esta API directamente con el código JavaScript.

Para empezar, se tienen que tener claras algunas nociones básicas de sonido para poder entender completamente qué es lo que hace el código. Para esto hay que entender que el sonido es un tipo de onda que se propaga por el aire a 343 metros por segundo. Estas ondas se propagan creando variaciones de presión que son las responsables de que nosotros escuchemos el sonido. Estas variaciones de presión varían dependiendo de qué tipo de sonido escuchemos.

Centrándonos en los aspectos musicales y entendiendo el sonido como un sonido puro, sin armónicos ni coloración del mismo, el sonido lo podemos clasificar en función de su frecuencia en siete notas musicales más sus sostenidos y bemoles.

Valores frecuenciales de las notas musicales

Nota Frecuencia
Do 261,63 Hz.
Re 293,66 Hz.
Mi 329,63 Hz.
Fa 349,23 Hz.
Sol 392,00 Hz.
La 440,00 Hz.
Si 493,88 Hz.

Cuando hablo de sonido puro hago referencia a que, en la naturaleza, el sonido siempre está compuesto por una frecuencia dominante mezclada con una serie de frecuencias en mayor o menor amplitud que juntas componen lo que llamamos timbre. Volviendo a la música para poder ilustrar con un ejemplo, se puede observar que una guitarra y un clarinete, aunque tienen rangos frecuenciales diferentes, pueden interpretar la misma nota, por ejemplo la nota mi. Los dos instrumentos generan la frecuencia dominante de mi, que son 329,63 Hz, más toda una cola de armónicos; normalmente octavas de la nota fundamental (mi*2). Tanto la guitarra como el clarinete tienen sus armónicos característicos y este fenómeno es el que nos hace distinguir auditivamente el timbre de una guitarra del clarinete.

En este ejemplo de JavaScript generaremos ondas artificiales como las que usan los sintetizadores. Las ondas artificiales solo están compuestas por una sola onda fundamental, sin armónicos de ningún tipo. Usaremos ondas sinusoidales, ondas cuadradas y ondas triangulares.

Diferentes tipos de ondas para usos de audio: A) Onda cuadrada, B) Onda triangular, C) Diente de sierra  y D) Onda sinusoidal.
Diferentes tipos de ondas para usos de audio: A) Onda cuadrada, B) Onda triangular, C) Diente de sierra y D) Onda sinusoidal.

El código:

Como HTML5 es una tecnología relativamente nueva, está bien saber si el navegador web que usas actualmente soporta la API de audio. Para ello, es interesante usar el siguiente código para saber si el navegador es compatible:

var context;
window.addEventListener('load', init, false);
function init() {
  try {
    // crear el contexto de audio
    window.AudioContext = window.AudioContext||window.webkitAudioContext;
    context = new AudioContext();
 console.log('Web Audio API si es soportado en este navegador');
  }
  catch(e) {
    console.log('Web Audio API no es soportado en este navegador');
  }
}

Este código no es más que un “escuchador de eventos” que dispara la función init() cuando la página se ha cargado del todo. La función init() está compuesta por un try catch que comprueba que el contexto del Audio se pueda inicializar. Esto solo es un testeo de navegador, más adelante ya analizaré el código.

El código HTML que usaremos será el siguiente:

<DOCTYPE html>
<html lang=”ca”>
<head>
<title>Web Audio API</title>
<meta charset="utf-8">
<meta name="author" content="Sergi Suelves">
<script type="text/javascript" src="js/audio.js"></script>
</head>
<body>
<div id="divMensajes">
</div>
<div id="controls">
<button id='btnReproducir' onclick="reproducirFrecuencia()">Reproducir Frecuencia</button>
<br />
<button id='btnReproducir' onclick="subirOctava()">Subir Octava</button>
<br />
<button id='btnReproducir' onclick="bajarOctava()">Bajar Octava</button>
<br />
<button id='btnDetener' onclick="detenerFrecuencia()">Detener Frecuencia</button>
</div>
<div id="tipos">
<button id='sino' onclick="sine()">Onda sinusoidal</button>
<br />
<button id='square' onclick="square()">Onda cuadrada</button>
<br />
<button id='triangle' onclick="triangle()">Onda triangular</button>
<br />
</div>
<style>
#controls {
margin-right: 40px;
float:left;
}
</style>
</body>
</html>

Este HTML se compone de siete botones. Cada uno creará o modificará un sonido o propiedad del mismo.

  • Reproducir frecuencia: Iniciará el sonido.
  • Subir octava: Subirá una octava el sonido.
  • Bajar Octava: Bajará una octava el sonido.
  • Detener frecuencia: Detendrá el sonido.
  • Onda sinusoidal: El tipo de onda del sonido será una onda sinusoidal.
  • Onda triangular: El tipo de onda del sonido será triangular.
  • Onda cuadrada: El tipo de onda del sonido será cuadrada.

Lo primero que se debe hacer es instanciar las variables de nuestro código. En este caso van a ser dos.

var context = null;
var osc = null;

El contexto servirá para crear un contexto de Audio para que nuestro navegador entienda que va a trabajar con sonido y la variable osc servirá para crear un oscilador. El oscilador se puede entender como un generador de funciones en el mundo real; un aparato que genera tipos de ondas.

Seguidamente, mediante un escuchador de eventos inicializaremos la función init() una vez se ha cargado la página.

//Funcion de inicio
function init() {  
  try {
    // creamos el contexto de audio
    window.AudioContext = window.AudioContext||window.webkitAudioContext;
    context = new AudioContext();
    console.log('Web Audio API es sorportado');
  }
  catch(e) {
    console.log('Web Audio API no es soportado por el explorador.');
  }
}

Dentro del try accedemos al objeto AudioContext del objeto window y lo inicializamos. Si te fijas, verás que hay dos tipos de AudioContext: el window.AudioContext y el window.webkitAudioContext. Esto es útil para poder utilizar esta API en navegadores que usen WebKit como renderizador (Safari, por ejemplo).

El paso siguiente es crear las funciones para cada botón. El primero será el de Reproducir Frecuencia:

//funciones de control de sonido
function reproducirFrecuencia() {
  // Crear Oscilador
  osc = context.createOscillator();
  osc.frequency.value = 261.63;
  osc.connect(context.destination);
  
  //Inicia la reproduccion de la frecuencia
   osc.start(0);
}

Esta función añade a la variable osc un oscilador con el método context.createOscilator() y después añade el valor de 261,63 Hz. al mismo. Así, el oscilador está preparado para reproducir la nota do. Así que solo falta explicar que el metodo osc.start(0): se usa para reproducir el sonido del oscilador.

Las siguiente funciones se encargan de modificar el valor frecuencial de nuestro oscilador. De modo que subiremos o bajaremos octavas de la nota do; si multiplicamos por dos su frecuencia subiremos una octava y si dividimos por dos bajaremos una octava. Así, las funciones quedan de la siguiente manera:

function subirOctava(){
  //subimos una octava
  osc.frequency.value = osc.frequency.value*2; 
}

function bajarOctava(){
  //Bajamos una octava
  osc.frequency.value = osc.frequency.value/2;
}

La siguiente función únicamente detiene la reproducción del sonido. Así que con el método stop(0) nos basta.

function detenerFrecuencia(){
  // Detiene la reproduccion de la frecuencia
  osc.stop(0);
}

Finalmente, basta con añadir las modificaciones del tipo de onda de nuestro oscilador para poder manipular el timbre de nuestro ejemplo. De esta propiedad no he hecho referéncia anteriormente porque por defecto, al crear un oscilador, está dispuesto para reproducir una onda sinusoidal. Así que con la propiedad osc.type podemos modificar con un string el tipo de onda. El código del ejemplo es este:

function triangle(){
     //Onda triangular
     osc.type = 'triangle';
}

function square(){
     //Onda cuadrada
     osc.type = 'square';
}

function sine(){
     //Onda sinusoidal
     osc.type = 'sine';
}

Yo he usado estos tipos de onda pero el oscilador acepta 5 valores: sine, square, triangle sawtooth (onda con diente de sierra) y custom (onda personalizada).

Deja un comentario